Back to home@aaronlei

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
GitHub repo

Introduction

dsh-web-search-diy

License: MIT

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 explicit tools: [{type: "web_search"}] declaration — Chat Completions search flags are silently ignored there. This plugin speaks the Responses protocol and parses the structured web_search_call blocks' action.sources into 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-diy loader entry
  • overrides the shared web row's searchProvider to diy-search and restates fetchProvider: 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 as peerDependencies (mirrored in devDependencies). A linked package resolves its own node_modules first, so run pnpm install inside 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.

KeyDefaultMeaning
apiKeyLiteral API key; overrides apiKeyEnv when set
apiKeyEnvQWEN_TOKEN_PLAN_CN_API_KEYCredential reference resolved per search via ctx.credentials
baseURLhttps://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1Responses API base; /responses is appended
modeldeepseek-v4-flash-0731Model 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
maxOutputTokens1024max_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.