fix(web-search): allow keyless Brave as a server-side default#642
fix(web-search): allow keyless Brave as a server-side default#642ly-wang19 wants to merge 1 commit into
Conversation
0a5eef1 to
70ebbe4
Compare
Brave Search is `requiresApiKey: false` and already falls back to scraping its public results page when no key is set (`searchWithBrave`). But the server-side wiring never let it activate without a key: - `loadEnvSection` for web search was not given `keylessProviders`, so Brave could only be configured via `BRAVE_API_KEY`, defeating keyless mode. - `resolveServerWebSearchProviderId` only auto-selected providers with an `apiKey`, so keyless Brave was never chosen. Net effect: in the autonomous classroom-generation flow, `resolveClassroomWebSearchConfig` returned `undefined` and web search was silently disabled for operators who wanted free, keyless Brave. This mirrors the existing keyless handling for Ollama/Lemonade: set `BRAVE_BASE_URL` (e.g. https://search.brave.com) to enable keyless Brave, which then becomes a valid server default (after any keyed providers). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wyuc
left a comment
There was a problem hiding this comment.
LGTM on the logic — keyless Brave mirrors the Ollama/Lemonade pattern, keyed providers still win in resolveServerWebSearchProviderId, and the tests cover both cases. Confirmed it stays opt-in: webSearch.brave is only set when BRAVE_BASE_URL is configured, and the classroom flow is still gated by enableWebSearch (off by default), so no silent scraping.
Before it can land:
- Branch conflicts with
main— please rebase. - Keyless mode scrapes Brave's public page; please confirm you verified it returns results end-to-end.
70ebbe4 to
ec7b3c3
Compare
|
Thanks @wyuc — both points addressed: 1. Rebase ✅ — rebased onto 2. Verify keyless returns results end-to-end — I did, and it turned up a real problem: it currently returns 0 results. A live scrape of Fixed in #688 (accept So this PR should land after / together with #688 — otherwise it enables a keyless provider that returns nothing. One caveat worth a note: keyless scraping is best-effort — rapid repeat requests get rate-limited/challenged by Brave (some responses come back empty). The keyed Brave API path is unaffected. Happy to add a short "best-effort, keyed recommended" note to the docs/env example if you want it in this PR. |
|
Heads-up on a merge-order interaction with #589 (SearXNG provider), which touches the same two spots in
No action needed on this PR — flagging so the rebase burden lands on #589, not here. Once this merges I'll rebase #589 to: union the keyless set, and follow this PR's pattern ( |
|
Second-pass review after #688 landed — end-to-end confirmed working; three findings before merge First, verification: on current Three findings from a second review pass, all verified against the code: 🟠 P2 — Setting Once the operator sets Two ways to resolve — your pick:
🟡 P3 — The preference check requires a truthy 🟡 P3 — New tests can leak host env: A dev/CI host with All three are small. Once they're addressed (P2 can be consciously resolved as doc-only if you prefer), this is good to merge — and #589 will follow this PR's pattern per the earlier thread. |
Summary
Brave Search is
requiresApiKey: falseandsearchWithBravealready scrapes Brave's public results page when no key is set — but the server-side wiring never let keyless Brave activate or be selected, so in the autonomous classroom-generation flowresolveClassroomWebSearchConfigreturnedundefinedand web search was silently disabled for operators who wanted free, keyless Brave.This mirrors the existing keyless handling for Ollama/Lemonade: set
BRAVE_BASE_URL(e.g.https://search.brave.com) to enable keyless Brave, which then becomes a valid server default (after any keyed providers).Related Issues
Closes #641
Changes
lib/server/provider-config.ts: passkeylessProviders: new Set(['brave'])to the web-searchloadEnvSection(soBRAVE_BASE_URLalone activates Brave), and add Brave to theresolveServerWebSearchProviderIdfallback chain (after keyed providers)..env.example: documentBRAVE_BASE_URLfor keyless Brave.tests/server/provider-config.test.ts: tests that keyless Brave is selected viaBRAVE_BASE_URL, and that a keyed provider still takes priority.Type of Change
Verification
Steps to reproduce / test
BRAVE_BASE_URL=https://search.brave.com, the server now resolvesbraveand web search works (previously:undefined, disabled).pnpm vitest run tests/server/provider-config.test.ts→ 31 passed (2 new).What you personally verified
BRAVE_BASE_URLis explicitly set; keyed-provider resolution is unchanged.Evidence
pnpm check✓,pnpm lint✓,npx tsc --noEmit✓,vitest31/31 ✓)Checklist
.env.example)🤖 AI-assisted PR (Claude). Self-reviewed before submission.