- search(..., allowed_hosts=[...]) extends (never replaces) the 15-domain
code list for that call only; scope=general + allowed_hosts raises,
empty/illegal values raise before any HTTP, dot-boundary matching,
extension values never in error strings or attempted entries.
- Native-filter parity: Tavily/Exa get the effective list, Perplexity
skips its native filter past its 20-domain cap (post-filter stays
authoritative), Brave/SearXNG/DuckDuckGo rely on post-filtering.
- MCP web_search gains allowed_hosts passthrough (only when supplied,
so older search_fn fakes keep working).
- JS-heavy evaluation documented in docs/web-search-mcp.md, mock-first:
direct fetch is shell-only by construction; provider extract can
supply rendered text in mock only; live SearXNG in this VM env
failed (remote closed connection) and paid-backend live effects are
unvalidated blockers, not claimed.
- Tests: test_code_search_ext (9) + test_js_heavy_extract (5 + 1 live
skipped); existing websearch/code-search suites still green.
(cherry picked from commit 9c26bbe848438e1f34bcb000700aeb4c284f4f23)
- search(..., scope=code) restricts to 15 programming domains
(official docs, GitHub, registries, Stack Overflow, CVE/NVD):
native include_domains/search_domain_filter where supported
(Tavily, Exa, Perplexity), post-filtering for all providers
(Brave, SearXNG, DuckDuckGo have no native filter).
- web_fetch now uses fetch_best: Tavily extract, then Exa
contents, then direct fetch; both-fail errors name both
failures, direct-fetch 403 under the egress whitelist is
fail-closed, not bypassed. Default general scope and direct
fetch_url behaviour unchanged.
- MCP web_search gains scope enum (general/code); docs updated.
- Tests all mock HTTP, no real keys.
web_search auto chain Perplexity/Exa/Tavily/Brave/SearXNG/DuckDuckGo
with pinned-provider no-fallback, web_fetch with head+tail truncation,
codex-home seeding helper (idempotent, never writes keys).
Tests: cloud/tests/test_websearch_mcp.py 12/12 (mocked HTTP).
Not wired into worker, not deployed, paid backends not live-tested.