# Telegram channels/chats to monitor channels: - id: "@channelname" name: "Example Channel" # group: Jobs # optional — bind to a digest_groups entry (or "Other") # prompt_extra: "" # optional — append extra instructions to this channel's AI prompt # lookback_hours: null # optional — override global lookback_hours for this channel # filters: null # optional — null=use global filters, []=no filters, list=override # Add your channels here # Format for public channels: "@channelname" (string with quotes) # Format for private channels/groups: -1001234567890 (integer, NO quotes!) # # IMPORTANT: Get the correct channel ID using @RawDataBot # - Forward a message from the channel to @RawDataBot # - Copy the complete chat ID (should start with -100) # # ✅ Correct: id: -1001234567890 (integer with -100 prefix, no quotes) # ❌ Wrong: id: "-1001234567890" (has quotes) # ❌ Wrong: id: -1234567890 (missing -100 prefix) # Application settings settings: # Scheduling schedule_time: "08:00" # UTC time for daily digest timezone: "UTC" lookback_hours: 24 # Message collection window # AI Provider: "openai", "ollama", or "anthropic" # Required env vars per provider: # openai -> OPENAI_API_KEY in .env # anthropic -> ANTHROPIC_API_KEY in .env # ollama -> no API key needed ai_provider: "openai" # AI Model (provider-specific) # OpenAI: "gpt-6-luna", "gpt-6-sol", "gpt-6-astra", "gpt-5-nano", "gpt-4o-mini", etc. # Ollama: "llama3", "mistral", "gemma2", etc. # Anthropic: "claude-sonnet-4-5-20250929", etc. ai_model: "gpt-5-nano" # Legacy OpenAI settings (used as fallback if ai_model not set) openai_model: "gpt-5-nano" openai_temperature: 1.0 max_tokens_per_summary: 1500 # Ollama settings (only used when ai_provider is "ollama") ollama_base_url: "http://localhost:11434" # Digest mode: "channel" (default) groups by channel, "digest" groups by topic digest_mode: "channel" # Deduplicate cross-channel topics: when true, the AI keeps only the most informative # bullet point when multiple channels cover the same event (sources are merged). # Only effective in digest_mode: "digest". # dedup_topics: false # Topic groups for digest mode (only used when digest_mode is "digest") # An implicit "Other" group catches anything that doesn't match defined groups. # digest_groups: # - name: "Events" # description: "Conferences, meetups, releases, launches, announcements" # prompt_extra: "" # optional — append extra instructions to all channels in this group # - name: "News" # description: "Politics, economy, world affairs, breaking news" # - name: "Sport" # description: "Sports results, transfers, tournaments, matches" # Filter chain — drop messages before they reach storage and the AI # Runs after collection; filtered messages are never stored or summarized. # Built-in filters: KeywordFilter, RegexFilter, MinLengthFilter # filters: # - class_path: src.extensions.filters.KeywordFilter # config: # include: ["job", "hiring", "remote"] # exclude: ["nsfw"] # - class_path: src.extensions.filters.MinLengthFilter # config: # min_chars: 30 # Output output_language: "Russian" # Language for AI summaries (e.g., "English", "Russian", "Spanish") use_emojis: true include_statistics: true # Telegram Bot target_user_id: 0 # Your Telegram user ID (`main.py init` fills it; or get from @userinfobot) auto_cleanup_old_digests: true # Automatically delete previous digest messages # Safety limits max_messages_per_channel: 500 max_prompt_chars: 8000 # Max characters of message content fed to AI per channel. # Keeps the most recent messages that fit. Increase for models with # large context windows; decrease if you hit "empty content + finish_reason=length". # # How to calculate: # 1. Find your model's context window (total tokens for input + output): # - OpenAI: https://platform.openai.com/docs/models # - Anthropic: https://docs.anthropic.com/en/docs/about-claude/models # - Ollama: check model card on https://ollama.com/library # 2. Subtract max output tokens (e.g. max_tokens_per_summary * 2 as buffer) # 3. Subtract ~2000 tokens for system prompt and formatting # 4. Multiply remaining tokens by chars-per-token ratio: # - English text: ~4 chars/token # - Russian/Cyrillic text: ~2-3 chars/token # - Mixed/CJK text: ~1.5-2 chars/token # # Example for gpt-4o-mini (128K context, 16K max output): # (128000 - 16000 - 2000) * 2.5 = 275,000 chars (aggressive) # Safe recommendation: 50000 (conservative for Russian content) # # Example for claude-sonnet (200K context, 8K max output): # (200000 - 8000 - 2000) * 2.5 = 475,000 chars (aggressive) # Safe recommendation: 100000 # # Example for ollama llama3-8b (8K context, 2K max output): # (8000 - 2000 - 2000) * 2.5 = 10,000 chars # Safe recommendation: 8000 api_timeout: 30 # Ollama may need 120-300s for local models (enforced minimum: 120s) # Prompt customization — top-level block (sibling of settings:, not nested inside it) # base_template: path to the system prompt template file ({language} is substituted at runtime) # composer: dotted path to a custom PromptComposer class; empty = built-in DefaultComposer # prompts: # base_template: src/prompts/base_summary.txt # composer: "" # Storage — persist raw messages for history / external LLM workflows # Note: storage is append-only; overlapping lookback windows produce duplicate rows. # storage: # enabled: false # backend: sqlite # "sqlite" (default, no extra setup) or "postgres" # path: data/messages.db # sqlite only — relative to project root; mount as volume in Docker # url: "" # postgres: postgresql://user:pass@host:5432/db # MCP server — expose digests to MCP clients (Claude Code, etc.) over HTTP # Runs inside the Telebrief process; tools: get_digest(hours), get_last_digest() # Connect with: claude mcp add --transport http telebrief http://127.0.0.1:8765/mcp # WARNING: there is no authentication. Keep host on loopback, or firewall the port. # In Docker, publish it as "127.0.0.1:8765:8765" rather than binding 0.0.0.0 openly. # mcp: # enabled: false # host: "127.0.0.1" # port: 8765 # path: "/mcp"