fix(delegation): remove the default subagent wall-clock timeout (#45149)
Subagents doing legitimate heavy work (deep code reviews, research fan-outs, slow reasoning models) were routinely killed at the blanket 600s child_timeout_seconds cap while making steady progress (e.g. 36 API calls completed when the axe fell). Failures should come from what the child is actually doing — API errors, tool errors, iteration budget — not a delegation-level stopwatch. - DEFAULT_CHILD_TIMEOUT: 600 -> None; Future.result(timeout=None) blocks until the child finishes - config default delegation.child_timeout_seconds: 600 -> 0 (0/negative = disabled; positive opts back in, floor 30s unchanged) - stuck-child protection unchanged: the heartbeat staleness monitor still stops refreshing parent activity so the gateway inactivity timeout fires on a truly wedged worker; the 0-API-call diagnostic dump still works when a cap is configured - docs updated (EN + zh-Hans)
This commit is contained in:
@@ -175,17 +175,22 @@ delegate_task(
|
||||
|
||||
## Child Timeout
|
||||
|
||||
Subagents are killed as stuck if they go quiet for more than `delegation.child_timeout_seconds` wall-clock seconds. The default is **600** (10 minutes) — bumped up from 300s in earlier releases because high-reasoning models on non-trivial research tasks were getting killed mid-think. Tune it per-install:
|
||||
By default there is **no wall-clock timeout** on subagents. Children fail only from what they're actually doing — API errors, tool errors, or hitting their iteration budget — never from a delegation-level stopwatch. Earlier releases shipped a hard cap (300s, later 600s), which kept killing legitimately busy children mid-task: deep code reviews, large research fan-outs, and slow reasoning models routinely need more than 10 minutes while making steady progress the whole time.
|
||||
|
||||
Genuinely stuck children are still detected: the heartbeat staleness monitor stops refreshing the parent's activity when a child makes no progress (no API calls, no tool starts), letting the gateway inactivity timeout fire on a truly wedged worker.
|
||||
|
||||
If you want a hard cap anyway (e.g. cost control on unattended cron-driven delegation), opt in per-install:
|
||||
|
||||
```yaml
|
||||
delegation:
|
||||
child_timeout_seconds: 600 # default
|
||||
child_timeout_seconds: 0 # default: 0 = no timeout
|
||||
# child_timeout_seconds: 1800 # opt-in hard cap (floor 30s)
|
||||
```
|
||||
|
||||
Lower it for fast local models; raise it for slow reasoning models on hard problems. The timer resets every time the child makes an API call or tool call — only genuinely idle workers trigger the kill.
|
||||
A positive value enforces a hard wall-clock limit on each child; `0` or a negative value disables it.
|
||||
|
||||
:::tip Diagnostic dump on zero-call timeout
|
||||
If a subagent times out having made **zero** API calls (usually: provider unreachable, auth failure, or tool-schema rejection), `delegate_task` writes a structured diagnostic to `~/.hermes/logs/subagent-timeout-<session>-<timestamp>.log` containing the subagent's config snapshot, credential-resolution trace, and any early error messages. Much easier to root-cause than the previous silent-timeout behavior.
|
||||
With a hard cap configured, if a subagent times out having made **zero** API calls (usually: provider unreachable, auth failure, or tool-schema rejection), `delegate_task` writes a structured diagnostic to `~/.hermes/logs/subagent-timeout-<session>-<timestamp>.log` containing the subagent's config snapshot, credential-resolution trace, and any early error messages. Much easier to root-cause than the previous silent-timeout behavior.
|
||||
:::
|
||||
|
||||
## Monitoring Running Subagents (`/agents`)
|
||||
|
||||
Reference in New Issue
Block a user