@cr1ms0n/pi-subagent 0.8.8 → 0.8.9
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/CHANGELOG.md +3 -5
- package/README.md +7 -20
- package/docs/ARCHITECTURE.md +125 -132
- package/docs/SECURITY.md +88 -97
- package/package.json +1 -1
- package/skills/subagent/SKILL.md +113 -121
- package/src/agents.ts +282 -288
- package/src/extension.ts +6 -33
- package/src/orchestrator.ts +247 -312
- package/src/policy.ts +531 -561
- package/src/schema.ts +189 -189
- package/src/context-policy.ts +0 -169
package/skills/subagent/SKILL.md
CHANGED
|
@@ -1,121 +1,113 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: subagent
|
|
3
|
-
description: Delegate work to isolated child agents with the subagent tool — model and thinking policy, explore/review/general profiles, parallel fanout with synthesis, worktree isolation and the diff/apply/discard loop, background runs, steering, output_schema, context fork, and backend tradeoffs (pi/codex/claude). Use when delegating exploration or implementation, running tasks in parallel, or when a subagent run needs inspecting, steering, or landing.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Subagent
|
|
7
|
-
|
|
8
|
-
Delegate research, parallel exploration, and clean-context implementation to child
|
|
9
|
-
agents. Prefer `subagent` over long in-thread digressions when the work benefits
|
|
10
|
-
from isolation, parallelism, or a fresh context.
|
|
11
|
-
|
|
12
|
-
## When to use
|
|
13
|
-
|
|
14
|
-
- Map a codebase area without bloating the parent context (`profile: "explore"`).
|
|
15
|
-
- Review a diff read-only (`profile: "review"`).
|
|
16
|
-
- Implement behind a worktree and land via apply (`profile: "general"`, `isolation: "worktree"`).
|
|
17
|
-
- Fan out independent questions, optionally with `synthesis` to fold results.
|
|
18
|
-
- Background long work (`async: true`) and collect later with `wait` / `subagent_wait`.
|
|
19
|
-
|
|
20
|
-
## Core calls
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
// Examples use placeholders only. Replace these with the exact model selected
|
|
24
|
-
// from the current modelPolicy route; they do not configure a real model.
|
|
25
|
-
const routeModel = "<exact model from current modelPolicy route>";
|
|
26
|
-
|
|
27
|
-
// Single foreground task (default profile: general)
|
|
28
|
-
{ task: "Find call sites of parseConfig", description: "Map parseConfig", model: routeModel }
|
|
29
|
-
|
|
30
|
-
// Parallel read-only explorers (default profile for tasks[]: explore)
|
|
31
|
-
{
|
|
32
|
-
tasks: [
|
|
33
|
-
{ task: "Map auth middleware", description: "Auth flow", model: routeModel },
|
|
34
|
-
{ task: "List env vars in server/", description: "Env inventory", model: routeModel }
|
|
35
|
-
],
|
|
36
|
-
synthesis: "Merge into one prioritized brief"
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Background — notified on completion; wait/status still work
|
|
40
|
-
{ task: "Audit dependency licenses", model: routeModel, async: true }
|
|
41
|
-
{ action: "status", id: "abc123" }
|
|
42
|
-
{ action: "wait", id: "abc123" } // interruptible; does not cancel
|
|
43
|
-
{ action: "cancel", id: "abc123" }
|
|
44
|
-
// Same wait semantics as a dedicated tool:
|
|
45
|
-
// subagent_wait { id: "abc123", timeout_ms?: number }
|
|
46
|
-
|
|
47
|
-
// Worktree loop
|
|
48
|
-
{ task: "Implement feature A", model: routeModel, profile: "general", isolation: "worktree" }
|
|
49
|
-
{ action: "diff", id: "abc123", index: 1 }
|
|
50
|
-
{ action: "apply", id: "abc123", index: 1 }
|
|
51
|
-
{ action: "discard", id: "abc123", index: 1 }
|
|
52
|
-
|
|
53
|
-
// Dry-run validation + resolved plan (no spawn)
|
|
54
|
-
// plan is a dry-run, but every task still needs the policy-routed model.
|
|
55
|
-
{ action: "plan", tasks: [{ task: "…", model: routeModel, isolation: "worktree" }] }
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Profiles
|
|
59
|
-
|
|
60
|
-
| Profile | Tools | Writes |
|
|
61
|
-
| --------- | --------------------------------------------------------- | ------------------------------------------- |
|
|
62
|
-
| `explore` | read/search/ls (+safe) +
|
|
63
|
-
| `review` | same as explore | no project-file writes |
|
|
64
|
-
| `general` | inherited active tools +
|
|
65
|
-
|
|
66
|
-
For Pi children, `new_context`, `get_context_remaining`, `history`, and
|
|
67
|
-
`notes` are control-plane tools.
|
|
68
|
-
the
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
`
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
exactly. An optional route `thinking` value is an opaque Pi thinking-level
|
|
115
|
-
string; common values include `off`, `minimal`, `low`, `medium`, `high`, `xhigh`,
|
|
116
|
-
and `max`, but model-specific values are passed through unchanged. It is a
|
|
117
|
-
default; explicit task, agent, and profile `taskDefaults.thinking` values
|
|
118
|
-
override it. Management actions do not require model. The extension re-reads
|
|
119
|
-
this policy on each dispatch and injects it into
|
|
120
|
-
the parent prompt. If the policy is missing or invalid, management remains
|
|
121
|
-
available but new spawns and synthesis are rejected.
|
|
1
|
+
---
|
|
2
|
+
name: subagent
|
|
3
|
+
description: Delegate work to isolated child agents with the subagent tool — model and thinking policy, explore/review/general profiles, parallel fanout with synthesis, worktree isolation and the diff/apply/discard loop, background runs, steering, output_schema, context fork, and backend tradeoffs (pi/codex/claude). Use when delegating exploration or implementation, running tasks in parallel, or when a subagent run needs inspecting, steering, or landing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Subagent
|
|
7
|
+
|
|
8
|
+
Delegate research, parallel exploration, and clean-context implementation to child
|
|
9
|
+
agents. Prefer `subagent` over long in-thread digressions when the work benefits
|
|
10
|
+
from isolation, parallelism, or a fresh context.
|
|
11
|
+
|
|
12
|
+
## When to use
|
|
13
|
+
|
|
14
|
+
- Map a codebase area without bloating the parent context (`profile: "explore"`).
|
|
15
|
+
- Review a diff read-only (`profile: "review"`).
|
|
16
|
+
- Implement behind a worktree and land via apply (`profile: "general"`, `isolation: "worktree"`).
|
|
17
|
+
- Fan out independent questions, optionally with `synthesis` to fold results.
|
|
18
|
+
- Background long work (`async: true`) and collect later with `wait` / `subagent_wait`.
|
|
19
|
+
|
|
20
|
+
## Core calls
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// Examples use placeholders only. Replace these with the exact model selected
|
|
24
|
+
// from the current modelPolicy route; they do not configure a real model.
|
|
25
|
+
const routeModel = "<exact model from current modelPolicy route>";
|
|
26
|
+
|
|
27
|
+
// Single foreground task (default profile: general)
|
|
28
|
+
{ task: "Find call sites of parseConfig", description: "Map parseConfig", model: routeModel }
|
|
29
|
+
|
|
30
|
+
// Parallel read-only explorers (default profile for tasks[]: explore)
|
|
31
|
+
{
|
|
32
|
+
tasks: [
|
|
33
|
+
{ task: "Map auth middleware", description: "Auth flow", model: routeModel },
|
|
34
|
+
{ task: "List env vars in server/", description: "Env inventory", model: routeModel }
|
|
35
|
+
],
|
|
36
|
+
synthesis: "Merge into one prioritized brief"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Background — notified on completion; wait/status still work
|
|
40
|
+
{ task: "Audit dependency licenses", model: routeModel, async: true }
|
|
41
|
+
{ action: "status", id: "abc123" }
|
|
42
|
+
{ action: "wait", id: "abc123" } // interruptible; does not cancel
|
|
43
|
+
{ action: "cancel", id: "abc123" }
|
|
44
|
+
// Same wait semantics as a dedicated tool:
|
|
45
|
+
// subagent_wait { id: "abc123", timeout_ms?: number }
|
|
46
|
+
|
|
47
|
+
// Worktree loop
|
|
48
|
+
{ task: "Implement feature A", model: routeModel, profile: "general", isolation: "worktree" }
|
|
49
|
+
{ action: "diff", id: "abc123", index: 1 }
|
|
50
|
+
{ action: "apply", id: "abc123", index: 1 }
|
|
51
|
+
{ action: "discard", id: "abc123", index: 1 }
|
|
52
|
+
|
|
53
|
+
// Dry-run validation + resolved plan (no spawn)
|
|
54
|
+
// plan is a dry-run, but every task still needs the policy-routed model.
|
|
55
|
+
{ action: "plan", tasks: [{ task: "…", model: routeModel, isolation: "worktree" }] }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Profiles
|
|
59
|
+
|
|
60
|
+
| Profile | Tools | Writes |
|
|
61
|
+
| --------- | --------------------------------------------------------- | ------------------------------------------- |
|
|
62
|
+
| `explore` | read/search/ls (+safe) + Pi context tools | no project-file writes |
|
|
63
|
+
| `review` | same as explore | no project-file writes |
|
|
64
|
+
| `general` | inherited active tools + Pi context tools | yes if tools include bash/edit/write |
|
|
65
|
+
|
|
66
|
+
For Pi children, `new_context`, `get_context_remaining`, `history`, and
|
|
67
|
+
`notes` are control-plane tools. When available in the parent they remain in
|
|
68
|
+
the child allowlist—even if a narrower tool list was requested—so Pi's remote
|
|
69
|
+
`contextManagement` can stay active. They may update context notes/window
|
|
70
|
+
state, but never grant `bash`, `edit`, or `write` access.
|
|
71
|
+
|
|
72
|
+
Parallel write-capable tasks sharing one checkout are rejected unless each uses
|
|
73
|
+
`isolation: "worktree"`, a distinct `cwd`, or `allow_shared_writes: true`.
|
|
74
|
+
|
|
75
|
+
## Backends
|
|
76
|
+
|
|
77
|
+
`backend: "pi" | "codex" | "claude"` (default `pi`). Unsupported combinations are
|
|
78
|
+
**refused**, not silently degraded:
|
|
79
|
+
|
|
80
|
+
| | pi | codex | claude |
|
|
81
|
+
| ------------------------ | -------------- | ---------------------- | -------------- |
|
|
82
|
+
| `max_cost` | yes | refused (tokens only) | yes |
|
|
83
|
+
| read-only profile | tool allowlist | OS sandbox | tool allowlist |
|
|
84
|
+
| steering / grace wrap-up | yes | no | no |
|
|
85
|
+
| `context: "fork"` | yes | refused | yes |
|
|
86
|
+
| `thinking` | yes | no | no |
|
|
87
|
+
| `output_schema` | yes | yes | yes |
|
|
88
|
+
|
|
89
|
+
## Budgets and safety
|
|
90
|
+
|
|
91
|
+
- Prefer `max_turns`, `max_cost`, and/or `timeout_ms` on long or write-capable runs.
|
|
92
|
+
- `output_schema` asks the child for a fenced `json:result` block (one repair round).
|
|
93
|
+
- `context: "fork"` continues from a fork of the parent session (pi/claude).
|
|
94
|
+
- Do not poll `status` in a tight loop — use `wait` / `subagent_wait`, or let the
|
|
95
|
+
completion notification arrive for `async: true` runs.
|
|
96
|
+
- Point the user at `/subagents` for the live inspector and `/subagent-cost` for
|
|
97
|
+
the root / subagent / combined ledger.
|
|
98
|
+
|
|
99
|
+
## Model policy
|
|
100
|
+
|
|
101
|
+
Every new task must pass a `model` that exactly matches the current
|
|
102
|
+
`modelPolicy` mapping in `~/.pi/subagent.json`; agent frontmatter,
|
|
103
|
+
`taskDefaults.model`, and parent-session model inheritance are ignored. An
|
|
104
|
+
agent route replaces the default route, and configured fallback order is
|
|
105
|
+
immutable. Omit `fallback_models` to use the route; if supplied, it must match
|
|
106
|
+
exactly. An optional route `thinking` value is an opaque Pi thinking-level
|
|
107
|
+
string; common values include `off`, `minimal`, `low`, `medium`, `high`, `xhigh`,
|
|
108
|
+
and `max`, but model-specific values are passed through unchanged. It is a
|
|
109
|
+
default; explicit task, agent, and profile `taskDefaults.thinking` values
|
|
110
|
+
override it. Management actions do not require model. The extension re-reads
|
|
111
|
+
this policy on each dispatch and injects it into
|
|
112
|
+
the parent prompt. If the policy is missing or invalid, management remains
|
|
113
|
+
available but new spawns and synthesis are rejected.
|