Skip to content
dsh.fish
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>

---

![Settings preview](assets/settings.png)

<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

  • 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.
Source