@dreki-gg/pi-subagent 0.7.0 → 0.8.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/.fallowrc.json +6 -0
- package/CHANGELOG.md +16 -0
- package/README.md +4 -13
- package/docs/plans/01_structured-handoffs-and-synthesis.plan.md +14 -14
- package/docs/plans/02_clean-context-review-loop.plan.md +12 -12
- package/docs/plans/03_parallel-recon-single-writer-docs.plan.md +4 -4
- package/docs/plans/04_manager-workflow.plan.md +10 -10
- package/docs/plans/05_advisor-routing.plan.md +22 -22
- package/extensions/subagent/agent-runner-types.ts +1 -1
- package/extensions/subagent/agent-runner.ts +40 -152
- package/extensions/subagent/agents.ts +31 -77
- package/extensions/subagent/index.ts +83 -354
- package/extensions/subagent/spawn-utils.ts +198 -0
- package/extensions/subagent/synthesis.ts +1 -51
- package/package.json +8 -8
- package/skills/write-an-agent/SKILL.md +5 -5
- /package/{agents → prompts}/advisor.md +0 -0
- /package/{agents → prompts}/bug-prover.md +0 -0
- /package/{agents → prompts}/docs-scout.md +0 -0
- /package/{agents → prompts}/manager.md +0 -0
- /package/{agents → prompts}/planner.md +0 -0
- /package/{agents → prompts}/reviewer.md +0 -0
- /package/{agents → prompts}/scout.md +0 -0
- /package/{agents → prompts}/ux-designer.md +0 -0
- /package/{agents → prompts}/validator.md +0 -0
- /package/{agents → prompts}/worker.md +0 -0
package/.fallowrc.json
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @dreki-gg/pi-subagent
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`3a246f3`](https://github.com/dreki-gg/pi-extensions/commit/3a246f3fd55b900ebfcfbea2eff2a7ab9f9f94cf) Thanks [@jalbarrang](https://github.com/jalbarrang)! - Refactor agent distribution from custom `pi.agents` to standard `pi.prompts`
|
|
8
|
+
|
|
9
|
+
- Rename `agents/` directory to `prompts/` to follow pi's standard resource type
|
|
10
|
+
- Use `pi.prompts` in package.json instead of non-standard `pi.agents`
|
|
11
|
+
- Remove legacy bundled-directory fallback — agent prompts are now resolved via pi's package manager
|
|
12
|
+
- Remove `/delegate-agents` command (unused; `/run-agent` and `subagent` tool cover all usage)
|
|
13
|
+
- Extract shared spawn logic into `spawn-utils.ts`, eliminating cross-file duplication between `agent-runner.ts` and `index.ts`
|
|
14
|
+
- Remove dead exports (`formatAgentList`, `buildSynthesisPrompt`, `SYNTHESIS_INSTRUCTION`)
|
|
15
|
+
- Clean up unused imports
|
|
16
|
+
- Maintainability score improved from 70.7 (moderate) to 90.6 (good)
|
|
17
|
+
- Model configuration (`model`, `thinking`, `tools` frontmatter) is unchanged
|
|
18
|
+
|
|
3
19
|
## 0.7.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @dreki-gg/pi-subagent
|
|
2
2
|
|
|
3
|
-
Subagent tool and direct agent runs for pi — isolated agents, parallel scouts, manager workflows, and bundled
|
|
3
|
+
Subagent tool and direct agent runs for pi — isolated agents, parallel scouts, manager workflows, and bundled prompts.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -118,7 +118,7 @@ If the chosen agent frontmatter sets `sessionStrategy: fork-at`, the command clo
|
|
|
118
118
|
|
|
119
119
|
## Agent Definitions
|
|
120
120
|
|
|
121
|
-
Create agent files in `~/.pi/agent/
|
|
121
|
+
Create agent prompt files in `~/.pi/agent/prompts/` or `.pi/prompts/` as markdown with YAML frontmatter:
|
|
122
122
|
|
|
123
123
|
```markdown
|
|
124
124
|
---
|
|
@@ -153,22 +153,13 @@ Notes:
|
|
|
153
153
|
- `worker`, `reviewer`, `bug-prover`, and `manager` default to `sessionStrategy: fork-at`.
|
|
154
154
|
- "Default reasoning level" maps to the frontmatter field `thinking` and can be overridden per run.
|
|
155
155
|
|
|
156
|
-
Resolution order is: bundled → user (`~/.pi/agent/
|
|
156
|
+
Resolution order is: bundled → user (`~/.pi/agent/prompts/`) → project (`.pi/prompts/`). Project agents override user and bundled agents by name.
|
|
157
157
|
|
|
158
158
|
Optional frontmatter:
|
|
159
159
|
- `thinking` — default reasoning effort for the spawned pi process
|
|
160
160
|
- `sessionStrategy: fork-at` — when used with `/run-agent`, clone the current active branch into a new session before running
|
|
161
161
|
|
|
162
|
-
> Note: pi
|
|
163
|
-
|
|
164
|
-
### Managing Agents
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
/delegate-agents # list all agents with source
|
|
168
|
-
/delegate-agents reset scout # restore bundled version
|
|
169
|
-
/delegate-agents reset --all # restore all bundled versions
|
|
170
|
-
/delegate-agents edit scout # copy bundled to user dir for customization
|
|
171
|
-
```
|
|
162
|
+
> Note: pi supports package-shipped prompts via `pi.prompts` (or conventional `prompts/` directories). This package publishes its bundled agent prompts that way, while user prompts in `~/.pi/agent/prompts/` and project prompts in `.pi/prompts/` still override them by name.
|
|
172
163
|
|
|
173
164
|
## Bundled Resources
|
|
174
165
|
|
|
@@ -39,12 +39,12 @@ Current relevant file tree on disk:
|
|
|
39
39
|
- `packages/subagent/extensions/subagent/agent-result-utils.ts`
|
|
40
40
|
- `packages/subagent/extensions/subagent/run-agent-args.ts`
|
|
41
41
|
- `packages/subagent/extensions/subagent/synthesis.ts`
|
|
42
|
-
- `packages/subagent/
|
|
43
|
-
- `packages/subagent/
|
|
44
|
-
- `packages/subagent/
|
|
45
|
-
- `packages/subagent/
|
|
46
|
-
- `packages/subagent/
|
|
47
|
-
- `packages/subagent/
|
|
42
|
+
- `packages/subagent/prompts/docs-scout.md`
|
|
43
|
+
- `packages/subagent/prompts/planner.md`
|
|
44
|
+
- `packages/subagent/prompts/reviewer.md`
|
|
45
|
+
- `packages/subagent/prompts/scout.md`
|
|
46
|
+
- `packages/subagent/prompts/ux-designer.md`
|
|
47
|
+
- `packages/subagent/prompts/worker.md`
|
|
48
48
|
- `packages/subagent/prompts/implement.md`
|
|
49
49
|
- `packages/subagent/prompts/implement-and-review.md`
|
|
50
50
|
- `packages/subagent/prompts/scout-and-plan.md`
|
|
@@ -326,10 +326,10 @@ export function buildHandoffFromResult(input: {
|
|
|
326
326
|
## 3. Tighten bundled prompts so handoffs have stable sections to summarize
|
|
327
327
|
|
|
328
328
|
### Files
|
|
329
|
-
- Modify `packages/subagent/
|
|
330
|
-
- Modify `packages/subagent/
|
|
331
|
-
- Modify `packages/subagent/
|
|
332
|
-
- Modify `packages/subagent/
|
|
329
|
+
- Modify `packages/subagent/prompts/scout.md`
|
|
330
|
+
- Modify `packages/subagent/prompts/docs-scout.md`
|
|
331
|
+
- Modify `packages/subagent/prompts/planner.md`
|
|
332
|
+
- Modify `packages/subagent/prompts/worker.md`
|
|
333
333
|
- Modify `packages/subagent/prompts/implement.md`
|
|
334
334
|
- Modify `packages/subagent/prompts/scout-and-plan.md`
|
|
335
335
|
|
|
@@ -352,10 +352,10 @@ export function buildHandoffFromResult(input: {
|
|
|
352
352
|
# Files to modify
|
|
353
353
|
|
|
354
354
|
- `packages/subagent/extensions/subagent/index.ts` — switch chain substitution from raw final text to rendered structured handoff
|
|
355
|
-
- `packages/subagent/
|
|
356
|
-
- `packages/subagent/
|
|
357
|
-
- `packages/subagent/
|
|
358
|
-
- `packages/subagent/
|
|
355
|
+
- `packages/subagent/prompts/scout.md` — make scout output easier to summarize deterministically
|
|
356
|
+
- `packages/subagent/prompts/docs-scout.md` — make docs handoff more consistent
|
|
357
|
+
- `packages/subagent/prompts/planner.md` — preserve plan structure but expose constraints explicitly
|
|
358
|
+
- `packages/subagent/prompts/worker.md` — add explicit decision / unresolved sections for downstream agents
|
|
359
359
|
- `packages/subagent/prompts/implement.md` — document structured `{previous}` expectations
|
|
360
360
|
- `packages/subagent/prompts/scout-and-plan.md` — document structured `{previous}` expectations
|
|
361
361
|
|
|
@@ -28,8 +28,8 @@ Improve the bundled review loop so the reviewer reasons from a fresh, diff-first
|
|
|
28
28
|
|
|
29
29
|
Current relevant file tree on disk:
|
|
30
30
|
|
|
31
|
-
- `packages/subagent/
|
|
32
|
-
- `packages/subagent/
|
|
31
|
+
- `packages/subagent/prompts/reviewer.md`
|
|
32
|
+
- `packages/subagent/prompts/worker.md`
|
|
33
33
|
- `packages/subagent/prompts/implement-and-review.md`
|
|
34
34
|
- `packages/subagent/skills/spawn-subagents/SKILL.md`
|
|
35
35
|
- `packages/subagent/extensions/subagent/index.ts`
|
|
@@ -43,10 +43,10 @@ Actual current behavior on disk:
|
|
|
43
43
|
3. run `worker` again to apply review feedback from `{previous}`
|
|
44
44
|
- Chain execution in `packages/subagent/extensions/subagent/index.ts:658-716` performs raw `{previous}` replacement with the previous step’s final assistant text. There is no review-specific minimization layer in code today.
|
|
45
45
|
- The current reviewer prompt already points in the right direction:
|
|
46
|
-
- `packages/subagent/
|
|
46
|
+
- `packages/subagent/prompts/reviewer.md:12-18` restricts bash to read-only commands and tells the agent to start with `git diff`, then read modified files.
|
|
47
47
|
- But the prompt does **not** explicitly tell the reviewer to distrust or deprioritize the worker’s implementation narrative when that narrative is also passed through `{previous}`.
|
|
48
48
|
- The current worker prompt includes a helpful but minimal handoff hint:
|
|
49
|
-
- `packages/subagent/
|
|
49
|
+
- `packages/subagent/prompts/worker.md:13-26` asks for `Completed`, `Files Changed`, and `Notes`, and says that if handing off to another agent it should include exact file paths changed and key functions/types touched.
|
|
50
50
|
- There is no required section for validation run, constraints, or unresolved risk, so the review handoff is underspecified.
|
|
51
51
|
- The `spawn-subagents` skill currently recommends a `reviewer` loop after implementation and says the main agent may apply fixes directly or send a focused follow-up to `worker` (`packages/subagent/skills/spawn-subagents/SKILL.md:44-58`). It does not yet describe “clean context” review explicitly.
|
|
52
52
|
- There is no additional workflow prompt for “clean review”; the current `/implement-and-review` prompt is the only bundled implementation review loop.
|
|
@@ -55,7 +55,7 @@ Actual current behavior on disk:
|
|
|
55
55
|
|
|
56
56
|
## Existing reviewer and worker contracts
|
|
57
57
|
|
|
58
|
-
From `packages/subagent/
|
|
58
|
+
From `packages/subagent/prompts/reviewer.md`:
|
|
59
59
|
|
|
60
60
|
```md
|
|
61
61
|
Strategy:
|
|
@@ -80,7 +80,7 @@ Output format:
|
|
|
80
80
|
Overall assessment in 2-3 sentences.
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
From `packages/subagent/
|
|
83
|
+
From `packages/subagent/prompts/worker.md`:
|
|
84
84
|
|
|
85
85
|
```md
|
|
86
86
|
Output format when finished:
|
|
@@ -126,7 +126,7 @@ This means the review workflow can be improved significantly even with prompt-on
|
|
|
126
126
|
## 1. Tighten the reviewer prompt so review starts from `git diff` and re-discovered code context
|
|
127
127
|
|
|
128
128
|
### Files
|
|
129
|
-
- Modify `packages/subagent/
|
|
129
|
+
- Modify `packages/subagent/prompts/reviewer.md`
|
|
130
130
|
|
|
131
131
|
### What to change
|
|
132
132
|
- Keep the reviewer read-only.
|
|
@@ -149,7 +149,7 @@ This means the review workflow can be improved significantly even with prompt-on
|
|
|
149
149
|
## 2. Change the worker output contract so implementation handoff becomes a compact review packet
|
|
150
150
|
|
|
151
151
|
### Files
|
|
152
|
-
- Modify `packages/subagent/
|
|
152
|
+
- Modify `packages/subagent/prompts/worker.md`
|
|
153
153
|
|
|
154
154
|
### What to change
|
|
155
155
|
- Keep the worker autonomous and implementation-focused.
|
|
@@ -217,8 +217,8 @@ This means the review workflow can be improved significantly even with prompt-on
|
|
|
217
217
|
|
|
218
218
|
# Files to modify
|
|
219
219
|
|
|
220
|
-
- `packages/subagent/
|
|
221
|
-
- `packages/subagent/
|
|
220
|
+
- `packages/subagent/prompts/reviewer.md` — make clean-context review an explicit prompt rule
|
|
221
|
+
- `packages/subagent/prompts/worker.md` — emit a compact review packet instead of only freeform notes
|
|
222
222
|
- `packages/subagent/prompts/implement-and-review.md` — encode diff-first review semantics in the bundled workflow
|
|
223
223
|
|
|
224
224
|
# Testing notes
|
|
@@ -233,8 +233,8 @@ This means the review workflow can be improved significantly even with prompt-on
|
|
|
233
233
|
|
|
234
234
|
# Patterns to follow
|
|
235
235
|
|
|
236
|
-
- `packages/subagent/
|
|
237
|
-
- `packages/subagent/
|
|
236
|
+
- `packages/subagent/prompts/reviewer.md:12-18` — existing diff-first reviewer stance to strengthen, not replace
|
|
237
|
+
- `packages/subagent/prompts/worker.md:24-26` — current handoff hints to make mandatory and more compact
|
|
238
238
|
- `packages/subagent/prompts/implement-and-review.md:4-10` — current workflow entry point to refine
|
|
239
239
|
- `packages/subagent/skills/spawn-subagents/SKILL.md:44-58` — current review-loop guidance
|
|
240
240
|
- `packages/subagent/skills/write-an-agent/SKILL.md:15-20` and `:62-67` — keep prompt files sharp, minimal, and output-contract-driven
|
|
@@ -33,10 +33,10 @@ Current relevant file tree on disk:
|
|
|
33
33
|
- `packages/subagent/prompts/implement.md`
|
|
34
34
|
- `packages/subagent/prompts/scout-and-plan.md`
|
|
35
35
|
- `packages/subagent/prompts/implement-and-review.md`
|
|
36
|
-
- `packages/subagent/
|
|
37
|
-
- `packages/subagent/
|
|
38
|
-
- `packages/subagent/
|
|
39
|
-
- `packages/subagent/
|
|
36
|
+
- `packages/subagent/prompts/scout.md`
|
|
37
|
+
- `packages/subagent/prompts/planner.md`
|
|
38
|
+
- `packages/subagent/prompts/reviewer.md`
|
|
39
|
+
- `packages/subagent/prompts/worker.md`
|
|
40
40
|
- `packages/subagent/package.json`
|
|
41
41
|
- `packages/subagent/CHANGELOG.md`
|
|
42
42
|
|
|
@@ -28,11 +28,11 @@ Introduce a first-class manager workflow that can decompose larger tasks into bo
|
|
|
28
28
|
|
|
29
29
|
Current relevant file tree on disk:
|
|
30
30
|
|
|
31
|
-
- `packages/subagent/
|
|
32
|
-
- `packages/subagent/
|
|
33
|
-
- `packages/subagent/
|
|
34
|
-
- `packages/subagent/
|
|
35
|
-
- `packages/subagent/
|
|
31
|
+
- `packages/subagent/prompts/scout.md`
|
|
32
|
+
- `packages/subagent/prompts/docs-scout.md`
|
|
33
|
+
- `packages/subagent/prompts/planner.md`
|
|
34
|
+
- `packages/subagent/prompts/worker.md`
|
|
35
|
+
- `packages/subagent/prompts/reviewer.md`
|
|
36
36
|
- `packages/subagent/prompts/implement.md`
|
|
37
37
|
- `packages/subagent/prompts/scout-and-plan.md`
|
|
38
38
|
- `packages/subagent/prompts/implement-and-review.md`
|
|
@@ -65,7 +65,7 @@ Actual current state on disk:
|
|
|
65
65
|
- `runSingleAgent()` in `index.ts:325-328` only passes `--tools` when the agent frontmatter declares a tool list.
|
|
66
66
|
- `runAgent()` in `agent-runner.ts:73-76` behaves the same way.
|
|
67
67
|
- This means a new `manager` agent can omit `tools:` in frontmatter if it needs access to the full tool set, including the `subagent` tool itself.
|
|
68
|
-
- There is no project-local `.pi/
|
|
68
|
+
- There is no project-local `.pi/prompts/*.md` manager override in this repo right now; `.pi/prompts/` exists but is empty.
|
|
69
69
|
|
|
70
70
|
# API inventory
|
|
71
71
|
|
|
@@ -154,7 +154,7 @@ Create a prompt contract that is directly usable by the main agent or a human:
|
|
|
154
154
|
## 1. Add a bundled `manager` agent with a narrow orchestration role
|
|
155
155
|
|
|
156
156
|
### Files
|
|
157
|
-
- Create `packages/subagent/
|
|
157
|
+
- Create `packages/subagent/prompts/manager.md`
|
|
158
158
|
|
|
159
159
|
### What to add
|
|
160
160
|
Author a concise bundled agent prompt that:
|
|
@@ -221,7 +221,7 @@ The manager should:
|
|
|
221
221
|
|
|
222
222
|
# Files to create
|
|
223
223
|
|
|
224
|
-
- `packages/subagent/
|
|
224
|
+
- `packages/subagent/prompts/manager.md`
|
|
225
225
|
- `packages/subagent/prompts/manage.md`
|
|
226
226
|
|
|
227
227
|
# Files to modify
|
|
@@ -243,6 +243,6 @@ The manager should:
|
|
|
243
243
|
|
|
244
244
|
- `packages/subagent/skills/spawn-subagents/SKILL.md:31-58` — existing orchestration philosophy to extend upward
|
|
245
245
|
- `packages/subagent/skills/write-an-agent/SKILL.md:15-20` and `:46-67` — agent-authoring constraints for concise, high-signal prompts
|
|
246
|
-
- `packages/subagent/
|
|
247
|
-
- `packages/subagent/
|
|
246
|
+
- `packages/subagent/prompts/planner.md:9-38` — good example of a narrow role with a clear output contract
|
|
247
|
+
- `packages/subagent/prompts/worker.md:9-26` — example of a task-focused executor the manager should call, not replace
|
|
248
248
|
- `packages/subagent/README.md:88-124` — bundled-agent and bundled-prompt sections to update
|
|
@@ -28,10 +28,10 @@ Introduce a lightweight advisor pattern so primary agents can consult a strong s
|
|
|
28
28
|
|
|
29
29
|
Current relevant file tree on disk:
|
|
30
30
|
|
|
31
|
-
- `packages/subagent/
|
|
32
|
-
- `packages/subagent/
|
|
33
|
-
- `packages/subagent/
|
|
34
|
-
- `packages/subagent/
|
|
31
|
+
- `packages/subagent/prompts/planner.md`
|
|
32
|
+
- `packages/subagent/prompts/reviewer.md`
|
|
33
|
+
- `packages/subagent/prompts/worker.md`
|
|
34
|
+
- `packages/subagent/prompts/docs-scout.md`
|
|
35
35
|
- `packages/subagent/prompts/implement.md`
|
|
36
36
|
- `packages/subagent/prompts/implement-and-review.md`
|
|
37
37
|
- `packages/subagent/README.md`
|
|
@@ -42,12 +42,12 @@ Current relevant file tree on disk:
|
|
|
42
42
|
|
|
43
43
|
Actual current state on disk:
|
|
44
44
|
|
|
45
|
-
- There is no bundled `advisor` agent in `packages/subagent/
|
|
45
|
+
- There is no bundled `advisor` agent in `packages/subagent/prompts/`.
|
|
46
46
|
- There is no advisor-oriented prompt template in `packages/subagent/prompts/`.
|
|
47
47
|
- The current bundled roles are:
|
|
48
|
-
- `planner` for planning (`packages/subagent/
|
|
49
|
-
- `worker` for implementation (`packages/subagent/
|
|
50
|
-
- `reviewer` for verification (`packages/subagent/
|
|
48
|
+
- `planner` for planning (`packages/subagent/prompts/planner.md`)
|
|
49
|
+
- `worker` for implementation (`packages/subagent/prompts/worker.md`)
|
|
50
|
+
- `reviewer` for verification (`packages/subagent/prompts/reviewer.md`)
|
|
51
51
|
- plus `scout`, `docs-scout`, and `ux-designer`
|
|
52
52
|
- The package runner already supports spawned agents consulting tools as needed:
|
|
53
53
|
- in `packages/subagent/extensions/subagent/index.ts:325-328`, `runSingleAgent()` passes `--tools` only when frontmatter declares them
|
|
@@ -63,21 +63,21 @@ Actual current state on disk:
|
|
|
63
63
|
|
|
64
64
|
## Existing agent prompt contracts that may invoke advisor
|
|
65
65
|
|
|
66
|
-
From `packages/subagent/
|
|
66
|
+
From `packages/subagent/prompts/planner.md`:
|
|
67
67
|
|
|
68
68
|
```md
|
|
69
69
|
You are a planning specialist.
|
|
70
70
|
You must NOT make any changes. Only read, analyze, and plan.
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
From `packages/subagent/
|
|
73
|
+
From `packages/subagent/prompts/worker.md`:
|
|
74
74
|
|
|
75
75
|
```md
|
|
76
76
|
You are a worker agent with full capabilities.
|
|
77
77
|
Work autonomously to complete the assigned task. Use all available tools as needed.
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
From `packages/subagent/
|
|
80
|
+
From `packages/subagent/prompts/reviewer.md`:
|
|
81
81
|
|
|
82
82
|
```md
|
|
83
83
|
You are a senior code reviewer.
|
|
@@ -124,7 +124,7 @@ The advisor should not claim to have implemented or verified anything it did not
|
|
|
124
124
|
## 1. Add a bundled `advisor` agent with a focused consultative contract
|
|
125
125
|
|
|
126
126
|
### Files
|
|
127
|
-
- Create `packages/subagent/
|
|
127
|
+
- Create `packages/subagent/prompts/advisor.md`
|
|
128
128
|
|
|
129
129
|
### What to add
|
|
130
130
|
Create a concise bundled agent whose sole job is to provide focused second-opinion guidance.
|
|
@@ -150,9 +150,9 @@ Create a concise bundled agent whose sole job is to provide focused second-opini
|
|
|
150
150
|
## 2. Teach bundled prompts when to call the advisor and what context to send
|
|
151
151
|
|
|
152
152
|
### Files
|
|
153
|
-
- Modify `packages/subagent/
|
|
154
|
-
- Modify `packages/subagent/
|
|
155
|
-
- Modify `packages/subagent/
|
|
153
|
+
- Modify `packages/subagent/prompts/worker.md`
|
|
154
|
+
- Modify `packages/subagent/prompts/planner.md`
|
|
155
|
+
- Modify `packages/subagent/prompts/reviewer.md`
|
|
156
156
|
|
|
157
157
|
### What to change
|
|
158
158
|
Add small, explicit escalation rules to the existing bundled roles.
|
|
@@ -215,14 +215,14 @@ The advisor should:
|
|
|
215
215
|
|
|
216
216
|
# Files to create
|
|
217
217
|
|
|
218
|
-
- `packages/subagent/
|
|
218
|
+
- `packages/subagent/prompts/advisor.md`
|
|
219
219
|
- `packages/subagent/prompts/consult-advisor.md`
|
|
220
220
|
|
|
221
221
|
# Files to modify
|
|
222
222
|
|
|
223
|
-
- `packages/subagent/
|
|
224
|
-
- `packages/subagent/
|
|
225
|
-
- `packages/subagent/
|
|
223
|
+
- `packages/subagent/prompts/worker.md` — add narrow escalation guidance
|
|
224
|
+
- `packages/subagent/prompts/planner.md` — add narrow escalation guidance
|
|
225
|
+
- `packages/subagent/prompts/reviewer.md` — add narrow escalation guidance
|
|
226
226
|
- `packages/subagent/README.md` — document the new advisor role and one or two examples
|
|
227
227
|
- `packages/subagent/skills/spawn-subagents/SKILL.md` — explain when to use advisor vs. planner/reviewer
|
|
228
228
|
|
|
@@ -238,7 +238,7 @@ The advisor should:
|
|
|
238
238
|
# Patterns to follow
|
|
239
239
|
|
|
240
240
|
- `packages/subagent/skills/write-an-agent/SKILL.md:15-20` and `:46-67` — keep the new agent narrow, concise, and output-contract-driven
|
|
241
|
-
- `packages/subagent/
|
|
242
|
-
- `packages/subagent/
|
|
243
|
-
- `packages/subagent/
|
|
241
|
+
- `packages/subagent/prompts/planner.md:9-38` — example of a specialist planner role that the advisor should complement, not replace
|
|
242
|
+
- `packages/subagent/prompts/reviewer.md:10-37` — example of a verifier role that may occasionally need escalation
|
|
243
|
+
- `packages/subagent/prompts/worker.md:9-26` — example of a primary owner role that should remain in charge after consulting advisor
|
|
244
244
|
- `packages/subagent/skills/spawn-subagents/SKILL.md:23-58` — existing specialist-selection guidance to extend with optional escalation
|
|
@@ -1,42 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { withFileMutationQueue } from '@mariozechner/pi-coding-agent';
|
|
6
|
-
import type { ResolvedPaths } from '@mariozechner/pi-coding-agent';
|
|
7
|
-
import type { Message } from '@mariozechner/pi-ai';
|
|
8
|
-
import { discoverAgentsWithPackages, type AgentScope } from './agents.js';
|
|
9
|
-
import type { AgentResult, UsageStats } from './agent-runner-types.js';
|
|
10
|
-
|
|
11
|
-
function emptyUsage(): UsageStats {
|
|
12
|
-
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function getPiInvocation(args: string[]): { command: string; args: string[] } {
|
|
16
|
-
const currentScript = process.argv[1];
|
|
17
|
-
if (currentScript && fs.existsSync(currentScript)) {
|
|
18
|
-
return { command: process.execPath, args: [currentScript, ...args] };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const execName = path.basename(process.execPath).toLowerCase();
|
|
22
|
-
const isGenericRuntime = /^(node|bun)(\.exe)?$/.test(execName);
|
|
23
|
-
if (!isGenericRuntime) return { command: process.execPath, args };
|
|
24
|
-
|
|
25
|
-
return { command: 'pi', args };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function writePromptToTempFile(
|
|
29
|
-
agentName: string,
|
|
30
|
-
prompt: string,
|
|
31
|
-
): Promise<{ dir: string; filePath: string }> {
|
|
32
|
-
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'pi-subagent-'));
|
|
33
|
-
const safeName = agentName.replace(/[^\w.-]+/g, '_');
|
|
34
|
-
const filePath = path.join(tmpDir, `prompt-${safeName}.md`);
|
|
35
|
-
await withFileMutationQueue(filePath, async () => {
|
|
36
|
-
await fs.promises.writeFile(filePath, prompt, { encoding: 'utf-8', mode: 0o600 });
|
|
37
|
-
});
|
|
38
|
-
return { dir: tmpDir, filePath };
|
|
39
|
-
}
|
|
1
|
+
import type { ResolvedPaths } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { discoverAgents, type AgentScope } from './agents.js';
|
|
3
|
+
import type { AgentResult } from './agent-runner-types.js';
|
|
4
|
+
import { emptyUsage, spawnPiAgent } from './spawn-utils.js';
|
|
40
5
|
|
|
41
6
|
export type OnPhaseUpdate = (phaseName: string, agentName: string, result: AgentResult) => void;
|
|
42
7
|
|
|
@@ -57,7 +22,7 @@ export async function runAgent(
|
|
|
57
22
|
task: string,
|
|
58
23
|
options: RunAgentOptions = {},
|
|
59
24
|
): Promise<AgentResult> {
|
|
60
|
-
const { agents } =
|
|
25
|
+
const { agents } = discoverAgents(cwd, options.agentScope ?? 'user', options.resolvedPaths);
|
|
61
26
|
const agent = agents.find((a) => a.name === agentName);
|
|
62
27
|
|
|
63
28
|
if (!agent) {
|
|
@@ -75,14 +40,6 @@ export async function runAgent(
|
|
|
75
40
|
const selectedModel = options.model ?? agent.model;
|
|
76
41
|
const selectedThinking = options.thinking ?? agent.thinking;
|
|
77
42
|
|
|
78
|
-
const args: string[] = ['--mode', 'json', '-p', '--no-session'];
|
|
79
|
-
if (selectedModel) args.push('--model', selectedModel);
|
|
80
|
-
if (selectedThinking) args.push('--thinking', selectedThinking);
|
|
81
|
-
if (agent.tools && agent.tools.length > 0) args.push('--tools', agent.tools.join(','));
|
|
82
|
-
|
|
83
|
-
let tmpPromptDir: string | null = null;
|
|
84
|
-
let tmpPromptPath: string | null = null;
|
|
85
|
-
|
|
86
43
|
const result: AgentResult = {
|
|
87
44
|
agent: agentName,
|
|
88
45
|
task,
|
|
@@ -93,110 +50,41 @@ export async function runAgent(
|
|
|
93
50
|
model: selectedModel,
|
|
94
51
|
};
|
|
95
52
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let buffer = '';
|
|
115
|
-
|
|
116
|
-
const processLine = (line: string) => {
|
|
117
|
-
if (!line.trim()) return;
|
|
118
|
-
let event: any;
|
|
119
|
-
try {
|
|
120
|
-
event = JSON.parse(line);
|
|
121
|
-
} catch {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (event.type === 'message_end' && event.message) {
|
|
126
|
-
const msg = event.message as Message;
|
|
127
|
-
result.messages.push(msg);
|
|
128
|
-
|
|
129
|
-
if (msg.role === 'assistant') {
|
|
130
|
-
result.usage.turns++;
|
|
131
|
-
const usage = msg.usage;
|
|
132
|
-
if (usage) {
|
|
133
|
-
result.usage.input += usage.input || 0;
|
|
134
|
-
result.usage.output += usage.output || 0;
|
|
135
|
-
result.usage.cacheRead += usage.cacheRead || 0;
|
|
136
|
-
result.usage.cacheWrite += usage.cacheWrite || 0;
|
|
137
|
-
result.usage.cost += usage.cost?.total || 0;
|
|
138
|
-
result.usage.contextTokens = usage.totalTokens || 0;
|
|
139
|
-
}
|
|
140
|
-
if (!result.model && msg.model) result.model = msg.model;
|
|
141
|
-
if (msg.stopReason) result.stopReason = msg.stopReason;
|
|
142
|
-
if (msg.errorMessage) result.errorMessage = msg.errorMessage;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (options.onUpdate)
|
|
146
|
-
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (event.type === 'tool_result_end' && event.message) {
|
|
150
|
-
result.messages.push(event.message as Message);
|
|
151
|
-
if (options.onUpdate)
|
|
152
|
-
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
proc.stdout.on('data', (data: Buffer) => {
|
|
157
|
-
buffer += data.toString();
|
|
158
|
-
const lines = buffer.split('\n');
|
|
159
|
-
buffer = lines.pop() || '';
|
|
160
|
-
for (const line of lines) processLine(line);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
proc.stderr.on('data', (data: Buffer) => {
|
|
164
|
-
result.stderr += data.toString();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
proc.on('close', (code: number | null) => {
|
|
168
|
-
if (buffer.trim()) processLine(buffer);
|
|
169
|
-
resolve(code ?? 0);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
proc.on('error', () => resolve(1));
|
|
173
|
-
|
|
174
|
-
if (options.signal) {
|
|
175
|
-
const killProc = () => {
|
|
176
|
-
proc.kill('SIGTERM');
|
|
177
|
-
setTimeout(() => {
|
|
178
|
-
if (!proc.killed) proc.kill('SIGKILL');
|
|
179
|
-
}, 5000);
|
|
180
|
-
};
|
|
181
|
-
if (options.signal.aborted) killProc();
|
|
182
|
-
else options.signal.addEventListener('abort', killProc, { once: true });
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
result.exitCode = exitCode;
|
|
187
|
-
return result;
|
|
188
|
-
} finally {
|
|
189
|
-
if (tmpPromptPath)
|
|
190
|
-
try {
|
|
191
|
-
fs.unlinkSync(tmpPromptPath);
|
|
192
|
-
} catch {
|
|
193
|
-
/* ignore */
|
|
53
|
+
const spawnResult = await spawnPiAgent({
|
|
54
|
+
cwd: options.cwd ?? cwd,
|
|
55
|
+
agentName: agent.name,
|
|
56
|
+
task,
|
|
57
|
+
systemPrompt: agent.systemPrompt,
|
|
58
|
+
model: selectedModel,
|
|
59
|
+
thinking: selectedThinking,
|
|
60
|
+
tools: agent.tools,
|
|
61
|
+
signal: options.signal,
|
|
62
|
+
onMessage: () => {
|
|
63
|
+
// Copy accumulated state for the phase update callback
|
|
64
|
+
if (options.onUpdate) {
|
|
65
|
+
result.messages = spawnResult.messages;
|
|
66
|
+
result.usage = spawnResult.usage;
|
|
67
|
+
result.model = spawnResult.model ?? result.model;
|
|
68
|
+
result.stopReason = spawnResult.stopReason;
|
|
69
|
+
result.errorMessage = spawnResult.errorMessage;
|
|
70
|
+
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
194
71
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
72
|
+
},
|
|
73
|
+
onToolResult: () => {
|
|
74
|
+
if (options.onUpdate) {
|
|
75
|
+
result.messages = spawnResult.messages;
|
|
76
|
+
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
200
77
|
}
|
|
201
|
-
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
result.exitCode = spawnResult.exitCode;
|
|
82
|
+
result.messages = spawnResult.messages;
|
|
83
|
+
result.stderr = spawnResult.stderr;
|
|
84
|
+
result.usage = spawnResult.usage;
|
|
85
|
+
result.model = spawnResult.model ?? result.model;
|
|
86
|
+
result.stopReason = spawnResult.stopReason;
|
|
87
|
+
result.errorMessage = spawnResult.errorMessage;
|
|
88
|
+
|
|
89
|
+
return result;
|
|
202
90
|
}
|