Repository navigation
Releases: godchen520/dsh-web-search-bing
Release list
v1.2.3 — 修复 DSH 0.2.1 下 web_fetch 全部失败
v1.2.3 — 修复 DSH 0.2.1 下 web_fetch 全部失败
⚠️ 如果你在用 DSH 0.2.1-rc.2,请务必升级到本版 —— 旧版在这个 DSH 上每一次web_fetch都会失败。
🐛 问题
DSH 0.2.1-rc.2 给 base 的 web 行新增了 fetchProvider: http。
而 cordis patch 的语义是「整体替换 config」而不是合并 —— 本插件的 patch 此前只重述了 searchProvider,
于是新出现的 fetchProvider 被静默抹掉。
后果:http 与 deepseek-fetch-api 两个抓取 provider 同时可用、且没有显式选择 →
每一次 web_fetch 调用都抛错:
WEB_PROVIDER_AMBIGUOUS: multiple usable web providers are registered
(deepseek-fetch-api, http); configure one explicitly
✅ 修复
cordis.patch.yml 补回 fetchProvider: http —— web 行现在同时重述两个 key
(fetchProvider 保持 base 默认值 http,即免费的本地抓取器)。
📊 兼容性
| DSH | 状态 |
|---|---|
| 0.2.1-rc.2 | ✅ 本版修复后可用 |
| 0.2.0-rc.2 | ✅ 可用(该版本 base 无 fetchProvider,多写一个 key 无副作用) |
| ≤ 0.1.6 | ❌ 不支持 |
另外 peerDependencies 的 @deepseek-ai/dsh-web 从 ^0.2.0-rc.2 改为 >=0.2.0-rc.2 <0.3.0
(semver 规则下 ^0.2.0-rc.2 不匹配 0.2.1-rc.2 —— 预发布只与同 major.minor.patch 比较)。
安装 / 升级
cd $DSH_HOME/profiles/web
pnpm add @godchen520/dsh-web-search-bing
# 重启 dsh web📋 完整技术细节(点开看 CHANGELOG 原文)
修复(严重)
-
cordis.patch.yml补回fetchProvider: http。DSH 0.2.1-rc.2 给 base 的
web行新增了fetchProvider: http。而 cordis
patch 的语义是整体替换config而非合并,本插件的 patch 此前只重述了
searchProvider,于是新出现的fetchProvider被静默抹掉。后果:
http与新版新增的deepseek-fetch-api两个抓取 provider 同时可用且
没有显式选择,每一次web_fetch调用都失败并抛:WEB_PROVIDER_AMBIGUOUS: multiple usable web providers are registered (deepseek-fetch-api, http); configure one explicitly修复后
web行同时重述两个 key(fetchProvider保持 base 默认值http,
即免费的本地抓取器;deepseek-fetch-api走 DeepSeek 付费 Search/Fetch API)。
说明(为什么这类 bug 会发生)
补丁层必须重述目标行拥有的每一个 key,否则被省略的 key 会在整个组合里消失。
dsh-base 自己的注释也写了这一点("a patch replaces the targeted row's whole
config … each row below restates every key it owns")。本文件顶部现已加入醒目
警告,升级 DSH 时需要对照 base 的 web 行同步这份 key 列表。
兼容性
| DSH | 状态 |
|---|---|
| 0.2.1-rc.2 | ✅ 本版修复后可用 |
| 0.2.0-rc.2 | ✅ 可用(该版本 base 无 fetchProvider,多写一个 key 无副作用) |
| ≤ 0.1.6 | ❌ 不支持 |
peerDependencies 的 @deepseek-ai/dsh-web 从 ^0.2.0-rc.2 改为
>=0.2.0-rc.2 <0.3.0:语义化版本对预发布版的处理规则下,^0.2.0-rc.2 不匹配
0.2.1-rc.2(预发布只与同 major.minor.patch 比较),换用区间表达式更准确。
v1.2.2 — 发布到 npm(改用组织作用域名)
v1.2.2 — 发布到 npm(改用组织作用域名)
运行时行为与 1.2.1 完全一致,本版只改包的身份与分发方式。
改动
- 包名改为
@godchen520/dsh-web-search-bing—— npm 上的dsh-web-search-bing
已被其他开发者占用,因此改用组织作用域名。GitHub 仓库名不变。 cordis.patch.yml中插入行的name同步改为作用域名
(该名字从 profile 的node_modules解析,必须与包名一致)package.json补齐repository/homepage/publishConfig.access=public- README / README_EN 安装章节:改为
pnpm add @godchen520/dsh-web-search-bing - 新增
.github/workflows/publish.yml:Release 时经 Trusted Publishing(GitHub OIDC)
自动发布到 npm,不需要任何令牌,并生成 SLSA 来源证明
⚠️ 从旧版本升级注意
老名字 dsh-web-search-bing 与新名字不能并存。升级时请把 profile 里
dependencies 的键和 dsh.profile.bundles 里的条目一起换成作用域名,否则
插件会在下次重启时加载失败(包目录名与 patch 行名不一致)。
// profiles/web/package.json
"dependencies": {
"@godchen520/dsh-web-search-bing": "^1.2.2" // 原来是 "dsh-web-search-bing"
},
"dsh": { "profile": { "bundles": [
// ...
"@godchen520/dsh-web-search-bing" // 原来写的是 "dsh-web-search-bing"
] } }安装
cd $DSH_HOME/profiles/web
pnpm add @godchen520/dsh-web-search-bing
# 把 @godchen520/dsh-web-search-bing 加进 dsh.profile.bundles,重启 dsh webv1.2.1 — 补齐端到端测试与开发依赖
v1.2.1 — 补齐端到端测试与开发依赖
纯开发侧改动:运行时行为与 1.2.0 完全一致,发布产物
lib/未变。
✨ 新增:可复跑的端到端测试
tests/e2e.provider.test.mjs —— 直接 import 真实的 BingFreeSearchProvider(不复制解析逻辑),用桩 fetch 驱动两种传输,因此走的是与运行时完全相同的代码路径。
离线 41 项(确定性,可进 CI):
- RSS 优先:默认只发一次请求且带
format=rss;publishedAt正确映射(含中文pubDate) - HTML 兜底:
preferRss: false时强制走 HTML,且不请求 RSS - 回退触发:RSS 返回非 feed、返回 HTTP 500 —— 都要回退到 HTML
- 取消不被吞:
AbortSignal取消后抛WEB_ABORTED,不继续回退 - 空 query / captcha 页:抛结构化
WEB_PROVIDER_ERROR,不伪装成「无结果」 maxResults截断、provider 元数据
--live 额外 7 项:真实请求 cn.bing.com,验证两条通道的线上行为,并断言标题/摘要无残留实体、无「阅读更多」UI 尾巴。
🔧 开发依赖与脚本
devDependencies:@deepseek-ai/dsh-web、@deepseek-ai/schemastery—— 测试需要 import 真实插件代码,而插件会 import 这两个官方包(不进发布产物)npm test—— 离线测试(40 项纯解析 + 41 项端到端)npm run test:live—— 额外含真实网络(+7 项)package-lock.json—— 锁定开发依赖版本
📝 背景
此前 CHANGELOG 里写的「真实网络 e2e 12 项」是开发时临时脚本跑的,代码未入库、无法复跑。本版把它固化为可重复执行的测试 —— 任何人 clone 后执行 npm install && npm test 即可验证,不再只是一句声明。
npm install
npm test # 离线,81 项
npm run test:live # 含真实网络,88 项兼容性
| DSH 版本 | 状态 |
|---|---|
| 0.2.x(0.2.0-rc.2 实测) | ✅ |
| 0.1.7 ~ 0.1.x | ✅ |
| ≤ 0.1.6 | ❌ |
v1.2.0 — 双通道:RSS 优先 + HTML 兜底
v1.2.0 — 双通道:RSS 优先 + HTML 兜底
✨ 新增:RSS 通道(默认优先)
改用 Bing 的 &format=rss 输出作为主路径。每个 <item> 直接给出 <title> / <link> / <description> / <pubDate>,无需 HTML 启发式解析。
- 体积:从 ~100 KB HTML 降到 ~4 KB XML
- 摘要质量:RSS 的 description 是完整段落,从结构上杜绝了「实体解码」「阅读更多 UI 尾巴」这类问题
- 新字段
publishedAt:来自<pubDate>,这是 HTML 通道拿不到的 - 抗变化:Bing 改 HTML class 名不再影响主路径
🛟 HTML 通道保留为兜底
RSS 返回 0 条、返回非 feed 内容、或请求失败时自动回退到 HTML 解析。取消信号(AbortSignal)不会被兜底吞掉。
新配置项 preferRss(默认 true,.volatile())—— 设为 false 可强制走 HTML。
🐛 修复
search()返回合约:HTML 分支此前直接返回 sources 数组,未包成{ sources, truncated },会导致 seam 拿到undefined。由真实网络 e2e 测试发现。
📝 实测结论(写进 CHANGELOG 供参考)
- RSS 不改变相关性:同一 query 下 HTML 与 RSS 返回完全相同的 10 条结果,顺序一致。RSS 的收益在健壮性、体积与摘要质量,不在排序。
&count=对两种通道均无效,Bing 每页固定约 10 条。- RSS 的
pubDate是本地化 RFC-822(如周三, 30 9月 2026 13:31:00 GMT),new Date()解析为Invalid Date(已实测)。故parseRssDate()先试原生、再手工组装中文月份/星期。
✅ 校验
- 单元测试 40 项通过(HTML 解析 / 实体 / UI 清理 / RSS feed / 本地化 pubDate)
- 真实网络 e2e 12 项通过(RSS 优先、强制 HTML、RSS 非 feed 回退、RSS 抛错回退、取消不被吞、空 query)
- 真实 seam 集成:
ctx.web.search()命中bing-free,339 ms,4 条 +truncated: true,每条带publishedAt
兼容性
| DSH 版本 | 状态 |
|---|---|
| 0.2.x(0.2.0-rc.2 实测) | ✅ |
| 0.1.7 ~ 0.1.x | ✅ |
| ≤ 0.1.6 | ❌ |
v1.1.1 — 适配 DSH 0.2.x
v1.1.1 — 适配 DSH 0.2.x 配置 API
⚠️ Breaking(针对旧版 DSH)
DSH 0.2.0-rc.2 移除了 @deepseek-ai/dsh-settings 的 settingsNamespace() 与 installSettingsSection()。继续使用会在模块链接阶段直接抛 SyntaxError,插件无法加载。本版已完成适配。
- 移除
@deepseek-ai/dsh-settings依赖与 import - 三个配置字段改为
.volatile(),由 host 从导出的Configschema 自动生成设置表单;运行时通过config.field.get()读取实时值 - 新增
readField():同时兼容.get()访问器与纯值配置对象 peerDependencies收敛为dsh-web/cordis/schemastery(移除已不使用的dsh-agent、dsh-settings)inject回到["web"](与官方dsh-web-search-deepseek一致)
兼容性
| DSH 版本 | 状态 |
|---|---|
| 0.2.x(0.2.0-rc.2 实测) | ✅ 支持 |
| 0.1.7 ~ 0.1.x | ✅ 支持(readField 兼容两种配置形态) |
| ≤ 0.1.6 | ❌ 不支持 |
修复(实测发现)
- 命名实体解码:真实 Bing 摘要含
 、·、 、—等命名实体,原实现只处理少数几个,导致摘要里出现 字样。现引入NAMED_ENTITIES表统一解码,并保持单遍替换(&lt;不会被二次解码成<) - 摘要 UI 尾巴:Bing 每条摘要尾部带「阅读更多」/「Read more」链接文字,属页面 UI 而非正文。新增
cleanSnippet()去除,句末真实句号保留
新增
tests/parse.smoke.test.cjs—— 25 项 HTML 解析测试(含真实抓取样本、实体解码、UI 尾巴剥离)
文档
- README 增加与内置
deepseek-official搜索的对比表、DSH 兼容性表、工作原理图 - LICENSE 修正项目名(原为
dsh-web-search-duckduckgo)
如果你在用 DSH 0.2.x 且本插件加载失败,请更新到本版本。
v1.0.2
Bing free search provider v1.0.2 - renamed from duckduckgo, switched to cn.bing.com for China accessibility
v0.1.0
Bing 免费搜索 provider 插件,为 DeepSeek Harness 提供网页搜索能力。
- 免费使用 cn.bing.com(国内可达)
- 无需 API Key
- 不消耗 DeepSeek 搜索配额
- 安装即用