dsh-deferred-approvals:DSH 非阻塞审批与定时提问

前言

在 DeepSeek Harness(DSH)里跑智能体时,一旦工具调用触发权限审批,原生流程往往会让整轮对话停在那里,直到你在界面上点允许或拒绝。你稍走开几分钟,模型就只能干等,同一回合里本来还能做的其它步骤也推进不了。ask_user_question 若一直等用户回答,同样会占住回合。

社区插件 dsh-deferred-approvals(维护者 Hao0311,分类 admin-security)把这两类交互改成「可稍后处理」:审批先挂成待办、工具立刻拿到「未执行」结果,模型继续干活;用户对问题的回答则走 DSH 内置的 timed 模式,超时后模型先继续,卡片仍保留供你补答。下面介绍它的定位、权限边界、安装配置与使用上需要注意的限制。

这是什么

dsh-deferred-approvals 是一个 DSH 插件 bundle,当前包版本 0.3.1(MIT 许可证),要求 DSH ≥0.2.1-0。它做两件事:

  1. 非阻塞审批:宿主本来就要弹审批的工具调用,由插件拦截并记为待办(编号如 #A1),同一 assistant 回合可继续做其它工作;你在输入框附近的「待处理审批」卡片里再允许或拒绝。
  2. 定时提问:把 standard 预设里的 ask_user_question 配成 timed 模式(能力来自 @deepseek-ai/dsh-tool-ask-user),提问后默认最多等一段时间,超时返回 {pending:true, callId},模型不阻塞。

目录页:SkillHub 插件页。源码与说明:GitHub — Hao0311/dsh-deferred-approvals。

权限边界(使用前先弄清)

审批权限属于宿主(sandbox / approval 层),不是对话里的「口头批准」。

  • 模型在 workspace-write 沙箱下只能发起 sandbox_permissions 升级请求;是否要审批完全由原生策略/沙箱决定。会话策略为 never 或原生不需要审批时,插件默认不介入(forceAskPolicy 默认为 false,不会擅自改会话策略)。
  • 插件在 approval/request 最外层拦截请求,给工具返回「未执行」,并登记待办;唯一授权来源是你在 UI 上点击(允许一次 / 本对话允许同类)。宿主记录「工具 + 参数指纹」的一次性授权,默认 5 分钟过期、用掉即销。
  • 批准后模型收到的是宿主事件通知(在 Chat 里多为上下文行,不是用户气泡),用于提示可以重试;对话内容不能授予权限。重试时 command 等实际参数必须与指纹一致,justification / description / timeoutMs 不参与指纹。

弄清这一点,可以避免误以为「模型说已批准」就等于已授权。

核心功能:非阻塞审批

和原生行为的对比

  • 以前:审批一出现,整个 turn 停住,必须等你点击。
  • 现在:审批变成后台待办;模型可跑其它子任务或换不需要提权的路径;你回来再在卡片里处理。允许一次后,重试时宿主按一次性授权放行,不再弹框。「本对话允许同类」会为会话记规则,之后同类请求直接放行,并已排队的同类待办可一并批准。

会话列表里对应对话旁会出现与原生审批类似的橙色小点,提示有待处理项。

工作方式概要

  1. 拦截:在审批瀑布最外层拿到请求,台账记下工具名、参数指纹、权限级别与理由,立刻对本次调用返回 rejected(工具层显示未执行)。
  2. 改写结果:经 tools/post-execute 把文案改成「已挂起为待办 #A1,不要等待也不要反复重试」等说明;若已用其它方式完成,可调用 pending(action="cancel") 撤销。
  3. 模型继续:同一回合内继续后续步骤。
  4. 用户决定:允许一次、本对话允许同类、拒绝或忽略;拒绝可带备注引导模型换方式。
  5. 送达:用户决定后通过宿主事件(source.kind = 'deferred-approval')通知模型。模型空闲时用 agent.followup;若正在长考且本会话没有工具在执行,默认会中断当前思考再投递(interruptOnDecision 默认为 true);有工具在执行则退回到 agent.steer,避免杀掉运行中的命令。
  6. 台账与幂等:批准/拒绝/忽略/过期/撤销都会记入「最近决定」;pending 的 list / cancel 可给出确定答复。同一按钮重复点击幂等;decide 带 sessionId 时会校验待办归属。
  7. 过期:待办默认 15 分钟过期,静默作废、不唤醒模型。

插件还提供 pending 工具,用于查询待办、最近决定和已放行规则;HTTP 路由在 /api/deferred-approvals/*(Host 侧)。

核心功能:定时提问(合并自原 dsh-timed-questions)

同一 bundle 通过 cordis.patch.yml 覆盖 standard 预设,把 ask_user_question 设为 timed 模式:

  • 提问后最多等 timeout 秒(默认 20);超时返回 {pending:true, callId},模型继续工作。
  • 问题卡片保留,可随时回答;回答作为用户消息送回(模型在跑则下一步收到,空闲则开新一轮)。
  • 单次调用可用 timeout 覆盖;-1 表示这次必须等到回答。

生效范围是新会话;已存在会话沿用启动时的预设组合,需新开对话才能用到 timed 配置。

DSH 升级后官方 standard 预设可能与本地 patch 副本漂移;插件启动时会对比并尝试重新生成(保留 mode: timed 与 timeout),并提示需重启后新会话才生效。也可手动执行:

node check-preset-drift.mjs --regenerate

安装与启用

面向 Web profile 的官方安装命令如下(与 README 一致,注意仓库名为 Hao0311):

dsh plugin --profile web add github:Hao0311/dsh-deferred-approvals

开发时可在工作区 plugins/dsh-deferred-approvals 目录,通过 plugin_manager 的 install_bundle 以该绝对路径为 target 安装。安装后 Client 半通常会自定加载;Host 半源码修改需重启 DSH 才生效(已 import 的模块默认不热替换,除非开启 HMR 源码监听)。

依赖方面,插件仅使用 node:crypto 与 ctx 服务(tools / approval / agents / systemPrompt,以及可选的 connection、typertGateway);Client 侧使用 slots / locale / uiSession。

卸载时用 plugin_manager 的 remove_bundle(target 为 dsh-deferred-approvals),审批与定时提问会恢复原生行为。

配置

配置写在 profile patch 里该插件 id 下的 config 字段,全部可选;仓库未导出 Config schema,加载期不做校验。

键 默认 含义
ttlMinutes 15 待办有效期(分钟)
grantMinutes 5 「允许一次」的一次性授权有效分钟数
softCapAway 20 无在线客户端时的待办上限
forceAskPolicy false 是否把显式 never 的根会话策略切回 ask
requireLiveClient true 无在线 Web 客户端时交回原生审批,不做挂起
excludeTools [] 不接管列出的工具的审批
interruptOnDecision true 用户决定时,纯长考场景是否中断思考并立即送达
sweepMs 20000 过期清理间隔

示例片段:

- id: deferred-approvals
  config:
    ttlMinutes: 15
    softCapAway: 20

典型用法(流程侧)

没有单独的「一键 Demo」脚本;实际使用跟随 DSH 里会触发审批的工具调用即可。可按下面 mental model 自测:

  1. 在 ask 策略且 Web 客户端在线 的会话中,让模型发起需要审批的命令(例如沙箱外写盘、需要 sandbox_permissions 的调用)。
  2. 观察工具结果是否为「已挂起为待办 #Ax」,且模型是否在同一回合继续其它步骤。
  3. 在输入框附近的待处理卡片选择「允许一次」或「本对话允许同类」,确认模型收到通知后重试且宿主放行。
  4. 若模型已用其它方式完成同一目标,应依提示调用 pending(action="cancel"),避免重复执行。

定时提问侧:新开会话后让模型调用 ask_user_question,等待超过默认 timeout,确认模型继续执行且卡片仍可作答。

仓库内回归测试(零依赖,Node ≥18):

node test/run.mjs

退出码 0 表示当前文档记载的 38 项断言全部通过。

适用场景与注意

适合谁:长时间 unattended 跑任务、又偶尔需要点审批的 DSH 用户;希望审批与追问不要占满整轮 turn 的智能体开发者。

务必注意:

  • 插件在当前 DSH 进程权限下运行;安装前请自行查看源码与 MIT 许可证,确认符合你的安全策略。
  • 待办只在 Host 内存里,DSH 重启后丢失;原生审计对挂起记 rejected,批准细节 v1 未落盘。
  • 需要 ask 策略 + 在线 Web 客户端(requireLiveClient 默认 true);never 时审批在插件之前就结束,插件收不到请求。
  • 批准后不会自动执行工具,由模型核对后重试,以保证调用仍出现在会话日志与 UI。
  • 参数一改指纹即变,会重新挂起,这是权限边界设计,不是误杀。
  • 社区目录 SkillHub 与 DeepSeek / 幻方无官方从属关系;DSH 生态是「一切皆插件」,本介绍事实均来自上述 GitHub README 与 package 元数据。

结尾

dsh-deferred-approvals 把审批变成可稍后处理的待办,并把 ask_user_question 接到 timed 模式,减少「人等机器、机器等人」的空转。若你经常在 DSH Web 里跑需要点头的工具链,可在 profile 里安装后,结合 ask 策略与在线客户端条件试一轮。

  • 目录页:https://www.skillhub.cn/plugins/Hao0311/dsh-deferred-approvals
  • 源码:https://github.com/Hao0311/dsh-deferred-approvals
羽毛球分组比赛记分
小程序二维码

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

小夜