@phi-code-admin/phi-code 0.64.2 โ 0.66.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/extensions/phi/orchestrator.ts +183 -64
- package/package.json +1 -1
|
@@ -467,7 +467,6 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
467
467
|
|
|
468
468
|
let phaseQueue: OrchestratorPhase[] = [];
|
|
469
469
|
let orchestrationActive = false;
|
|
470
|
-
let idlePollTimer: ReturnType<typeof setInterval> | null = null;
|
|
471
470
|
let activeAgentPrompt: string | null = null;
|
|
472
471
|
let activeAgentTools: string[] | null = null;
|
|
473
472
|
let savedTools: string[] | null = null;
|
|
@@ -504,6 +503,7 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
504
503
|
|
|
505
504
|
/**
|
|
506
505
|
* Load routing config and build phase queue with model assignments + agent definitions.
|
|
506
|
+
* Each phase now reads outputs from previous phases and writes structured outputs.
|
|
507
507
|
*/
|
|
508
508
|
function buildPhases(description: string): OrchestratorPhase[] {
|
|
509
509
|
const routingPath = join(homedir(), ".phi", "agent", "routing.json");
|
|
@@ -526,31 +526,195 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
526
526
|
const test = getModel("test");
|
|
527
527
|
const review = getModel("review");
|
|
528
528
|
|
|
529
|
+
const ts = timestamp();
|
|
530
|
+
|
|
529
531
|
return [
|
|
530
532
|
{
|
|
531
533
|
key: "explore", label: "๐ Phase 1 โ EXPLORE", model: explore.preferred, fallback: explore.fallback,
|
|
532
534
|
agent: loadAgentDef("explore"),
|
|
533
|
-
instruction: `Analyze the project requirements and existing codebase.
|
|
535
|
+
instruction: `You are the EXPLORE agent. Analyze the project requirements and existing codebase.
|
|
536
|
+
|
|
537
|
+
**Project Request:** ${description}
|
|
538
|
+
|
|
539
|
+
**Your tasks:**
|
|
540
|
+
1. List all existing files and read key ones
|
|
541
|
+
2. Identify tech stack, patterns, and constraints
|
|
542
|
+
3. Create a STRUCTURED PROJECT BRIEF in \`.phi/plans/brief-${ts}.md\`:
|
|
543
|
+
- Context: what exists now
|
|
544
|
+
- Objective: what needs to be built
|
|
545
|
+
- Requirements: specific features needed
|
|
546
|
+
- Tech decisions: frameworks, patterns to use
|
|
547
|
+
- Constraints: what to NOT break
|
|
548
|
+
|
|
549
|
+
**Step 4:** Write your findings to \`.phi/plans/explore-${ts}.md\`
|
|
550
|
+
|
|
551
|
+
**Format for the project brief:**
|
|
552
|
+
\`\`\`markdown
|
|
553
|
+
## Project Brief
|
|
554
|
+
|
|
555
|
+
### Context
|
|
556
|
+
[Analyze what the user is asking for]
|
|
557
|
+
|
|
558
|
+
### Objective
|
|
559
|
+
[Clear, specific goal]
|
|
560
|
+
|
|
561
|
+
### Requirements
|
|
562
|
+
[Bullet list of what must be built]
|
|
563
|
+
|
|
564
|
+
### Tech Decisions
|
|
565
|
+
[Frameworks, patterns, architecture choices]
|
|
566
|
+
|
|
567
|
+
### Constraints
|
|
568
|
+
- Production-quality code, no placeholders
|
|
569
|
+
- Every function fully implemented
|
|
570
|
+
- Follow existing patterns if codebase exists
|
|
571
|
+
- [Any other specific constraints]
|
|
572
|
+
\`\`\``,
|
|
534
573
|
},
|
|
535
574
|
{
|
|
536
575
|
key: "plan", label: "๐ Phase 2 โ PLAN", model: plan.preferred, fallback: plan.fallback,
|
|
537
576
|
agent: loadAgentDef("plan"),
|
|
538
|
-
instruction: `
|
|
577
|
+
instruction: `You are the PLAN agent. Design the architecture and create a detailed task list.
|
|
578
|
+
|
|
579
|
+
**Project Request:** ${description}
|
|
580
|
+
|
|
581
|
+
**Step 1:** Read \`.phi/plans/brief-*.md\` (created by the explore phase)
|
|
582
|
+
**Step 2:** Read \`.phi/plans/explore-*.md\` to understand the codebase analysis
|
|
583
|
+
**Step 3:** Design the architecture based on findings
|
|
584
|
+
**Step 4:** Create a DETAILED TODO LIST in \`.phi/plans/todo-${ts}.md\`:
|
|
585
|
+
For each task:
|
|
586
|
+
- Task number and title
|
|
587
|
+
- Agent assignment (code/test)
|
|
588
|
+
- Files to create/modify
|
|
589
|
+
- Specific implementation details
|
|
590
|
+
- Dependencies on other tasks
|
|
591
|
+
|
|
592
|
+
**Format for the todo list:**
|
|
593
|
+
\`\`\`markdown
|
|
594
|
+
# TODO: Project Tasks
|
|
595
|
+
|
|
596
|
+
## Task 1: [Task Title] [agent-type]
|
|
597
|
+
- [ ] Specific implementation details
|
|
598
|
+
- [ ] Files to create: path/to/file.ext
|
|
599
|
+
- [ ] Expected behavior
|
|
600
|
+
- Dependencies: None
|
|
601
|
+
|
|
602
|
+
## Task 2: [Task Title] [agent-type]
|
|
603
|
+
- [ ] Implementation details
|
|
604
|
+
- Dependencies: Task 1
|
|
605
|
+
\`\`\``,
|
|
539
606
|
},
|
|
540
607
|
{
|
|
541
608
|
key: "code", label: "๐ป Phase 3 โ CODE", model: code.preferred, fallback: code.fallback,
|
|
542
609
|
agent: loadAgentDef("code"),
|
|
543
|
-
instruction: `
|
|
610
|
+
instruction: `You are the CODE agent. Implement the complete project.
|
|
611
|
+
|
|
612
|
+
**Project Request:** ${description}
|
|
613
|
+
|
|
614
|
+
**Step 1:** Read \`.phi/plans/brief-*.md\` for project context
|
|
615
|
+
**Step 2:** Read \`.phi/plans/todo-*.md\` to get your task list
|
|
616
|
+
**Step 3:** Implement EVERY task from the todo list, in order
|
|
617
|
+
**Step 4:** Write a progress report to \`.phi/plans/progress-${ts}.md\`
|
|
618
|
+
|
|
619
|
+
**Rules:**
|
|
620
|
+
- Create every file listed in the plan
|
|
621
|
+
- No placeholders, no TODOs, no stubs
|
|
622
|
+
- Every function must be fully implemented
|
|
623
|
+
- Follow the architecture from the plan
|
|
624
|
+
- Check off tasks in your progress report as you complete them
|
|
625
|
+
|
|
626
|
+
**Progress report format:**
|
|
627
|
+
\`\`\`markdown
|
|
628
|
+
# Progress Report
|
|
629
|
+
|
|
630
|
+
## Completed Tasks
|
|
631
|
+
- [x] Task 1: Description - DONE
|
|
632
|
+
- [x] Task 2: Description - DONE
|
|
633
|
+
|
|
634
|
+
## Files Created
|
|
635
|
+
- path/to/file1.ext - Purpose
|
|
636
|
+
- path/to/file2.ext - Purpose
|
|
637
|
+
|
|
638
|
+
## Implementation Notes
|
|
639
|
+
[Any important decisions or changes made]
|
|
640
|
+
\`\`\``,
|
|
544
641
|
},
|
|
545
642
|
{
|
|
546
643
|
key: "test", label: "๐งช Phase 4 โ TEST", model: test.preferred, fallback: test.fallback,
|
|
547
644
|
agent: loadAgentDef("test"),
|
|
548
|
-
instruction: `
|
|
645
|
+
instruction: `You are the TEST agent. Verify the implementation.
|
|
646
|
+
|
|
647
|
+
**Project Request:** ${description}
|
|
648
|
+
|
|
649
|
+
**Step 1:** Read \`.phi/plans/todo-*.md\` to know what was planned
|
|
650
|
+
**Step 2:** Read \`.phi/plans/progress-*.md\` to see what was done
|
|
651
|
+
**Step 3:** Run the code, check for errors, test key features
|
|
652
|
+
**Step 4:** Fix any errors you find
|
|
653
|
+
**Step 5:** Write test results to \`.phi/plans/test-${ts}.md\`
|
|
654
|
+
|
|
655
|
+
**Test report format:**
|
|
656
|
+
\`\`\`markdown
|
|
657
|
+
# Test Report
|
|
658
|
+
|
|
659
|
+
## Tests Executed
|
|
660
|
+
- [ ] Feature 1: Description - PASS/FAIL
|
|
661
|
+
- [ ] Feature 2: Description - PASS/FAIL
|
|
662
|
+
|
|
663
|
+
## Errors Found & Fixed
|
|
664
|
+
- Error: Description
|
|
665
|
+
- Fix: What was done
|
|
666
|
+
|
|
667
|
+
## Manual Testing
|
|
668
|
+
- Tested: What was manually verified
|
|
669
|
+
- Result: Pass/Fail with details
|
|
670
|
+
|
|
671
|
+
## Final Status
|
|
672
|
+
โ
All tests pass / โ Issues remain
|
|
673
|
+
\`\`\``,
|
|
549
674
|
},
|
|
550
675
|
{
|
|
551
676
|
key: "review", label: "๐ Phase 5 โ REVIEW", model: review.preferred, fallback: review.fallback,
|
|
552
677
|
agent: loadAgentDef("review"),
|
|
553
|
-
instruction: `
|
|
678
|
+
instruction: `You are the REVIEW agent. Final quality review.
|
|
679
|
+
|
|
680
|
+
**Project Request:** ${description}
|
|
681
|
+
|
|
682
|
+
**Step 1:** Read all \`.phi/plans/*.md\` files
|
|
683
|
+
**Step 2:** Review code quality, security, performance
|
|
684
|
+
**Step 3:** Fix any issues found
|
|
685
|
+
**Step 4:** Write final report to \`.phi/plans/review-${ts}.md\`
|
|
686
|
+
|
|
687
|
+
**Review checklist:**
|
|
688
|
+
- Code quality: naming, structure, readability
|
|
689
|
+
- Security: input validation, error handling
|
|
690
|
+
- Performance: efficiency, resource usage
|
|
691
|
+
- Documentation: comments, README if needed
|
|
692
|
+
- Completeness: all requirements met
|
|
693
|
+
|
|
694
|
+
**Final report format:**
|
|
695
|
+
\`\`\`markdown
|
|
696
|
+
# Final Review
|
|
697
|
+
|
|
698
|
+
## Code Quality โ
/โ
|
|
699
|
+
- Structure: Good/Needs work
|
|
700
|
+
- Naming: Clear/Unclear
|
|
701
|
+
- Comments: Adequate/Missing
|
|
702
|
+
|
|
703
|
+
## Security โ
/โ
|
|
704
|
+
- Input validation: Present/Missing
|
|
705
|
+
- Error handling: Robust/Weak
|
|
706
|
+
|
|
707
|
+
## Performance โ
/โ
|
|
708
|
+
- Efficiency: Good/Could improve
|
|
709
|
+
- Resource usage: Optimal/Excessive
|
|
710
|
+
|
|
711
|
+
## Completeness โ
/โ
|
|
712
|
+
- All requirements met: Yes/No
|
|
713
|
+
- All files created: Yes/No
|
|
714
|
+
|
|
715
|
+
## Final Verdict
|
|
716
|
+
โ
Project ready for production / โ Issues need resolution
|
|
717
|
+
\`\`\``,
|
|
554
718
|
},
|
|
555
719
|
];
|
|
556
720
|
}
|
|
@@ -629,34 +793,11 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
629
793
|
activateAgent(phase, ctx);
|
|
630
794
|
const agentName = phase.agent?.name || phase.key;
|
|
631
795
|
ctx.ui.notify(`\n${phase.label} โ \`${modelId}\` (agent: ${agentName})`, "info");
|
|
632
|
-
//
|
|
633
|
-
|
|
796
|
+
// Small delay to let the model switch settle, then send instruction
|
|
797
|
+
setTimeout(() => pi.sendUserMessage(phase.instruction), 500);
|
|
634
798
|
});
|
|
635
799
|
}
|
|
636
800
|
|
|
637
|
-
/**
|
|
638
|
-
* Reliable phase sending: poll isIdle() then sendUserMessage.
|
|
639
|
-
* Retries up to 240 attempts (120 seconds).
|
|
640
|
-
*/
|
|
641
|
-
function waitForIdleThenSend(message: string, ctx: any) {
|
|
642
|
-
let attempts = 0;
|
|
643
|
-
const timer = setInterval(() => {
|
|
644
|
-
attempts++;
|
|
645
|
-
if (attempts > 240) {
|
|
646
|
-
clearInterval(timer);
|
|
647
|
-
ctx.ui.notify("โ ๏ธ Orchestrator timeout โ agent never became idle.", "warning");
|
|
648
|
-
setOrchestrationActive(false);
|
|
649
|
-
phasePending = false;
|
|
650
|
-
deactivateAgent();
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
if (ctx.isIdle()) {
|
|
654
|
-
clearInterval(timer);
|
|
655
|
-
setTimeout(() => pi.sendUserMessage(message), 300);
|
|
656
|
-
}
|
|
657
|
-
}, 500);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
801
|
// โโโ System Prompt Injection โ Agent personas โโโโโโโโโโโโโโโโโโโโ
|
|
661
802
|
|
|
662
803
|
pi.on("before_agent_start", async (event, _ctx) => {
|
|
@@ -667,42 +808,20 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
|
|
|
667
808
|
return { systemPrompt: activeAgentPrompt };
|
|
668
809
|
});
|
|
669
810
|
|
|
670
|
-
// โโโ
|
|
671
|
-
//
|
|
672
|
-
//
|
|
811
|
+
// โโโ Agent End Event โ Phase Chaining โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
812
|
+
// "agent_end" fires when the full agent loop completes (all tool calls
|
|
813
|
+
// resolved, response fully generated). This is the ONLY reliable signal
|
|
814
|
+
// that a phase has finished.
|
|
815
|
+
//
|
|
816
|
+
// Previous approach used "output" event which DOES NOT EXIST in Pi.
|
|
817
|
+
// That's why phases 2-5 never executed.
|
|
673
818
|
|
|
674
|
-
pi.on("
|
|
819
|
+
pi.on("agent_end", async (_event, ctx) => {
|
|
675
820
|
if (!orchestrationActive || !phasePending) return;
|
|
676
|
-
if (phaseQueue.length === 0 && phasePending) {
|
|
677
|
-
// Last phase in progress โ wait for it to finish, then complete
|
|
678
|
-
}
|
|
679
821
|
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
idlePollTimer = null;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// After output, wait a bit then check if the agent is truly idle
|
|
687
|
-
// Use a longer initial delay (2 seconds) to let tool calls complete
|
|
688
|
-
idlePollTimer = setTimeout(() => {
|
|
689
|
-
let attempts = 0;
|
|
690
|
-
idlePollTimer = setInterval(() => {
|
|
691
|
-
attempts++;
|
|
692
|
-
if (attempts > 60) { // 30 seconds after last output
|
|
693
|
-
clearInterval(idlePollTimer!);
|
|
694
|
-
idlePollTimer = null;
|
|
695
|
-
// Don't timeout โ the phase might still have tool calls
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
if (ctx.isIdle()) {
|
|
699
|
-
clearInterval(idlePollTimer!);
|
|
700
|
-
idlePollTimer = null;
|
|
701
|
-
phasePending = false;
|
|
702
|
-
sendNextPhase(ctx);
|
|
703
|
-
}
|
|
704
|
-
}, 500) as any;
|
|
705
|
-
}, 2000) as any;
|
|
822
|
+
// Phase complete โ chain to next
|
|
823
|
+
phasePending = false;
|
|
824
|
+
sendNextPhase(ctx);
|
|
706
825
|
});
|
|
707
826
|
|
|
708
827
|
// โโโ /plan Command โ Full workflow โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|