dsh-approval-timeout:为 DSH 授权与提问等待加上超时

前言

在 DeepSeek Harness(DSH)里跑 agent 时,浏览器 Web UI 会在两类场景下阻塞整条链路:工具需要用户点「批准 / 拒绝」的授权(approval),以及 agent 通过 ask_user_question 向用户提问。Harness 会一直等到有人点击为止。人离开屏幕、会话挂着不动时,agent 可能长时间卡在授权或提问面板,既占着会话,也谈不上「没人应就按安全侧默认收尾」。

原生 DSH 对这两种等待没有截止时间。下面介绍社区插件 dsh-approval-timeout(维护者 EviMing,分类 admin-security):在 Web 客户端 为当前阻塞中的授权与提问设置可配置超时,到点按与手动操作等价的语义自动结束等待,避免无限挂起。

这是什么

dsh-approval-timeout 是面向 dsh web 的 DSH 插件(npm 包名 dsh-approval-timeout,当前版本 1.1.0,MIT 许可证)。它不改变服务端 profile 文件,也不发网络请求;只在浏览器里读取当前会话的 pendingInteraction,在截止时刻调用与用户点击相同的路径完成收尾。

插件目录页:https://www.skillhub.cn/plugins/EviMing/dsh-approval-timeout(社区 SkillHub 目录,与 DeepSeek / 幻方无官方从属关系)。源码与说明:https://github.com/EviMing/dsh-approval-timeout。

核心行为

默认超时 10 分钟(可在 UI 中调整或选「关闭」恢复原生无限等待)。没有等待中的交互时,插件完全静默。

授权(approval)

超时且用户未点击时,自动按 拒绝 处理:写入与用户点「拒绝」一致的 approval/decided: rejected 审计事件,面板消失,工具调用以拒绝结束(fail closed)。插件 没有 任何自动批准的路径。

提问(ask_user_question)

超时且用户未回答时,自动按 跳过 处理:等价于每道题留空并点「跳过」,agent 收到 { answers: [{ id, selected: [] }, ...] },表示用户未作答,不会默许,也不会伪造回复;面板消失,工具返回空答案并继续。

若用户正在作答(面板聚焦或输入框编辑中),截止时间 顺延 60 秒,避免写到一半被掐断。

故意不处理的等待

只处理「当前真的阻塞 agent、且面板仍有效」的请求,例如:

  • 已结算、只读的提问卡片;
  • 已断开实时通道的旧卡片(continued);
  • 客户端自带倒计时的提问(ask_user_question 的 timed 模式);
  • 计划审批(plan-review):不自动跳过,避免超时后 agent 改 plan 再提、形成循环;
  • 没有 callId、又无法取消的卡片:仅 dismiss() 收起面板,不假装结束请求。

为什么在客户端实现

授权与提问面板由 @deepseek-ai/dsh-client-ui-approval、@deepseek-ai/dsh-client-ui-user-questions 等在浏览器渲染;HOST 侧 waterfall 转发请求并等待客户端作答。若在 HOST 侧抢先 return,面板可能仍在而工具已结束,用户再点会变成空操作。因此插件读取 ctx.uiSession.sessionStatus 中的 PendingApproval / PendingQuestion,到点调用 pending.answer('rejected')、pending.answer({ answers: [...] }) 或 pending.dismiss(),与用户按钮同一路径,保证审计、面板与工具结局一致。

安装与启用

安装前建议自行查看 GitHub 源码与 MIT 许可证;插件在 当前 DSH Web 会话对应的浏览器环境 中运行,副作用限于一次 pending.answer(...) 与 localStorage 中的一个整数。

官方 README 给出的安装方式:

dsh plugin --profile web add github:EviMing/dsh-approval-timeout
# 或用 npm 包(如有发布):
dsh plugin --profile web add dsh-approval-timeout

安装后重启或刷新 dsh web。输入框(composer)下方会出现一行控件,例如:

审批/提问超时   [10 分钟 ▾]

卸载:

dsh plugin --profile web remove dsh-approval-timeout

或在插件页禁用后刷新,README 说明不留残留。

典型用法

  1. 用下拉框选择超时:关闭 / 1 / 3 / 5 / 10 / 15 / 30 / 60 分钟,立即生效并记住。
  2. 有授权在等待时,该行变黄并显示倒计时,例如 bash: 9:58 后自动拒绝。
  3. 有提问在等待时同样变黄,例如 提问:9:58 后自动跳过。
  4. 设置保存在浏览器 localStorage,键名为 dsh.approval-timeout.minutes,按浏览器 profile 持久化;无服务端配置项。

适用场景与注意

适合在 dsh web 无人值守或长时间离开 时,避免 agent 永久卡在授权/提问 UI;也适合希望「超时默认拒绝授权、跳过提问」的安全偏好(与 fail closed、不伪造用户答案的设计一致)。

兼容性:README 写明在 dsh 0.2.0-rc.2(dsh web)上测试,依赖 @deepseek-ai/dsh-client-ui-session、@deepseek-ai/dsh-client-ui-approval,提问部分与 @deepseek-ai/dsh-client-ui-user-questions 协作。桌面版若捆绑更旧 dsh、缺少 uiSession.sessionStatus,插件会保持静默而不报错。

安全侧要点(来自 README):无网络请求、不读凭据、不写 document.body;仅上述两类客户端副作用。计划审批仍建议人工处理,不要指望本插件替你在 plan-review 上超时跳过。

结尾

dsh-approval-timeout 用可配置的超时,把 Web UI 里两种最常见的「等人点击」等待收成可预期的拒绝或跳过,而不是无限阻塞。需要安装命令、边界行为与实现理由时,以仓库 README 为准。

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

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

小夜