dsh-web-search-tavily
liufeicc/dsh-web-search-tavily
给 DSH 的网页搜索接缝接上 Tavily,默认免注册、免 API key。
安装
dsh plugin --profile web add github:liufeicc/dsh-web-search-tavilyREADME
dsh-web-search-tavily
把 Tavily 的搜索能力接到 DSH 的 ctx.web 搜索接缝上,替换掉依赖公网 DeepSeek API key 的内置 provider。
为什么需要它
DSH 自带的 web-search-deepseek 走 api.deepseek.com/anthropic/v1/messages 的
web_search_20250305 服务端工具,必须有一把有效的公网 DeepSeek API key。
当聊天模型走内网网关、而公网 key 又失效时,内置搜索只会返回:
DeepSeek API error (HTTP 401): Authentication Fails
本插件用 Tavily 补上这条路,并且默认不需要注册账号或 API key。
免注册:keyless 模式
Tavily 官方提供 keyless 通道,只要一个请求头:
X-Tavily-Access-Mode: keyless
返回的 schema 与带 key 时完全一致。官方定位是 exploration / light use,有速率上限; 撞上限后注册免费 key(1000 credits/月,无需信用卡)即可,代码一行都不用改。
配置
在 profile 的 cordis.patch.yml 里给插件行写 config:
| 字段 | 默认值 | 说明 |
|---|---|---|
accessMode | keyless | keyless 或 api-key |
apiKey | — | 正式 key;仅 api-key 模式使用 |
apiKeyEnv | TAVILY_API_KEY | apiKey 未配置时从这个环境变量读 |
baseURL | https://api.tavily.com | 便于指向代理或自建网关 |
searchDepth | basic | basic = 1 credit/次;advanced = 2 credits/次 |
timeoutMs | 20000 | 本地硬超时,见下 |
maxResults | 8 | 单次搜索来源上限 |
两道保险:为什么不只是"传一个 signal"
DSH 的 timeout-policy 是协作式的:它只 abort 一个 AbortSignal,指望下游自己响应。
只要链路上任何一环没有把 abort 传下去,调用就会无限期挂起——用户看到的就是
"一直转圈、点停止也没反应"。
本插件把两个信号融合成一个:
AbortSignal.any([callerSignal, AbortSignal.timeout(timeoutMs)])
callerSignal:用户点停止、或工具层 60s 预算触发;AbortSignal.timeout(...):本插件自己的硬上限。
所以即使上层取消链路断了,一次搜索也一定会在 timeoutMs 内结束并返回明确错误。
实测:取消在 513ms 返回 WEB_ABORTED;1s 硬超时在 1023ms 返回 WEB_PROVIDER_ERROR。
安装
- 把本仓库放到一个固定目录,例如
$HOME/data/claude-workspace/dsh/dsh-web-search-tavily/ - profile 的
package.json加依赖(路径换成你的实际路径):"@local/dsh-web-search-tavily": "link:/absolute/path/to/dsh-web-search-tavily" - profile 的
cordis.patch.yml末尾追加:- insert: - id: web-search-tavily name: '@local/dsh-web-search-tavily' - id: web config: searchProvider: tavily fetchProvider: http
- id: web 是「覆盖整行、config 整体替换」语义,两个 provider 都要写全,
只写 searchProvider 会把 fetchProvider 抹掉,连带 web_fetch 一起坏掉。
- profile 是
patchReload: live,改完 patch 即热加载,不需要重启 dsh。
本目录里的 node_modules
插件 import '@deepseek-ai/schemastery' 和 '@deepseek-ai/dsh-web'。由于 profile 通过
link: 引用它,pnpm 不会在插件目录安装 peer 依赖,Node 从真实路径向上解析会失败。
所以本目录里放了两个符号链接指向 $DSH_HOME/profiles/node_modules/@deepseek-ai/:
node_modules/@deepseek-ai/schemastery -> ~/.dsh/profiles/node_modules/@deepseek-ai/schemastery
node_modules/@deepseek-ai/dsh-web -> ~/.dsh/profiles/node_modules/@deepseek-ai/dsh-web
如果换 DSH_HOME 或升级后报 ERR_MODULE_NOT_FOUND,重建这两个链接即可。
已知限制
- keyless 有速率上限,官方未给具体数字;高频使用请注册免费 key。
- 返回的
content摘要被截断到 600 字符(避免塞满上下文);需要全文请配合web_fetch。 - 只实现搜索(
WebSearchProvider),不实现抓取;web_fetch仍由内置httpprovider 提供。