Files
Coder 81159a22e8
Some checks failed
build-and-publish / build-test (push) Failing after 1m6s
build-and-publish / publish (push) Has been skipped
chore: isolate shared dsh plugins into independent monorepo
2026-08-26 22:44:31 +07:00

4.0 KiB

@deepseek-ai/dsh-web-search-searxng

English | 中文

A SearXNG-backed WebSearchProvider for the harness web capability seam (ctx.web). It calls a SearXNG instance's JSON API (GET /search?format=json) and maps the flat results[] into the seam's normalized WebSearchResult. It targets a self-hosted or private SearXNG: there is no single canonical public instance, so baseURL has no default, and the provider deliberately carries no API key or Authorization header.

This is an implementation package: it registers a provider into ctx.web, it does not own the ctx.web key and it does not register a model-facing tool (that is @deepseek-ai/dsh-tool-web). Like @deepseek-ai/dsh-llm-deepseek, it is a function/namespace plugin (inject: ['web']) that registers its backend, not a default-export service.

Config

Key Default Meaning
baseURL (none) SearXNG instance base; /search is appended. Empty/unparseable makes the provider unavailable.
language auto SearXNG language request value; auto lets the instance decide per user preferences.
timeRange (unset) SearXNG time_range recency filter: day, week, month, or year. Omitted sends no filter.
- id: web-search-searxng
  name: '@deepseek-ai/dsh-web-search-searxng'
  config:
    baseURL: https://searx.example

The entry above is the base layer of the web-search-searxng Settings section: a user layer over it (a settings.yaml section or an in-session settings edit) reaches the NEXT search, because the provider projects the section per call rather than capturing it at registration. The seam's provider selection therefore never flickers when the instance or a filter changes. A section without baseURL still passes the schema but leaves the provider unavailable — no endpoint is guessed.

# $DSH_HOME/settings.yaml
web-search-searxng:
  baseURL: https://searx.example
  language: auto
  timeRange: day

SearXNG exposes no per-request result-count control — page size is instance configuration — so no numResults option exists; the seam enforces maxResults on the result.

Mapping

SearXNG returns a flat results[] and no generated answer, so content is omitted. Each result maps to a WebSearchSource: urlurl, titletitle, snippetcontent, publishedAtpublishedDate. Unlike the Exa provider it does not drop snippet-less entries: URL and title are still useful, so every result is kept. Provider failures (HTTP errors, network failure, unparseable or wrong-shape bodies) surface as WebError WEB_PROVIDER_ERROR; an aborted request surfaces as WEB_ABORTED. HTTP redirects are rejected before the Location target is contacted and surface as WEB_PROVIDER_ERROR. The request carries no Authorization header, so no credential can leak to a redirect target.

Model Experience

Indirectly, through dsh-tool-web, which retains this provider's maxResults-bounded URLs, titles, snippets, and publication dates or its exact SearXNG search aborted, SearXNG search request failed: <error>, and SearXNG returned an unprocessable response body: <error> failures under the consumer's error wrapper while generated answers and provider-private fields remain outside context.

KV Cache effect

No direct invalidation; the named consumer owns any request-prefix changes.

Known Limitations and Deferred Work

  • Result count is not bounded at the request — SearXNG page size is instance configuration, so the provider sends no count and the seam truncates on return; a single page (typically ~20 results) is fetched.
  • No aggregate-answer or infobox content is surfaced — SearXNG answers and infoboxes are not mapped into content. No generated answer is trusted.
  • Abort classification is error-shape-based — only a DOMException named AbortError maps to WEB_ABORTED; an abort carrying a custom reason (e.g. dsh-timeout's TimeoutReason) surfaces as WEB_PROVIDER_ERROR.