dsh-subagent-watchdog:給死掉的子代理向父代理報喪

前言

在 DSH 裏用多代理編排時,一個常見隱患是:上游斷線把子代理打死,父代理卻以爲它還在正常跑。

原因是 AgentStatus 只有 'idle' | 'running',沒有 failed:

  • agent/status 裏 idle 的語義是 “no driver remains scheduled or active”;
  • list_agents 只展示 running / inactive;
  • 父級的 subagent-settled notice 在斷線路徑上不會發出。

於是「正常跑完」「在等我回話」「上游斷線死了」三者在父代理看來完全一樣。目前唯一可靠的信號是輪詢任務板,看任務仍 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

核心功能

它做四件事:

  1. 在 root scope 監聽 agent/error。root 監聽器能收到所有 agent 的事件。
  2. 解析子代理的父代理:先按創建歸屬 ctx.agents.isOwnedBy(),再退回 fork 譜系 session.header.parentSession。
  3. 等 settleDelayMs(默認 2500ms):
    - 子代理已經回到 running → harness 自己重試成功了,不發;
    - 子代理仍是 idle → 它沒恢復,發。
  4. 用 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-settled notice,父代理會同時收到官方通知和本插件的通知。通知正文已寫明「若已收到正常完成通知請忽略」。
  • 不區分錯誤類型。 工具報錯、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

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

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

小夜