feat(brain): add Gemini CLI OAuth path for STREAM_BROWSER=false real-time search

Adds a GEMINI_AUTH=oauth (default) sub-mode that shells out to the Gemini CLI
using the user's Google-account login instead of an API key. gemini_cli_search()
runs `gemini -p <query> -o json --skip-trust --approval-mode yolo`, strips
GEMINI_API_KEY/GOOGLE_API_KEY and sets GOOGLE_GENAI_USE_GCA=true so the CLI
selects the account OAuth method and fails fast when no login exists. Bounded by
a 30s timeout and fail-open to the DDG/Brave/Wikipedia cascade on any failure
(CLI missing, login expired, quota 429, timeout). GEMINI_AUTH=apikey keeps the
legacy REST path. Specs and docs/llm_contexts.md updated; behaviour covered by
tests/test_realtime_gemini_cli.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-11 00:53:10 +09:00
parent 702fe8017e
commit b88def6756
8 changed files with 207 additions and 23 deletions

View File

@@ -598,12 +598,17 @@ class WebSearchTool(Tool):
# true -> drive the on-screen Chrome (visible on the broadcast),
# false -> Gemini grounded search. Either falls through to the
# DDG/Brave/Wikipedia cascade below if it yields nothing (fail-open).
from .realtime_search import browser_search, gemini_search
from .realtime_search import browser_search, gemini_search, gemini_cli_search
if getattr(cfg, "stream_browser", True):
routed = browser_search(search_query)
if routed:
debug_log(" 🌐 routed via browser (STREAM_BROWSER=true)", "web")
return ToolExecutionResult(success=True, reply_text=routed)
elif getattr(cfg, "gemini_auth", "oauth") == "oauth":
routed = gemini_cli_search(search_query)
if routed:
debug_log(" 🌐 routed via Gemini CLI (OAuth login)", "web")
return ToolExecutionResult(success=True, reply_text=routed)
elif getattr(cfg, "gemini_api_key", ""):
routed = gemini_search(
search_query,
@@ -611,7 +616,7 @@ class WebSearchTool(Tool):
getattr(cfg, "gemini_model", "gemini-2.0-flash"),
)
if routed:
debug_log(" 🌐 routed via Gemini (STREAM_BROWSER=false)", "web")
debug_log(" 🌐 routed via Gemini API key (REST)", "web")
return ToolExecutionResult(success=True, reply_text=routed)
# Overall wall-clock deadline across the full provider chain.