Vai al contenuto principale
F

langsearch-dsh

foxworld306/langsearch-dsh

LangSearch web search provider and langsearch_search tool for DeepSeek Harness

Installazione

dsh plugin --profile web add github:foxworld306/langsearch-dsh

README

langsearch-dsh

LangSearch(免费 Web Search API)接入 DeepSeek Harness(DSH)内置 web_search 的插件,另附一个可控制结果条数与时间范围、返回长文摘要的独立 langsearch_search 工具,以及一张 Web GUI 设置卡片(含限流等级选择)。

它做什么

  1. 接管内置 web_search:向 DSH 的 web 能力层(ctx.web)注册名为 langsearch 的搜索 Provider,并把 web.searchProvider 指向它。之后 agent 调用内置 web_search 时,实际请求走你自己的 LangSearch 账号。
  2. 新增 langsearch_search 工具:比内置 web_search 多两个控制项——结果条数 count(1-10)和时间范围 freshnessoneDay/oneWeek/oneMonth/oneYear/noLimit),并返回 LangSearch 的长文摘要(summary,每条默认截断到 2000 字符)。
  3. Web GUI 设置卡片设置 → 插件 → 插件配置 中出现 LangSearch 卡片,可以直接填写 API Key(写入 DSH 凭证库,不写入设置文件),并可修改接口地址、限流等级、超时、摘要上限。除 toolEnabled 外保存后热生效,无需重启

安装(官方插件命令)

前提:Node ≥ 20(本插件在 24.x 验证)+ 全局安装 DSH(npm i -g @deepseek-ai/dsh,在 0.1.0-rc.6 验证)+ PATH 上有 pnpmdsh plugin 是 pnpm 的转发命令,没有 pnpm 会直接报错提示)。

# 方式一:GitHub 仓库(仓库需公开)
dsh plugin --profile web add github:foxworld306/langsearch-dsh

# 方式二:tarball(本仓库 Release v0.3.0 的资产 langsearch-dsh-0.3.0.tgz,或本地 npm pack 的产物)
dsh plugin --profile web add .\langsearch-dsh-0.3.0.tgz

# 方式三:npm
dsh plugin --profile web add langsearch-dsh

命令行为:profile 不存在时自动初始化;依赖交给 pnpm 写入 profile;随后 dsh.profile.bundles自动追加 langsearch-dsh(追加在末尾,bundle 层顺序靠后者优先,web.searchProvider: langsearch 因此可靠覆盖其他搜索 Provider 行)。装完重启 dsh web 生效。

# 卸载(依赖与 bundle 自动移除,幂等)
dsh plugin --profile web remove langsearch-dsh

一次性步骤:GUI 设置卡片(host 补丁)

DSH 的 Web 设置页只对硬编码白名单(dsh-host-apiproxyWEB_SETTINGS_NAMESPACES)内的设置命名空间开放;官方注释写明把白名单改为插件自暴露(settings.register())是 "deferred work"。所以要让设置卡片显示,需要对这个白名单打一个单行补丁:

# 在本仓库克隆里运行(host 补丁是仓库级工件,不含在 npm 包内;
# 从 npm / tarball 安装的用户请 clone 本仓库或单独下载 patches/apply-settings-namespace.mjs)
node patches/apply-settings-namespace.mjs            # 应用(幂等;首次改动保留 .bak-langsearch 备份)
node patches/apply-settings-namespace.mjs --check    # 只校验;未达规范形态时退出码 2
  • 基线与细节见 patches/README.md(改哪两个文件、为什么、回滚、何时可移除)。
  • 每次全局升级 dsh 后要重跑一次(升级会覆盖被补丁的文件)。
  • 补丁只在首次改动后需要重启 dsh web
  • 跳过这一步不影响核心功能web_searchlangsearch_search 照常工作,只是 GUI 设置卡片不显示(命名空间返回 settings-not-exposed,卡片按设计不渲染)。

