web_search_context
Web Search Context Manager.
Manages per-channel web-search configuration and provides automatic context injection by generating search queries (via a cheap LLM) and fetching results from the Brave Search API.
Adapted for the v3 multi-platform architecture: channel keys use the
platform:channel_id composite format.
- class web_search_context.WebSearchContextManager(redis_client, default_api_key='', config=None)[source]
Bases:
objectPer-channel automatic web-search context injection.
For every incoming message the manager:
Checks the channel config (enabled by default).
Calls
search_query_generator.generate_search_queries()to decide whether web search is warranted.Runs Brave searches via the shared rate-limiter in
tools.brave_search.Returns XML-formatted results for injection into the LLM context.
- Parameters:
redis_client (aioredis.Redis)
default_api_key (str)
config (Any)
- __init__(redis_client, default_api_key='', config=None)[source]
Store the Redis client, fallback Brave key, and bot config.
Lightweight constructor that just captures its collaborators; no Redis I/O or network calls happen here. The Redis client backs the per-channel config CRUD (keys under
stargazer:v3:web_search:auto_search:), the default API key is the last-resort Brave key when per-user and pooled keys are unavailable, and the config object is threaded through totools.manage_api_keys.get_user_api_key()for encrypted key lookup. Constructed once per inference worker ininference_main.py(asself.web_search).- Parameters:
- Return type:
None
- async set_channel_config(channel_key, enabled=True, max_queries=2, results_per_query=3)[source]
Write (create or overwrite) the auto-search config for a channel.
Persists the per-channel web-search settings so
search_for_message()can later decide whether and how aggressively to search. The values are clamped to safe ranges (max_queriesto 1-5,results_per_queryto 1-10), stamped with anupdated_atUTC timestamp, JSON-encoded, and stored under the Redis keystargazer:v3:web_search:auto_search:<channel_key>with a plainSET(no TTL). Also logs the change. Called from the dashboard RAG config endpoint (web/rag_config_api.py) and the RAG tools (tools/rag.py,tools/cloud_rag.py).- Parameters:
channel_key (
str) – Compositeplatform:channel_idkey identifying the channel.enabled (
bool) – Whether automatic web search is on for this channel.max_queries (
int) – Maximum search queries to generate per message; clamped to the inclusive range 1-5.results_per_query (
int) – Results to request per query; clamped to the inclusive range 1-10.
- Returns:
The persisted config dict, including the clamped values and the
updated_attimestamp.- Return type:
- async get_channel_config(channel_key)[source]
Read the stored auto-search config for a channel, if any.
Fetches and JSON-decodes the value at the Redis key
stargazer:v3:web_search:auto_search:<channel_key>. A missing key means the channel has never been configured, in which case callers treat web search as enabled by default. Used internally bysearch_for_message(),disable_channel(), and externally by the dashboard and RAG tools (web/rag_config_api.py,tools/rag.py,tools/cloud_rag.py); a sibling override exists onrag_system.auto_search.RAGAutoSearchManager.
- async disable_channel(channel_key)[source]
Turn off automatic web search for a channel, preserving its settings.
Unlike
remove_channel_config(), this keeps the channel’smax_queriesandresults_per_queryvalues and only flipsenabledtoFalse, so re-enabling later restores prior tuning. It first reads the current config viaget_channel_config(); if none exists there is nothing to disable. Otherwise it refreshesupdated_atand writes the config back to Redis with a plainSET. Called from the RAG toggle path intools/rag.py.
- async remove_channel_config(channel_key)[source]
Delete a channel’s auto-search config entirely.
Issues a Redis
DELonstargazer:v3:web_search:auto_search:<channel_key>, wiping all stored settings (after which the channel falls back to the enabled-by-default behaviour). Usedisable_channel()instead when the tuning should be kept. Called from the dashboard config endpoint (web/rag_config_api.py) and the RAG tools (tools/rag.py,tools/cloud_rag.py).
- async search_for_message(channel_key, message_content, *, user_id='', redis_client=None, channel_id='')[source]
Run automatic web search for a message and return injectable context.
The manager’s primary entry point: given an incoming message it decides whether to search and, if so, returns a block of supplementary context to splice into the LLM message list. The flow is to load the channel config (bailing out early if web search is explicitly disabled), ask the cheap query LLM via
search_query_generator.generate_search_queries()for up tomax_queriessearch strings, resolve a Brave key through_resolve_key(), fan the queries out in parallel over the nested_search_onehelper (which callstools.brave_search.search_with_key()under the shared Brave rate-limiter), and hand the collected results to_format_xml(). Query-generation failures and the no-query and no-result cases all short-circuit toNone; only logging and outbound HTTP search calls are side effects (no Redis writes or KG access). Invoked from the message pipeline inmessage_processor/generate_and_send.py.- Parameters:
channel_key (str) – Composite
platform:channel_idkey used to load the channel config.message_content (str) – The user message text driving query generation.
user_id (str) – User id used when resolving a per-user Brave API key.
redis_client (aioredis.Redis | None) – Optional Redis client to use for key resolution; falls back to the instance client when omitted.
channel_id (str) – Channel id used when resolving a channel-pooled key.
- Returns:
XML-formatted web-search context ready for LLM injection, or
Nonewhen search is disabled, no queries are generated, or every search returns nothing.- Return type:
Optional[str]