@ferris1225/pi-subagents 4.1.16 → 4.1.18
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/README.md +8 -4
- package/package.json +9 -9
- package/src/announcements.ts +16 -0
- package/src/dispatch.ts +4 -2
- package/src/rpc-run.ts +993 -962
- package/src/session-fork.ts +4 -5
- package/src/spawn.ts +4 -0
- package/src/temp-hygiene.ts +37 -29
- package/src/thread-lifecycle.ts +6 -3
- package/src/worktree.ts +5 -5
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ the main agent automatically; there is no polling loop.
|
|
|
71
71
|
|
|
72
72
|
## Quick start
|
|
73
73
|
|
|
74
|
-
Requires **pi >= 0.
|
|
74
|
+
Requires **pi >= 0.84.4** and **Node.js >= 22.19.0**.
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
77
|
pi install npm:@ferris1225/pi-subagents
|
|
@@ -197,7 +197,7 @@ Every dispatch returns a stable `#id` — the handle for all control tools:
|
|
|
197
197
|
| `subagent_control` | `resume` a parked/settled thread with its full retained context, optionally with a new `objective` appended. Only interrupted (parked) threads survive a reload. |
|
|
198
198
|
| `subagent_status` | List active and recent runs, or return one run's full result and failed-tool diagnostics. |
|
|
199
199
|
| `subagent_wait` | Non-blocking in-turn lookup; `timeoutMs` only when you must wait. |
|
|
200
|
-
| `subagent_stop` | Destructively cancel, deliver the partial output, retire the thread.
|
|
200
|
+
| `subagent_stop` | Destructively cancel, deliver the partial output, retire the thread. Stopping also drops any steering/follow-up messages still queued in the child so a stopped or later resumed thread cannot be revived by stale queue entries. |
|
|
201
201
|
|
|
202
202
|
```ts
|
|
203
203
|
subagent_control({ action: "resume", id: 7, objective: "Finish the tests." });
|
|
@@ -205,8 +205,10 @@ subagent_control({ action: "resume", id: 7, objective: "Finish the tests." });
|
|
|
205
205
|
|
|
206
206
|
Threads are durable while work is unfinished: parked sessions, worktree
|
|
207
207
|
checkpoints, and result excerpts live under
|
|
208
|
-
`~/.pi/agent/ferris-pi-subagents/<project>/` (grouped per project;
|
|
209
|
-
|
|
208
|
+
`~/.pi/agent/ferris-pi-subagents/<project>/` (grouped per project; nothing is
|
|
209
|
+
written to the OS temp directory — transient per-run scratch lives in the
|
|
210
|
+
project's `tmp/` and is swept for dead owners on the next load) and are
|
|
211
|
+
restored when pi reloads or restarts — a reload
|
|
210
212
|
interrupts a live run into a restorable checkpoint instead of losing it. A
|
|
211
213
|
thread that completes or fails cleanly drops its durable record, so the
|
|
212
214
|
threads manifest exists only
|
|
@@ -292,6 +294,8 @@ config-file only, stored at
|
|
|
292
294
|
Invalid values fall back safely; stale keys (including the former
|
|
293
295
|
`maxConcurrency`/`maxFixRounds` knobs) are dropped automatically. At session
|
|
294
296
|
start, model overrides Pi no longer reports are removed with a one-time notice.
|
|
297
|
+
When pi's own session compaction fails mid-thread, a notice surfaces the error
|
|
298
|
+
(and the automatic retry) instead of failing silently.
|
|
295
299
|
|
|
296
300
|
## Custom agents
|
|
297
301
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.18",
|
|
4
4
|
"description": "A managed sub-agent team for pi: specialized roles, pre-commit documentation sync, retained threads, auto-fix chains, model fallback, and Git worktree isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"prepack": "npm run check && npm test"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@earendil-works/pi-agent-core": ">=0.
|
|
37
|
-
"@earendil-works/pi-ai": ">=0.
|
|
38
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
39
|
-
"@earendil-works/pi-tui": ">=0.
|
|
36
|
+
"@earendil-works/pi-agent-core": ">=0.84.4",
|
|
37
|
+
"@earendil-works/pi-ai": ">=0.84.4",
|
|
38
|
+
"@earendil-works/pi-coding-agent": ">=0.84.4",
|
|
39
|
+
"@earendil-works/pi-tui": ">=0.84.4",
|
|
40
40
|
"typebox": "*"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
44
|
-
"@earendil-works/pi-ai": "^0.
|
|
45
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
46
|
-
"@earendil-works/pi-tui": "^0.
|
|
43
|
+
"@earendil-works/pi-agent-core": "^0.84.4",
|
|
44
|
+
"@earendil-works/pi-ai": "^0.84.4",
|
|
45
|
+
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
46
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
47
47
|
"@types/node": "^22.10.0",
|
|
48
48
|
"typebox": "^1.3.9",
|
|
49
49
|
"typescript": "^5.9.0",
|
package/src/announcements.ts
CHANGED
|
@@ -56,4 +56,20 @@ export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime
|
|
|
56
56
|
if (ctx.mode !== "tui") return;
|
|
57
57
|
installActiveRunsWidget(ctx);
|
|
58
58
|
});
|
|
59
|
+
|
|
60
|
+
// Compaction failures are otherwise silent in long orchestration sessions
|
|
61
|
+
// where subagent results accumulate; aborted (user-cancelled) compactions
|
|
62
|
+
// are deliberate and not worth a notice.
|
|
63
|
+
pi.on("session_compact_failed", async (event, ctx) => {
|
|
64
|
+
if (event.aborted && !event.errorMessage) return;
|
|
65
|
+
const detail = event.errorMessage ? `: ${event.errorMessage}` : "";
|
|
66
|
+
if (event.willRetry) {
|
|
67
|
+
ctx.ui.notify(`pi-subagents: session compaction failed${detail} — retrying automatically.`, "warning");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
ctx.ui.notify(
|
|
71
|
+
`pi-subagents: session compaction failed${detail}. Long threads may hit context limits soon; run /compact to retry or trim old results.`,
|
|
72
|
+
"error",
|
|
73
|
+
);
|
|
74
|
+
});
|
|
59
75
|
}
|
package/src/dispatch.ts
CHANGED
|
@@ -251,6 +251,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
|
|
|
251
251
|
...(request.worktreeId ? { worktreeId: request.worktreeId } : {}),
|
|
252
252
|
});
|
|
253
253
|
const onLive = makeLiveHandler(runId);
|
|
254
|
+
const projectRoot = getProjectRoot(runtime.configPath, request.executionCwd);
|
|
254
255
|
try {
|
|
255
256
|
const result = await runSingleAgentWithMainFallback(
|
|
256
257
|
{
|
|
@@ -266,7 +267,8 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
|
|
|
266
267
|
onLive,
|
|
267
268
|
makeDetails: makeDetails("single", true),
|
|
268
269
|
idleTimeoutMs: stageConfig.idleTimeoutSec * 1000,
|
|
269
|
-
sessionRoot: join(
|
|
270
|
+
sessionRoot: join(projectRoot, "sessions"),
|
|
271
|
+
scratchRoot: join(projectRoot, "tmp"),
|
|
270
272
|
...(stage.session
|
|
271
273
|
? { sessionId: stage.session.sessionId, sessionDir: stage.session.sessionDir, stdinText: task }
|
|
272
274
|
: {}),
|
|
@@ -407,7 +409,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
|
|
|
407
409
|
? { sessionId: gateReview.sessionId, sessionDir: gateReview.sessionDir }
|
|
408
410
|
: undefined;
|
|
409
411
|
if (reviewVerdict(getResultOutput(gateReview)) !== "fail" || !gateSession || !canContinue()) break;
|
|
410
|
-
const fixStage: WorkflowStage = { agent: "reviewer", relation: "fix", status: "pending" };
|
|
412
|
+
const fixStage: WorkflowStage = { agent: "reviewer", relation: "review fix", status: "pending" };
|
|
411
413
|
workflowStages.push(fixStage);
|
|
412
414
|
publishWorkflowStages();
|
|
413
415
|
const fixResult = await launchStep(
|