前言¶
在 DSH 裏用多代理編排時,一個常見隱患是:上游斷線把子代理打死,父代理卻以爲它還在正常跑。
原因是 AgentStatus 只有 'idle' | 'running',沒有 failed:
agent/status裏idle的語義是 “no driver remains scheduled or active”;list_agents只展示running/inactive;- 父級的
subagent-settlednotice 在斷線路徑上不會發出。
於是「正常跑完」「在等我回話」「上游斷線死了」三者在父代理看來完全一樣。目前唯一可靠的信號是輪詢任務板,看任務仍 in_progress 但成員已 inactive,這在多代理編排裏不可接受。Lequait/dsh-subagent-watchdog 就是補這個缺口的插件:子代理因上游斷線去世時,替它給父代理報喪。
下面介紹它的定位、安裝方式和配置項。
這是什麼¶
一句話定位:監聽 agent/error,確認子代理沒有恢復後,向父代理投遞一條可處理的中斷通知。它不重試任何東西,也不改會話歷史,只負責讓父代理知道「這個子代理死了,你來決定」。
- 維護者:Lequait
- 分類:工作流
- 星標:0
- 許可證:MIT
- 版本:0.1.0(來自
package.json) - 依賴:
schemastery,Node>=20,dsh>=0.2.0-rc.1
核心功能¶
它做四件事:
- 在 root scope 監聽
agent/error。root 監聽器能收到所有 agent 的事件。 - 解析子代理的父代理:先按創建歸屬
ctx.agents.isOwnedBy(),再退回 fork 譜系session.header.parentSession。 - 等
settleDelayMs(默認 2500ms):
- 子代理已經回到running→ harness 自己重試成功了,不發;
- 子代理仍是idle→ 它沒恢復,發。 - 用
parent.followup(message)投遞通知:父代理空閒時會被喚醒,正在跑時排到當前輪之後。
父代理收到的通知大致是:
[subagent-watchdog] 子代理中斷
子代理: 01J8X...
層級: 1
輪次/步驟: turn 2 / step 5
錯誤: socket hang up code=ECONNRESET
狀態: 已停止(idle),不會自行恢復
請決定如何處理:
- 重新派發同一任務(spawn 新的子代理)
- 換 provider/model 重試
- 自己接手
- 放棄並記錄
正文末尾還帶一句「若已收到該子代理的正常完成通知,請忽略」。
安裝與啓用¶
README 給了三種方式,按場景選一種即可。
方式一:絕對路徑(本地開發,無需 npm)¶
在 ~/.dsh/cordis.patch.yml 追加:
- insert:
- id: subagent-watchdog
name: "H:/AI/dsh-subagent-watchdog/index.js"
loader 會把絕對路徑轉成 file:// URL,不需要 profile 的 node_modules 鏈接。注意必須是 - insert: 列表——profile 層的 patch 是 id-targeted 的,裸 - id: 會被當成「patch 已存在條目」。依賴 schemastery 需要在插件目錄裏 npm install 一次。
方式二:從倉庫安裝¶
dsh plugin --profile <name> add git+https://github.com/Lequait/dsh-subagent-watchdog.git
方式三:從插件市場安裝¶
把下面這個索引地址加進 Discover 的索引源,然後在市場裏裝:
https://github.com/Lequait/dsh-subagent-watchdog/raw/main/market/index.json
jsDelivr 鏡像(國內更快):
https://cdn.jsdelivr.net/gh/Lequait/dsh-subagent-watchdog@main/market/index.json
配置¶
全部可選,寫在 patch 條目的 config: 下:
- insert:
- id: subagent-watchdog
name: "H:/AI/dsh-subagent-watchdog/index.js"
config:
settleDelayMs: 2500
cooldownMs: 60000
dryRun: false
| 選項 | 默認 | 說明 |
|---|---|---|
enabled |
true |
總開關 |
settleDelayMs |
2500 |
agent/error 之後等多久再判定死亡。期間恢復成 running 就不發 |
cooldownMs |
60000 |
同一個子代理兩次通知的最小間隔 |
maxPerChild |
5 |
同一個子代理的通知上限(每進程) |
notifyOnDisposed |
true |
子代理帶着未處理失敗被 dispose 時也報 |
dryRun |
false |
只寫日誌不投遞,首次安裝建議先開 |
messagePrefix |
[subagent-watchdog] |
通知前綴 |
適用場景與注意¶
適合在 DSH 裏做多代理編排、把任務拆給子代理的人。它以當前 dsh 進程權限運行,能在 root scope 監聽所有 agent 事件併發消息給父代理;安裝前應檢查源碼與許可證(MIT)。
它也有一些邊界,README 已明確列出:
- 只覆蓋「錯誤後停住」這一種死法。 上游靜默掛起(流一直不返回、也不報錯)時
agent/error不會觸發,本插件不說話。這種情況要靠 provider 的streamIdleTimeoutMs(默認 5 分鐘)把它變成TIMEOUT。 - 可能重複通知。 如果 harness 某天補上斷線路徑的
subagent-settlednotice,父代理會同時收到官方通知和本插件的通知。通知正文已寫明「若已收到正常完成通知請忽略」。 - 不區分錯誤類型。 工具報錯、provider 斷線、上下文溢出都會觸發
agent/error,判定標準是「錯誤之後沒有恢復」,不是錯誤碼。 - 依賴
ctx.agents服務;inject = ['agents']保證它在服務就緒後才掛載。
結尾¶
這個插件解決的是一個很具體的問題:不是給子代理加重試,而是把「子代理死了」這件事可靠地告訴父代理,把處置權交回去。對依賴 idle / running 二元狀態做編排的人來說,它把原本只能靠輪詢任務板判斷的場景,變成了一條投遞到父代理的可處理消息。
目錄頁:https://www.skillhub.cn/plugins/Lequait/dsh-subagent-watchdog
GitHub:https://github.com/Lequait/dsh-subagent-watchdog