dshbase

插件目录 / Developer / dsh-web-search-searxng

dsh-web-search-searxng

未验证 chinng-inta

✓ 持续维护 基于 6 个官方 DSH 包

查看 GitHub ↗ ← 返回插件目录

2Stars
0Forks
0未关闭 issue
语言
2026-08-22最近推送
跨平台平台

功能简介

Developer 类别的 DeepSeek Harness 插件。

我们的评价
未验证 — 尚未实测

Developer 类别的 DeepSeek Harness 插件。 尚未验证——请自行安装测试。

「未验证」表示我们的自动化 CI 尚未安装过该插件。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

你是插件作者? 想拿到「已验证」标签——提交你自己的验证证据(截图、日志或短视频),我们审核通过后即改为「已验证」。

提交验证证据 ↗

README

dsh-web-search-searxng

A SearXNG-backed WebSearchProvider for the
DeepSeek Harness web capability seam (ctx.web).

SearXNG is a self-hosted metasearch engine. One search here is a plain retrieval call against the
instance's /search?format=json endpoint, so unlike the shipped DeepSeek provider it needs no API
key
and costs no model turn — the shipped provider issues a full Messages request with the
native web_search server tool, paying latency and generated tokens for every search.

This is an implementation package: it registers a provider into ctx.web and does not
register a model-facing tool. @deepseek-ai/dsh-tool-web owns web_search, its schema, its prompt
guidance, and the result card. Installing this package makes that existing tool work against your
own instance.

Install

From npm

dsh plugin --profile web add dsh-web-search-searxng

From this repository

dsh plugin --profile web add github:chinng-inta/dsh-web-search-searxng

A git dependency ships no lib/, so the package builds itself through its prepare script — and
pnpm blocks install scripts until you allow them. The first run therefore fails and prints the exact
key to allow. Add it to your profile's pnpm-workspace.yaml and re-run:

allowBuilds:
  "dsh-web-search-searxng@https://codeload.github.com/chinng-inta/dsh-web-search-searxng/tar.gz/<commit-sha>": true

The key pins a commit, so it changes whenever you install a newer revision. Building from source also
needs the dev toolchain fetched (~20 s versus ~2 s for the registry). Prefer npm unless you are
tracking unreleased changes.

Either way

The package declares dsh.bundle, so a single command also activates it: the bundle patch
inserts the provider row and selects it on the web row. Point it at your instance and restart:

export SEARXNG_URL=http://searxng.internal:8888

Verify the composition before booting:

dsh --profile web --dump-config | grep -A3 'id: web'

Your instance must serve JSON

SearXNG does not enable the JSON API by default. In the instance's settings.yml:

search:
  formats:
    - html
    - json

Without it the endpoint answers with the HTML result page, and this provider fails with a message
naming the fix rather than a parse error.

A public instance is a poor backend: most refuse programmatic access (HTTP 403 from a bot filter)
or rate-limit aggressively. Run your own.

Configuration

The plugin owns the web-search-searxng settings namespace, so its section resolves in the harness's
own layering:

schema defaults  →  the plugin row's `config` (composition base)  →  the user layer in the settings document

baseURL additionally falls back to $SEARXNG_URL when no layer sets it. Nothing else is needed to
get started: export the variable and the provider is configured.

The section is projected per search, so an edit to the settings document reaches the next search
without a restart — and clearing baseURL falls back to the environment again rather than stranding
the provider on a value it can no longer see. Registration itself never moves, so provider selection
does not flicker when configuration changes.

A deployment without a settings provider mounted keeps working: the source falls back to the
composition entry, exactly as composed.

All keys are optional.

Key Default Meaning
baseURL $SEARXNG_URL Instance root; /search is appended. Missing or non-http(s) makes the provider report unavailable rather than fail every search.
categories instance default categories= filter, e.g. ['news'].
engines instance default engines= filter, e.g. ['duckduckgo', 'brave'].
language instance default language= filter, e.g. ja, en-US.
timeRange unset time_range= filter: day / week / month / year.
safesearch instance default safesearch=: 0 off, 1 moderate, 2 strict.
timeoutMs 10000 Resource backstop for one search.
maxSnippetChars 500 Per-source snippet cap.
headers none Extra request headers, e.g. for an instance behind an authenticating proxy.

As the plugin row's composition base:

- id: web-search-searxng
  name: 'dsh-web-search-searxng'
  config:
    baseURL: http://searxng.internal:8888
    language: ja
    categories:
      - general
      - news

…or as the user layer in the harness settings document ($DSH_HOME/settings.yaml by default),
which wins over the row above and is what a configuration surface writes:

web-search-searxng:
  language: ja
  maxSnippetChars: 300

