dsh-web-search-diy
DeepSeek Harness(DSH)网页搜索提供方插件:把内置 web_search 工具接到 OpenAI 兼容 Responses API 及其原生 web_search 工具上。
- Stars
- 1
- Language
- JavaScript
- Created
- Sep 3, 2026
- Updated
- Sep 6, 2026
Introduction
dsh-web-search-diy
A web search provider plugin for the DeepSeek Harness (DSH) that backs
the built-in web_search tool with any OpenAI-compatible Responses API
gateway's native web search, returning structured citation sources.
Endpoint, model, and key reference are yours to swap — the only requirement
is a model that actually exposes the web_search tool on its gateway. The
default points at Qwen Token Plan, purely as a working out-of-the-box example.
- Default model:
deepseek-v4-flash-0731 - Default endpoint:
https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 - Default key reference:
QWEN_TOKEN_PLAN_CN_API_KEY
Why
The shipped DSH search provider (deepseek-official) calls DeepSeek's own
Anthropic-compatible endpoint — it cannot be pointed at other gateways, and
switching per deployment is hard. This plugin is a first-class DSH plugin:
it registers a ctx.web search provider and overrides the shared
searchProvider to it, exactly like the ecosystem's other provider plugins.
Search and conversation models stay fully decoupled — use it with any chat LLM.
Why Responses API? Many OpenAI-compatible gateways only trigger their built-in web search through the Responses API (
/responses) with an explicittools: [{type: "web_search"}]declaration — Chat Completions search flags are silently ignored there. This plugin speaks the Responses protocol and parses the structuredweb_search_callblocks'action.sourcesinto seam-standard citation sources.
Install
Published on npm:
dsh plugin --profile web add dsh-web-search-diy
The bundle patch then (no manual cordis.patch.yml edits needed):
- inserts the
web-search-diyloader entry - overrides the shared
webrow'ssearchProvidertodiy-searchand restatesfetchProvider: http(a patch replaces the whole row config) - disables the shipped DeepSeek-official search (
web-search-deepseek)
For local development, install the checkout as a linked package (the same way other local plugins are linked):
dsh plugin --profile web add link:./dsh-web-search-diy
(replace ./dsh-web-search-diy with the actual path to your local checkout)
Note for local linked installs: the plugin declares its
@deepseek-ai/*hooks aspeerDependencies(mirrored indevDependencies). A linked package resolves its ownnode_modulesfirst, so runpnpm installinside the plugin directory once; the harness install supplies the runtime peers.
Configuration
The provider resolves options with precedence: UI-managed file
($DSH_HOME/dsh-web-search-diy.json, written by the Settings card) >
settings section / entry config > package defaults.
| Key | Default | Meaning |
|---|---|---|
apiKey | — | Literal API key; overrides apiKeyEnv when set |
apiKeyEnv | QWEN_TOKEN_PLAN_CN_API_KEY | Credential reference resolved per search via ctx.credentials |
baseURL | https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 | Responses API base; /responses is appended |
model | deepseek-v4-flash-0731 | Model served by the endpoint; before switching, confirm the model actually exposes the web_search tool on the gateway (not all models support live web search) — otherwise the search fails loudly with WEB_PROVIDER_ERROR, never a no-search fallback |
maxOutputTokens | 1024 | max_output_tokens for one search call |
Settings card
The configuration card lives under Settings → Plugins → Plugin configuration → Custom web search, in the same form as the shipped Shell / Agent loop cards: edits stage locally (an "unsaved" badge appears in the header) and only Save writes, while Discard reverts to the stored values. Saving takes effect immediately — no restart. Card copy follows Settings → Language (zh / en). The API key input is write-only: leave it blank to keep the stored key.
How it works
you ──> chat LLM
│ decides it needs live info
▼
web_search tool (model-agnostic)
│ ctx.web seam ──> diy-search provider
▼
POST {baseURL}/responses
tools: [{ type: "web_search" }]
│
▼
your configured gateway/model (default deepseek-v4-flash-0731) ──> structured web_search_call sources
│
▼
chat LLM answers grounded in the results
Each search is one Responses API call (a full model turn). Results return as
deduped sources[] (url + optional title from url_citation annotations)
plus the model's grounded content. A response without any web_search_call
block fails loudly with WEB_PROVIDER_ERROR — never a prose-scraping
fallback.
Credential
Store the key through the web Models page / credentials service under
QWEN_TOKEN_PLAN_CN_API_KEY, or export it in the launching environment. The
provider resolves it per search; no key is retained on the provider.
License
MIT — see LICENSE. Copyright (c) 2026 aaronlei.