Bundle
dsh-search-hub
Multi-entry web search hub for DeepSeek Harness: route ctx.web search through configurable model entries (DeepSeek official, GLM Coding Plan Zhipu web_search, future Kimi) with exactly one active entry; ships a Settings page tab for management.
- Source
- Lzh3070
- License
- MIT
- Updated
- Updated 2 days ago
Readme
<h1 align="center">dsh-search-hub</h1>
<p align="center"><b>Multi-entry web search hub for DeepSeek Harness · DeepSeek Harness 联网搜索多入口管理中枢</b></p>
<p align="center"><a href="#english">English</a> · <a href="#中文">简体中文</a></p>
---

<a id="english"></a>
## English
DeepSeek Harness's built-in web search is a single fixed channel (`deepseek-official`, an Anthropic-compatible Messages call with the server-side `web_search` tool). **dsh-search-hub** turns that channel into a configurable hub:
- **Multiple search entries, exactly one active.** Each entry = label + protocol vendor + baseURL + model + API-key env-var name. Switching is one click in the Settings page — no restart, the provider snapshots config per search.
- **Two protocol adapters:**
- `anthropic` — Anthropic Messages + native `web_search_20250305` tool (covers DeepSeek official; ready for Kimi Coding endpoints once verified);
- `zai` — Zhipu's standalone **Web Search API** (`POST {base}/web_search`): deterministic retrieval with no model turn, no tool-call discretion — every call IS a search. Works with **GLM Coding Plan** keys.
- **A top-level「搜索」tab in the dsh Settings dialog**: card list per entry, radio-style activation, add/edit/delete with templates (DeepSeek / GLM / Kimi placeholder). Built-in entries cannot be deleted.
- **Clean fallback.** The bundle patch points the `web` capability at the hub; remove the bundle and the composition falls back to your previous provider by itself.
### Tested against
| | |
|---|---|
| DeepSeek Harness | 0.1.1-rc.2 (web profile) |
| GLM Coding Plan (`zai` adapter) | real searches verified against `https://api.z.ai/api/paas/v4` (and the `/api/coding/paas/v4` variant), structured sources returned |
| DeepSeek official (`anthropic` adapter) | same wire format as the stock provider |
| Kimi Coding (`anthropic` template) | template only — endpoint support for `web_search_20250305` not yet probed |
### Install (dsh web profile)
The repo ships prebuilt artifacts under `lib/`, so no build toolchain is needed on the installing machine.
1. Add the dependency and bundle row in `<harness-home>/profiles/web/package.json`:
```jsonc
"dependencies": {
"dsh-search-hub": "git+https://github.com/Lzh3070/dsh-search-hub.git"
// or a local checkout:
// "dsh-search-hub": "link:D:/path/to/dsh-search-hub"
},
"dsh": { "profile": { "bundles": [
// ... existing rows ...
"dsh-search-hub"
] } }
```
2. Install:
```sh
npx -y @deepseek-ai/dsh plugin --profile web install
```
3. Restart Harness, open **设置 → 搜索**, pick the active search model.
### How it works
```
chat session ── web_search tool ──▶ ctx.web seam ──▶ search-hub provider
│ active entry
┌───────────────┴────────────────┐
vendor: anthropic vendor: zai
POST {base}/messages POST {base}/web_search
tools:[web_search_20250305] { search_query, search_engine }
→ web_search_tool_result blocks → search_result[] items
```
Settings persist under the `search-hub:` namespace of `<harness-home>/settings.yaml`. **Only env-var NAMES are stored** (e.g. `ZAI_API_KEY`); actual keys stay in the credentials store (managed on the Settings → Models page). Each search snapshots the section, so edits apply to the next call without re-registering anything.
### Security notes
- Searches are plain HTTPS calls from the Harness host process to whatever `baseURL` you configure — treat entry config with the same care as the stock provider's base-URL override.
- The `anthropic` adapter bills as a full model turn on the respective plan (server-side search runs inside a Messages call). The `zai` adapter is a deterministic per-call search API — no model turn — but still bills against your Zhipu/GLM quota per request.
- Zhipu search results may arrive without URLs; entries with `allowLinkless: true` map them to `zhipu-websearch://` placeholder URLs so titles and snippets still reach the model.
### Development
```sh
npm install # tsdown + typescript + pinned @deepseek-ai type deps
npm run typecheck
npm run build # lib/index.js (Node ESM) + lib/client.js (browser CJS)
DSH_HOME=<home> node scripts/test-zai-adapter.mjs "query" # live zai adapter test
```
Requires Node.js ≥ 22.
### License
[MIT](./LICENSE)
---
<a id="中文"></a>
## 中文
DeepSeek Harness 自带的联网搜索是单一固定通道(`deepseek-official`,Anthropic 兼容 Messages 请求挂服务端 `web_search` 工具)。**dsh-search-hub** 把这条通道变成可配置的搜索中枢:
- **多条目、唯一生效**:每条 = 名称 + 协议(vendor)+ baseURL + 模型名 + key 环境变量名;设置页一键切换,配置按次快照,即时生效不重启;
- **两种协议适配器**:
- `anthropic` —— Anthropic Messages + 原生 `web_search_20250305`(覆盖 DeepSeek 官方;Kimi Coding 端点验证通过后直接可用);
- `zai` —— 智谱独立 **Web Search API**(`POST {base}/web_search`):确定性检索,不消耗模型轮次、模型无权跳过——每次调用必是一次搜索。**GLM Coding Plan 的 key 可直接用**;
- **设置对话框顶层「搜索」标签页**:条目卡片列表、单选激活、新增(内置 DeepSeek/GLM/Kimi 模板)/编辑/删除,内置条目锁删;
- **卸载即回落**:bundle patch 把 `ctx.web` 的 `searchProvider` 接管到本插件,移除 bundle 后自动回落原通道,无需手工改配置。
### 已验证环境
| | |
|---|---|
| DeepSeek Harness | 0.1.1-rc.2(web profile) |
| GLM Coding Plan(zai 适配器) | 已对 `https://api.z.ai/api/paas/v4`(及 `/api/coding/paas/v4` 变体)实测真实搜索,返回结构化来源 |
| DeepSeek 官方(anthropic 适配器) | 与官方 provider 同 wire 格式 |
| Kimi Coding(anthropic 模板) | 仅模板占位——端点对 `web_search_20250305` 的支持尚未探针验证 |
### 安装(dsh web profile)
仓库内含预构建产物 `lib/`,安装机器无需任何构建工具链。
1. 在 `<harness-home>/profiles/web/package.json` 加入依赖与 bundle 行:
```jsonc
"dependencies": {
"dsh-search-hub": "git+https://github.com/Lzh3070/dsh-search-hub.git"
// 本地开发调试可用:
// "dsh-search-hub": "link:D:/path/to/dsh-search-hub"
},
"dsh": { "profile": { "bundles": [
// ...原有行...
"dsh-search-hub"
] } }
```
2. 安装:
```sh
npx -y @deepseek-ai/dsh plugin --profile web install
```
3. 重启 Harness,打开 **设置 → 搜索**,选择生效的搜索模型。
### 工作原理
会话里的 `web_search` 工具经 `ctx.web` seam 进入本插件的统一入口,按当前生效条目分发到对应协议适配器。配置持久化在 `<harness-home>/settings.yaml` 的 `search-hub:` 命名空间下;**只保存 key 的环境变量名**(如 `ZAI_API_KEY`),明文密钥仍在凭据体系(设置 → 模型)里管理。
### 安全说明
- 搜索是从宿主进程向你配置的 `baseURL` 发起的普通 HTTPS 请求,请像对待官方通道的地址覆盖一样谨慎填写;
- `anthropic` 适配器按一整轮模型调用计费(服务端搜索跑在 Messages 请求里);`zai` 适配器是确定性的按次检索 API——不走模型轮次——但每次请求仍计智谱/GLM 额度;
- 智谱结果可能不带 URL;开启 `allowLinkless` 的条目会映射成 `zhipu-websearch://` 占位链接,标题与摘要照常传给模型。
### 开发
```sh
npm install
npm run typecheck
npm run build
DSH_HOME=<home> node scripts/test-zai-adapter.mjs "query" # 直调 zai 适配器真实搜索
```
需要 Node.js ≥ 22。
## 许可证
[MIT](./LICENSE)
Install
dsh plugin --profile web add github:Lzh3070/dsh-search-hub
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-search-hub from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.