@phi-code-admin/phi-code 0.58.5 → 0.58.7
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/extensions/phi/orchestrator.ts +116 -38
- package/package.json +1 -1
|
@@ -144,6 +144,12 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
144
144
|
task: TaskDef,
|
|
145
145
|
agentDefs: Map<string, AgentDef>,
|
|
146
146
|
cwd: string,
|
|
147
|
+
sharedContext: {
|
|
148
|
+
projectTitle: string;
|
|
149
|
+
projectDescription: string;
|
|
150
|
+
specSummary: string;
|
|
151
|
+
completedTasks: Array<{ index: number; title: string; agent: string; output: string }>;
|
|
152
|
+
},
|
|
147
153
|
timeoutMs: number = 300000,
|
|
148
154
|
): Promise<TaskResult> {
|
|
149
155
|
return new Promise((resolve) => {
|
|
@@ -153,7 +159,33 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
153
159
|
const phiBin = findPhiBinary();
|
|
154
160
|
const startTime = Date.now();
|
|
155
161
|
|
|
156
|
-
|
|
162
|
+
// Build prompt with shared context
|
|
163
|
+
let taskPrompt = "";
|
|
164
|
+
|
|
165
|
+
// Inject shared project context (lightweight, always included)
|
|
166
|
+
taskPrompt += `# Project Context\n\n`;
|
|
167
|
+
taskPrompt += `**Project:** ${sharedContext.projectTitle}\n`;
|
|
168
|
+
taskPrompt += `**Description:** ${sharedContext.projectDescription}\n\n`;
|
|
169
|
+
|
|
170
|
+
if (sharedContext.specSummary) {
|
|
171
|
+
taskPrompt += `## Specification Summary\n${sharedContext.specSummary}\n\n`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Inject results from dependency tasks (only the ones this task depends on)
|
|
175
|
+
const deps = task.dependencies || [];
|
|
176
|
+
if (deps.length > 0) {
|
|
177
|
+
const depResults = sharedContext.completedTasks.filter(ct => deps.includes(ct.index));
|
|
178
|
+
if (depResults.length > 0) {
|
|
179
|
+
taskPrompt += `## Previous Task Results (your dependencies)\n\n`;
|
|
180
|
+
for (const dep of depResults) {
|
|
181
|
+
const truncatedOutput = dep.output.length > 1500 ? dep.output.slice(0, 1500) + "\n...(truncated)" : dep.output;
|
|
182
|
+
taskPrompt += `### Task ${dep.index}: ${dep.title} [${dep.agent}]\n\`\`\`\n${truncatedOutput}\n\`\`\`\n\n`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// The actual task
|
|
188
|
+
taskPrompt += `---\n\n# Your Task\n\n**${task.title}**\n\n${task.description}`;
|
|
157
189
|
if (task.subtasks && task.subtasks.length > 0) {
|
|
158
190
|
taskPrompt += "\n\nSub-tasks:\n" + task.subtasks.map((st, i) => `${i + 1}. ${st}`).join("\n");
|
|
159
191
|
}
|
|
@@ -199,17 +231,25 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
199
231
|
tasks: TaskDef[],
|
|
200
232
|
todoFile: string,
|
|
201
233
|
notify: (msg: string, type: "info" | "error" | "warning") => void,
|
|
234
|
+
projectContext?: { title: string; description: string; specSummary: string },
|
|
202
235
|
): Promise<{ results: TaskResult[]; progressFile: string }> {
|
|
203
236
|
const agentDefs = loadAgentDefs();
|
|
204
237
|
const progressFile = todoFile.replace("todo-", "progress-");
|
|
205
238
|
const progressPath = join(plansDir, progressFile);
|
|
206
239
|
let progress = `# Progress: ${todoFile}\n\n`;
|
|
207
240
|
progress += `**Started:** ${new Date().toLocaleString()}\n`;
|
|
208
|
-
progress += `**Tasks:** ${tasks.length}\n**Mode:** parallel (dependency-aware)\n\n`;
|
|
241
|
+
progress += `**Tasks:** ${tasks.length}\n**Mode:** parallel (dependency-aware, shared context)\n\n`;
|
|
209
242
|
await writeFile(progressPath, progress, "utf-8");
|
|
210
243
|
|
|
244
|
+
// Shared context for sub-agents
|
|
245
|
+
const sharedContext = {
|
|
246
|
+
projectTitle: projectContext?.title || "Project",
|
|
247
|
+
projectDescription: projectContext?.description || "",
|
|
248
|
+
specSummary: projectContext?.specSummary || "",
|
|
249
|
+
completedTasks: [] as Array<{ index: number; title: string; agent: string; output: string }>,
|
|
250
|
+
};
|
|
251
|
+
|
|
211
252
|
// Build dependency graph
|
|
212
|
-
// Task indices are 1-based in the plan files
|
|
213
253
|
const completed = new Set<number>();
|
|
214
254
|
const failed = new Set<number>();
|
|
215
255
|
const results: TaskResult[] = [];
|
|
@@ -268,22 +308,29 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
268
308
|
notify(`⏳ Task ${idx + 1}: **${t.title}** [${t.agent || "code"}]`, "info");
|
|
269
309
|
}
|
|
270
310
|
|
|
271
|
-
// Launch all ready tasks simultaneously
|
|
311
|
+
// Launch all ready tasks simultaneously (each gets shared context)
|
|
272
312
|
const promises = readyIndices.map(async (idx) => {
|
|
273
313
|
const task = tasks[idx];
|
|
274
|
-
const result = await executeTask(task, agentDefs, process.cwd());
|
|
314
|
+
const result = await executeTask(task, agentDefs, process.cwd(), sharedContext);
|
|
275
315
|
result.taskIndex = idx + 1;
|
|
276
316
|
return result;
|
|
277
317
|
});
|
|
278
318
|
|
|
279
319
|
const waveResults = await Promise.all(promises);
|
|
280
320
|
|
|
281
|
-
// Process results
|
|
321
|
+
// Process results and feed into shared context for next wave
|
|
282
322
|
for (const result of waveResults) {
|
|
283
323
|
results.push(result);
|
|
284
324
|
|
|
285
325
|
if (result.status === "success") {
|
|
286
326
|
completed.add(result.taskIndex);
|
|
327
|
+
// Add to shared context so dependent tasks can see this result
|
|
328
|
+
sharedContext.completedTasks.push({
|
|
329
|
+
index: result.taskIndex,
|
|
330
|
+
title: result.title,
|
|
331
|
+
agent: result.agent,
|
|
332
|
+
output: result.output,
|
|
333
|
+
});
|
|
287
334
|
} else {
|
|
288
335
|
failed.add(result.taskIndex);
|
|
289
336
|
}
|
|
@@ -399,33 +446,35 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
399
446
|
name: "orchestrate",
|
|
400
447
|
label: "Project Orchestrator",
|
|
401
448
|
description: "Create a project plan AND automatically execute all tasks with sub-agents in parallel. Each agent gets its own isolated context, model, and system prompt. Tasks without dependencies run simultaneously.",
|
|
402
|
-
promptSnippet: "Plan + execute projects.
|
|
449
|
+
promptSnippet: "Plan + execute projects in parallel waves. Each sub-agent gets isolated context + model. Use prompt-architect patterns for structured task descriptions.",
|
|
403
450
|
promptGuidelines: [
|
|
404
|
-
"When asked to plan or build a project: analyze the request, then call orchestrate. It
|
|
405
|
-
"
|
|
406
|
-
"
|
|
407
|
-
"
|
|
408
|
-
"
|
|
451
|
+
"When asked to plan or build a project: analyze the request thoroughly, then call the orchestrate tool. It plans AND executes automatically.",
|
|
452
|
+
"CRITICAL: Each task description must be SELF-CONTAINED. The sub-agent has NO shared history, NO access to the conversation, NO memory of previous tasks. Include ALL context it needs: file paths, expected behavior, relevant code patterns, and success criteria.",
|
|
453
|
+
"Structure each task description using the prompt-architect pattern: [CONTEXT] what exists and why → [TASK] what to do specifically → [FORMAT] expected output → [CONSTRAINTS] rules and limitations.",
|
|
454
|
+
"Assign agent types strategically: 'explore' (read-only analysis, codebase understanding), 'plan' (architecture, design decisions), 'code' (implementation, file creation/modification), 'test' (write + run tests, validate behavior), 'review' (security audit, quality check, read-only).",
|
|
455
|
+
"Set dependencies to maximize parallelism: tasks without dependencies run simultaneously in the same wave. Only add dependencies when a task truly needs another task's output.",
|
|
456
|
+
"Order tasks logically: explore → plan → code → test → review. But allow independent tasks at each stage to run in parallel.",
|
|
457
|
+
"Set priority=high for critical-path tasks, medium for standard work, low for nice-to-haves.",
|
|
409
458
|
],
|
|
410
459
|
parameters: Type.Object({
|
|
411
|
-
title: Type.String({ description: "
|
|
412
|
-
description: Type.String({ description: "Full project description
|
|
413
|
-
goals: Type.Array(Type.String(), { description: "
|
|
460
|
+
title: Type.String({ description: "Concise project title" }),
|
|
461
|
+
description: Type.String({ description: "Full project description: what to build, why, and any relevant context" }),
|
|
462
|
+
goals: Type.Array(Type.String(), { description: "Measurable project goals (what success looks like)" }),
|
|
414
463
|
requirements: Type.Array(Type.String(), { description: "Technical and functional requirements" }),
|
|
415
|
-
architecture: Type.Optional(Type.Array(Type.String(), { description: "Architecture decisions" })),
|
|
464
|
+
architecture: Type.Optional(Type.Array(Type.String(), { description: "Architecture decisions, tech stack choices, trade-offs" })),
|
|
416
465
|
tasks: Type.Array(
|
|
417
466
|
Type.Object({
|
|
418
|
-
title: Type.String({ description: "
|
|
419
|
-
description: Type.String({ description: "
|
|
420
|
-
agent: Type.Optional(Type.String({ description: "Agent type: explore, plan, code, test,
|
|
421
|
-
priority: Type.Optional(Type.String({ description: "high, medium,
|
|
422
|
-
dependencies: Type.Optional(Type.Array(Type.Number(), { description: "
|
|
423
|
-
subtasks: Type.Optional(Type.Array(Type.String(), { description: "
|
|
467
|
+
title: Type.String({ description: "Clear, action-oriented task title" }),
|
|
468
|
+
description: Type.String({ description: "SELF-CONTAINED task description. Include ALL context the sub-agent needs: file paths, expected behavior, code patterns, conventions. The agent has NO shared history." }),
|
|
469
|
+
agent: Type.Optional(Type.String({ description: "Agent type: explore (read-only analysis), plan (architecture), code (implementation), test (write+run tests), review (quality audit)" })),
|
|
470
|
+
priority: Type.Optional(Type.String({ description: "high (critical path), medium (standard), low (nice-to-have)" })),
|
|
471
|
+
dependencies: Type.Optional(Type.Array(Type.Number(), { description: "Task numbers this depends on (1-indexed). Only add when truly needed — fewer dependencies = more parallelism" })),
|
|
472
|
+
subtasks: Type.Optional(Type.Array(Type.String(), { description: "Specific sub-steps within this task" })),
|
|
424
473
|
}),
|
|
425
|
-
{ description: "Ordered list of tasks
|
|
474
|
+
{ description: "Ordered list of tasks. Independent tasks run in parallel. Dependent tasks wait for prerequisites." }
|
|
426
475
|
),
|
|
427
|
-
constraints: Type.Optional(Type.Array(Type.String(), { description: "
|
|
428
|
-
successCriteria: Type.Optional(Type.Array(Type.String(), { description: "
|
|
476
|
+
constraints: Type.Optional(Type.Array(Type.String(), { description: "Hard constraints: frameworks, patterns, rules, things to avoid" })),
|
|
477
|
+
successCriteria: Type.Optional(Type.Array(Type.String(), { description: "How to verify the project is complete and correct" })),
|
|
429
478
|
}),
|
|
430
479
|
|
|
431
480
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -457,7 +506,18 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
457
506
|
notify(`📋 Plan created: **${p.title}** (${p.tasks.length} tasks)\nNow executing with sub-agents...`, "info");
|
|
458
507
|
|
|
459
508
|
// Auto-execute all tasks
|
|
460
|
-
|
|
509
|
+
// Build spec summary for shared context
|
|
510
|
+
const specSummary = [
|
|
511
|
+
`Goals: ${p.goals.join("; ")}`,
|
|
512
|
+
`Requirements: ${p.requirements.join("; ")}`,
|
|
513
|
+
p.architecture?.length ? `Architecture: ${p.architecture.join("; ")}` : "",
|
|
514
|
+
p.constraints?.length ? `Constraints: ${p.constraints.join("; ")}` : "",
|
|
515
|
+
].filter(Boolean).join("\n");
|
|
516
|
+
|
|
517
|
+
const { results, progressFile } = await executePlan(
|
|
518
|
+
p.tasks, todoFile, notify,
|
|
519
|
+
{ title: p.title, description: p.description, specSummary },
|
|
520
|
+
);
|
|
461
521
|
|
|
462
522
|
const succeeded = results.filter(r => r.status === "success").length;
|
|
463
523
|
const failed = results.filter(r => r.status === "error").length;
|
|
@@ -527,18 +587,36 @@ All files in \`.phi/plans/\``;
|
|
|
527
587
|
}
|
|
528
588
|
|
|
529
589
|
ctx.sendUserMessage(
|
|
530
|
-
`Analyze this project
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
Instructions
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
-
|
|
541
|
-
-
|
|
590
|
+
`Analyze this project and call the orchestrate tool. It will create the plan AND execute all tasks automatically with parallel sub-agents.
|
|
591
|
+
|
|
592
|
+
## Project
|
|
593
|
+
${description}
|
|
594
|
+
|
|
595
|
+
## Instructions
|
|
596
|
+
|
|
597
|
+
1. **Analyze** the project: identify goals, requirements, technical constraints, and architecture decisions.
|
|
598
|
+
|
|
599
|
+
2. **Decompose** into tasks. Each task will be executed by an isolated sub-agent that has:
|
|
600
|
+
- NO access to this conversation
|
|
601
|
+
- NO shared memory or context
|
|
602
|
+
- Its own model and system prompt
|
|
603
|
+
- Full tool access (read, write, edit, bash, grep, find, ls)
|
|
604
|
+
|
|
605
|
+
3. **Write self-contained task descriptions** using this pattern:
|
|
606
|
+
- CONTEXT: What exists, relevant file paths, current state
|
|
607
|
+
- TASK: Exactly what to implement/analyze/test
|
|
608
|
+
- FORMAT: Expected output (files created, test results, etc.)
|
|
609
|
+
- CONSTRAINTS: Rules, conventions, things to avoid
|
|
610
|
+
|
|
611
|
+
4. **Assign agents**: explore (read-only analysis), plan (design), code (implementation), test (write+run tests), review (quality audit)
|
|
612
|
+
|
|
613
|
+
5. **Set dependencies** to maximize parallelism:
|
|
614
|
+
- Tasks without dependencies → same wave → run simultaneously
|
|
615
|
+
- Only add a dependency when a task truly needs another's output
|
|
616
|
+
- Typical flow: explore(wave 1) → plan(wave 2) → code(wave 3) → test(wave 4) → review(wave 5)
|
|
617
|
+
- But independent code tasks can run in parallel within the same wave
|
|
618
|
+
|
|
619
|
+
6. **Call the orchestrate tool** with all structured data. It handles execution automatically.`
|
|
542
620
|
);
|
|
543
621
|
},
|
|
544
622
|
});
|