vllm-project / vllm-project/agentic-api
feat: Add SearXNG as a selectable web_search provider
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 289
- Forks
- 74
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 93
Description
Problem statement / motivation
Part of #291
Status: Ready for implementation (builds on typed provider contract established in #293 and #294)
Scope: SearXNG provider integration, configuration plumbing, and tests
With You.com (commercial cloud) and Brave Search (free-tier cloud) in place, the gateway still lacks a fully self-hosted, on-premise, privacy-respecting search backend.
SearXNG is the open-source industry standard for self-hosted metasearch:
- Zero data leakage / On-Premise compliance: Ideal for enterprise and air-gapped deployments where user prompts and search queries must never leave the local network.
- No API key required: Connects directly to an internal or self-hosted SearXNG container instance.
- Metasearch aggregation: Capable of aggregating results across dozens of engines (Google, Bing, DuckDuckGo, Wikipedia) in a single normalized query.
- Differences from You.com / Brave that must be adapted: endpoint requires mandatory base URL (no single public endpoint), queries use
format=json, category selection maps to news/web, and domain filtering is post-filtered client-side.
Proposed solution
A. Provider Implementation (tool/web_search/searxng.rs)
- Endpoint:
GET {base_url}/search?q={query}&format=json&categories={categories}. - Authentication: Optional. By default SearXNG requires no auth; optionally supports Bearer token or basic auth if behind a proxy via
SEARXNG_API_KEY. - Deserialization: Minimal forward-compatible structs with
#[serde(default)]matching SearXNG's{ "query": "...", "results": [ ... ] }JSON envelope. - Transport Rule: Ensure
Accept: application/jsonis sent; preserve gzip exclusion rule (corereqwestlacks gzip).
B. Input Adaptation Policy Matrix
| Parameter / Input | SearXNG Behavior | Gateway Adaptation Policy |
|---|---|---|
allowed_domains / blocked_domains |
Some engines support site:, but behavior across aggregated engines is inconsistent |
Post-filter results client-side by host suffix on label boundary using DomainFilter. |
count |
pageno pagination; default returns ~10–20 results per section |
Bound to SearXNG capabilities; clamp requested count with tracing::debug!. |
freshness |
Accepts time_range=day/week/month/year |
Map Freshness::Day -> "day", Week -> "week", Month -> "month", Year -> "year". Date ranges can be client-side filtered or best-effort mapped. |
| News | Dedicated category: categories=general,news |
Include news in query via categories=general,news parameter. |
language |
language query parameter (e.g. en-US, all) |
Mapped to SearXNG language parameter. |
You.com specifics (livecrawl, etc.) |
Not supported | Ignored with tracing::debug!. |
C. Concurrency & Rate Limiting
- Concurrency Ceiling: Operator-governed. Inherits
max_concurrent_gateway_callsby default, or configurable viaAGENTIC_WEB_SEARCH_MAX_CONCURRENT_QUERIES. - Error Handling: Non-2xx and non-JSON responses (e.g., if JSON format is disabled on the SearXNG instance) report actionable configuration errors guiding the operator to enable
format=jsonin SearXNG'ssettings.yml.
D. Configuration & Precedence Matrix
| Setting | Environment Variable | config.toml Key |
Default Value |
|---|---|---|---|
| Provider | AGENTIC_WEB_SEARCH_PROVIDER |
[web_search].provider |
"you" |
| API Key | Named by api_key_env |
[web_search].api_key_env |
Optional (default "SEARXNG_API_KEY") |
| Base URL | AGENTIC_WEB_SEARCH_BASE_URL |
[web_search].base_url |
Mandatory (no public default URL) |
| Max Concurrency | AGENTIC_WEB_SEARCH_MAX_CONCURRENT_QUERIES |
[web_search].max_concurrent_queries |
Inherits gateway limit |
Scope Boundaries
| In Scope | Explicitly Out of Scope (Deferred) |
|---|---|
✅ SearXNGSearchProvider implementation |
❌ Deploying/hosting SearXNG inside agentic-api container |
| ✅ Client-side domain filtering & freshness mapping | ❌ Engine-specific engine tuning (e.g. !g, !ddg bang operators) |
| ✅ Mandatory base URL validation & error diagnostics | ❌ Multi-page scraping / deep crawling |
✅ Axum mock HTTP tests (tests/web_search_searxng_test.rs) |
❌ Dynamic auth schemes beyond optional Bearer token |
Verification Checklist
- 200 OK (Web + News): Verify SearXNG JSON envelope maps cleanly to
WebSearchResult. - Missing Base URL: Startup / call fails with actionable message explaining SearXNG requires a configured endpoint.
- Malformed / Disabled JSON: If SearXNG returns HTML instead of JSON, fail with diagnostic recommending
search.formats: [html, json]insettings.yml. - Domain Filtering: Verified client-side via
DomainFilter. - Freshness: Verified
time_rangetranslation. - Metadata: Echoes
"provider": "searxng"inmetadata[]. - Zero Regressions: You.com and Brave Search remain byte-identical and unaffected.
- Hygiene:
cargo fmt,cargo clippy --all-targets -- -D warnings, and file size limits pass.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the typed provider contract established in #293 and #294, then read tool/web_search/searxng.rs and the surrounding provider configuration. Run or add Axum mock coverage in tests/web_search_searxng_test.rs for the JSON envelope, base URL and filtering mappings. Done means the verification checklist passes without regressions to You.com or Brave Search.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100