Install
Inside DeepSeek Harness, with dsh-market
dsh plugin --profile web add dshmarket
Or from the command line
dsh plugin --profile web add github:rebron1900/dsh-web-search-9router
Installing runs third-party code with your own permissions — it can read your files, use your credentials and reach the network. Review the source first, and pin a commit (github:owner/repo#sha) when you can.
README
Web search & fetch for DeepSeek Harness, powered by 9router. Wires the native
web_searchandweb_fetchtools into 9router's/v1/searchand/v1/web/fetchendpoints — no server-side search tool required.
🇺🇸 English · 🇨🇳 简体中文
✨ What it does
- 🔎 Search provider — routes DSH's native
web_searchthrough 9router's/v1/search, returning deduplicatedWebSourceresults (title, snippet, published date). - 📄 Fetch provider — routes DSH's native
web_fetchthrough 9router's/v1/web/fetch, returning clean text/markdown bodies. - 🎛️ Bundle settings — configure the API key, base URL, models, and limits directly on the plugin's bundle detail page.
- 🔐 Credentials-aware — stores API keys through DSH's credentials service and resolves the configured credential reference (
NINE_ROUTER_API_KEYby default). - 🧱 Zero build — pure ESM, plain JavaScript, no bundler required.
🧭 Why this plugin
DSH's default web_search uses the web-search-deepseek provider, which requires the upstream service to implement Anthropic's web_search_20250305 server-side search tool and return web_search_tool_result blocks.
9router is an OpenAI-compatible gateway: it passes that tool definition to the model as a regular function instead of executing searches server-side — so it cannot provide native search by itself.
web-search-deepseek (default) |
9router (this plugin) | |
|---|---|---|
| Requires | Anthropic web_search_20250305 server-side tool |
Any 9router-compatible gateway |
| Works with 9router | ❌ | ✅ |
| Search endpoint | model-provided | POST /v1/search |
| Fetch endpoint | model-provided | POST /v1/web/fetch |
This plugin calls 9router's own endpoints directly and maps their responses to the WebSource and WebFetchBody types expected by the DSH web seam.
⚙️ How it works
web_search / web_fetch (native DSH tools)
│
▼
ctx.web seam
│ provider = "9router"
▼
dsh-web-search-9router
├── search → POST {baseURL}/search → WebSource[]
└── fetch → POST {baseURL}/web/fetch → WebFetchBody
│
▼
9router gateway (9router)
Errors surface as machine-routable WebError codes (WEB_PROVIDER_ERROR, WEB_PROVIDER_CREDENTIAL_MISSING, WEB_ABORTED), and non-2xx fetch responses come back as results — never silent throws.
🚀 Quick start
Requirements: DSH >=0.2.0-rc.2 and Node.js 20 or later.
1. Install the plugin
npx @deepseek-ai/dsh plugin --profile web add github:rebron1900/dsh-web-search-9router
2. Select the providers
In your profile's cordis.patch.yml, set searchProvider and fetchProvider to 9router:
- id: web
config:
searchProvider: 9router
fetchProvider: 9router
3. Configure the plugin
Restart DSH and refresh the browser. Open Plugins, select dsh-web-search-9router, and configure it directly on the bundle detail page. Entering an API key stores it in DSH credentials under the selected credential reference; the key is never written to plugin settings.
🔒 Reproducible installs — append a release tag to pin an exact version:
npx @deepseek-ai/dsh plugin --profile web add github:rebron1900/dsh-web-search-9router#v0.2.3
🛠️ Configuration
| Key | Type | Default | Description |
|---|---|---|---|
baseURL |
string | 9router default endpoint | Base URL of your 9router-compatible API (NINE_ROUTER_BASE_URL env also honored) |
searchModel |
string | search-combo |
Model name for the search endpoint |
fetchModel |
string | fetch-combo |
Model name for the fetch endpoint |
searchType |
string | web |
search_type sent to the search endpoint |
maxResults |
number | 8 |
Max sources per search |
timeoutMs |
number | 30000 |
Per-request timeout |
| API key | credential | — | Write-only field stored by the DSH credentials service, not in plugin settings |
apiKeyEnv |
credential-ref | NINE_ROUTER_API_KEY |
Credential reference used to store and resolve the API key |
🧪 Development
pnpm install # install dependencies
pnpm test # run the test suite (node:test)
Repository layout
dsh-web-search-9router/
├── src/index.js # plugin entry: search + fetch providers
├── client.js # bundle detail settings form
├── cordis.patch.yml # bundle patch registering the plugin
├── test/ # node --test suite
└── package.json # ESM plugin manifest
🌱 Ecosystem & releases
- 📦 Distribution — the GitHub repository is the only distribution source; stable versions ship as
v<version>GitHub Releases. - 📚 Directory — listed in awesome-dsh-plugin.
- 🐛 Issues & requests — open an issue.
📄 License
Comments
Comments live in GitHub Discussions. Sign in with GitHub to post or react.