为 DeepSeek Harness 提供后台子代理的主动等待:注册 wait_subagent 模型工具,阻塞等待指定的后台 continuable(可续会话)子代理收尾(settlement),返回停止原因与收尾消息——可选超时、成员资格门控拒绝未知 id、事件驱动零轮询。补齐 run_in_background 发后不管与异步收尾通知之间的缺口:等待后台子代理(subagent wait)不再轮询 list_agents、不再靠猜。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-wait-subagent
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:john-walks-slow/dsh-wait-subagent
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 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-tools0.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
社区
- 感谢 LINUX DO 社区提供的交流环境。
链接
同类插件
DayuanJiang/next-ai-draw-io#dsh-plugin★ 36802
dsh 的 draw.io 绘图插件:通过 next-ai-drawio MCP 服务器作图,点回复里的链接在右侧栏打开实时预览,可以手动修改图,AI 的每次修改都是可以恢复的版本。需 Node.js 18+,首次使用由 npx 下载 MCP 服务器。
Tencent/WeKnora#dsh-weknora★ 36302
把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己带引用的 RAG 或 ReAct agent 回答(含可续聊的 session id)。
superdesigndev/treg★ 7042
给 Agent 的工具目录:按「要做的事」检索约 2,600 个外部接口(SEO 与 SERP、外链、社交、人物与公司信息补全、广告库、抓取),查看参数与单次调用价格后直接调用,凭据由服务端注入。附带技能,MCP 行在未设置 TREG_TOKEN 前保持禁用。
T-Auto/dsh-ops★ 5074
为 Windows 的 DSH 提供 bash、PowerShell 7 及 Rust 高性能工具,减少 token 消耗。
sixtysevenlf/dsh-blender-plugin★ 1575
让 DSH agent 通过直连 TCP 通道驱动本地 Blender,提供 15 个工具:视口帧、自定义视角渲染、Python 执行、无头与作业卸载、事务回滚,以及 34 个 family / 228 个 op 的规划层。
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1155
把腾讯云 CloudBase 后端接入 DeepSeek Harness——在对话里搭好并部署全栈应用,查询结果渲染为表格卡片(分页、排序、导出 CSV),部署后可预览真实域名,并提供 CloudBase MCP 工具集(`mcp__cloudbase__*`),登录走 device-code 流程。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。