跳到正文
dsh-market 浏览插件 GitHub EN

john-walks-slow/dsh-wait-subagent

为 DeepSeek Harness 提供后台子代理的主动等待:注册 wait_subagent 模型工具,阻塞等待指定的后台 continuable(可续会话)子代理收尾(settlement),返回停止原因与收尾消息——可选超时、成员资格门控拒绝未知 id、事件驱动零轮询。补齐 run_in_background 发后不管与异步收尾通知之间的缺口:等待后台子代理(subagent wait)不再轮询 list_agents、不再靠猜。

Star 数 ★ 0 分类 工具与能力 收录于 2026-09-25 npm dsh-wait-subagent

安装

在 DeepSeek Harness 里通过 dsh-market 安装

dsh plugin --profile web add dshmarket

或使用命令行

dsh plugin --profile web add dsh-wait-subagent

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。

README

一个 DeepSeek Harness(cordis)插件,注册 wait_subagent 工具:主动阻塞等待指定的后台 continuable 子代理收尾(settle),并在同一次调用里拿到它的停止原因与收尾消息。

它补齐了子代理工作流的一个真实缺口:run_in_background 立即返回 subagentId,但想知道结果只能被动等异步 settlement 通知——此前没有任何工具能主动等待子代理完成。

真实输出

以后台方式启动子代理,然后等待它:

wait_subagent({ subagent_id: "session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3" })

子代理运行期间该调用阻塞。子代理收尾后工具返回:

{
  "status": "settled",
  "subagent_id": "session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3",
  "stop_reason": "completed",
  "closing_message": "Spec written to docs/plan.md; 3 files changed, ready for review."
}

模型看到的文本:

Subagent session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3 settled: completed
Spec written to docs/plan.md; 3 files changed, ready for review.

其他结果:

情形 返回
调用前子代理已收尾 { "status": "settled", "subagent_id": "…", "stop_reason": "unknown" } —— "had already settled before this call; its closing message was delivered separately as a settlement notice."
timeout_ms 超时 { "status": "timeout", "subagent_id": "…" } —— "Timed out waiting for subagent …; it may still be running."
调用方的 AbortSignal 触发 { "status": "cancelled", "subagent_id": "…" }
未知 / 不属于自己的子代理 id 直接报错:"… is not one of your subagents — pass the id a background dispatch returned (see list_agents)"

为什么需要它

现有子代理系统能给你的:

  • subagent + run_in_background: true → 立即返回 subagentId,工作异步继续,稍后才送达 settlement 通知。
  • subagent + run_in_background: false → 只在启动时阻塞。
  • send_message → 发完即返回,从不等待回答。
  • list_agents → 快照,不是等待(且明确提示"不要用来轮询")。

缺的是:后台启动子代理之后,没有工具能阻塞等待它完成。这正是 wait_subagent 做的事——当你的下一步依赖子代理的结果时用它,而不是靠猜或轮询。

工作原理

  • 在每个 root agent 上注册 wait_subagent 工具(与 dsh-proactive 相同的注册模式)。
  • 成员资格门控:ctx.subagents.listChildren(parent.id) —— 与 list_agents 读的同一个 projection —— 同时覆盖存活与仅存于存储的子代理,未知 id 直接报错,而不是被误报为已收尾。已知子代理若不在存活注册表中,说明早已收尾。
  • 工具监听 subagent/end 生命周期事件(子代理 activation 被释放时触发),作用域挂在插件上下文上(所有 agent 上下文的公共祖先)。
  • 收尾时,子代理从存活注册表移除与 subagent/end 派发发生在同一个同步块里(finishDisposal),因此"先挂监听、再复查注册表"的顺序无竞态。
  • 可选 timeout_ms 参数:超时未收尾则返回 status: "timeout"。省略则无限等待——通常这是最佳选择;若要设置,请给足量级(分钟级),不要用反复短等待轮询。
  • 尊重调用方的 AbortSignal(返回 status: "cancelled")。

工具签名

wait_subagent(subagent_id: string, timeout_ms?: integer)
→ { status: "settled" | "timeout" | "cancelled",
    subagent_id: string,
    stop_reason?: "completed" | "aborted" | "error" | "max-tokens" | "refusal" | "unknown",
    closing_message?: string }

注意:不要在同一步里既等待又打断

wait_subagent 是并发安全的,但 interrupt_agent 不是——它独占工具通道,会排在任何进行中的调用之后。在同一步并行发起 wait_subagent 和 interrupt_agent 会被串行化:等待先跑满超时,打断才落地。请先调用 interrupt_agent,下一步再 wait_subagent(已被打断的子代理会很快收尾)。

安装

dsh plugin --profile web add dsh-wait-subagent

或从 GitHub 直装(源码安装——纯 ESM JavaScript,无构建步骤,pnpm ≥ 10 无需 allowBuilds 批准):

dsh plugin --profile web add github:john-walks-slow/dsh-wait-subagent

安装后重启 DSH 实例即可;插件自带的 cordis.patch.yml 会自动注册 loader entry。

权限与兼容

  • 涉及范围:仅在每个 root agent 上注册一个模型可调用的 Agent 工具(wait_subagent)。无 web client、无 UI 改动、无配置项。
  • 阻塞语义:等待期间该调用占用调用方 agent 的工具通道,直到子代理收尾、可选超时到期或调用方中止——这正是功能本身。等待机制是事件驱动(subagent/end 生命周期事件),非轮询,阻塞期间 CPU 占用可忽略。省略 timeout_ms 的等待不设上限(设计如此);需要上限时请给足量级的 timeout_ms。
  • 无副作用:无网络请求、无外部服务、无文件系统写入。
  • 依赖:@deepseek-ai/dsh-tools 0.1.2-rc.1(与 dsh 0.1.2-rc.1 锁定版本对齐),Node ≥ 22.5。

本地开发

npm install

就这些——lib/ 是纯 ESM JavaScript,没有构建步骤,也没有测试套件。

发新版

npm run release        # 递增 patch 版本号并打包到 /tmp/dsh-wait-subagent-<新版>.tgz

然后把 tarball 发布到 npm,并推送版本 commit 与 tag:

git push --follow-tags

用 npm view dsh-wait-subagent version 复验。

许可证

MIT

内容来自项目 README(GitHub)↗

评论

评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。