修掉 DeepSeek Harness 里 buddy / CodeBuddy腾讯 渠道每个请求都返回 HTTP…
31.5/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add AsterLuo/dsh-buddy-guard该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · desktop
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 1 处,展示前 1 条)
- 写入本地文件lib/index.js:179
appendFileSync(join(home, 'buddy-guard.log'), new Date().toISOString() + ' ' + line + '\n')
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(118 字)↓
修复 CodeBuddy(腾讯)通道在 DeepSeek Harness 中返回 HTTP 400 Illegal API invocation from an unapproved channel 的问题:给系统提示词前面加一个空格。
README
由 DeepSeek 最新模型翻译生成dsh-buddy-guard
修掉 DeepSeek Harness 里 buddy / CodeBuddy(腾讯) 渠道每个请求都返回 HTTP 400 的问题:
buddy: 请求被拦截,请重新发送 Illegal API invocation from an unapproved channel
dsh plugin add github:AsterLuo/dsh-buddy-guard --profile <你的 profile>
固定版本(推荐,防止上游改动影响你):
dsh plugin add github:AsterLuo/dsh-buddy-guard#v0.1.2 --profile <你的 profile>
装完必须重启 DSH,然后在 buddy 渠道新开一个会话再试(已经在会话历史里的 system prompt,插件改不到)。
v0.1.2(2026-10-29):上游把第一道门收紧成 ^\s,前导空格对策彻底失效;插件改为直接改写句式。
见 第三道变更。
问题是什么
在 buddy 渠道选任意模型(hy4-preview、deepseek-v4.1-flash、hy3 …),每一轮都失败, HTTP 400 INVALID_REQUEST。同一个账号、同一个端点,只要请求不带 DSH 的 system prompt 就一切正常。
展开完整文档(README 剩余 1 节)
dsh-buddy-guard
修掉 DeepSeek Harness 里 buddy / CodeBuddy(腾讯) 渠道每个请求都返回 HTTP 400 的问题:
buddy: 请求被拦截,请重新发送 Illegal API invocation from an unapproved channel
dsh plugin add github:AsterLuo/dsh-buddy-guard --profile <你的 profile>
固定版本(推荐,防止上游改动影响你):
dsh plugin add github:AsterLuo/dsh-buddy-guard#v0.1.2 --profile <你的 profile>
装完必须重启 DSH,然后在 buddy 渠道新开一个会话再试(已经在会话历史里的 system prompt,插件改不到)。
v0.1.2(2026-10-29):上游把第一道门收紧成 ^\s,前导空格对策彻底失效;插件改为直接改写句式。
见 第三道变更。
问题是什么
在 buddy 渠道选任意模型(hy4-preview、deepseek-v4.1-flash、hy3 …),每一轮都失败, HTTP 400 INVALID_REQUEST。同一个账号、同一个端点,只要请求不带 DSH 的 system prompt 就一切正常。
上游目前有三道独立规则,全都回 400 / code 11128:
| # | 实测时间 | 规则 |
| 1 | 2026-10-21,2026-10-29 收紧 | system 文本以身份句开头 |
| 2 | 2026-10-27 | system 文本里短语 A 与短语 B 同时出现 |
| 3 | 见下 | 身份句判据忽略前导空白 |
第一道拦截:身份句(2026-10-21 实测,2026-10-29 收紧)
上游对 system 内容做开头匹配。只要 system 文本以
You are an AI agent powered by DeepSeek Harness.
开头就直接拒。下面这些全都无关(逐一改过,状态码一律 400):
- X-Domain(copilot.tencent.com vs www.codebuddy.cn)
- X-Product-Code / X-Product / X-Agent-Purpose
- X-IDE-Name / X-IDE-Type / X-IDE-Version / User-Agent
- 端点(copilot.tencent.com 与 www.codebuddy.cn 表现完全一致)
- 模型(hy4-preview、hy3、deepseek-v4.1-flash 全拦)
边界测试 —— 中间那列是 2026-10-29 之前有效的对策,右边是现在有效的:
| system 内容 | 2026-10-21 | 2026-10-29 |
| You are an AI agent powered by DeepSeek Harness. | 400 | 400 |
| 同一行前面加一个空格 | 200 | 400 |
| 前面加两个空格 | 200 | 400 |
| 前面加一个字母 / 一个句点 | 200 | 200 |
| Note: You are an AI agent powered by … | — | 200 |
| You are an AI agent, powered by … | — | 200 |
| 后面加空格 / 换行 / 句号 / 整段正文 | 400 | 400 |
| 这句话放进 user 消息 | 200 | 200 |
| 只有 DeepSeek Harness,或小写 deepseek harness | 200 | 200 |
第三道变更:第一道门被收紧(2026-10-29 实测)
上游只改了一个正则:
- ^You are an AI agent powered by … Harness
+ ^\sYou are an AI agent powered by … Harness
前导空白被忽略,于是所有「前面加个字符」的补丁全部作废 —— 这正是 v0.1.1 (前置一个空格)开始失效的原因:插件明明生效了,照样被拦。
现在插件改为改写句子本身:powered by → , powered by。
判据是整句式,不是关键词。2026-10-29 实测(同账号、同端点、同一条 user 消息):
| system 内容 | 结果 |
| 只有 DeepSeek Harness | 200 |
| powered by DeepSeek Harness. | 200 |
| You are an AI agent powered by Foo Harness.(换品牌) | 200 |
| You are an AI agent powered by DeepSeek Harness. | 400 |
| 同一句前面加 1 个或 2 个空格 | 400 |
| You are an AI agent, powered by DeepSeek Harness. | 200 |
| Note: You are an AI agent powered by … | 200 |
| I am an AI agent powered by … / running on … / 拆成两句 | 200 |
第二道拦截:A+B 组合指纹(2026-10-27 实测)
上游还有独立的一道规则:system 文本里同时出现下面两个短语时照样拒(AND 匹配,单独出现都放行):
- Tokens prefixed with @ are paths the user explicitly referenced
- Relative paths resolve from the workspace root
这两句都是 DSH system prompt 里描述 @ 路径引用语法的正文,每轮请求必带。
实测(同账号、同端点):
| system 内容 | 结果 |
| 只有短语 A | 200 |
| 只有短语 B | 200 |
| A 和 B 同时出现 | 400 11128 |
| 改写 A、B 保留原文 | 200 |
| 改写 B、A 保留原文 | 200 |
所以插件只改写 A,B 原样保留 —— B 描述的是 read / write / glob 依赖的相对路径规则,保留原文对模型最友好;改写与原文语义等价。
2026-10-29 复测:这条规则仍在。 对照实验:修好身份句、但把 A 还原成原文 → 仍 400。
所以 A 句改写不能删。
历史消息是盲区
上游会扫每一条消息,所以对话历史里出现过 A/B(或身份句)一样会被拦。插件对此无能为力: agent/request 的契约明确写着它 cannot mutate messages,而 llm/stream 的 options 是 deep-frozen(改就抛错)。如果某个会话引用过这些句子,请新开会话。
这个结论是怎么查出来的(可复现)
1. 取到完整的外发 system 文本 —— 最省事的是直接看会话日志: <DSH_HOME>/sessions/…/session.v4.jsonl.zstd,找其中的 system/message 事件。
⚠️ 该文件是多帧 zstd(header 帧 + 每批事件一帧)。zstdDecompressSync() 只解第一帧,直接读会看到一个只有 1 行的"空会话"。要按魔数 28 B5 2F FD 切帧、逐帧解。
2. 用该账号的 token + channel-pack 里 BuddyAdapter.send() 的请求头,把这段文本直接回放到端点。
3. 对首段做一次只改一个变量的矩阵(原句 / 加空格 / 插逗号 / 换主语 / 拆两句)。
只有在首段单独就能复现时才需要往下二分 —— 这次就是「前 1 段已经 400」,直接收敛到首段。
4. 把修法套回全量(十几万字)system 再打一次 —— 局部通过不等于整包通过,第二道门还等着。
被拦的请求不消耗 token,所以这套流程很便宜。
现成的端到端校验:真实加载插件 + 真实打上游
node docs/tools/buddy-guard-verify.mjs
期望:上游(原始) 400/11128 → 上游(插件输出) 200
插件怎么修
监听 system-prompt/assemble,对 config.providers 里的渠道返回改写过的 assembly:
1. 改写所有 section 里的身份句 —— 先剥掉前导空白,再把 You are an AI agent powered by 换成 You are an AI agent, powered by(幂等;不以该短语开头就不动);
2. 扫描每一个 section,把短语 A 改写成等价表述。
不要再退回去用前导空格。^\s 让它彻底变成空操作。
注册用 { global: true, prepend: true },prepend 是必须的:没有它,更外层只要有一个 不调用 next() 的监听器(例如 dsh-ops 的 discovery 分支会 return prompt.assemble(context)),按 cordis 的规则 "a listener that does not call next() vetoes the rest of the chain"* 就会把本插件整条短路 —— 插件照样加载、照样打日志、--dump-config 里也看得到,但请求一个字没变。
为什么不用 llm/stream
第一版就是钩 llm/stream 然后 next(改过的options) —— 完全无效,而且不报错。cordis 的 waterfall 实现是:
const next = () => (cbs.shift() ?? inner)(...args);
next 不接受参数,改过的 options 被直接丢弃。插件加载成功、日志正常、 --dump-config 里也能看到,但发出去的请求一个字节都没变。
改写入参只能靠监听器的返回值,不能靠给 next 传参。
安装
dsh plugin add github:AsterLuo/dsh-buddy-guard --profile <你的 profile>
这条命令会把包装进 profile 的 node_modules 并登记到 dsh.profile.bundles,你自己的 cordis.patch.yml 不会被改动。
然后重启 DSH —— 配置只在启动时读一次。
手动安装
1. 把本仓库复制到 <DSH_HOME>/profiles/<profile>/node_modules/dsh-buddy-guard/
2. 在该 profile 的 package.json 里,把 "dsh-buddy-guard" 追加到 dsh.profile.bundles
3. 同一个文件里,往 dependencies 加 "dsh-buddy-guard": "0.1.2"
4. 跑 --dump-config 确认里面有 buddy-guard 这一行
5. 重启 DSH
配置
- id: buddy-guard
name: 'dsh-buddy-guard'
config:
enabled: true
providers:
- buddy
- enabled —— 总开关。
- providers —— 要打补丁的渠道列表,默认 ['buddy'];其它渠道原样透传。
- debug —— 为 true 时每次命中写一行到 $DSH_HOME/buddy-guard.log。默认关闭,热路径不写盘。
装完怎么验
重启后把模型切到 buddy,发一句话。正常回复就是通了。还是 400 的话:
1. 重跑 --dump-config,确认 buddy-guard 那一行在。
2. 确认 lib/index.js 里有 PREFIX_REWRITES(0.1.2+)—— 升级会整包覆盖,本地热修会丢。
3. 确认包名在 dsh.profile.bundles 里 —— 这一步最常被漏。
4. 确认你真的重启了 DSH,并且开了新会话。
Full step-by-step troubleshooting (Chinese): docs/troubleshooting.zh-CN.md
注意
这是绕过上游内容审查。规则随时可能变,目前已知就有三道(其中一道还改过一次形态)。
哪天又报同样的错,先照着上面的「取 dump + 一次一变量」重做一遍,再决定改什么。
另外,出问题的那个账号是 CodeBuddy 中国版(www.codebuddy.cn,JWT 的 iss 指向那里),而客户端发的是国际版产品形态。这个不匹配本身就是上游说的 "unapproved channel" —— 本插件只是让它暂时能用,并没有解决这个不匹配。换用 workbuddy(国际版)可以完全绕开这道检查。
测试
npm test
许可
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
AsterLuo/dsh-buddy-guard
修掉 DeepSeek Harness 里 buddy / CodeBuddy腾讯 渠道每个请求都返回 HTTP…
相关插件 · 桌面端
Codex 任务面板chuspeeism/dashi-taskboard
现代化可灵活嵌入的任务面板,支持 Codex、DeepSeek Harness
★ 3,409已汉化DSH
71.7
多智能体自进化开发平台Prism-Shadow/penguin-harness
统一、稳定的 Agent 自进化框架全自动优化:任意模型 · 任意算法 · 任意 Benchmark
★ 3,111已汉化DSH
71.1
桌面宠物PC2005-cloud/dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI…
★ 5,341已汉化DSH
71
多端 Agent 工作台GCWing/OpenBitFun
OpenBitFun 是一个高度可定制的开源 Agent 工作台,让任务按你的方式持续推进。
★ 3,449已汉化DSH
70.8
DSH Desktopanywhere-labs/dsh-desktop
为 DeepSeek Harness DSH 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。
★ 34,532已汉化DSH
70.7
桌面宠物伴侣OpenPetsHQ/openpets
桌面伴侣平台,带宠物、插件,还能选配本地智能体集成。
★ 1,353已汉化DSH
70.2