前言¶
如果你在用 DSH(DeepSeek Harness)的 web 模式跑智能体,大概率遇到过这两个问题:
1、工具调用触发审批窗,你点「拒绝」,但模型不会停下,而是继续下一轮思考,猜测你拒绝的原因、换一个方案接着跑。
2、你手动停止任务,拒绝这件事不进模型上下文,下一次请求就像什么都没发生过。
真实协作里,拒绝通常附带原因:「不要动这个文件,改到工作目录去」。默认审批流程既不接收这个原因,也不让模型基于它重新思考。dsh-approval-comment 就是为补齐这一环而写的插件。
这是什么¶
dsh-approval-comment 是一个 DSH Web 审批增强插件,由 MaYiFei1995 维护,MIT 许可证,当前版本 0.1.0。它的定位是无感替代内置审批窗口:审批窗保持原样(警示条、工具名、允许一次/拒绝),新增一个附言输入框;拒绝后终止当前回合,让模型重新结合附言思考。
它是纯 host + client 双半区插件,零第三方依赖、零构建步骤(纯 JS),不修改任何 @deepseek-ai/dsh* 核心包,因此核心升级不会覆盖本插件。安装进 web profile 即生效,下次 dsh web 启动自动加载。
README 中声明:本项目代码及文档由 deepseek-v4-pro 模型生成。
核心行为¶
插件支持「允许一次/拒绝 × 无附言/有附言」四种组合:
| 允许一次 | 拒绝 | |
|---|---|---|
| 无附言 | 继续执行 | 中断任务(停止,等待下一条指令) |
| 有附言 | 附言一并生效,继续执行 | 据附言调整并自动继续(不停止) |
几个关键点:
- 拒绝并附言:附言经
session.prompt(…, 'steer')注入当前回合,模型读到「拒绝 + 附言」后据此调整,自动继续,不停止。 - 无附言的纯拒绝:
agent/pre-step守卫返回{ kind: 'reject' }终止当前回合,模型停止并等待你的下一条指令。 - 允许并附言:附言同样以 steer 注入,工具照常执行,模型在下一步读到附言并据此调整。
- grant-next 一次性放行:附言后模型调整出的越权调用自动放行,全程只弹一次审批窗。
- 拒绝与附言都留在 transcript 中,手动停止后也不丢上下文。
对无人值守场景也做了兼容:approval/policy = 'never' 的自动拒绝在应答链之前短路,不受停止守卫影响,CI 行为与现状一致。
工作原理¶
插件分两个半区:
| 半区 | 文件 | 作用 |
|---|---|---|
| host | lib/index.js |
approval/request 前置监听:观察拒绝结果 + grant-next 一次性放行;agent/pre-step 守卫:纯拒绝 → { kind: 'reject' } 终止回合,拒绝+附言 → 放行 |
| client | lib/client.js |
以 conversation.composer 链 priority: 0 顶替内置审批面板,新增附言框;允许/拒绝时若有附言,先经 session.prompt(…, 'steer') 注入附言再应答 |
以「拒绝并附言」为例,完整时序是:
模型调用需越权的工具
→ 审批面板(本插件版)弹出,附言框可用
→ 用户填写说明并点「拒绝」
a) 附言经 session.prompt(…, 'steer') 注入当前回合(插话)
b) 应答 rejected → 工具结果 = the user rejected tool "X"(核心文本,不可改)
→ agent/pre-step 守卫:检测到刚被拒绝,且本步消息里有附言 → 放行(不终止)
→ 模型读到「拒绝 + 附言」→ 据附言调整并自动继续
→ 调整的越权调用命中 grant-next → 自动放行,不再弹第二次审批窗
安装与启用¶
前置要求 Node >= 18。官方推荐从 GitHub Release 远程安装:
dsh plugin --profile web add https://github.com/MaYiFei1995/dsh-approval-comment/releases/download/v0.1.0/dsh-approval-comment-0.1.0.tgz
如果目标设备不便联网,先从 Release 下载 .tgz(或本机 npm pack 生成),再用本地路径安装:
# 绝对路径
dsh plugin --profile web add C:\path\to\dsh-approval-comment-0.1.0.tgz
# 相对路径(锚定到执行命令的目录)
dsh plugin --profile web add ./dsh-approval-comment-0.1.0.tgz
也可以直接从 git 源安装:
dsh plugin --profile web add git+https://github.com/MaYiFei1995/dsh-approval-comment.git
注意:git 源安装会运行 prepare 脚本,pnpm 默认拦截,需按 pnpm 提示把包名加入 profile 的 pnpm-workspace.yaml 的 allowBuilds。Release tarball 是预构建产物,无需此步。
安装后重启 dsh web(Ctrl+C 后重新 dsh web)生效。用下面的命令验证:
dsh --profile web --dump-config # 应能看到 approval-comment 行
卸载:
dsh plugin --profile web remove dsh-approval-comment
卸载后同样重启 dsh web 生效,可再用 --dump-config 确认 approval-comment 行已移除。
客户端半区改动后需要浏览器硬刷新(非 dev 模式无热更新),排查「改了没生效」时先确认这一点。
构建与分发¶
如果你要自己改代码或发布:
npm run check # 契约校验(host/client 半区、package.json、cordis.patch.yml 的挂载契约)
npm run build # 别名:同 check(本插件纯 JS,无需转译)
npm pack # 产出 dsh-approval-comment-<version>.tgz
仓库自带 GitHub Actions:push 时跑语法+契约校验并产出 tarball,推 v* tag 时自动把 tarball 作为 Release 资产发布。
已知边界¶
使用前需要了解几个边界:
- grant-next 是一次性授权、回合作用域:只放行附言后紧接着的那一次越权调用,
turn/end或离开附言调整步即作废,不跨回合残留。 - 允许+附言时原命令先执行:审批语义是「批准本次调用」,附言无法改写已定参数,旧参数命令先执行,模型再据附言自动修正。要完全跳过旧参数需上游支持改参执行。
- 审批面板以
reason(或「工具 X 请求越权执行」)为标题,内置面板额外显示的命令原文未复刻。 - 若目标设备无可用审批 UI(非 web 场景),应答链回退为
unavailable,行为与现状一致。
适用场景与注意¶
这个插件适合经常在 dsh web 下与审批窗交互的开发者:你希望拒绝时带上原因、让模型按你的意图修正,而不是让它自己猜;也希望手动停止后对话上下文不丢失。如果你主要跑无人值守/CI 流程,现有 approval/policy = 'never' 的行为不受影响,无需为此安装。
最后提醒一点:插件以当前 dsh 进程的权限运行,安装前建议检查源码(本插件就两个文件 lib/index.js 和 lib/client.js,均为纯 JS、零依赖,审查成本不高)并确认许可证条款。
结尾¶
dsh-approval-comment 解决的是一个很具体的问题:让审批交互里的拒绝带上原因,并让模型基于原因重新思考,而不是猜测或丢上下文。实现上不碰核心包、零依赖,安装和卸载都可以随时回退。
- GitHub:https://github.com/MaYiFei1995/dsh-approval-comment
- 社区目录页:https://www.skillhub.cn/plugins/MaYiFei1995/dsh-approval-comment
社区目录为独立站点,与 DeepSeek / 幻方无官方从属关系。