feat: headless Chrome fallback for browser web search outside broadcast

browse-search.mjs only connected to the on-screen broadcast Chrome over
CDP, so browser-based Google search worked only during a live broadcast;
plain text turns fell through to the DDG cascade. Add a headless fallback
(system Chrome via channel:'chrome', else Playwright's bundled chromium)
for `search` mode so general conversation can use Google at no API cost.
`youtube` still requires the visible broadcast Chrome.

Detect Google's /sorry bot-detection interstitial structurally by URL and
fail fast so the caller fail-opens to DDG/Brave/Wikipedia instead of
treating the challenge page as empty results.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-22 20:52:54 +09:00
parent da27c5a306
commit 98a1825d01
2 changed files with 73 additions and 11 deletions

View File

@@ -22,7 +22,17 @@ path (evals, text entry) and falls back to the master flag:
- **on-screen Chrome**: `browser_search()` drives 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.
the action is visible on the Go-Live broadcast. When no broadcast Chrome is
reachable on CDP (e.g. a plain text turn with no active broadcast), the helper
falls back to launching its own headless Chrome (system `channel: 'chrome'`,
else Playwright's bundled chromium) so browser-based Google search still works
with no API cost. The `youtube` action never uses the headless fallback (it
only makes sense on the visible broadcast Chrome). Caveat: a freshly-launched
headless session with no logged-in profile can be served Google's
bot-detection interstitial (`/sorry/index`); the helper detects this
structurally by URL and fails fast, so the caller fail-opens to the DDG /
Brave / Wikipedia cascade rather than treating the challenge page as "no
results".
- **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