@ferris1225/pi-subagents 0.32.2 → 1.0.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/README.md +35 -16
- package/package.json +2 -2
- package/src/announcements.ts +59 -0
- package/src/dispatch.ts +1833 -1878
- package/src/fixloop.ts +1 -1
- package/src/format.ts +2 -1
- package/src/index.ts +4 -8
- package/src/models.ts +23 -35
- package/src/monitor.ts +29 -88
- package/src/rpc-run.ts +1 -26
- package/src/runtime.ts +284 -285
- package/src/setup.ts +4 -4
- package/src/spawn.ts +1 -6
- package/src/tools.ts +730 -748
- package/src/trajectory.ts +16 -207
- package/src/inspector-panel.ts +0 -363
- package/src/inspector.ts +0 -369
- package/src/widget.ts +0 -195
package/README.md
CHANGED
|
@@ -11,6 +11,28 @@ Focused background delegation for [pi](https://pi.dev): `explore` / `worker` /
|
|
|
11
11
|
to the main agent automatically. Install it, and the main model starts using it
|
|
12
12
|
on its own — no prompt engineering, no babysitting.
|
|
13
13
|
|
|
14
|
+
## 1.0 — controllable agent threads
|
|
15
|
+
|
|
16
|
+
Version 1.0 turns pi-subagents from a one-shot background runner into a small
|
|
17
|
+
thread runtime. Every dispatch has a stable run id and retained Pi session, so
|
|
18
|
+
work can be steered while it runs, parked without losing context, resumed after
|
|
19
|
+
settlement, retargeted, or forked into another path. An internal append-only
|
|
20
|
+
lifecycle trajectory keeps retries and stale generations from corrupting the
|
|
21
|
+
logical thread.
|
|
22
|
+
|
|
23
|
+
The common quality loop now runs end to end without waking the main agent between
|
|
24
|
+
steps:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
reviewer (find blockers) → worker (fix) → reviewer (verify) → final PASS/FAIL
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Each chain is delivered as one concise completion group, while full per-run
|
|
31
|
+
reports remain available through `subagent_status`. Ordered model pools keep the
|
|
32
|
+
same retained context across provider fallback, and isolated parallel workers
|
|
33
|
+
use detached Git worktrees whose changes are applied back without touching the
|
|
34
|
+
parent index.
|
|
35
|
+
|
|
14
36
|
## Highlights
|
|
15
37
|
|
|
16
38
|
- **Zero-setup proactive dispatch** — the extension injects a delegation directive
|
|
@@ -19,8 +41,8 @@ on its own — no prompt engineering, no babysitting.
|
|
|
19
41
|
to `reviewer`. You just use pi; delegation happens by itself.
|
|
20
42
|
- **Vision-capable image tasks** — flag screenshot/mockup/design work with
|
|
21
43
|
`vision: true`. The configured vision primary is followed by that agent's
|
|
22
|
-
backup and the current main-window model.
|
|
23
|
-
image-capable models
|
|
44
|
+
backup and the current main-window model. Setup lists only in-scope,
|
|
45
|
+
image-capable models from providers with a configured API key or OAuth session,
|
|
24
46
|
and runtime failures never silently rewrite your configuration.
|
|
25
47
|
- **Results come back on their own** — completions are delivered as messages that
|
|
26
48
|
wake the main agent automatically, even mid-turn. No polling, no `sleep`, no
|
|
@@ -52,12 +74,6 @@ on its own — no prompt engineering, no babysitting.
|
|
|
52
74
|
configurable limit (default 4). Parallel workers default to detached Git
|
|
53
75
|
worktrees; tracked, deleted, untracked, and binary changes are applied back
|
|
54
76
|
without touching the parent index. Failed integration keeps recovery artifacts.
|
|
55
|
-
- **Live inspector** — `/subagents-inspect` opens a master/detail
|
|
56
|
-
overlay with thread state, model chain, usage, transcript, recent tools,
|
|
57
|
-
worktree/fork relations, and the append-only control trajectory.
|
|
58
|
-
- **Live progress widget** — each run's status, current activity, model, token
|
|
59
|
-
usage, and elapsed time; auto-fix chain rounds hang under their triggering
|
|
60
|
-
review as a tree, each finished round keeping a one-line outcome.
|
|
61
77
|
- **Recursion is structurally impossible** — children are leaf processes; the
|
|
62
78
|
`subagent` tool is excluded from their toolset.
|
|
63
79
|
- **Zero runtime dependencies** — agents are plain Markdown files; overriding or
|
|
@@ -134,7 +150,10 @@ once, then skipped as a permanent candidate error; it is not rewritten. A
|
|
|
134
150
|
vision-flagged auto-fix chain keeps the flag for worker/re-review rounds because
|
|
135
151
|
they may need to inspect the same images.
|
|
136
152
|
|
|
137
|
-
### Controlling
|
|
153
|
+
### Controlling and stopping
|
|
154
|
+
|
|
155
|
+
Dispatch confirmations, tool result rows, and completion blocks all show the
|
|
156
|
+
stable `#id`, so a thread remains directly controllable after its live UI is gone.
|
|
138
157
|
|
|
139
158
|
- `subagent_control` — `steer`, `retarget`, `park`, `resume`, or `fork` a logical
|
|
140
159
|
thread by stable run id. Resume accepts an optional replacement objective;
|
|
@@ -144,8 +163,6 @@ they may need to inspect the same images.
|
|
|
144
163
|
run returns immediately; an active run tells the model to end its turn. Pass
|
|
145
164
|
`timeoutMs` only when you must stay in the turn.
|
|
146
165
|
- `subagent_status` — active/parked/finished runs and full result by run id.
|
|
147
|
-
- `/subagents-inspect` — interactive live thread/transcript/tool/trajectory
|
|
148
|
-
overlay; press `p` to park or resume the selected thread.
|
|
149
166
|
- `subagent_stop` — destructive cancellation. It retires that thread's retained
|
|
150
167
|
session (independent forks survive) and delivers exactly one aborted partial
|
|
151
168
|
result after the run and any worktree integration have quiesced.
|
|
@@ -187,8 +204,9 @@ Stored at `~/.pi/agent/pi-subagents.json` (follows `PI_CODING_AGENT_DIR` when
|
|
|
187
204
|
set). The `/subagents-setup` wizard drives every field interactively — models, the
|
|
188
205
|
default plus each enabled agent's thinking level, the vision model, concurrency,
|
|
189
206
|
fix rounds, idle timeout, scope, and injection — with a per-agent "configure
|
|
190
|
-
one" menu when the config already exists.
|
|
191
|
-
|
|
207
|
+
one" menu when the config already exists. Model pickers show only models in the
|
|
208
|
+
current session scope that are available through a configured API key or OAuth
|
|
209
|
+
session. `notifyOnReviewPass` and `maxResultLines` are edited directly in the file.
|
|
192
210
|
|
|
193
211
|
```json
|
|
194
212
|
{
|
|
@@ -298,6 +316,7 @@ after an update via a toast (marker persisted in `announcedFeatures`).
|
|
|
298
316
|
- **Dispatch failures surface** — partial parallel startup reports every failed
|
|
299
317
|
item and reason; if none start, the tool throws so Pi records a real tool error.
|
|
300
318
|
Dispatch crashes likewise produce a failed result instead of a silent hang.
|
|
319
|
+
- **Safe live status** — tool activity is credential-redacted and stripped of terminal control sequences before `subagent_status` can return it.
|
|
301
320
|
- **Leaf children** — no nested delegation, no runaway trees.
|
|
302
321
|
|
|
303
322
|
## Development
|
|
@@ -311,9 +330,9 @@ npm test
|
|
|
311
330
|
The source is modular: `dispatch.ts` (dispatch, controls, isolation, auto-fix),
|
|
312
331
|
`rpc-run.ts` / `spawn.ts` (persistent child transport + model pools),
|
|
313
332
|
`worktree.ts` / `session-fork.ts` (filesystem/session branching),
|
|
314
|
-
`trajectory.ts`
|
|
315
|
-
(wait/status/control/stop), `
|
|
316
|
-
`runtime.ts` (session-scoped ownership). No runtime dependencies beyond pi peer
|
|
333
|
+
`trajectory.ts` (internal lifecycle history), `tools.ts`
|
|
334
|
+
(wait/status/control/stop), `announcements.ts` (recovery and feature notices),
|
|
335
|
+
and `runtime.ts` (session-scoped ownership). No runtime dependencies beyond pi peer
|
|
317
336
|
dependencies.
|
|
318
337
|
|
|
319
338
|
## License
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Controllable background sub-agent threads for pi: explore, worker, reviewer, auto-fix chains, model pools, and Git worktree isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"publishConfig": {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Session-start recovery and one-time feature announcements. */
|
|
2
|
+
|
|
3
|
+
import { stat } from "node:fs/promises";
|
|
4
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { loadConfig, saveConfig } from "./config.ts";
|
|
6
|
+
import { announceRecoveryRecords } from "./recovery.ts";
|
|
7
|
+
import type { SubagentRuntime } from "./runtime.ts";
|
|
8
|
+
|
|
9
|
+
const ANNOUNCEMENTS: Array<{
|
|
10
|
+
key: string;
|
|
11
|
+
condition: (config: Awaited<ReturnType<typeof loadConfig>>) => boolean;
|
|
12
|
+
message: string;
|
|
13
|
+
}> = [
|
|
14
|
+
{
|
|
15
|
+
key: "visionModel",
|
|
16
|
+
condition: (config) => config.visionModel === undefined,
|
|
17
|
+
message:
|
|
18
|
+
"pi-subagents: new — a vision-capable model can now handle image tasks (screenshots, mockups, designs). Run /subagents-setup to configure it; until set, vision tasks use the main session's current model.",
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
async function announceNewFeatures(
|
|
23
|
+
ctx: { ui: { notify: (message: string, kind: "info" | "warning" | "error") => void } },
|
|
24
|
+
runtime: SubagentRuntime,
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
let configExists = true;
|
|
28
|
+
try {
|
|
29
|
+
await stat(runtime.configPath);
|
|
30
|
+
} catch {
|
|
31
|
+
configExists = false;
|
|
32
|
+
}
|
|
33
|
+
if (!configExists) return;
|
|
34
|
+
|
|
35
|
+
const config = await loadConfig(runtime.configPath);
|
|
36
|
+
const pending = ANNOUNCEMENTS.filter(
|
|
37
|
+
(announcement) =>
|
|
38
|
+
announcement.condition(config) && !config.announcedFeatures.includes(announcement.key),
|
|
39
|
+
);
|
|
40
|
+
if (pending.length === 0) return;
|
|
41
|
+
await saveConfig(
|
|
42
|
+
{
|
|
43
|
+
...config,
|
|
44
|
+
announcedFeatures: [...config.announcedFeatures, ...pending.map((announcement) => announcement.key)],
|
|
45
|
+
},
|
|
46
|
+
runtime.configPath,
|
|
47
|
+
);
|
|
48
|
+
for (const announcement of pending) ctx.ui.notify(announcement.message, "info");
|
|
49
|
+
} catch {
|
|
50
|
+
/* announcement failures are non-fatal */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime): void {
|
|
55
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
56
|
+
await announceRecoveryRecords(runtime.configPath, ctx);
|
|
57
|
+
if (ctx.mode === "tui") await announceNewFeatures(ctx, runtime);
|
|
58
|
+
});
|
|
59
|
+
}
|