Every search-shaping knob is a deployment setting, not a model argument. The seam's
WebSearchRequest is deliberately just query + maxResults; provider-neutral controls (recency,
domain filters, search depth) are named deferred work upstream. Keeping them in config is what makes
this provider substitutable for the shipped ones.

timeoutMs is a resource backstop, not the model-facing tool-call budget —
@deepseek-ai/dsh-tool-call-timeout-policy owns that via tool-web's searchTimeoutMs. Leave this
below the tool budget so a slow instance surfaces as a provider failure rather than a tool timeout.

Provider selection

The bundle patch sets web.searchProvider: searxng. This is required, not opinionated.

The seam auto-selects only when exactly one registered provider is usable, and
@deepseek-ai/dsh-web-search-deepseek reports usable whenever a credential resolver exists — which
its own apply() always supplies — so it answers available() === true on a stock composition even
with no key configured. Registering a second provider without naming one would make every search fail
with WEB_PROVIDER_AMBIGUOUS.

Bundle layers apply before your profile's cordis.patch.yml, the home patch, and any --patch
overlay, so you can always override the choice. But note that a patch replaces the targeted row's
whole config: if you patch the web row yourself for anything else, restate
searchProvider: searxng there too.

Mapping

SearXNG Seam
results[].url sources[].url (required; results without one are dropped)
results[].title sources[].title
results[].content sources[].snippet, capped at maxSnippetChars
results[].publishedDate sources[].publishedAt
answers[] content, newline-joined; omitted when empty

Sources are deduplicated by URL, because a metasearch merges engines that routinely return the same
page. Blank strings are treated as absent rather than emitted as empty fields — the seam's optional
fields exist so an adapter never has to invent them.

truncated is always false from this provider: the seam owns maxResults enforcement, and
reporting our own truncation would misattribute whose bound cut the list.

Errors

Failures are WebErrors the tool layer turns into a readable tool result.

Situation Code
Caller cancelled WEB_ABORTED
timeoutMs elapsed WEB_PROVIDER_ERROR
Non-2xx from the instance (403 carries a bot-filter hint) WEB_PROVIDER_ERROR
Response was not JSON (usually formats misconfiguration) WEB_PROVIDER_ERROR
Unparseable body WEB_PROVIDER_ERROR

available() is a cheap synchronous check — a parseable http(s) base URL — as the seam requires;
it never touches the network.

Redirects are refused (redirect: 'error'). A self-hosted instance has no reason to redirect a
search, and following one would send the query to a host the deployment never configured.

Known limitations

  • maxResults is not pushed down. SearXNG exposes no result-count parameter, so the instance
    returns its full first page and the seam truncates. This bounds tokens, not the instance's work.
  • publishedDate is usually absent. General web engines rarely date results; news engines
    usually do. Filter with categories: ['news'] if you need dates.
  • Infoboxes are not surfaced. They are structured entity cards rather than an answer to the
    query, so flattening them into content would present them as one.
  • No per-engine failure reporting. SearXNG reports unresponsive_engines[] on partial failures;
    the seam's result shape has nowhere to put it, so a degraded search looks like a thin one.

Compatibility

This package DeepSeek Harness
0.3.3+ 0.1.0-rc.8
0.1.x0.3.2 0.1.0-rc.6

0.3.3 is not backward compatible, and neither is anything before it forward compatible.
Installing the wrong pair does not merely lose this card — it fails the whole Web UI's plugin
load, because both breakages surface as an unanswerable client require or an invalid slot
registration (#1):

  • rc.8 dropped @deepseek-ai/dsh-client-web-react from the loader's seed table. Up to 0.3.2
    this package imported bindSnapshotSelector from it. 0.3.3 hands its store to the renderer
    through the slot inject face's hooks compartment instead, which is where rc.8 synthesizes
    selector hooks.
  • rc.8 turned settings.plugin.item from a list slot (id + order) into a keyed one
    (key = the settings namespace the card edits). 0.3.3 registers the keyed way, which rc.6
    rejects.

0.3.0 shipped the settings card without its stylesheet — it works, but renders with browser
defaults. Use 0.3.1 or later.

The harness is a developer preview with breaking changes between release candidates, and its
packages publish the active line under the next dist-tag (latest still points at the older
0.0.1-rc.1). Pin your harness version.

License

MIT

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-web-search-searxng」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:chinng-inta/dsh-web-search-searxng

Headless(CLI)profile:

dsh plugin --profile headless add github:chinng-inta/dsh-web-search-searxng

实测报告

尚未 L3 验证——若已跑过,见下方失败备注。

状态:pending · 最近测试 2026-08-26
备注:验证: runtime-fail 浏览全部待验证失败 →
安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Developer 里更多

浏览全部 7789 个插件 →