DeepSeek Harness 插件

dsh-web-search-searxng

SearXNG-backed web search provider for the DeepSeek Harness web capability seam (ctx.web) — self-hosted metasearch, no API key, no model turn per search(英文原文)

跳到安装方式

来源信息

GitHub 仓库
chinng-inta/dsh-web-search-searxng
最近更新
2026年8月22日
分类
工具与能力
GitHub stars
2
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/chinng-inta/dsh-web-search-searxng
插件名:dsh-web-search-searxng
作者:chinng-inta

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器3 个文件
README.md来源说明 · 只读预览

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.

KeyDefaultMeaning
baseURL$SEARXNG_URLInstance root; /search is appended. Missing or non-http(s) makes the provider report unavailable rather than fail every search.
categoriesinstance defaultcategories= filter, e.g. ['news'].
enginesinstance defaultengines= filter, e.g. ['duckduckgo', 'brave'].
languageinstance defaultlanguage= filter, e.g. ja, en-US.
timeRangeunsettime_range= filter: day / week / month / year.
safesearchinstance defaultsafesearch=: 0 off, 1 moderate, 2 strict.
timeoutMs10000Resource backstop for one search.
maxSnippetChars500Per-source snippet cap.
headersnoneExtra 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

SearXNGSeam
results[].urlsources[].url (required; results without one are dropped)
results[].titlesources[].title
results[].contentsources[].snippet, capped at maxSnippetChars
results[].publishedDatesources[].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.

SituationCode
Caller cancelledWEB_ABORTED
timeoutMs elapsedWEB_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 bodyWEB_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 packageDeepSeek Harness
0.3.3+0.1.0-rc.8
0.1.x0.3.20.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