dsh-wb-intl-guard
一条命令修掉 DeepSeek Harness 用 WorkBuddy 国际版(www.workbuddy.ai)时每轮都失败的 400。
workbuddy: 请求被拦截,请重新发送 request illegal (INVALID_REQUEST, 400)
上游真实响应:
{"code":11128,"msg":"request illegal",
"displayTips":{"zh":"这次调用没通过渠道校验,可能不是官方客户端发出的。"}}
根因
11128 在国际版网关上是渠道校验,跟 system 里写了什么字无关。同一账号、同一 token, 只换请求(本机实测 2026-11-01):
| 请求 | 结果 |
|---|---|
| 干净 prompt、无五件套 | 400 11128 request illegal |
真实 DSH system prompt(含 DeepSeek-Harness、(at) 文件引用段)、无五件套 |
400 11128 |
| 加五件套、但首条不是 system | 400 11128 first message is not system prompt |
| 五件套 + 首条 system | 200 流式响应 |
| 真实 prompt 原文(未做任何文本改写)+ 五件套 | 200 |
缺的是两样东西,缺谁都报同一个 11128:
- 渠道身份五件套请求头 —— 官方客户端每轮都带:
X-Trace-ID(32 位裸 hex)、X-Request-ID、X-Conversation-ID、X-Conversation-Request-ID、X-Conversation-Message-ID(UUID v4)。 - 首条消息必须是 system —— 否则 msg 换成
first message is not system prompt。
国内版 copilot.tencent.com 不校验这两样,所以本插件默认只作用于 www.workbuddy.ai。
顺带说明:那条「把
@改成(at)、DeepSeek-Harness改成DeepSeek-Harness」的 修法治的是国内网关的指纹匹配,对国际版无效——原文 + 五件套照样 200, 文本改写在这里是空转。
安装
零运行时依赖,只用 node 内置模块。需要 Node ^22.19.0 || >=24.0.0。
node install.mjs # 装到 desktop profile
node install.mjs <profile目录> # 装到指定 profile
node install.mjs --uninstall # 卸载
它做四件事:拷到 <profile>/vendor/dsh-wb-intl-guard、往 package.json 写
dependencies 与 dsh.profile.bundles(放最前,保证先包 fetch)、建 symlink 让模块可解析、
跑一遍 22 条自测。
装完完全退出 DSH 再打开(不是关窗口)。宿主日志里应该出现:
[I] [dsh-wb-intl-guard] fetch guard installed for www.workbuddy.ai
为什么挂在 fetch 层
另一条路是直接改渠道包的 vendor/channel-pack/pack.js,但插件一升级 vendor 就被覆盖,
得重打一次。fetch 层是宿主进程的最后一道:无论哪个渠道包发起请求都会经过它,
不受插件升级影响。
配置
cordis.patch.yml 里可调:
| 键 | 默认 | 说明 |
|---|---|---|
enabled |
true |
关掉就完全不碰 fetch |
gatewayHosts |
["www.workbuddy.ai"] |
要防护的 host;以 . 开头做后缀匹配 |
identityHosts |
同 gatewayHosts |
只在这些 host 上注入五件套 |
fallbackSystem |
You are WorkBuddy, a helpful AI assistant. |
首条不是 system 时补的内容 |
logPath |
"" |
空则写 ~/.dsh/logs/dsh-wb-intl-guard.jsonl |
dryRun |
false |
true 时只观测:请求一个字节都不改,只记 would-rewrite |
安全边界
- 只加请求头、只在首条补 system。user 与 tool 消息里的邮箱
a@b.com、@某人、 代码里的装饰器一个字不动。 - 只改受防护的 host。别家 API 原样透传。
- 非 JSON、非字符串、无 body 的请求原样透传。
- 幂等。已合法的 body 原样返回。
- fail-open。改写链路任何异常都退回原始请求,不阻断对话。
- 剔除陈旧的
Content-Length。body 变长/变短后若还带旧长度,上游会按旧长度截断。 - 日志脱敏。URL 只留 origin + path,查询串(可能带
prompt_cache_key、token)一律剥离。 - 只包一层 fetch。用
Symbol.for('dsh-wb-intl-guard.installed')保证,卸载时也不会覆盖别人后来装的 fetch。
验证
node --test # 22 条自测
tail -f ~/.dsh/logs/dsh-wb-intl-guard.jsonl # 看真实流量是否被注入
日志里出现 identity-added 就说明五件套真的上了请求;system-added 表示补了兜底 system。
已知限制
- 网关若不再校验渠道身份,插件空转(五件套仍会加,无害)。
- 本插件只解决
11128。429(额度)与11101(非流式请求)与它无关。 - 磁盘文件与运行中进程是两回事:装完不重启,进程里仍是旧代码。
许可
MIT
No comments yet. Be the first to write one.