pi-watchdog-supervisor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tmp/2026-07-08_pi_watchdog_extension_requirement.md +907 -0
- package/.tmp/2026-07-08_pi_watchdog_high_level_spec.md +192 -0
- package/.tmp/2026-07-08_pi_watchdog_task01_low_level_spec.md +234 -0
- package/.tmp/2026-07-08_pi_watchdog_task02_low_level_spec.md +158 -0
- package/.tmp/2026-07-08_pi_watchdog_task03_low_level_spec.md +175 -0
- package/.tmp/2026-07-08_pi_watchdog_task04_low_level_spec.md +151 -0
- package/.tmp/2026-07-08_pi_watchdog_task05_low_level_spec.md +116 -0
- package/.tmp/2026-07-08_pi_watchdog_task06_low_level_spec.md +69 -0
- package/.tmp/detect_approach.patch +253 -0
- package/README.md +176 -0
- package/examples/AGENTS.md +27 -0
- package/examples/watchdog-supervisor.json +12 -0
- package/package.json +39 -0
- package/prompts/watchdog-agent.md +36 -0
- package/skills/watchdog-supervisor/SKILL.md +35 -0
- package/src/checker.ts +54 -0
- package/src/collector.ts +223 -0
- package/src/commands.ts +159 -0
- package/src/config.ts +80 -0
- package/src/detector.ts +150 -0
- package/src/index.ts +94 -0
- package/src/integrations/gotgenes-subagents.ts +45 -0
- package/src/lmdebug.ts +128 -0
- package/src/normalize.ts +40 -0
- package/src/registry.ts +121 -0
- package/src/store.ts +137 -0
- package/src/tools.ts +289 -0
- package/src/types.ts +80 -0
- package/test/Screenshot_20260708_220337.png +0 -0
- package/test/checker.test.ts +118 -0
- package/test/collector.test.ts +201 -0
- package/test/config.test.ts +131 -0
- package/test/detector.test.ts +224 -0
- package/test/integration.test.ts +57 -0
- package/test/lmdebug.test.ts +114 -0
- package/test/normalize.test.ts +78 -0
- package/test/registry.test.ts +149 -0
- package/test/store.test.ts +176 -0
- package/test/tools.test.ts +315 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,907 @@
|
|
|
1
|
+
# Pi Watchdog Supervisor Extension — Requirement & Tech Spec
|
|
2
|
+
|
|
3
|
+
- Date: 2026-07-08
|
|
4
|
+
- Target reader: coding agent / implementation engineer
|
|
5
|
+
- Status: Draft for review
|
|
6
|
+
- Goal: design a Pi extension that lets a `watchdog` sub-agent supervise sibling task sub-agents and report likely stuck/loop states to the main agent session.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Problem
|
|
11
|
+
|
|
12
|
+
Current Pi agent / sub-agent workflow can get stuck in repetitive tool loops, such as:
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
same rg / grep command
|
|
16
|
+
same output
|
|
17
|
+
no new patch
|
|
18
|
+
no new plan
|
|
19
|
+
manual user intervention required
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The user wants an automated mechanism where:
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
main agent session
|
|
26
|
+
├─ watchdog sub-agent session
|
|
27
|
+
├─ task sub-agent session 1
|
|
28
|
+
└─ task sub-agent session 2
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The watchdog sub-agent detects whether task sub-agents are stuck, then notifies the main agent or suggests a rescue action.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Core Requirement
|
|
36
|
+
|
|
37
|
+
### 2.1 Functional Goals
|
|
38
|
+
|
|
39
|
+
- Provide a Pi extension that can observe sub-agent activity.
|
|
40
|
+
- Allow the main agent to spawn or use a dedicated `watchdog` sub-agent.
|
|
41
|
+
- The watchdog sub-agent must be able to inspect summarized status/events of sibling task sub-agents.
|
|
42
|
+
- When a task sub-agent is likely stuck, the watchdog should report to the main agent.
|
|
43
|
+
- The main agent decides whether to:
|
|
44
|
+
- send rescue message to task sub-agent,
|
|
45
|
+
- stop / restart task sub-agent,
|
|
46
|
+
- ask the task sub-agent to summarize and re-plan,
|
|
47
|
+
- ignore the alert.
|
|
48
|
+
|
|
49
|
+
### 2.2 User-defined Rescue Message
|
|
50
|
+
|
|
51
|
+
Default:
|
|
52
|
+
|
|
53
|
+
```txt
|
|
54
|
+
AI agent 是不是卡死了?
|
|
55
|
+
請停止目前重複動作,總結你已知的資訊,重新規劃下一步。
|
|
56
|
+
不要再執行相同 command,除非 query 或 path 有改變。
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Must be configurable per project and per session.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 3. Non-goals
|
|
64
|
+
|
|
65
|
+
- Do not let watchdog sub-agent directly read private context of sibling sub-agents unless Pi/subagent API explicitly exposes it.
|
|
66
|
+
- Do not rely only on LLM reasoning for deterministic timeout / repeat-count detection.
|
|
67
|
+
- Do not require MCP for MVP.
|
|
68
|
+
- Do not require GUI automation such as `xdotool`.
|
|
69
|
+
- Do not auto-kill task sub-agents by default.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 4. Important Design Constraint
|
|
74
|
+
|
|
75
|
+
A watchdog sub-agent is still an LLM session. It cannot magically observe sibling sub-agents.
|
|
76
|
+
|
|
77
|
+
Therefore the architecture must include a shared observation channel:
|
|
78
|
+
|
|
79
|
+
```txt
|
|
80
|
+
task sub-agent events
|
|
81
|
+
↓
|
|
82
|
+
pi-watchdog extension runtime
|
|
83
|
+
↓
|
|
84
|
+
watchdog sub-agent tools
|
|
85
|
+
↓
|
|
86
|
+
watchdog sub-agent analysis
|
|
87
|
+
↓
|
|
88
|
+
main agent alert
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The extension runtime is the deterministic collector. The watchdog sub-agent is the reasoning / summary layer.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 5. Proposed Architecture
|
|
96
|
+
|
|
97
|
+
```txt
|
|
98
|
+
Pi Main Agent Session
|
|
99
|
+
│
|
|
100
|
+
├─ Watchdog Sub-agent Session
|
|
101
|
+
│ ├─ uses watchdog_list_targets()
|
|
102
|
+
│ ├─ uses watchdog_read_events()
|
|
103
|
+
│ ├─ uses watchdog_detect_stuck()
|
|
104
|
+
│ └─ sends alert to main agent
|
|
105
|
+
│
|
|
106
|
+
├─ Task Sub-agent Session 1
|
|
107
|
+
│ └─ emits lifecycle/tool/progress events
|
|
108
|
+
│
|
|
109
|
+
├─ Task Sub-agent Session 2
|
|
110
|
+
│ └─ emits lifecycle/tool/progress events
|
|
111
|
+
│
|
|
112
|
+
└─ pi-watchdog-supervisor extension
|
|
113
|
+
├─ listens to Pi events
|
|
114
|
+
├─ integrates with pi-subagents service if available
|
|
115
|
+
├─ stores compact event history
|
|
116
|
+
├─ computes deterministic stuck signals
|
|
117
|
+
├─ exposes watchdog tools
|
|
118
|
+
└─ optionally routes alert through pi-intercom / subagent steering
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 6. Package Name
|
|
124
|
+
|
|
125
|
+
Suggested package:
|
|
126
|
+
|
|
127
|
+
```txt
|
|
128
|
+
pi-watchdog-supervisor
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Alternative names:
|
|
132
|
+
|
|
133
|
+
```txt
|
|
134
|
+
pi-subagent-watchdog
|
|
135
|
+
pi-watchdog-extension
|
|
136
|
+
pi-agent-supervisor
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 7. Extension Responsibilities
|
|
142
|
+
|
|
143
|
+
### 7.1 Event Collection
|
|
144
|
+
|
|
145
|
+
The extension should collect:
|
|
146
|
+
|
|
147
|
+
- sub-agent created / started / completed / failed / steered / compacted events.
|
|
148
|
+
- tool call events.
|
|
149
|
+
- tool result summaries, if available.
|
|
150
|
+
- last active time.
|
|
151
|
+
- command string for bash / shell tools.
|
|
152
|
+
- output hash, not full output by default.
|
|
153
|
+
- patch/write/edit count.
|
|
154
|
+
- repeated command count.
|
|
155
|
+
- repeated output count.
|
|
156
|
+
- current status text, if available.
|
|
157
|
+
|
|
158
|
+
### 7.2 Event Normalization
|
|
159
|
+
|
|
160
|
+
Normalize commands before comparison:
|
|
161
|
+
|
|
162
|
+
```txt
|
|
163
|
+
trim whitespace
|
|
164
|
+
collapse repeated spaces
|
|
165
|
+
remove ANSI escape codes
|
|
166
|
+
optional: normalize temp paths
|
|
167
|
+
optional: normalize line numbers if needed
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Normalize output:
|
|
171
|
+
|
|
172
|
+
```txt
|
|
173
|
+
strip ANSI
|
|
174
|
+
truncate to max bytes
|
|
175
|
+
hash normalized output with sha256
|
|
176
|
+
store first N lines as preview only
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 7.3 Stuck Detection
|
|
180
|
+
|
|
181
|
+
MVP stuck signals:
|
|
182
|
+
|
|
183
|
+
```txt
|
|
184
|
+
same command + same output hash >= 3 times
|
|
185
|
+
same type-check error >= 2 times
|
|
186
|
+
no patch/edit/write event for >= N minutes while tools keep running
|
|
187
|
+
read-only loop: rg / grep / cat / ls repeated without plan change
|
|
188
|
+
sub-agent heartbeat active, but progress score unchanged
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Default thresholds:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"repeatThreshold": 3,
|
|
196
|
+
"typecheckRepeatThreshold": 2,
|
|
197
|
+
"idleNoProgressSec": 300,
|
|
198
|
+
"cooldownSec": 60,
|
|
199
|
+
"maxPreviewLines": 20,
|
|
200
|
+
"maxEventsPerAgent": 200
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 8. Watchdog Sub-agent Role
|
|
207
|
+
|
|
208
|
+
The watchdog sub-agent should not monitor raw logs itself. It should call extension-provided tools.
|
|
209
|
+
|
|
210
|
+
### 8.1 Suggested Watchdog Prompt
|
|
211
|
+
|
|
212
|
+
```md
|
|
213
|
+
You are a watchdog supervisor for Pi task sub-agents.
|
|
214
|
+
|
|
215
|
+
Your job:
|
|
216
|
+
- Check task sub-agent status through watchdog tools.
|
|
217
|
+
- Detect likely loop/stuck cases.
|
|
218
|
+
- Report compact alerts to the main agent.
|
|
219
|
+
- Do not fix code yourself unless explicitly asked.
|
|
220
|
+
- Do not spam alerts; respect cooldown.
|
|
221
|
+
- Prefer evidence-based alerts.
|
|
222
|
+
|
|
223
|
+
When reporting a stuck task, include:
|
|
224
|
+
- sub-agent id/name
|
|
225
|
+
- reason
|
|
226
|
+
- repeated command or error summary
|
|
227
|
+
- last activity time
|
|
228
|
+
- suggested rescue message
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 8.2 Alert Format
|
|
232
|
+
|
|
233
|
+
```txt
|
|
234
|
+
[Watchdog Alert]
|
|
235
|
+
|
|
236
|
+
Target: task-sub-agent-1
|
|
237
|
+
Status: likely stuck
|
|
238
|
+
Confidence: high
|
|
239
|
+
|
|
240
|
+
Evidence:
|
|
241
|
+
- same command repeated 3 times
|
|
242
|
+
- same output hash repeated 3 times
|
|
243
|
+
- no patch/edit event in 6 minutes
|
|
244
|
+
|
|
245
|
+
Last command:
|
|
246
|
+
rg "CAMPAIGN_RULES_QUERY_KEY" apps/campaign-list
|
|
247
|
+
|
|
248
|
+
Suggested rescue:
|
|
249
|
+
AI agent 是不是卡死了?
|
|
250
|
+
請停止目前重複動作,總結你已知的資訊,重新規劃下一步。
|
|
251
|
+
不要再執行相同 command,除非 query 或 path 有改變。
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## 9. Tools Exposed by Extension
|
|
257
|
+
|
|
258
|
+
### 9.1 `watchdog_list_targets`
|
|
259
|
+
|
|
260
|
+
List sub-agents visible to the current main session.
|
|
261
|
+
|
|
262
|
+
Input:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
type Input = {
|
|
266
|
+
includeCompleted?: boolean;
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Output:
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
type Output = {
|
|
274
|
+
targets: Array<{
|
|
275
|
+
id: string;
|
|
276
|
+
name?: string;
|
|
277
|
+
kind: 'task' | 'watchdog' | 'unknown';
|
|
278
|
+
status: 'running' | 'completed' | 'failed' | 'unknown';
|
|
279
|
+
lastActiveAt?: string;
|
|
280
|
+
toolCallCount: number;
|
|
281
|
+
patchCount: number;
|
|
282
|
+
repeatedCommandCount: number;
|
|
283
|
+
likelyStuck: boolean;
|
|
284
|
+
}>;
|
|
285
|
+
};
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 9.2 `watchdog_read_events`
|
|
289
|
+
|
|
290
|
+
Read compact recent events for one target.
|
|
291
|
+
|
|
292
|
+
Input:
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
type Input = {
|
|
296
|
+
targetId: string;
|
|
297
|
+
limit?: number;
|
|
298
|
+
sinceEventId?: string;
|
|
299
|
+
};
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Output:
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
type Output = {
|
|
306
|
+
targetId: string;
|
|
307
|
+
events: WatchdogEvent[];
|
|
308
|
+
};
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 9.3 `watchdog_detect_stuck`
|
|
312
|
+
|
|
313
|
+
Return deterministic stuck analysis.
|
|
314
|
+
|
|
315
|
+
Input:
|
|
316
|
+
|
|
317
|
+
```ts
|
|
318
|
+
type Input = {
|
|
319
|
+
targetId: string;
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Output:
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
type Output = {
|
|
327
|
+
targetId: string;
|
|
328
|
+
likelyStuck: boolean;
|
|
329
|
+
confidence: 'low' | 'medium' | 'high';
|
|
330
|
+
reasons: string[];
|
|
331
|
+
evidence: Array<{
|
|
332
|
+
type: 'repeated_command' | 'repeated_output' | 'idle_no_progress' | 'typecheck_loop';
|
|
333
|
+
summary: string;
|
|
334
|
+
}>;
|
|
335
|
+
suggestedRescueMessage: string;
|
|
336
|
+
};
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### 9.4 `watchdog_alert_main`
|
|
340
|
+
|
|
341
|
+
Send a compact alert to the main agent session.
|
|
342
|
+
|
|
343
|
+
Input:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
type Input = {
|
|
347
|
+
targetId: string;
|
|
348
|
+
message: string;
|
|
349
|
+
severity?: 'info' | 'warning' | 'critical';
|
|
350
|
+
};
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
MVP behavior:
|
|
354
|
+
|
|
355
|
+
- Append a message / notification to the main session if Pi API supports it.
|
|
356
|
+
- Otherwise use pi-intercom if installed.
|
|
357
|
+
- Otherwise print a visible extension UI notification.
|
|
358
|
+
|
|
359
|
+
### 9.5 `watchdog_steer_subagent`
|
|
360
|
+
|
|
361
|
+
Optional. Send rescue message to target sub-agent.
|
|
362
|
+
|
|
363
|
+
Input:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
type Input = {
|
|
367
|
+
targetId: string;
|
|
368
|
+
message: string;
|
|
369
|
+
dryRun?: boolean;
|
|
370
|
+
};
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Default:
|
|
374
|
+
|
|
375
|
+
```txt
|
|
376
|
+
dryRun = true
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Reason: main agent should approve direct intervention first.
|
|
380
|
+
|
|
381
|
+
### 9.6 `watchdog_config`
|
|
382
|
+
|
|
383
|
+
Read or update policy.
|
|
384
|
+
|
|
385
|
+
Input:
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
type Input = {
|
|
389
|
+
action: 'get' | 'set';
|
|
390
|
+
config?: Partial<WatchdogConfig>;
|
|
391
|
+
};
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## 10. Internal Data Model
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
type WatchdogConfig = {
|
|
400
|
+
enabled: boolean;
|
|
401
|
+
rescueMessage: string;
|
|
402
|
+
repeatThreshold: number;
|
|
403
|
+
typecheckRepeatThreshold: number;
|
|
404
|
+
idleNoProgressSec: number;
|
|
405
|
+
cooldownSec: number;
|
|
406
|
+
maxPreviewLines: number;
|
|
407
|
+
maxEventsPerAgent: number;
|
|
408
|
+
alertMode: 'main_only' | 'direct_subagent' | 'both';
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
type WatchdogTarget = {
|
|
412
|
+
id: string;
|
|
413
|
+
parentSessionId: string;
|
|
414
|
+
name?: string;
|
|
415
|
+
kind: 'task' | 'watchdog' | 'unknown';
|
|
416
|
+
status: 'running' | 'completed' | 'failed' | 'unknown';
|
|
417
|
+
createdAt: number;
|
|
418
|
+
lastActiveAt: number;
|
|
419
|
+
lastCommandKey?: string;
|
|
420
|
+
lastOutputHash?: string;
|
|
421
|
+
repeatedCommandCount: number;
|
|
422
|
+
repeatedOutputCount: number;
|
|
423
|
+
toolCallCount: number;
|
|
424
|
+
editCount: number;
|
|
425
|
+
lastAlertAt?: number;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
type WatchdogEvent = {
|
|
429
|
+
id: string;
|
|
430
|
+
targetId: string;
|
|
431
|
+
at: number;
|
|
432
|
+
type:
|
|
433
|
+
| 'subagent_created'
|
|
434
|
+
| 'subagent_started'
|
|
435
|
+
| 'subagent_completed'
|
|
436
|
+
| 'subagent_failed'
|
|
437
|
+
| 'tool_call'
|
|
438
|
+
| 'tool_result'
|
|
439
|
+
| 'edit'
|
|
440
|
+
| 'patch'
|
|
441
|
+
| 'alert';
|
|
442
|
+
summary: string;
|
|
443
|
+
commandKey?: string;
|
|
444
|
+
outputHash?: string;
|
|
445
|
+
outputPreview?: string;
|
|
446
|
+
};
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 11. Config Files
|
|
452
|
+
|
|
453
|
+
Global config:
|
|
454
|
+
|
|
455
|
+
```txt
|
|
456
|
+
~/.pi/agent/watchdog-supervisor/config.json
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Project config:
|
|
460
|
+
|
|
461
|
+
```txt
|
|
462
|
+
.pi/watchdog-supervisor.json
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Project config overrides global config.
|
|
466
|
+
|
|
467
|
+
Example:
|
|
468
|
+
|
|
469
|
+
```json
|
|
470
|
+
{
|
|
471
|
+
"enabled": true,
|
|
472
|
+
"rescueMessage": "AI agent 是不是卡死了? 請停止重複動作,總結已知資訊並重新規劃。",
|
|
473
|
+
"repeatThreshold": 3,
|
|
474
|
+
"typecheckRepeatThreshold": 2,
|
|
475
|
+
"idleNoProgressSec": 300,
|
|
476
|
+
"cooldownSec": 60,
|
|
477
|
+
"alertMode": "main_only"
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## 12. Integration Options
|
|
484
|
+
|
|
485
|
+
### 12.1 Preferred: `@gotgenes/pi-subagents`
|
|
486
|
+
|
|
487
|
+
Use when available because it provides in-process sub-agent core, lifecycle events, typed API, and steering support.
|
|
488
|
+
|
|
489
|
+
Expected integration points:
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
const { getSubagentsService } = await import('@gotgenes/pi-subagents');
|
|
493
|
+
const svc = getSubagentsService?.();
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Use cases:
|
|
497
|
+
|
|
498
|
+
- enumerate subagents,
|
|
499
|
+
- observe lifecycle events,
|
|
500
|
+
- read status/transcripts if exposed,
|
|
501
|
+
- steer a running subagent,
|
|
502
|
+
- identify parent/child relationships.
|
|
503
|
+
|
|
504
|
+
Implementation note:
|
|
505
|
+
|
|
506
|
+
- Treat this dependency as optional peer dependency.
|
|
507
|
+
- Extension must still load when this package is absent.
|
|
508
|
+
|
|
509
|
+
### 12.2 Optional: `pi-intercom`
|
|
510
|
+
|
|
511
|
+
Use as a message broker when cross-session message routing is needed.
|
|
512
|
+
|
|
513
|
+
Use cases:
|
|
514
|
+
|
|
515
|
+
- send alert from watchdog sub-agent to main session,
|
|
516
|
+
- send rescue message from main session to task sub-agent,
|
|
517
|
+
- coordinate if task sub-agents are separate Pi sessions instead of in-process children.
|
|
518
|
+
|
|
519
|
+
### 12.3 Fallback: Pi Events + Tool Hooks
|
|
520
|
+
|
|
521
|
+
If subagent service is unavailable:
|
|
522
|
+
|
|
523
|
+
- listen to Pi lifecycle events,
|
|
524
|
+
- listen to `tool_call`,
|
|
525
|
+
- track visible tool calls in current session,
|
|
526
|
+
- expose partial watchdog status only.
|
|
527
|
+
|
|
528
|
+
### 12.4 Fallback: External Daemon / Log Parser
|
|
529
|
+
|
|
530
|
+
Out of MVP scope, but useful if Pi API does not expose enough sub-agent internals.
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## 13. Main Agent Supervisor Flow
|
|
535
|
+
|
|
536
|
+
```txt
|
|
537
|
+
1. User asks main agent to run work with sub-agents.
|
|
538
|
+
2. Main agent starts watchdog sub-agent.
|
|
539
|
+
3. Main agent starts task sub-agent 1 and task sub-agent 2.
|
|
540
|
+
4. Extension records sub-agent events.
|
|
541
|
+
5. Watchdog sub-agent periodically calls watchdog tools.
|
|
542
|
+
6. Watchdog detects task-sub-agent-1 likely stuck.
|
|
543
|
+
7. Watchdog alerts main agent.
|
|
544
|
+
8. Main agent decides whether to steer task-sub-agent-1.
|
|
545
|
+
9. If approved, extension sends rescue message to task-sub-agent-1.
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## 14. Periodic Watchdog Execution
|
|
551
|
+
|
|
552
|
+
Important: a watchdog sub-agent does not run continuously by itself unless the runtime keeps prompting it.
|
|
553
|
+
|
|
554
|
+
MVP options:
|
|
555
|
+
|
|
556
|
+
### Option A: Main-agent driven
|
|
557
|
+
|
|
558
|
+
Main agent periodically asks watchdog sub-agent to check status.
|
|
559
|
+
|
|
560
|
+
Pros:
|
|
561
|
+
|
|
562
|
+
- simpler,
|
|
563
|
+
- safer,
|
|
564
|
+
- no timer injection needed.
|
|
565
|
+
|
|
566
|
+
Cons:
|
|
567
|
+
|
|
568
|
+
- if main agent forgets, watchdog is idle.
|
|
569
|
+
|
|
570
|
+
### Option B: Extension-driven tick
|
|
571
|
+
|
|
572
|
+
Extension periodically sends a compact prompt to watchdog sub-agent:
|
|
573
|
+
|
|
574
|
+
```txt
|
|
575
|
+
Check current task sub-agent status. Report only if likely stuck.
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Pros:
|
|
579
|
+
|
|
580
|
+
- closer to real watchdog behavior.
|
|
581
|
+
|
|
582
|
+
Cons:
|
|
583
|
+
|
|
584
|
+
- needs reliable Pi API for sending messages into sub-agent sessions.
|
|
585
|
+
- must avoid spamming / token waste.
|
|
586
|
+
|
|
587
|
+
Recommended MVP: Option A first, then Option B.
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## 15. Safety & Anti-spam
|
|
592
|
+
|
|
593
|
+
- Alert cooldown per target: default 60 seconds.
|
|
594
|
+
- Do not send direct rescue message unless `alertMode` allows it.
|
|
595
|
+
- Default alert mode is `main_only`.
|
|
596
|
+
- Store output hash and short preview only; avoid storing large command output.
|
|
597
|
+
- Avoid repeated alerts for same evidence key.
|
|
598
|
+
- Ignore completed / failed sub-agents unless explicitly requested.
|
|
599
|
+
- Provide `/watchdog pause` and `/watchdog resume` commands.
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## 16. Commands
|
|
604
|
+
|
|
605
|
+
### `/watchdog status`
|
|
606
|
+
|
|
607
|
+
Show current targets and stuck signals.
|
|
608
|
+
|
|
609
|
+
### `/watchdog config`
|
|
610
|
+
|
|
611
|
+
Show current config.
|
|
612
|
+
|
|
613
|
+
### `/watchdog set rescueMessage <message>`
|
|
614
|
+
|
|
615
|
+
Update rescue message for current session.
|
|
616
|
+
|
|
617
|
+
### `/watchdog pause`
|
|
618
|
+
|
|
619
|
+
Disable alerting temporarily.
|
|
620
|
+
|
|
621
|
+
### `/watchdog resume`
|
|
622
|
+
|
|
623
|
+
Enable alerting.
|
|
624
|
+
|
|
625
|
+
### `/watchdog inspect <targetId>`
|
|
626
|
+
|
|
627
|
+
Show recent compact event summary.
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## 17. MVP Milestones
|
|
632
|
+
|
|
633
|
+
### Milestone 1 — Basic Extension Skeleton
|
|
634
|
+
|
|
635
|
+
- Create Pi package / extension.
|
|
636
|
+
- Register `/watchdog status` command.
|
|
637
|
+
- Register `watchdog_list_targets` tool.
|
|
638
|
+
- Load global/project config.
|
|
639
|
+
|
|
640
|
+
Acceptance:
|
|
641
|
+
|
|
642
|
+
```txt
|
|
643
|
+
pi -e ./src/index.ts
|
|
644
|
+
/watchdog status
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
shows extension is loaded.
|
|
648
|
+
|
|
649
|
+
### Milestone 2 — Sub-agent Discovery
|
|
650
|
+
|
|
651
|
+
- Integrate with `@gotgenes/pi-subagents` if installed.
|
|
652
|
+
- List running sub-agents.
|
|
653
|
+
- Mark watchdog sub-agent vs task sub-agent.
|
|
654
|
+
|
|
655
|
+
Acceptance:
|
|
656
|
+
|
|
657
|
+
```txt
|
|
658
|
+
main session has 2 task sub-agents + 1 watchdog sub-agent
|
|
659
|
+
/watchdog status lists all 3 correctly
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Milestone 3 — Event Collection
|
|
663
|
+
|
|
664
|
+
- Listen to lifecycle events.
|
|
665
|
+
- Listen to tool calls.
|
|
666
|
+
- Record command key and output hash if available.
|
|
667
|
+
- Store compact event ring buffer.
|
|
668
|
+
|
|
669
|
+
Acceptance:
|
|
670
|
+
|
|
671
|
+
```txt
|
|
672
|
+
running task sub-agent tool calls appear in watchdog_read_events()
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Milestone 4 — Stuck Detection
|
|
676
|
+
|
|
677
|
+
- Implement repeated command/output detector.
|
|
678
|
+
- Implement idle no-progress detector.
|
|
679
|
+
- Implement cooldown.
|
|
680
|
+
|
|
681
|
+
Acceptance:
|
|
682
|
+
|
|
683
|
+
```txt
|
|
684
|
+
a task sub-agent repeating same rg command 3 times is marked likelyStuck=true
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Milestone 5 — Watchdog Sub-agent Tools
|
|
688
|
+
|
|
689
|
+
- Add `watchdog_detect_stuck`.
|
|
690
|
+
- Add `watchdog_alert_main`.
|
|
691
|
+
- Add `watchdog_steer_subagent` dry-run.
|
|
692
|
+
|
|
693
|
+
Acceptance:
|
|
694
|
+
|
|
695
|
+
```txt
|
|
696
|
+
watchdog sub-agent can call watchdog_detect_stuck and produce compact alert
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### Milestone 6 — Main Agent Supervisor Mode
|
|
700
|
+
|
|
701
|
+
- Provide recommended watchdog sub-agent prompt.
|
|
702
|
+
- Provide sample main-agent workflow.
|
|
703
|
+
- Ensure main agent receives alert before direct intervention.
|
|
704
|
+
|
|
705
|
+
Acceptance:
|
|
706
|
+
|
|
707
|
+
```txt
|
|
708
|
+
watchdog sub-agent detects stuck task
|
|
709
|
+
main agent receives alert
|
|
710
|
+
main agent can choose to send rescue message
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
## 18. Suggested File Structure
|
|
716
|
+
|
|
717
|
+
```txt
|
|
718
|
+
pi-watchdog-supervisor/
|
|
719
|
+
├─ package.json
|
|
720
|
+
├─ README.md
|
|
721
|
+
├─ src/
|
|
722
|
+
│ ├─ index.ts
|
|
723
|
+
│ ├─ config.ts
|
|
724
|
+
│ ├─ events.ts
|
|
725
|
+
│ ├─ detector.ts
|
|
726
|
+
│ ├─ tools.ts
|
|
727
|
+
│ ├─ commands.ts
|
|
728
|
+
│ ├─ integrations/
|
|
729
|
+
│ │ ├─ gotgenes-subagents.ts
|
|
730
|
+
│ │ ├─ pi-intercom.ts
|
|
731
|
+
│ │ └─ fallback.ts
|
|
732
|
+
│ └─ types.ts
|
|
733
|
+
├─ prompts/
|
|
734
|
+
│ └─ watchdog-agent.md
|
|
735
|
+
└─ examples/
|
|
736
|
+
├─ AGENTS.md
|
|
737
|
+
└─ watchdog-supervisor.json
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## 19. Example `package.json` Pi Manifest
|
|
743
|
+
|
|
744
|
+
```json
|
|
745
|
+
{
|
|
746
|
+
"name": "pi-watchdog-supervisor",
|
|
747
|
+
"version": "0.1.0",
|
|
748
|
+
"type": "module",
|
|
749
|
+
"dependencies": {
|
|
750
|
+
"typebox": "latest"
|
|
751
|
+
},
|
|
752
|
+
"peerDependenciesMeta": {
|
|
753
|
+
"@gotgenes/pi-subagents": {
|
|
754
|
+
"optional": true
|
|
755
|
+
},
|
|
756
|
+
"pi-intercom": {
|
|
757
|
+
"optional": true
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
"pi": {
|
|
761
|
+
"extensions": [
|
|
762
|
+
"./src/index.ts"
|
|
763
|
+
],
|
|
764
|
+
"skills": [
|
|
765
|
+
"./skills/watchdog-supervisor.md"
|
|
766
|
+
]
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
---
|
|
772
|
+
|
|
773
|
+
## 20. Example Main Agent Instruction
|
|
774
|
+
|
|
775
|
+
```md
|
|
776
|
+
## Sub-agent watchdog workflow
|
|
777
|
+
|
|
778
|
+
When running multiple background sub-agents:
|
|
779
|
+
|
|
780
|
+
1. Start one watchdog sub-agent.
|
|
781
|
+
2. Start task sub-agents normally.
|
|
782
|
+
3. Ask watchdog sub-agent to periodically inspect task sub-agent status using watchdog tools.
|
|
783
|
+
4. If watchdog reports likely stuck, decide whether to steer the task sub-agent.
|
|
784
|
+
5. Prefer sending a rescue message before stopping/restarting a sub-agent.
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
## 21. Example Watchdog Skill
|
|
790
|
+
|
|
791
|
+
```md
|
|
792
|
+
# Watchdog Supervisor
|
|
793
|
+
|
|
794
|
+
Use this skill when supervising task sub-agents.
|
|
795
|
+
|
|
796
|
+
Steps:
|
|
797
|
+
1. Call `watchdog_list_targets`.
|
|
798
|
+
2. Ignore yourself and completed agents.
|
|
799
|
+
3. For each running task agent, call `watchdog_detect_stuck`.
|
|
800
|
+
4. If likely stuck, call `watchdog_read_events` for evidence.
|
|
801
|
+
5. Report a compact alert to the main agent.
|
|
802
|
+
6. Do not directly steer unless explicitly allowed.
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
## 22. Open Questions for Coder
|
|
808
|
+
|
|
809
|
+
Need verify from Pi runtime/source:
|
|
810
|
+
|
|
811
|
+
- Exact event names for tool results, message updates, and sub-agent lifecycle.
|
|
812
|
+
- Whether extension can send a message directly into a sub-agent session.
|
|
813
|
+
- Whether `@gotgenes/pi-subagents` exposes enough service API for listing and steering sub-agents.
|
|
814
|
+
- Whether watchdog sub-agent can be scheduled/ticked by extension safely.
|
|
815
|
+
- How to identify parent-child relationship across sub-agent sessions.
|
|
816
|
+
- Whether pi-intercom is enough for cross-session alerts.
|
|
817
|
+
- Whether output content can be accessed or only tool call metadata is exposed.
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
## 23. Testing Plan
|
|
822
|
+
|
|
823
|
+
### Unit Tests
|
|
824
|
+
|
|
825
|
+
- `normalizeCommand()`
|
|
826
|
+
- `hashOutput()`
|
|
827
|
+
- repeated command detection
|
|
828
|
+
- repeated output detection
|
|
829
|
+
- cooldown handling
|
|
830
|
+
- config merge: global + project
|
|
831
|
+
|
|
832
|
+
### Integration Tests
|
|
833
|
+
|
|
834
|
+
- extension loads in Pi.
|
|
835
|
+
- sub-agents are discovered.
|
|
836
|
+
- repeated tool calls generate stuck signal.
|
|
837
|
+
- watchdog tool returns evidence.
|
|
838
|
+
- alert is routed to main session.
|
|
839
|
+
|
|
840
|
+
### Manual Scenario Test
|
|
841
|
+
|
|
842
|
+
Create a dummy sub-agent that loops:
|
|
843
|
+
|
|
844
|
+
```txt
|
|
845
|
+
Run `rg "SOME_TOKEN" src` three times without changing query/path.
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
Expected:
|
|
849
|
+
|
|
850
|
+
```txt
|
|
851
|
+
watchdog_detect_stuck(targetId).likelyStuck === true
|
|
852
|
+
main agent receives [Watchdog Alert]
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
857
|
+
## 24. Risks
|
|
858
|
+
|
|
859
|
+
| Risk | Impact | Mitigation |
|
|
860
|
+
|---|---:|---|
|
|
861
|
+
| Pi does not expose enough sub-agent internals | High | Use `@gotgenes/pi-subagents` service API or pi-intercom |
|
|
862
|
+
| Watchdog sub-agent stays idle | Medium | Start with main-agent-driven checks; add extension tick later |
|
|
863
|
+
| Too many false positives | Medium | Use cooldown, confidence levels, and main-agent approval |
|
|
864
|
+
| Token waste from monitoring | Medium | Store compact summaries and hashes only |
|
|
865
|
+
| Direct rescue causes bad intervention | Medium | Default to `main_only` alert mode |
|
|
866
|
+
| Third-party extension API changes | Medium | Keep adapters isolated under `integrations/` |
|
|
867
|
+
|
|
868
|
+
---
|
|
869
|
+
|
|
870
|
+
## 25. Recommended MVP Decision
|
|
871
|
+
|
|
872
|
+
Build this as a Pi extension, but keep roles separate:
|
|
873
|
+
|
|
874
|
+
```txt
|
|
875
|
+
extension runtime = event collector + deterministic detector
|
|
876
|
+
watchdog sub-agent = reasoning/reporting layer
|
|
877
|
+
main agent = final decision maker
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
Default behavior:
|
|
881
|
+
|
|
882
|
+
```txt
|
|
883
|
+
Detect stuck → alert main agent → main agent decides rescue
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
Not default:
|
|
887
|
+
|
|
888
|
+
```txt
|
|
889
|
+
Detect stuck → auto steer task sub-agent
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
---
|
|
893
|
+
|
|
894
|
+
## 26. Reference Materials
|
|
895
|
+
|
|
896
|
+
- Pi Documentation — Extensions, latest docs, extension locations, imports, command registration, accessed 2026-07-08.
|
|
897
|
+
- https://pi.dev/docs/latest/extensions
|
|
898
|
+
- Pi extension examples README, includes examples for lifecycle events, `tool_call`, `send-user-message.ts`, `event-bus.ts`, and `subagent/`, accessed 2026-07-08.
|
|
899
|
+
- https://github.com/earendil-works/pi/blob/main/packages/coding-agent/examples/extensions/README.md
|
|
900
|
+
- `@gotgenes/pi-subagents` package page, in-process sub-agent core, typed API, lifecycle events, steering, accessed 2026-07-08.
|
|
901
|
+
- https://pi.dev/packages/%40gotgenes/pi-subagents
|
|
902
|
+
- `pi-intercom` package page, local IPC broker, direct messages between Pi sessions, incoming messages can trigger a turn, accessed 2026-07-08.
|
|
903
|
+
- https://pi.dev/packages/pi-intercom
|
|
904
|
+
- Pi Documentation — Packages, package manifest and install/config behavior, accessed 2026-07-08.
|
|
905
|
+
- https://pi.dev/docs/latest/packages
|
|
906
|
+
- Pi Documentation — SDK, programmatic agent session/events overview, accessed 2026-07-08.
|
|
907
|
+
- https://pi.dev/docs/latest/sdk
|