# 安装与升级 > 记录基线:`dsh-web-search-pool` 0.5.1(2026-10-21 起为本机 desktop profile 实际安装版本);官方桌面版 **0.1.7-rc.2 与 0.2.0-rc.1** 双线验证记录(后者 2026-09-28 app.asar 源码核对 + e2e 实测)。后续宿主须重新核对,不由版本号较大推定兼容。 > 装配机制的源码依据见 [架构与机制](架构与机制.md)(2026-09-25 / 2026-09-28 复核);机制结论均标注了调研日期。 ## 1. 前置条件 - 目标宿主二选一:**0.1.7+** 或 **0.2.0+**(0.4.0 的 peer 范围 `^0.1.7-rc.1 || ^0.2.0-rc.1`);不支持旧 `0.1.1-rc.x / 0.1.2`。其他版本先核对 manifest peer 范围及实际服务/slot,再验证。 - `pnpm` 在 PATH 上:`dsh plugin` 是 pnpm 转发器,在 profile 目录执行 `pnpm add`。 - 至少一个搜索 key(Tavily / Exa);Exa 也支持**匿名免费层**(不填 key 即可用,1 次/秒)。 ## 2. 安装 ### 2.1 官方桌面版(推荐:应用内插件管理) ```powershell # 项目目录打包(Windows PowerShell) npm pack ``` 1. 打开 DeepSeek Harness 桌面版 → **设置 → 插件 → 安装**(install); 2. 选择本地 `dsh-web-search-pool-.tgz`; 3. 安装完成后在「已安装」里点开 `dsh-web-search-pool`,找到它声明的 **`web-search-pool` 行**; 4. 行上的**「配置」**按钮即「搜索 Key 池」卡片(见 §4)。 > 桌面版 profile(`desktop`)由 Electron 应用独占管理,`dsh plugin --profile desktop …` > 会被 CLI 拒绝(`profile "desktop" is managed exclusively by the Electron application`), > 请一律走应用内插件管理。 ### 2.2 命令行(非 desktop profile:web / headless / 自建 profile) ```bash npm pack dsh plugin --profile web add ./dsh-web-search-pool-.tgz ``` ### 2.3 开发期 link 安装 ```bash dsh plugin --profile web add link:<项目目录> ``` link 模式直接读源码,改完 `src/` 后必须重启 DSH 进程(刷新浏览器不加载新代码);生产用 tarball。 ## 3. 安装后验证 ```bash dsh --profile web --dump-config # 期望(0.5.0+ 只要求插件行存在;web 行保持官方配置,由运行时接管): # web config.searchProvider: <官方 provider> # 不被插件改写 # web-search-pool id: web-search-pool name: dsh-web-search-pool ``` 桌面版验证(无需 CLI): 1. 插件管理页能看到 `dsh-web-search-pool` 及其 `web-search-pool` 行(标题「搜索 Key 池」); 2. 行的「配置」能打开卡片,开关/策略/数值/key 列表都在; 3. 会话里让模型搜一次网页,确认 Tavily/Exa 命中(日志 `search-pool attempt …`); 0.5.0 起日志还会出现 `search-pool: takeover installed at web.search`。`web` 行的 `searchProvider` 仍是官方值属于正常现象——接管在 `ctx.web.search` 方法上。 > 深度验证(开发者):`node scripts/e2e-boot.mjs [tgz]` 会用桌面版 > app.asar 里的真实运行时,在**隔离的临时 profile** 里启动整棵宿主树并逐项断言 > (bundle 加载、patch 生效、插件 ACTIVE、settings 投影、写入落盘、client 图谱下发)。 > 可选 `--live-search` 会复制真实凭据到隔离 home 并发起联网搜索,可能计费;须有相应授权,结束后确认临时敏感副本清理。普通文档检查不执行此脚本。 ## 4. 配置 API Key 插件管理页 → `dsh-web-search-pool` → `web-search-pool` 行 → **配置** →「搜索 Key 池」卡片: - 添加 key(环境变量名 / 限流 RPM / 备注)→ 保存。保存是单次事务,只写变化的字段。 - 密钥只经 DSH credentials 服务保存,**不写入 profile patch**;也可用同名环境变量提供。 - Exa 的「环境变量名」留空即启用匿名免费层(全局 1 req/s,配置不可覆盖)。 - Tavily 额度总览:0.3.0 起不再进设置卡片(0.1.7 的 settings 写入会落盘进用户 patch, 运行时数据不能放那里)。Host 每次启动后、配置变化后、以及按 `usageCacheMs` 后台自动刷新 Tavily `/usage`,快照写入 DSH 日志:`search-pool usage used=… limit=… keys=…`。 - 卡片默认收起,已保存的 key 折叠为一行摘要(备注 / 引用名 / 已配置状态)。 ## 4.1 fetch(web_fetch 工具)的接管与配置(0.6.0+) 启用插件后 `web_fetch` 默认一并被接管(`fetchEnabled: true`),抓取走 Tavily Extract,与搜索共享同一批 key 和月度额度(basic 抓取 1 credit/5 URL,advanced 2 credits/URL)。 - **关闭 fetch 接管**:在 patch 层把 `fetchEnabled` 改为 `false`,`web_fetch` 原样走宿主 fetch provider(按 `web.fetchProvider` 配置,官方桌面版常见值为 `deepseek-fetch-api`——消耗 DeepSeek 平台额度——或 `http` 本机直连免费抓取)。 - **抓取深度**:`providers.tavily.fetchDepth` 默认 `basic`(成本约为 advanced 的 1/10);JS 渲染/反爬站点抓不到正文时改 `advanced`。输出格式 `providers.tavily.fetchFormat` 默认 `markdown`。 - **抓取回退**:`fetchFallbackToOfficial` 默认 `false`(与 `fallbackToOfficial` 语义对齐);打开后池抓取失败自动改走官方 fetch provider。 - **只有 Exa key 的池**:fetch 仅接了 Tavily Extract,池里没有 Tavily key 时 `web_fetch` 返回「抓取暂不可用」。 - 这些都是 patch 层配置(设置卡片不编辑),示例见 [cordis.patch.yml](../cordis.patch.yml);配置字段语义详见 [架构与机制](架构与机制.md) §6。 - 想零成本替代官方 Fetch 而不启用本插件时:宿主自带的 `dsh-web-fetch-http`(provider id `http`)是本机直连匿名抓取,把 `web.fetchProvider` 配成 `http` 即可,但对 JS 渲染/反爬站点成功率低于 Tavily Extract。 ## 5. 升级 升级前备份目标 profile 的 `package.json`、`pnpm-lock.yaml` 和 `cordis.patch.yml`;旧版本如仍使用 `settings.yaml` 才额外备份它。不要复制凭据到项目目录。 - **桌面版**:在应用内插件管理安装新包,按应用提示重启;正常升级不手工修改 profile。若已确认旧手工插入行导致重复挂载,备份并退出应用后仅清理该旧行,再启动应用继续安装。 - 2026-10-21 本机升级 0.5.0 → 0.5.1 的实际做法(与插件管理等价,供无 UI 时参考):备份 `package.json` / `pnpm-lock.yaml`(带日期后缀)→ 把依赖里的 tag 改成 `refs/tags/v0.5.1.tar.gz` → 在 profile 目录用运行时自带 pnpm 执行 `pnpm install` → 重启应用。注意 `pnpm install` 会清理 `package.json` 未声明但残留在 `node_modules` 的包(本次清掉了一个未被任何 profile 配置引用的旧 `dsh-purge` 副本)。 - **CLI profile**:停掉对应宿主进程,确认旧手工 `web-search-pool` row 不与 Bundle 重复,再执行 `dsh plugin --profile add .tgz`;用该 profile 的 `--dump-config` 核对后启动。 - 旧白名单 patch 不属于现行安装步骤。版本迁移细节见 [CHANGELOG](../CHANGELOG.md),不要把旧版安装方法套用到新宿主。 - 启动后按 §3 验证。真实 key 搜索是会联网、可能计费的单独检查,不因整理文档自动执行。 ## 6. 回滚 ```bash # CLI profile dsh plugin --profile remove dsh-web-search-pool dsh plugin --profile add .tgz ``` 桌面版:插件管理页 → `dsh-web-search-pool` → 卸载/停用;要回到旧版本就装回旧 tgz(旧版本要求对应旧宿主,别在 0.1.7 上回滚到 ≤0.2.1——它起不来)。 临时回到官方搜索:关闭插件配置中的 `enabled`(wrapper 委托回原 `web.search`),或直接停用插件。0.5.0 不再改写 `web` 行,因此无需手工改 profile;若 profile 里残留 0.4.0 的 `- id: web / searchProvider: search-pool`,可删掉该覆盖(运行时接管不依赖它)。相关机制见 [架构与机制](架构与机制.md)。长期回滚移除 Bundle。 ## 7. 失败更新语义 - loader 对装配失败 **fail loud**,不会自动改 DSH 安装目录。 - 0.1.7 起有**版本兼容门**:`evaluatePluginCompatibility` 把每个 `@deepseek-ai/dsh*` peer 范围对运行时版本求 `satisfies`(prerelease 参与判定),不满足 → bundle 层被跳过 (`skippedBundles`),插件**静默不加载**;拒绝记录带 `incompatible-version` 与未满足的 peers 清单。0.4.0 的 peer 范围为双线 `^0.1.7-rc.1 || ^0.2.0-rc.1`(0.1.7 与 0.2.0 都放行)。 排障时先核对 peer 范围与宿主版本(启动诊断里会列 skipped bundle 及原因)。 - 保留 profile 的 package.json / pnpm-lock.yaml 备份,按报错定位是 package resolve、 client bundle、settings schema、slot 还是 provider apply 失败。 - 修复后重新 `npm pack` + 安装。 ## 8. 卸载 ```bash # CLI profile dsh plugin --profile remove dsh-web-search-pool ``` 桌面版:插件管理页卸载。key 的凭据保存在 DSH credentials 里,卸载插件**不会**删除凭据。 ## 9. 故障排查 | 现象 | 判断 | 处理 | |---|---|---| | 插件没出现在插件页 / 没有「搜索 Key 池」 | bundle 层被跳过(peer 兼容门)或 client bundle 没下发 | 核对 manifest 的 peer 范围、目标宿主服务/slot 与历史基线;看启动诊断的 skippedBundles,必要时按应用提示重启 | | 启动/重启报 web boot 失败、`pending (waiting for service: …)` | client half 在 inject 里等了不存在的服务(0.2.1 等 `settingsScope` 的线上事故) | 升级到 0.3.0+;不要手改 injections | | 保存设置被拒 / 卡片报冲突 | 别处改了同一 namespace,revision 过期 | 重新打开卡片再保存 | | `Cannot find package dsh-web-search-pool` | profile 依赖未安装 | 重跑安装(插件管理 / `dsh plugin add`) | | provider duplicate | 旧 profile patch 仍 insert provider | 删除旧手工 row | | 仍走 `deepseek-official` | 0.4.0 的 web 行覆盖被 profile patch 覆盖;或开关关闭 | 升级 0.5.0+(运行时接管 `ctx.web.search`);看卡片开关与日志 `takeover installed at web.search` | | 点击保存无反应 | Host 未就绪 / namespace 未投影 | 重启 DSH;确认插件行 ACTIVE(日志 `apply plugin dsh-web-search-pool`) | | Tavily 额度不对 | 0.3.0 起额度只进日志 | 看 `search-pool usage …` 日志行 |