Delegating Rejection Reasons to the Model in DSH Permission Approval

前言

DeepSeek Harness(DSH)在 Agent 请求越权执行时会弹出权限审批,原生界面只有「允许一次」和「拒绝」。模型收到的是工具被拒绝的结果,并不知道你是担心路径不对、命令太危险,还是这次只是在测流程。若希望模型据此改方案、先解释计划再申请权限,或明确说明「这次拒绝是故意的」,就需要把原因写进模型能读到的 channel,而不是另起一条用户消息。dsh-why-reject-me 是社区维护的 Host 插件,在审批面板上增加可选的「拒绝原因」输入框,并在你点拒绝且原因非空时,把原因追加到该次工具的 tool result 里,模型在同一轮对话中即可读到。

这是什么

dsh-why-reject-me 由 Jorgen233 维护,在 SkillHub 等目录中归类为 admin-security。它以 npm 包名 dsh-why-reject-me 发布(当前资料中的版本为 v0.3.3),源码仓库为 Jorgen233/dsh-why-reject-me。插件不修改 DSH 自带包,只在 Desktop 内嵌的审批界面运行;dsh-TUI 不使用该面板。留空原因再拒绝时,行为与原生 DSH 完全一致。

核心功能

下面介绍插件在审批链路上的具体能力,均可在 README 与安装后手测中核对。

拒绝原因进入 tool result

在「拒绝原因(可选)」中填写内容并点「拒绝」(或 Ctrl/⌘ + Enter)后,模型看到的 tool result 末尾会多出一段前缀加原因。中文界面前缀为 【审批请求已拒绝】原因:,英文为 [Approval request rejected] Reason:。例如:

【审批请求已拒绝】原因:先不要动系统目录,把 diff 发给我看。

原因只在拒绝时发送;点「允许一次」不会发送输入框里的内容。不输入原因直接拒绝,不会附加任何额外文本。

不新增用户消息

原因通过 Host 的 tools/post-execute 监听器追加到被拒绝工具的 result content,属于普通工具结果,不是 user/message,也不会单独再起一轮对话。

草稿与失败重试

未发送的草稿按「Session + Tool call」在页面内存中保留约 30 分钟,切换会话再回来一般不会丢字;刷新 Desktop 页面会丢失草稿。若原因提交失败,审批不会自动结束,面板会显示错误并允许重试。

快捷键

按键 行为
Enter(焦点不在输入框或按钮上) 允许一次
Ctrl/⌘ + Enter 拒绝并附上原因
Esc(焦点在输入框且有内容) 让输入框失焦
Esc(输入框为空) 直接拒绝

输入法组合输入期间按 Enter 不会触发审批动作。

安装与启用

插件以 Host 身份在 DSH 进程内运行,安装会修改当前 profile,影响该 profile 下的所有会话。安装前建议查看仓库源码与 MIT 许可证,只从 npm 上的 dsh-why-reject-me、本仓库或你信任的副本安装。

前置条件包括:DSH Desktop(资料中在 0.2.1-rc.5 上完成真实审批验证;0.2.1-rc.2 与 0.2.1-rc.5 均做过验证)。从 npm 安装不需要 Git;从 GitHub 安装需要本机有 Git 且能访问 GitHub。Host 半在启动时加载,安装或更新后需按提示重启 DSH Desktop,仅刷新页面可能不够。

方式一:从 npm 安装(推荐)

在 DSH Desktop 中:

  1. 打开左侧 Plugins(插件) 页面。
  2. 点 Add plugin(添加插件) → Install a third-party plugin(安装第三方插件)。
  3. 输入包名并安装:
dsh-why-reject-me
  1. 若出现 Enable now(立即启用) 则启用;在 Installed plugins 中确认开关已打开。
  2. 重启 DSH Desktop。

在启用了 plugin_manager 的会话(默认 Creator 模式)中,也可让 Agent 执行:

请在我的 DSH profile 中安装这个插件:
plugin_manager action=install_bundle target=dsh-why-reject-me

安装完成后确认 bundle 已启用,并告诉我是否需要重启 DSH Desktop。

方式二:从 GitHub 安装

在 Plugins → Add plugin 中填写:

git+https://github.com/Jorgen233/dsh-why-reject-me.git

Agent 等价写法:

plugin_manager action=install_bundle target=git+https://github.com/Jorgen233/dsh-why-reject-me.git

安装、启用与重启步骤同方式一。

确认安装

  • Plugins 列表中可见 dsh-why-reject-me 且为开启状态;
  • 将会话权限切到会触发审批的模式(例如 danger-full-access 下运行需审批的操作),审批面板应出现「拒绝原因(可选)」;
  • 输入原因并拒绝后,展开对应工具结果卡片,应能看到原因文本。

更新 npm 版时可先移除再安装:

plugin_manager action=remove_bundle target=dsh-why-reject-me
plugin_manager action=install_bundle target=dsh-why-reject-me

更新 Host 半后同样需要重启 DSH Desktop。

典型用法

经过上面的安装与重启,可按下面步骤在真实审批里使用。

  1. Agent 请求越权执行,审批面板出现。
  2. 在「拒绝原因(可选)」中填写说明,也可留空。
  3. 点「拒绝」,或按 Ctrl/⌘ + Enter。
  4. 原因先 POST 到 Host 的 /api/dsh-why-reject-me/reason 并暂存,随后审批以 rejected 结束;Host 在生成 tool result 时把原因追加到 content 末尾。
  5. 模型在同一 tool result 中读到原因并继续推理。

常见动机包括:不想放行某操作但希望模型换做法;测试权限流程时需要说明「故意拒绝」;要求模型先解释计划或给出 diff 再决定是否放行。

适用场景与注意

适合谁: 经常在 Desktop 里人工审批 Agent 工具调用、且希望拒绝附带可执行反馈的 DSH 用户。

工作原理概要: 客户端在 conversation.composer 链上接管审批面板(priority: 0),仅在待处理交互为审批且非子代理会话时生效;Host 在内存中按 Session + Tool call 暂存原因,5 分钟内未匹配到拒绝结果则丢弃;原因上限 2000 字。

务必知晓的限制:

  • 原因会作为 tool/result 的一部分进入会话记录,并随上下文发送给模型提供商;展开被拒绝工具的结果卡片时也能看到这段文本。
  • 子代理会话不适用:子代理上下文中插件不会接管审批,没有原因输入框,拒绝文案仍为运行时原文。
  • 只处理权限审批,不处理 ask_user_question 或其他确认框。
  • 原因附加后模型会读到,但不保证一定照做。
  • 若同时安装多个抢占 conversation.composer 的审批类插件,可能只有其中一个生效。

卸载时在 Plugins 页面关闭或卸载 dsh-why-reject-me 并重启 Desktop;已写入会话记录的原因不会被删除。也可用:

plugin_manager action=set_bundle target=dsh-why-reject-me enabled=false

或 plugin_manager action=remove_bundle target=dsh-why-reject-me。

结尾

dsh-why-reject-me 在不大改 DSH 审批模型的前提下,把「为什么拒绝」写进 tool result,方便模型在同一轮里调整行为;留空拒绝则保持原生体验。DSH 生态强调「一切皆插件」,社区目录(如 SkillHub)为独立站点,与 DeepSeek / 幻方无官方从属关系;本插件为第三方社区组件,非 DSH 官方内置。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye