dsh-tool-wait-until:DSH 里的事件驱动等待与空等拦截

前言

在 DeepSeek Harness(DSH)里跑长任务时,模型和脚本常会「等满超时再查一遍」:wait_agent(timeout=30min) 在队友卡死时仍要等满上限且只返回布尔值;job_output(wait:true) 在作业无进展时同样烧时间;更常见的是 sleep 90 再查文件,一轮往返就要一分半。超时返回后往往还要二次查询才能区分成功、失败还是单纯超时。下面介绍的插件 dsh-tool-wait-until 由社区维护者 tongsh6 发布,分类为工作流,用事件驱动的 wait_until 工具替代上述空等路径,并在工具层硬拦截过长的 sleep 与超长 job_output / wait_agent 等待。

这是什么

dsh-tool-wait-until 是 DSH 的 Host 插件:给模型注册 wait_until 等待原语,在后台作业结束、队友空闲、文件出现或日志命中等条件满足时立即返回结构化结果;在目标失败、连续无进展或调用方取消时提前结束,而不是把 timeout_sec 当作主要判定手段。插件零依赖,手写 JSON Schema,要求 Node 20+ 与 dsh 0.2.1 及以上(engines.dsh 声明为 >=0.2.1-rc.1 <0.3.0,README 写明在 0.2.1-rc.5 上验证过)。许可证 MIT,当前 npm 包版本 1.0.5。

维护者设计上的关键判断是:只提供新工具不够,模型仍可能在思考里决定「先 sleep 再查」。因此插件分三层——系统提示词注入等待纪律、tools.guard 拒绝典型空等调用、以及 wait_until 本身的事件驱动实现。

核心功能

wait_until:一次调用、五种状态

调用一次即可决策,无需再查 list_agents 或重复 job_output。返回字段包括 status、elapsed / elapsed_ms、failure_reason、output_tail 等。

status 为五态:completed、failed、stalled、timeout、cancelled。README 明确:超时不是失败,单独一态。

多个 conditions 为 wait_all 语义:全部满足才 completed;fail_fast 命中时任一条件失败即 failed。若需要「任一完成就返回」,应拆成多次 wait_until。

条件类型

kind 必填 until 说明
job id settled(默认)/ failed 作业结束(含失败)或仅失败
agent — inactive(默认)/ failed / status_changed 成员空闲 / 失败 / 状态变化
file path exists(默认)/ changed 文件出现 / 版本变化
log path, matches matches 日志尾部或新增内容命中正则

平台可能把「进程退出但退出码非零」记为 completed;插件会结合退出码与输出里的 EXIT=N 自行判定为 failed,避免把脚本报错当成功。

fail_fast 与卡住检测

  • fail_fast: true(默认):覆盖 job_failed、job_killed、agent_failed。
  • 也可设为 false 或数组,支持 exit_code_nonzero、stderr_matches:/re/、output_matches:/re/ 等。
  • stall_after_sec:连续 N 秒无任何进展返回 stalled,而不是等到 timeout_sec。

事件驱动与轮询边界

作业类条件订阅 jobs.events,在 settle、输出增长或 progress 时唤醒主循环,不受 poll_interval_sec 限制。文件、日志、队友条件按 poll_interval_sec 采样(默认 2s)。全程响应 exec.signal,打断时返回 cancelled。

行为拦截(tools.guard)

拦截对象 条件 行为
前台 bash 含 sleep ≥ 20s(非后台、非 run_in_background) 拒绝,并在原因中给出 wait_until 替代示例
job_output wait:true 且 timeout_ms > 120000 拒绝,要求改用 wait_until
wait_agent timeout_ms > 120000 拒绝,要求改用 agent 条件

短 sleep、后台 sleep 与其余调用不受影响。拦截为硬拒绝,模型需重试一步;拒绝信息里附带可复制的替代调用。

安装与启用

CLI 从 npm 安装(命令以 README 为准):

dsh plugin --profile web add dsh-tool-wait-until

桌面应用可在插件管理器中搜索同名包安装。本地开发可链接源码目录:

dsh plugin --profile web add link:/path/to/dsh-tool-wait-until

安装后 Plugin Manager 会写入 profile 的 package.json 与 bundle,cordis.patch.yml 插入 tool-wait-until 条目;卸载从插件管理器移除即可。

注意:DSH 会缓存已加载的插件模块;仅改 link 包 JS 再重装时,运行中进程可能仍跑旧代码,需重启 Desktop。插件在宿主进程内以当前 dsh 进程权限运行,安装前宜查看 GitHub 仓库 源码与 MIT 许可证。

典型用法

下面示例来自 README,展示多条件等待与常用参数:

wait_until({
  conditions: [
    { kind: 'job',   id: '<job_id>' },
    { kind: 'agent', target: 'worker' },
    { kind: 'file',  path: '/tmp/out.zip', until: 'exists' },
    { kind: 'log',   path: '/tmp/build.log', matches: '/EXIT=0/' },
  ],
  fail_fast: true,
  stall_after_sec: 120,
  timeout_sec: 900,
  poll_interval_sec: 2,
})

失败时返回示例结构(节选):

{
  "status": "failed",
  "elapsed_ms": 1250,
  "elapsed": "1.2s",
  "failure_reason": "后台作业 bash-xxxx 失败:退出码 3",
  "output_tail": "BOOM: intentional failure\n",
  "hint": "目标已失败,不必再等:按 output_tail / failure_reason 决策……"
}

仓库内单测入口:

node test/unit.mjs

适用场景与限制

适合:需要在 DSH 工作流中等待后台 job、Agent Teams 成员、文件或日志条件,且希望失败、卡住时快速得到可解释结果的多步自动化任务。

限制(README 已知项):

  • 思考阶段是否「想 sleep 180 秒」无法直接干预;仅当落成工具调用时才会被 guard 改道。
  • agent 条件依赖 Agent Teams;非 Team 会话会立即 failed 并说明原因,不会空等。
  • 多条件为 wait_all,非「任一满足」。
  • 日志按字节窗口读取,多字节字符在边界可能出现替换符,一般不影响 ASCII 正则匹配。

DSH 生态理念是「一切皆插件」;SkillHub 目录页 为社区站点,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-tool-wait-until 把 DSH 里常见的「睡满超时再查」改成事件驱动的一次性裁决,并用 guard 堵住 sleep 轮询与超长内置等待。进一步了解可阅读 GitHub README 与 目录页。

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

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

Xiaoye