feat(brain): route real-time search by live broadcast state

STREAM_BROWSER becomes the broadcast *capability* master flag; the live
screen-share state (new ToolContext.broadcasting, passed per turn by the bot)
decides the backend:
  - master off            -> broadcast disabled, always Gemini
  - master on + live on    -> on-screen Chrome (visible on the stream)
  - master on + live off   -> Gemini
context.broadcasting is None outside the voice path (evals, text entry, older
bot) and falls back to the master flag, so current behaviour is unchanged.
This is the brain-side foundation; bot-side wiring (bridge passes broadcast
state, auto-broadcast on voice join, voice on/off toggle) follows.

Specs + docs/llm_contexts.md updated. Covered by
tests/test_web_search_broadcast_routing.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-11 01:17:50 +09:00
parent f54e2a46ae
commit 5d45d1d3bd
6 changed files with 144 additions and 22 deletions

View File

@@ -22,6 +22,7 @@ class ToolContext:
max_retries: int,
user_print: Callable[[str], None],
language: Optional[str] = None,
broadcasting: Optional[bool] = None,
):
self.db = db
self.cfg = cfg
@@ -36,6 +37,13 @@ class ToolContext:
# treat absence as "no signal" and fall back to their own default
# rather than assuming English.
self.language = language
# Live broadcast (screen-share / Go-Live) state for THIS turn, passed in
# by the bot per request. Controls real-time search routing when the
# master flag ``cfg.stream_browser`` is on: broadcasting -> on-screen
# Chrome search (visible on the stream), not broadcasting -> Gemini.
# ``None`` means "no signal" (evals, text entry, older bot): callers
# fall back to the master flag so behaviour is unchanged.
self.broadcasting = broadcasting
class Tool(ABC):