How thysrael/horizon works
Purpose and Entry Points
Horizon is a Python CLI system that turns configured multi-source news into ranked, AI-enriched daily Markdown briefings, then publishes or delivers them. The primary runtime entry point is src/main.py, with CLI parsing in src/_cli.py; scheduled execution is supported by scripts/daily-run.sh. An interactive setup path produces user configuration via src/setup/wizard.py.
Configuration, Profiles, and Domain Model
Runtime behavior is driven by a data directory: configuration supplies AI provider/model, sources, processing settings, digest limits, and delivery options; persistent output/state lives under that directory. Example presets reside in data/config.example.json and data/presets.json. Profile definitions partition editorial behavior—matching, analysis, and enrichment prompts—for example profiles/tech-news/profile.json, profiles/tech-news/analysis.md, and profiles/tech-news/enrichment.md. Shared domain objects and pipeline contracts are centered in src/models.py.
Pipeline Orchestration
src/orchestrator.py coordinates the end-to-end control flow: load configuration/profiles, fetch recent source items concurrently, deduplicate, route/filter by profile and score, optionally balance categories, enrich selected items, summarize/localize, persist the briefing, and invoke outputs. src/processing/profiles.py resolves configured or AI-selected profiles; src/processing/content.py handles selection-oriented processing. This is the primary boundary between source acquisition, AI processing, and delivery.
Source Acquisition and Content Extraction
Scrapers implement a common source boundary in src/scrapers/base.py; concrete integrations include src/scrapers/rss.py, src/scrapers/hackernews.py, src/scrapers/reddit.py, src/scrapers/github.py, src/scrapers/telegram.py, src/scrapers/twitter.py, and src/scrapers/openbb.py. They call external feeds/APIs/services and may collect community discussions. RSS/article-body extraction is decoupled behind the extractor registry: src/extractors/registry.py, src/extractors/base.py, and optional src/extractors/trafilatura.py. URL validation/security is isolated in src/url_security.py.
AI Processing Layer
AI provider access is abstracted by src/ai/client.py, while editorial stages are separated into src/ai/classifier.py (profile/category matching and scoring), src/ai/analyzer.py, src/ai/enricher.py, and src/ai/summarizer.py. Prompt construction is versioned as code in src/ai/prompting/analysis.py, src/ai/prompting/classification.py, and src/ai/prompting/enrichment.py. Supported deployments include hosted model providers and local Ollama-compatible use, selected from configuration and environment-provided credentials.
Storage and Outputs
src/storage/manager.py owns local persistence of generated summaries and related state. The main artifact is Markdown for local use and GitHub Pages publication into docs/; the site assets/configuration are in docs/_config.yml and docs/assets/. Delivery adapters are separate side-effect boundaries: SMTP/IMAP subscription email in src/services/email.py, and chat/custom HTTP notifications in src/services/webhook.py and src/services/webhook_cli.py.
MCP and Deployment Boundaries
The optional MCP server exposes pipeline capabilities to compatible AI clients rather than requiring CLI execution: src/mcp/server.py, src/mcp/service.py, and src/mcp/horizon_adapter.py; src/mcp/run_store.py tracks MCP run state. Local execution uses Python/uv; containerized execution is defined by Dockerfile and docker-compose.yml, with optional dependency extras for extraction, OpenBB, and Twitter/Playwright. GitHub Pages documentation deployment is represented by .github/workflows/deploy-docs.yml.
Main entry points: orchestrator.py Pipeline orchestrator · main.py CLI runtime · rss.py Source integrations · content.py Profile resolution & selection
Components 20
Entry points
- CLI runtime
src/main.py - CLI parser
src/_cli.py - Daily scheduler
scripts/daily-run.sh - Setup wizard · Creates user configuration in the data directory.
src/setup/wizard.py
Briefing pipeline
- Configuration & presets · Selects sources, models, processing, limits, and delivery.
data/config.example.json - Editorial profiles · Defines matching, analysis, and enrichment behavior.
profiles/tech-news/profile.json - Pipeline orchestrator · Runs acquisition, selection, enrichment, persistence, and outputs.
src/orchestrator.py - Domain contracts
src/models.py - Profile resolution & selection · Resolves profiles, filters, scores, deduplicates, and balances items.
src/processing/content.py
Content acquisition
- Scraper boundary · Common interface for configured news sources.
src/scrapers/base.py - Source integrations · Fetches feeds, Hacker News, Reddit, GitHub, Telegram, Twitter, and OpenBB data.
src/scrapers/rss.py - Article extraction · Decouples article-body extraction from source collection.
src/extractors/registry.py - URL security
src/url_security.py
AI editorial layer
- AI provider client · Uses configured hosted or Ollama-compatible models.
src/ai/client.py - Classification & scoring · Matches profiles/categories and ranks items.
src/ai/classifier.py - Analysis, enrichment & summary · Analyzes, enriches, summarizes, and localizes selected content.
src/ai/analyzer.py
Storage & delivery
- Briefing storage · Persists Markdown briefings and related state.
src/storage/manager.py - GitHub Pages briefing · Publishes briefing artifacts under docs/.
docs/_config.yml - Email & webhook delivery · Sends subscriptions and chat/custom HTTP notifications.
src/services/email.py
MCP interface
- MCP server · Exposes pipeline capabilities and tracks MCP runs.
src/mcp/server.py
Connections 20
- Daily scheduler → CLI runtime: runs
- CLI runtime → CLI parser: parses commands
- Setup wizard → Configuration & presets: creates
- CLI runtime → Pipeline orchestrator: starts briefing run
- Configuration & presets → Pipeline orchestrator: configures
- Editorial profiles → Profile resolution & selection: defines editorial rules
- Domain contracts → Pipeline orchestrator: pipeline contracts
- Pipeline orchestrator → Scraper boundary: fetches recent items
- Scraper boundary → Source integrations: implemented by
- Source integrations → URL security: validates URLs
- Source integrations → Article extraction: extracts article bodies
- Pipeline orchestrator → Profile resolution & selection: deduplicates and selects
- Profile resolution & selection → Classification & scoring: classifies and scores
- Classification & scoring → AI provider client: model calls
- Pipeline orchestrator → Analysis, enrichment & summary: enriches and summarizes
- Analysis, enrichment & summary → AI provider client: model calls
- Pipeline orchestrator → Briefing storage: persists briefing
- Briefing storage → GitHub Pages briefing: publishes Markdown
- Pipeline orchestrator → Email & webhook delivery: delivers briefing
- MCP server → Pipeline orchestrator: invokes pipeline