@dreki-gg/pi-subagent 0.6.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 +37 -0
- package/README.md +82 -70
- package/docs/orchestration-principles.md +132 -0
- package/docs/plans/01_structured-handoffs-and-synthesis.plan.md +376 -0
- package/docs/plans/02_clean-context-review-loop.plan.md +240 -0
- package/docs/plans/03_parallel-recon-single-writer-docs.plan.md +199 -0
- package/docs/plans/04_manager-workflow.plan.md +248 -0
- package/docs/plans/05_advisor-routing.plan.md +244 -0
- package/extensions/subagent/agent-result-utils.ts +12 -0
- package/extensions/subagent/agent-runner-types.ts +23 -0
- package/extensions/subagent/agent-runner.ts +90 -0
- package/extensions/subagent/agents.ts +31 -77
- package/extensions/subagent/handoffs.ts +273 -0
- package/extensions/subagent/index.ts +359 -581
- package/extensions/subagent/run-agent-args.ts +90 -0
- package/extensions/subagent/{delegate-executor.ts → spawn-utils.ts} +64 -87
- package/extensions/subagent/synthesis.ts +1 -51
- package/package.json +7 -10
- package/prompts/advisor.md +37 -0
- package/prompts/bug-prover.md +42 -0
- package/{agents → prompts}/docs-scout.md +2 -2
- package/prompts/manager.md +52 -0
- package/{agents → prompts}/planner.md +16 -1
- package/prompts/reviewer.md +93 -0
- package/{agents → prompts}/scout.md +5 -1
- package/prompts/validator.md +42 -0
- package/prompts/worker.md +61 -0
- package/skills/spawn-subagents/SKILL.md +80 -8
- package/skills/write-an-agent/SKILL.md +5 -5
- package/agents/reviewer.md +0 -37
- package/agents/worker.md +0 -26
- package/extensions/subagent/delegate-args.ts +0 -145
- package/extensions/subagent/delegate-types.ts +0 -62
- package/extensions/subagent/delegate-ui.ts +0 -132
- package/extensions/subagent/workflows.ts +0 -150
- package/prompts/implement-and-review.md +0 -10
- package/prompts/implement.md +0 -10
- package/prompts/scout-and-plan.md +0 -9
- /package/{agents → prompts}/ux-designer.md +0 -0
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import type { ExtensionCommandContext } from '@mariozechner/pi-coding-agent';
|
|
2
|
-
import type {
|
|
3
|
-
AgentResult,
|
|
4
|
-
DelegateState,
|
|
5
|
-
PhaseResult,
|
|
6
|
-
UsageStats,
|
|
7
|
-
WorkflowDefinition,
|
|
8
|
-
} from './delegate-types';
|
|
9
|
-
import { WORKFLOWS, suggestWorkflow } from './workflows';
|
|
10
|
-
|
|
11
|
-
function formatTokens(count: number): string {
|
|
12
|
-
if (count < 1000) return count.toString();
|
|
13
|
-
if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
|
|
14
|
-
if (count < 1000000) return `${Math.round(count / 1000)}k`;
|
|
15
|
-
return `${(count / 1000000).toFixed(1)}M`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function formatUsage(usage: UsageStats): string {
|
|
19
|
-
const parts: string[] = [];
|
|
20
|
-
if (usage.turns) parts.push(`${usage.turns} turns`);
|
|
21
|
-
if (usage.input) parts.push(`↑${formatTokens(usage.input)}`);
|
|
22
|
-
if (usage.output) parts.push(`↓${formatTokens(usage.output)}`);
|
|
23
|
-
if (usage.cacheRead) parts.push(`R${formatTokens(usage.cacheRead)}`);
|
|
24
|
-
if (usage.cacheWrite) parts.push(`W${formatTokens(usage.cacheWrite)}`);
|
|
25
|
-
if (usage.cost) parts.push(`$${usage.cost.toFixed(4)}`);
|
|
26
|
-
return parts.join(' ');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function getFinalText(result: AgentResult): string {
|
|
30
|
-
for (let i = result.messages.length - 1; i >= 0; i--) {
|
|
31
|
-
const msg = result.messages[i];
|
|
32
|
-
if (msg.role === 'assistant') {
|
|
33
|
-
for (const part of msg.content) {
|
|
34
|
-
if (part.type === 'text') return part.text;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return '(no output)';
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function confirmSynthesis(
|
|
42
|
-
ctx: ExtensionCommandContext,
|
|
43
|
-
synthesis: string,
|
|
44
|
-
): Promise<boolean> {
|
|
45
|
-
return ctx.ui.confirm('Delegate — Task Synthesis', `${synthesis}\n\nProceed with this task?`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function pickWorkflow(
|
|
49
|
-
ctx: ExtensionCommandContext,
|
|
50
|
-
synthesis: string,
|
|
51
|
-
): Promise<WorkflowDefinition | null> {
|
|
52
|
-
const suggested = suggestWorkflow(synthesis);
|
|
53
|
-
const options = WORKFLOWS.map((wf) => {
|
|
54
|
-
const marker = wf.id === suggested ? ' ← suggested' : '';
|
|
55
|
-
return `${wf.label}${marker} — ${wf.description}`;
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const choice = await ctx.ui.select('Delegate — Choose Workflow', options);
|
|
59
|
-
if (choice === undefined || choice === null) return null;
|
|
60
|
-
|
|
61
|
-
const selectedIndex = options.indexOf(choice as string);
|
|
62
|
-
if (selectedIndex < 0) return null;
|
|
63
|
-
|
|
64
|
-
return WORKFLOWS[selectedIndex];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function confirmPlan(
|
|
68
|
-
ctx: ExtensionCommandContext,
|
|
69
|
-
planText: string,
|
|
70
|
-
): Promise<boolean> {
|
|
71
|
-
return ctx.ui.confirm('Delegate — Review Plan', `${planText}\n\nContinue with implementation?`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function formatPhaseHeader(
|
|
75
|
-
phaseName: string,
|
|
76
|
-
status: 'running' | 'done' | 'failed' | 'skipped',
|
|
77
|
-
): string {
|
|
78
|
-
const icons = { running: '⏳', done: '✓', failed: '✗', skipped: '⊘' };
|
|
79
|
-
return `${icons[status]} ${phaseName}`;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function formatAgentResult(result: AgentResult): string {
|
|
83
|
-
const icon = result.exitCode === 0 ? '✓' : '✗';
|
|
84
|
-
const output = getFinalText(result);
|
|
85
|
-
const preview = output.length > 200 ? `${output.slice(0, 200)}...` : output;
|
|
86
|
-
const usage = formatUsage(result.usage);
|
|
87
|
-
const model = result.model ? ` [${result.model}]` : '';
|
|
88
|
-
|
|
89
|
-
return `${icon} ${result.agent}${model}\n${preview}\n${usage}`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function formatPhaseSummary(phase: PhaseResult): string {
|
|
93
|
-
if (phase.skipped) return `⊘ ${phase.name} — skipped`;
|
|
94
|
-
|
|
95
|
-
const header = `── ${phase.name} (${phase.kind}) ──`;
|
|
96
|
-
const agentSummaries = phase.agents.map(formatAgentResult).join('\n\n');
|
|
97
|
-
return `${header}\n${agentSummaries}`;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function formatFullSummary(state: DelegateState): string {
|
|
101
|
-
const sections = [
|
|
102
|
-
`── Synthesis ──\n${state.synthesis}`,
|
|
103
|
-
`── Workflow: ${state.workflow.label} ──`,
|
|
104
|
-
...state.phases.map(formatPhaseSummary),
|
|
105
|
-
`── Usage ──\nTotal: ${formatUsage(state.totalUsage)}`,
|
|
106
|
-
];
|
|
107
|
-
|
|
108
|
-
return sections.join('\n\n');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function aggregateUsage(results: AgentResult[]): UsageStats {
|
|
112
|
-
const total: UsageStats = {
|
|
113
|
-
input: 0,
|
|
114
|
-
output: 0,
|
|
115
|
-
cacheRead: 0,
|
|
116
|
-
cacheWrite: 0,
|
|
117
|
-
cost: 0,
|
|
118
|
-
contextTokens: 0,
|
|
119
|
-
turns: 0,
|
|
120
|
-
};
|
|
121
|
-
for (const r of results) {
|
|
122
|
-
total.input += r.usage.input;
|
|
123
|
-
total.output += r.usage.output;
|
|
124
|
-
total.cacheRead += r.usage.cacheRead;
|
|
125
|
-
total.cacheWrite += r.usage.cacheWrite;
|
|
126
|
-
total.cost += r.usage.cost;
|
|
127
|
-
total.turns += r.usage.turns;
|
|
128
|
-
}
|
|
129
|
-
return total;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export { getFinalText };
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { WorkflowDefinition, WorkflowId } from './delegate-types';
|
|
2
|
-
|
|
3
|
-
export const WORKFLOWS: WorkflowDefinition[] = [
|
|
4
|
-
{
|
|
5
|
-
id: 'scout-only',
|
|
6
|
-
label: 'Scout only',
|
|
7
|
-
description: 'Parallel scouts for exploration — no plan, no implementation',
|
|
8
|
-
phases: [
|
|
9
|
-
{
|
|
10
|
-
kind: 'parallel',
|
|
11
|
-
name: 'Scouts',
|
|
12
|
-
agents: ['scout', 'docs-scout'],
|
|
13
|
-
taskTemplate: '{synthesis}',
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
id: 'scout-and-plan',
|
|
19
|
-
label: 'Scout and plan',
|
|
20
|
-
description: 'Parallel scouts → planner — produces a plan without implementing',
|
|
21
|
-
phases: [
|
|
22
|
-
{
|
|
23
|
-
kind: 'parallel',
|
|
24
|
-
name: 'Scouts',
|
|
25
|
-
agents: ['scout', 'docs-scout'],
|
|
26
|
-
taskTemplate: '{synthesis}',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
kind: 'single',
|
|
30
|
-
name: 'Planner',
|
|
31
|
-
agents: ['planner'],
|
|
32
|
-
taskTemplate:
|
|
33
|
-
'Create an implementation plan based on the following context.\n\n## Task\n{synthesis}\n\n## Scout findings\n{previous}',
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
id: 'implement',
|
|
39
|
-
label: 'Implement',
|
|
40
|
-
description: 'Parallel scouts → planner → worker — full implementation',
|
|
41
|
-
phases: [
|
|
42
|
-
{
|
|
43
|
-
kind: 'parallel',
|
|
44
|
-
name: 'Scouts',
|
|
45
|
-
agents: ['scout', 'docs-scout'],
|
|
46
|
-
taskTemplate: '{synthesis}',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
kind: 'single',
|
|
50
|
-
name: 'Planner',
|
|
51
|
-
agents: ['planner'],
|
|
52
|
-
requiresConfirmation: true,
|
|
53
|
-
taskTemplate:
|
|
54
|
-
'Create an implementation plan based on the following context.\n\n## Task\n{synthesis}\n\n## Scout findings\n{previous}',
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
kind: 'single',
|
|
58
|
-
name: 'Worker',
|
|
59
|
-
agents: ['worker'],
|
|
60
|
-
taskTemplate:
|
|
61
|
-
'Implement the following plan.\n\n## Task\n{synthesis}\n\n## Plan\n{previous}',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
id: 'implement-and-review',
|
|
67
|
-
label: 'Implement and review',
|
|
68
|
-
description:
|
|
69
|
-
'Parallel scouts → planner → worker → reviewer — full implementation with code review',
|
|
70
|
-
phases: [
|
|
71
|
-
{
|
|
72
|
-
kind: 'parallel',
|
|
73
|
-
name: 'Scouts',
|
|
74
|
-
agents: ['scout', 'docs-scout'],
|
|
75
|
-
taskTemplate: '{synthesis}',
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
kind: 'single',
|
|
79
|
-
name: 'Planner',
|
|
80
|
-
agents: ['planner'],
|
|
81
|
-
requiresConfirmation: true,
|
|
82
|
-
taskTemplate:
|
|
83
|
-
'Create an implementation plan based on the following context.\n\n## Task\n{synthesis}\n\n## Scout findings\n{previous}',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
kind: 'single',
|
|
87
|
-
name: 'Worker',
|
|
88
|
-
agents: ['worker'],
|
|
89
|
-
taskTemplate:
|
|
90
|
-
'Implement the following plan.\n\n## Task\n{synthesis}\n\n## Plan\n{previous}',
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
kind: 'single',
|
|
94
|
-
name: 'Reviewer',
|
|
95
|
-
agents: ['reviewer'],
|
|
96
|
-
taskTemplate:
|
|
97
|
-
'Review the implementation described below.\n\n## Task\n{synthesis}\n\n## Implementation output\n{previous}',
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
id: 'quick-fix',
|
|
103
|
-
label: 'Quick fix',
|
|
104
|
-
description: 'Worker only — fast, no scouts or planning',
|
|
105
|
-
phases: [
|
|
106
|
-
{
|
|
107
|
-
kind: 'single',
|
|
108
|
-
name: 'Worker',
|
|
109
|
-
agents: ['worker'],
|
|
110
|
-
taskTemplate: '{synthesis}',
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
id: 'review',
|
|
116
|
-
label: 'Review',
|
|
117
|
-
description: 'Reviewer only — code review of recent changes',
|
|
118
|
-
phases: [
|
|
119
|
-
{
|
|
120
|
-
kind: 'single',
|
|
121
|
-
name: 'Reviewer',
|
|
122
|
-
agents: ['reviewer'],
|
|
123
|
-
taskTemplate: '{synthesis}',
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
},
|
|
127
|
-
];
|
|
128
|
-
|
|
129
|
-
export function getWorkflow(id: WorkflowId): WorkflowDefinition {
|
|
130
|
-
const wf = WORKFLOWS.find((w) => w.id === id);
|
|
131
|
-
if (!wf) throw new Error(`Unknown workflow: ${id}`);
|
|
132
|
-
return wf;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export function suggestWorkflow(synthesis: string): WorkflowId {
|
|
136
|
-
const lower = synthesis.toLowerCase();
|
|
137
|
-
|
|
138
|
-
const hasReview = /review|audit|check quality|security/.test(lower);
|
|
139
|
-
const hasFix = /fix|bug|patch|hotfix|quick/.test(lower);
|
|
140
|
-
const hasImplement = /implement|build|create|add|refactor|migrate/.test(lower);
|
|
141
|
-
const hasDesign = /design|plan|architect|explore|investigate|scout/.test(lower);
|
|
142
|
-
|
|
143
|
-
if (hasFix && !hasImplement && !hasDesign) return 'quick-fix';
|
|
144
|
-
if (hasReview && !hasImplement && !hasDesign) return 'review';
|
|
145
|
-
if (hasDesign && !hasImplement) return 'scout-and-plan';
|
|
146
|
-
if (hasImplement && hasReview) return 'implement-and-review';
|
|
147
|
-
if (hasImplement) return 'implement';
|
|
148
|
-
|
|
149
|
-
return 'implement';
|
|
150
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Worker implements, reviewer reviews, worker applies feedback
|
|
3
|
-
---
|
|
4
|
-
Use the subagent tool with the chain parameter to execute this workflow:
|
|
5
|
-
|
|
6
|
-
1. First, use the "worker" agent to implement: $@
|
|
7
|
-
2. Then, use the "reviewer" agent to review the implementation from the previous step (use {previous} placeholder)
|
|
8
|
-
3. Finally, use the "worker" agent to apply the feedback from the review (use {previous} placeholder)
|
|
9
|
-
|
|
10
|
-
Execute this as a chain, passing output between steps via {previous}.
|
package/prompts/implement.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Full implementation workflow - scout gathers context, planner creates plan, worker implements
|
|
3
|
-
---
|
|
4
|
-
Use the subagent tool with the chain parameter to execute this workflow:
|
|
5
|
-
|
|
6
|
-
1. First, use the "scout" agent to find all code relevant to: $@
|
|
7
|
-
2. Then, use the "planner" agent to create an implementation plan for "$@" using the context from the previous step (use {previous} placeholder)
|
|
8
|
-
3. Finally, use the "worker" agent to implement the plan from the previous step (use {previous} placeholder)
|
|
9
|
-
|
|
10
|
-
Execute this as a chain, passing output between steps via {previous}.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Scout gathers context, planner creates implementation plan (no implementation)
|
|
3
|
-
---
|
|
4
|
-
Use the subagent tool with the chain parameter to execute this workflow:
|
|
5
|
-
|
|
6
|
-
1. First, use the "scout" agent to find all code relevant to: $@
|
|
7
|
-
2. Then, use the "planner" agent to create an implementation plan for "$@" using the context from the previous step (use {previous} placeholder)
|
|
8
|
-
|
|
9
|
-
Execute this as a chain, passing output between steps via {previous}. Do NOT implement - just return the plan.
|
|
File without changes
|