Skip to content

feat(tool): add Brave Search as a selectable web_search provider (#294) - #324

Merged
franciscojavierarceo merged 3 commits into
vllm-project:mainfrom
Zheng-Lu:feat/294-brave-search-provider
Sep 17, 2026
Merged

franciscojavierarceo merged 3 commits into
vllm-project:mainfrom
Zheng-Lu:feat/294-brave-search-provider

Conversation

@Zheng-Lu

@Zheng-Lu Zheng-Lu commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #294 (Phase 2 of #291).

Implements the Brave Search API provider behind the typed WebSearchProvider contract established in Phase 1 (#293), making search backends cleanly selectable via AGENTIC_WEB_SEARCH_PROVIDER (environment) or [web_search].provider (configuration file), while keeping default You.com behavior and recorded cassettes byte-identical.

Key Implementation Details

  1. Provider Implementation (crates/agentic-server-core/src/tool/web_search/brave.rs):

    • Hits GET {base_url}/res/v1/web/search with result_filter=web,news and X-Subscription-Token.
    • Passes text_decorations=false so the LLM receives clean, unadorned snippet text without raw <strong> HTML tags.
    • Strictly respects transport rules: avoids Accept-Encoding: gzip (core reqwest lacks gzip decompression).
    • Maps freshness accurately: supports both short codes (pd, pw, pm, py) AND date ranges (YYYY-MM-DDtoYYYY-MM-DD).
    • Clamps count to the Brave 20-result limit with tracing::debug!.
    • Post-filters domain allowlists/blocklists client-side using label-boundary suffix matching.
    • Non-retrying 401/403 (names BRAVE_API_KEY without secret leaks) and 429 (surfaces Retry-After or X-RateLimit-Reset).
  2. Concurrency & Rate Limiting:

  3. Wire Compatibility & RFC [RFC] Pluggable Web Search Providers and Typed Result Normalization #291 Q5 Resolution:

    • Resolves Q5: surfaces "provider": "brave" in metadata[].
    • Uses #[serde(skip_serializing_if = "WebSearchProviderKind::is_you")] to ensure existing You.com output and recorded Messages cassettes remain 100% byte-identical.
  4. Zero Extra Dependencies & Non-Breaking API:

    • Zero added external crates (no strum dependency added; uses standard library FromStr).
    • Keeps WebSearchProviderConfig::new backward-compatible; introduces fluent .with_provider(...) / .with_max_concurrent_queries(...) builders and WebSearchHandler::from_config(...).
  5. Testing & Documentation:

    • Dedicated integration test suite: crates/agentic-server-core/tests/web_search_brave_test.rs covering 200 OK (web+news), empty results, domain filtering, 401/403, 429 with Retry-After/X-RateLimit-Reset, batched query serialization, and concurrency overrides.
    • Fully updated README.md, docs/deploying/README.md, docs/deploying/kubernetes.md, CHANGELOG.md, and ARCHITECTURE.md.

Review follow-up: keep provider credentials unpinned in generated configs so provider switches select the matching default API-key variable, preserve HTTP-date Retry-After values verbatim, and split shared provider types/config resolution into focused modules to pass the production file-size checks.

Test Plan

Validation after the review patch:

  • After merging fix: preserve and verify image input through Responses #263 and fix(mcp): follow tools/list pagination cursors #311, the integrated tree exactly matches the combined checkout with 1,532 passing workspace tests (9 ignored) and passing launcher contract tests. All pre-commit hooks passed again after baseline reconciliation.

  • 60 core tests matching web_search passed.

  • 10 Brave integration tests and 25 common/You integration tests passed.

  • 6 configuration-resolution tests passed.

  • Provider-switch and HTTP-date Retry-After regressions failed before their fixes and passed afterward.

  • cargo clippy --all-targets -- -D warnings passed.

  • pre-commit run --all-files passed, including formatting and production file-size checks.

New Brave coverage uses local Axum HTTP mocks. No live Brave provider call or new Brave cassette was recorded during review.

…m-project#294)

Phase 2 of vllm-project#291. Add `tool/web_search/brave.rs` behind the typed provider
contract from Phase 1 and make the backend selectable through
`AGENTIC_WEB_SEARCH_PROVIDER` / `[web_search] provider`.

- Brave requests use `GET /res/v1/web/search` with `result_filter=web,news`
  and `X-Subscription-Token`; `Accept-Encoding` is never sent because the
  core reqwest build has no gzip support.
- Adapt the shared tool contract: apply `allowed_domains` / `blocked_domains`
  client-side through `DomainFilter`, clamp `count` to 20, render `freshness`
  as `pd`/`pw`/`pm`/`py`, map `language` to `search_lang`, and ignore the
  You.com-specific livecrawl arguments.
- Fail 401/403 naming `BRAVE_API_KEY` without echoing the body; fail 429
  without retrying and surface `Retry-After` (or `X-RateLimit-Reset`).
- Add `[web_search] max_concurrent_queries` and
  `AGENTIC_WEB_SEARCH_MAX_CONCURRENT_QUERIES`; Brave defaults to one
  in-flight request for its free-plan rate limit, You.com keeps inheriting
  `max_concurrent_gateway_calls`.
- Resolve the endpoint as `AGENTIC_WEB_SEARCH_BASE_URL`, then
  `YOU_API_BASE_URL` (You.com only), then the file, then the provider
  default; generated config files record the selected provider.
- Serialize `metadata[].provider` for non-default providers only, so
  You.com output and the recorded Messages cassettes stay byte-identical.
- Make `WebSearchProviderConfig` non-exhaustive with `with_provider` and
  `with_max_concurrent_queries` builders so later providers are additive.

Claude-Session: https://claude.ai/code/session_01EsbCF1Smauv41qnpnqYvfz
Signed-off-by: Zheng Lu <Lz429671594@gmail.com>
Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>

@franciscojavierarceo franciscojavierarceo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

patched provider switching in generated configs and HTTP-date Retry-After handling, with regression tests. the provider/configuration tests, Clippy, and pre-commit checks pass locally. Brave HTTP behavior is covered by mocks; no live Brave run was performed.

Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>

@franciscojavierarceo franciscojavierarceo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reconciled the baseline after #263 and #311 merged. the resulting Git tree is identical to the combined checkout that passed all 1,532 workspace tests and launcher tests; all pre-commit hooks also pass on this head.

@franciscojavierarceo
franciscojavierarceo merged commit 137783e into vllm-project:main Sep 17, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add Brave Search as a selectable web_search provider

2 participants