feat: reuse a signed-in Chrome profile for browser web search

Add CHROME_USER_DATA_DIR so the browser search fallback can open Chrome
against a dedicated, Google-signed-in profile instead of a fresh anonymous
session. A returning signed-in profile is what actually avoids Google's
/sorry bot-detection page, so this is the reliable way to get browser
Google search in plain text turns. Fallback order is now CDP (broadcast
Chrome) -> persistent profile (when configured) -> ephemeral headless,
all still fail-open to the DDG/Brave/Wikipedia cascade.

Document the profile in .env.example and web_search.spec.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-22 20:57:25 +09:00
parent 98a1825d01
commit 597207dd33
3 changed files with 86 additions and 45 deletions

View File

@@ -24,15 +24,24 @@ path (evals, text entry) and falls back to the master flag:
`bot/scripts/stream-test/browse-search.mjs`) to Google-search the query, so
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".
falls back, for `search` only, to launching its own Chrome so browser-based
Google search still works with no API cost. Fallback order:
- **CDP** (the broadcast Chrome) — preferred, visible on the stream.
- **Persistent profile** when `CHROME_USER_DATA_DIR` is set — Chrome opened
against that profile dir (system `channel: 'chrome'`, else bundled chromium).
Logging that dedicated profile into Google once lets Google treat later
searches as a returning signed-in user, which is what avoids the
bot-detection interstitial. This is the reliable way to get browser Google
search in plain text turns.
- **Ephemeral headless** otherwise — a fresh anonymous session; works only
where Google does not challenge it (e.g. a non-flagged residential IP).
The `youtube` action never uses the fallback (it only makes sense on the
visible broadcast Chrome). Caveat: an anonymous (not-signed-in) session 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