dsh-subagent-watchdog: Reporting the death of subagents to the parent agent

Introduction

When using multi-agent orchestration in DSH, a common pitfall is: an upstream disconnection kills the child agent, but the parent agent thinks it’s still running normally.

The reason is that AgentStatus only has 'idle' | 'running', without failed:

  • The semantics of idle in agent/status is “no driver remains scheduled or active”;
  • list_agents only displays running / inactive;
  • The parent’s subagent-settled notice is not sent on the disconnection path.

Thus, “finished normally”, “waiting for me to respond”, and “died due to upstream disconnection” look exactly the same to the parent agent. Currently, the only reliable signal is polling the task board to see if the task is still in_progress but members are inactive, which is unacceptable in multi-agent orchestration. Lequait/dsh-subagent-watchdog is the plugin to fill this gap: when a child agent dies due to upstream disconnection, it reports the death to the parent agent on its behalf.

Below is an introduction to its positioning, installation methods, and configuration options.

What is it

One-sentence positioning: Listen to agent/error, and after confirming the child agent has not recovered, deliver a handleable interrupt notification to the parent agent. It does not retry anything and does not modify session history; it is only responsible for letting the parent agent know “this child agent is dead, you decide”.

  • Maintainer: Lequait
  • Category: Workflow
  • Stars: 0
  • License: MIT
  • Version: 0.1.0 (from package.json)
  • Dependencies: schemastery, Node >=20, dsh >=0.2.0-rc.1

Core Features

It does four things:

  1. Listen to agent/error in the root scope. Root listeners can receive all agent events.
  2. Resolve the parent agent of the child agent: first check ownership via ctx.agents.isOwnedBy(), then fall back to the fork lineage session.header.parentSession.
  3. Wait for settleDelayMs (default 2500ms):
    • Child agent has returned to running → harness itself retried successfully, do not send;
    • Child agent is still idle → it hasn’t recovered, send.
  4. Deliver the notification using parent.followup(message): The parent agent is woken up when idle, or queued after the current turn if it is running.

The notification received by the parent agent looks roughly like this:

[subagent-watchdog] Child agent interrupted

Child agent: 01J8X...
Level: 1
Turn/Step: turn 2 / step 5
Error: socket hang up code=ECONNRESET
Status: Stopped (idle), will not recover on its own

Please decide how to handle:
- Redeploy the same task (spawn a new child agent)
- Retry with a different provider/model
- Take over yourself
- Give up and log it

The end of the message also includes a note: “If you have already received a notification of normal completion for this child agent, please ignore this message.”

Installation and Activation

The README provides three methods; choose one based on your scenario.

Method 1: Absolute Path (Local development, no npm needed)

Append to ~/.dsh/cordis.patch.yml:

- insert:
    - id: subagent-watchdog
      name: "H:/AI/dsh-subagent-watchdog/index.js"

The loader converts the absolute path to a file:// URL, so you don’t need the profile’s node_modules link. Note that it must be a - insert: list—the patch at the profile layer is id-targeted, so a bare - id: will be treated as “patch already exists”. You need to run npm install once in the plugin directory for the dependency schemastery.

Method 2: Install from Repository

dsh plugin --profile <name> add git+https://github.com/Lequait/dsh-subagent-watchdog.git

Method 3: Install from Plugin Market

Add the index address below to the Discover index source, then install it from the market:

https://github.com/Lequait/dsh-subagent-watchdog/raw/main/market/index.json

jsDelivr mirror (faster in China):

https://cdn.jsdelivr.net/gh/Lequait/dsh-subagent-watchdog@main/market/index.json

Configuration

All are optional, written under config: in the patch entry:

- insert:
    - id: subagent-watchdog
      name: "H:/AI/dsh-subagent-watchdog/index.js"
      config:
        settleDelayMs: 2500
        cooldownMs: 60000
        dryRun: false
Option Default Description
enabled true Master switch
settleDelayMs 2500 How long to wait after agent/error before determining death. If it recovers to running during this period, do not send
cooldownMs 60000 Minimum interval between two notifications for the same child agent
maxPerChild 5 Maximum notifications for the same child agent (per process)
notifyOnDisposed true Report even when the child agent is disposed with an unhandled failure
dryRun false Log only, do not deliver; recommended to enable during first installation
messagePrefix [subagent-watchdog] Notification prefix

Applicable Scenarios and Notes

Suitable for those using DSH for multi-agent orchestration and splitting tasks to child agents. It runs with the permissions of the current dsh process, allowing it to listen to all agent events in the root scope and send messages to the parent agent; you should check the source code and license (MIT) before installing.

It also has some limitations, which are explicitly listed in the README:

  • Only covers one way of dying: “stopped after an error”. When the upstream hangs silently (stream never returns and doesn’t report an error), agent/error will not trigger, so this plugin remains silent. In this case, rely on the provider’s streamIdleTimeoutMs (default 5 minutes) to convert it to a TIMEOUT.
  • Possible duplicate notifications. If the harness one day adds back the subagent-settled notice for the disconnection path, the parent agent will receive both the official notice and the plugin’s notice. The message body already states “If you have already received a notification of normal completion, please ignore”.
  • Does not distinguish error types. Tool errors, provider disconnections, and context overflows will all trigger agent/error. The judgment criterion is “no recovery after an error”, not the error code.
  • Depends on the ctx.agents service; inject = ['agents'] ensures it is mounted only after the service is ready.

Conclusion

This plugin solves a very specific problem: it doesn’t add retries for the child agent, but reliably tells the parent agent “this child agent is dead,” handing the decision-making power back. For those orchestrating based on the idle / running binary states, it turns a scenario that previously could only be judged by polling the task board into a handleable message delivered to the parent agent.

Directory page: https://www.skillhub.cn/plugins/Lequait/dsh-subagent-watchdog
GitHub: https://github.com/Lequait/dsh-subagent-watchdog

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

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

Xiaoye