API 与鉴权

  • 端点:POST https://api.langsearch.com/v1/web-search(Bing 兼容响应格式;已对照官方文档快速上手核实)
  • 请求体:{ query, count?, freshness?, summary? }
  • 鉴权:Authorization: Bearer <API_KEY>,Key 在 LangSearch 控制台 > API Key Management 获取
  • Key 解析顺序(每次请求时取值,改 Key 无需重启):
    1. 设置中的字面量 apiKey(secret 字段,从不出现在任何接口响应里,一般不填);
    2. 凭证引用 apiKeyEnv(默认 LANGSEARCH_API_KEY)——从 $DSH_HOME/.credentials.yaml 或同名环境变量解析。在 GUI 卡片里填的 Key 就是写到这里。

访问披露

  • 网络:唯一出网请求是 LangSearch 搜索接口(默认 https://api.langsearch.com/v1/web-search,可用 baseURL 覆盖);请求体只含搜索词与 count/freshness 参数,Authorization 头含你的 API Key。
  • 凭证:API Key 只写入 $DSH_HOME/.credentials.yaml(经 DSH 凭证库 credentials.set 或手动),不出现在任何 API 响应或设置文件里。
  • 设置:卡片保存的内容写入 $DSH_HOME/settings.yamllangsearch 段。
  • 没有遥测、统计、日志上报或搜索以外的数据外发。

GUI 设置卡片说明

  • API Key:密码框,留空 = 保持当前密钥;填写后点“保存”写入凭证库(credentials.set)。徽标显示“已配置密钥 / 未配置密钥”。
  • 接口地址:默认 https://api.langsearch.com(字段不可清空;如无必要请勿修改)。
  • 限流等级:下拉框(Free Tier / Tier 1 / Tier 2 / Tier 3,按账户累计充值对应,见官方限流页)。客户端按该等级 QPS(1 / 5 / 10 / 30 次/秒)对本 dsh 进程的全部搜索限速排队,避免突发触发上游秒级限流。不选则按 Free 处理(最严格,对任何账户都安全)。
  • 超时(毫秒) / 摘要长度上限(字符):数字框,留空 = 恢复默认;出现“已覆盖”徽标时可一键“恢复默认”。
  • 保存写入的是 DSH 设置用户层($DSH_HOME/settings.yamllangsearch 段),凭证单独存于 $DSH_HOME/.credentials.yaml;除 toolEnabled(工具注册,重启生效)外各字段都热生效。
  • 卡片只有在 Host 加载了本插件、且网关 allowlist 已打补丁时才显示(见上文“一次性步骤”)。

配置项(web-search-langsearch 行 / GUI 卡片)

默认说明
apiKey(空)字面量密钥(secret,GUI 不展示值;优先级高于 apiKeyEnv
apiKeyEnvLANGSEARCH_API_KEY凭证引用(环境变量名 / 凭证文件键名)
baseURLhttps://api.langsearch.comAPI 地址覆盖
tierfree账户限流等级(free / tier1 / tier2 / tier3,按累计充值);客户端按该等级 QPS(1 / 5 / 10 / 30 次/秒)限速
timeoutMs30000工具调用与 HTTP 超时(毫秒)
toolEnabledtrue是否注册 langsearch_search 工具(重启生效
maxSummaryChars2000工具输出中每条长摘要的字符上限;0 关闭摘要

在 profile 的 cordis.patch.yml(用户层,优先级最高)中覆盖:

- id: web-search-langsearch
  config:
    maxSummaryChars: 0

# 想把默认搜索后端切回 DeepSeek 官方:
- id: web
  config:
    searchProvider: deepseek-official

常见问题(FAQ)

  • 搜索报错 HTTP 429 / rate limit reached:LangSearch 按账户等级限流(Free 1 QPS / 60 QPM / 1000 QPD,Tier 1 5 / 200 / 2000,Tier 2 10 / 500 / 10000,Tier 3 30 / 2000 / 100000,见限流页),不是密钥或配置问题。请在卡片“限流等级”中选择与账户充值对应的等级——客户端会按该等级 QPS 把并发搜索排队限速。仍见 429(例如多个 dsh 进程共用同一账户、或持续超过 QPM/QPD)时,按报错提示等待数秒后单条重试即可。
  • dsh plugin add 提示 pnpm not founddsh plugin 依赖 pnpm 管理 profile 依赖,先 npm i -g pnpm 再重试。
  • tarball 路径含空格时安装报 ENOENT(Windows):dsh CLI 在 Windows 上以 shell: true 转发 pnpm,含空格的 tarball 路径会被拆词(某些网盘同步目录的默认路径就带空格)。把 tarball 放到不含空格的路径(如 C:\temp\langsearch-dsh-0.3.0.tgz)再安装,或用 GitHub / npm 方式。
  • 升级 dsh 后设置卡片消失:全局升级会覆盖被补丁的网关文件,重跑 node patches/apply-settings-namespace.mjs 并重启 dsh web

文件结构

langsearch-dsh/
├── package.json          # dsh.bundle 清单 + dsh.client 声明(platform: web)+ peer 依赖契约
├── cordis.patch.yml      # bundle 补丁:切 provider + 挂载插件行
├── lib/
│   ├── client.js         # LangSearch HTTP 客户端(超时/取消/错误分类/响应校验)
│   ├── provider.js       # ctx.web 搜索 Provider(id: langsearch)
│   ├── tools.js          # langsearch_search 模型工具 + 系统提示词段
│   ├── invariant.js      # invariant companion(前瞻导出;rc.6 host 无 invariants 服务,未挂载)
│   └── index.js          # cordis 插件入口(注册 langsearch 设置段 + 热更新 + Provider/工具)
├── browser/
│   └── client.js         # 浏览器端 bundle:设置 → 插件 里的 LangSearch 卡片(经典脚本,经 /plugins 分发)
├── patches/              # 仓库级工件,不属于发布的 npm 包(见 patches/README.md)
│   ├── langsearch-settings-namespace.patch   # 基线快照的自包含 diff(已验证可正向应用)
│   ├── host-patch.config.json                # name / baseline / out / 逐文件 seam
│   ├── apply-settings-namespace.mjs          # 幂等收敛的应用脚本(--check 只校验)
│   └── README.md
├── scripts/              # 开发与自检脚本,不属于发布的 npm 包
│   ├── link-deps.mjs     # 本地开发:建立/校验 node_modules 解析垫片(--check 含入口导入 + bundle 语法检查)
│   ├── test-patch.mjs    # host 补丁的自包含测试(无安装依赖)
│   └── smoke-client.mjs  # 无头冒烟测试:模拟浏览器环境跑通卡片注册逻辑
└── .github/workflows/ci.yml  # smoke + 补丁测试 + npm pack 文件清单 + 自包含检查

开发验证

node scripts/link-deps.mjs --check      # 自检:依赖链接 + 插件入口可导入 + 浏览器 bundle 可解析
node scripts/smoke-client.mjs           # 无头跑一遍浏览器 bundle 的 apply/插槽/凭证逻辑
node scripts/test-patch.mjs             # host 补丁脚本的自包含测试
node patches/apply-settings-namespace.mjs --check  # 检查本机网关 allowlist 是否已含 langsearch
dsh --profile web --dump-config         # 离线查看合成后的配置树
dsh --profile web --port 3999           # 临时端口起一份 web,验证插件挂载
# 浏览器端验证:访问 http://127.0.0.1:3999,确认启动图含 langsearch-dsh 条目
# (GET / 的 window.__DSH_BOOT__),且 /plugins/langsearch-dsh/client.js 返回 200

本地用 file: 依赖开发时,修改插件源码后要在 profile 目录重新同步(pnpm 对 file: 依赖按文件硬链接,不自动跟随源码更新):

Remove-Item $env:USERPROFILE\.dsh\profiles\web\node_modules\langsearch-dsh -Recurse -Force
cd $env:USERPROFILE\.dsh\profiles\web; pnpm install

Plugin correlati