background_agents.channel_summarizer module

Channel summarizer — periodically summarises recent channel activity.

Scans Redis for the 10 most-recently-used channel_msgs:* sorted sets, fetches recent messages, generates a per-channel summary via an LLM call (gemini-3-flash-preview), and stores the result in Redis for retrieval by channel_summary_tools and cross_channel_query.

async background_agents.channel_summarizer.summarise_channel(channel_id, platform, redis, openrouter, messages_limit=300)[source]

Summarise one channel’s recent messages and cache the result in Redis.

Builds a transcript from the channel’s recent history, asks the LLM for a structured JSON summary (overview, key topics, active users, notable discussions, mood), enriches it with metadata, and stores it under a per-channel key for later retrieval by the summary tools and cross-channel query. This is the per-channel unit of work behind the broader summarisation pass.

Loads messages via _fetch_channel_messages() (reading the channel_msgs:{platform}:{channel_id} ZSET in Redis), renders them into the canonical bot transcript format, truncates to roughly 120k characters, and calls openrouter.chat with _CHANNEL_SYSTEM_PROMPT and no tools. The reply is parsed by _parse_json_response() (falling back to raw text on parse failure), stamped with channel_id, platform, message_count and generated_at, and written to {_SUMMARY_KEY_PREFIX}{channel_id} with a 7-day TTL. It also fires observability.publish_debug_event as a background task on both success and LLM failure. Called by summarise_all_active() (in batches and on retry); no other callers.

Parameters:
  • channel_id (str) – Platform-specific channel identifier to summarise.

  • platform (str) – Platform the channel belongs to (e.g. "discord").

  • redis (Any) – Async Redis client used to read messages and store the summary.

  • openrouter (Any) – openrouter_client.OpenRouterClient (flash model, no tools) used for the chat completion.

  • messages_limit (int) – Maximum recent messages to pull into the transcript; defaults to _MESSAGES_PER_CHANNEL.

Returns:

The stored summary dict, or None when the channel has no usable messages or the LLM call fails.

Return type:

dict | None

async background_agents.channel_summarizer.summarise_all_active(redis, max_channels=10)[source]

Summarise the most recently active channels and build a meta-summary.

The top-level orchestration entry point: it discovers the busiest channels, summarises them concurrently in small batches with a one-shot retry, then rolls the per-channel overviews up into a single cross-channel meta-summary cached in Redis. This keeps both the per-channel and server-wide summaries used in retrieval and context assembly fresh.

Constructs its own dedicated openrouter_client.OpenRouterClient on _SUMMARY_MODEL (gemini-3-flash-preview, no tools) from Config.load(), finds channels via message_cache.get_active_channels() (which scans the channel_msgs:* ZSETs), and fans each out to summarise_channel() in batches of four under asyncio.gather(), retrying any that raised once. When at least one channel succeeds it sends a combined overview through the same client with _META_SYSTEM_PROMPT and writes the parsed meta-summary to _META_KEY with a 7-day TTL. Closes the client in a finally. Called by the inference/agents service’s channel_summarization task in background_tasks.py (the only caller), which logs the processed count.

Parameters:
  • redis (Any) – Async Redis client for channel discovery and storage.

  • max_channels (int) – Cap on how many active channels to process; defaults to _MAX_CHANNELS.

Returns:

A result dict with channels_processed (int) and summaries (a mapping of channel id to a truncated overview string).

Return type:

dict[str, Any]