feat(KB-206): add stuck task detection and auto-recovery

- Add taskStuckTimeoutMs setting to detect tasks with no activity
- Create StuckTaskDetector to poll in-progress tasks every 30s
- Integrate heartbeat tracking into executor via step callbacks
- Implement recovery flow: abort stuck sessions, retry with preserved progress
- Export detector and wire into dashboard for real-time monitoring
- Add comprehensive tests and documentation to AGENTS.md
This commit is contained in:
gsxdsm
2026-03-30 17:16:35 -07:00
parent cf5a98fdf0
commit 93f0cb75b4
8 changed files with 754 additions and 4 deletions

View File

@@ -172,6 +172,35 @@ When true, enables ntfy.sh push notifications for task completion and failures.
- Topic must be 1–64 alphanumeric/hyphen/underscore characters
- Notifications are best-effort: failures are logged but don't block task execution
### `taskStuckTimeoutMs` (default: `undefined` — disabled)
Timeout in milliseconds for detecting stuck tasks. When a task's agent session shows no activity (no text deltas, tool calls, or progress updates) for longer than this duration, the task is considered stuck and will be terminated and retried.
**How it works:**
- The `StuckTaskDetector` polls tracked in-progress tasks every 30 seconds
- When no agent activity is detected for longer than `taskStuckTimeoutMs`, the detector:
1. Terminates the stuck agent session
2. Logs the event to the task log
3. Moves the task back to "todo" (preserving current step progress)
4. The scheduler picks it up for retry, resuming from where it left off
**Suggested value:** `600000` (10 minutes)
```json
{
"settings": {
"taskStuckTimeoutMs": 600000
}
}
```
**Notes:**
- When `undefined` (default), stuck task detection is completely disabled
- Activity is tracked on text deltas, tool calls, tool results, and step status updates
- Recovery preserves step progress — the task resumes from the current step, not from scratch
- Paused tasks are automatically untracked from monitoring
- The timeout is read from settings on every poll cycle, so changes take effect immediately
### `worktreeNaming` (default: `"random"`)
Controls how worktree directory names are generated when `recycleWorktrees` is NOT enabled. This setting only affects fresh worktrees (not pooled/recycled ones).