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

@@ -14,11 +14,21 @@ Before the DuckDuckGo cascade, `run()` routes by the env flag `STREAM_BROWSER`
- **true** (default): `browser_search()` drives the on-screen Chrome (Node CDP
helper `bot/scripts/stream-test/browse-search.mjs`) to Google-search the
query, so the action is visible on the Go-Live broadcast.
- **false**: `gemini_search()` answers via the Gemini API (`google_search`
grounding), keyed by `GEMINI_API_KEY` / `GEMINI_MODEL`.
- **false**: Gemini answers, with the sub-mode chosen by `cfg.gemini_auth`
(env `GEMINI_AUTH`, default `oauth`):
- `oauth` (default): `gemini_cli_search()` shells out to the Gemini CLI
(`gemini -p <query> -o json --skip-trust --approval-mode yolo`) using the
user's Google-account login and the CLI's built-in web-search grounding.
`GEMINI_API_KEY` / `GOOGLE_API_KEY` are stripped from the child env so the
CLI uses the account login, not API-key auth. Requires a one-time
`gemini` "Sign in with Google"; the CLI binary is resolved from `PATH` or
`~/.local/bin/gemini`.
- `apikey`: legacy `gemini_search()` REST path (`google_search` grounding),
keyed by `GEMINI_API_KEY` / `GEMINI_MODEL`.
Both return the same fenced `UNTRUSTED WEB EXTRACT` envelope and are fail-open:
if the route yields nothing (Chrome down, no/invalid key, error) the tool falls
All three return the same fenced `UNTRUSTED WEB EXTRACT` envelope and are
fail-open: if the route yields nothing (Chrome down, CLI not installed, login
expired, quota exhaustion, timeout, no/invalid key, error) the tool falls
through to the normal DDG / Brave / Wikipedia cascade below.
### Pipeline