opencode-orchestrator 0.6.0 → 0.6.2
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/README.md +79 -272
- package/dist/core/agents/interfaces/launch-input.interface.d.ts +1 -0
- package/dist/core/agents/interfaces/parallel-task.interface.d.ts +1 -0
- package/dist/core/agents/logger.d.ts +3 -0
- package/dist/core/orchestrator/index.d.ts +1 -2
- package/dist/core/orchestrator/interfaces/index.d.ts +0 -1
- package/dist/core/orchestrator/interfaces/session-state.d.ts +0 -2
- package/dist/core/orchestrator/types/index.d.ts +0 -1
- package/dist/index.js +159 -441
- package/dist/scripts/postinstall.js +19 -2
- package/dist/scripts/preuninstall.js +18 -2
- package/dist/shared/constants.d.ts +1 -0
- package/package.json +3 -2
- package/dist/core/orchestrator/interfaces/task.d.ts +0 -17
- package/dist/core/orchestrator/task-graph.d.ts +0 -17
- package/dist/core/orchestrator/types/task-type.d.ts +0 -4
package/dist/index.js
CHANGED
|
@@ -57,8 +57,10 @@ var PARALLEL_TASK = {
|
|
|
57
57
|
// 10 per agent type
|
|
58
58
|
MAX_CONCURRENCY: 50,
|
|
59
59
|
// 50 total
|
|
60
|
-
SYNC_TIMEOUT_MS: 10 * TIME.MINUTE
|
|
60
|
+
SYNC_TIMEOUT_MS: 10 * TIME.MINUTE,
|
|
61
61
|
// 10 minutes for sync mode
|
|
62
|
+
MAX_DEPTH: 3
|
|
63
|
+
// Max nesting depth (Commander -> Agent -> Sub-task)
|
|
62
64
|
};
|
|
63
65
|
var MEMORY_LIMITS = {
|
|
64
66
|
MAX_TASKS_IN_MEMORY: 1e3,
|
|
@@ -236,7 +238,7 @@ RECORD findings if on Deep Track.
|
|
|
236
238
|
|-------|----------|
|
|
237
239
|
| Fast | Use \`${AGENT_NAMES.BUILDER}\` directly. Skip \`${AGENT_NAMES.ARCHITECT}\`. |
|
|
238
240
|
| Normal | Call \`${AGENT_NAMES.ARCHITECT}\` for lightweight plan. |
|
|
239
|
-
| Deep | Full
|
|
241
|
+
| Deep | Full planning + \`${AGENT_NAMES.RECORDER}\` state tracking. |
|
|
240
242
|
|
|
241
243
|
AVAILABLE AGENTS:
|
|
242
244
|
- \`${AGENT_NAMES.ARCHITECT}\`: Task decomposition and planning
|
|
@@ -1003,70 +1005,6 @@ var AGENTS = {
|
|
|
1003
1005
|
[AGENT_NAMES.RESEARCHER]: researcher
|
|
1004
1006
|
};
|
|
1005
1007
|
|
|
1006
|
-
// src/core/orchestrator/task-graph.ts
|
|
1007
|
-
var TaskGraph = class _TaskGraph {
|
|
1008
|
-
tasks = /* @__PURE__ */ new Map();
|
|
1009
|
-
constructor(tasks) {
|
|
1010
|
-
if (tasks) {
|
|
1011
|
-
tasks.forEach((t) => this.addTask(t));
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
addTask(task) {
|
|
1015
|
-
this.tasks.set(task.id, { ...task, status: "pending", retryCount: 0 });
|
|
1016
|
-
}
|
|
1017
|
-
getTask(id) {
|
|
1018
|
-
return this.tasks.get(id);
|
|
1019
|
-
}
|
|
1020
|
-
updateTask(id, updates) {
|
|
1021
|
-
const task = this.tasks.get(id);
|
|
1022
|
-
if (task) {
|
|
1023
|
-
this.tasks.set(id, { ...task, ...updates });
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
getReadyTasks() {
|
|
1027
|
-
return Array.from(this.tasks.values()).filter((task) => {
|
|
1028
|
-
if (task.status !== "pending") return false;
|
|
1029
|
-
return task.dependencies.every((depId) => {
|
|
1030
|
-
const dep = this.tasks.get(depId);
|
|
1031
|
-
return dep && dep.status === "completed";
|
|
1032
|
-
});
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
isCompleted() {
|
|
1036
|
-
return Array.from(this.tasks.values()).every((t) => t.status === "completed");
|
|
1037
|
-
}
|
|
1038
|
-
hasFailed() {
|
|
1039
|
-
return Array.from(this.tasks.values()).some((t) => t.status === "failed" && t.retryCount >= 3);
|
|
1040
|
-
}
|
|
1041
|
-
getTaskSummary() {
|
|
1042
|
-
const tasks = Array.from(this.tasks.values());
|
|
1043
|
-
const completed = tasks.filter((t) => t.status === "completed");
|
|
1044
|
-
const notCompleted = tasks.filter((t) => t.status !== "completed");
|
|
1045
|
-
let summary = "\u{1F4CB} **Mission Status**\n";
|
|
1046
|
-
if (completed.length > 0) {
|
|
1047
|
-
summary += `\u2705 Completed: ${completed.length} tasks
|
|
1048
|
-
`;
|
|
1049
|
-
}
|
|
1050
|
-
for (const task of notCompleted) {
|
|
1051
|
-
const icon = task.status === "running" ? "\u23F3" : task.status === "failed" ? "\u274C" : "\u{1F4A4}";
|
|
1052
|
-
summary += `${icon} [${task.id}] ${task.description}
|
|
1053
|
-
`;
|
|
1054
|
-
}
|
|
1055
|
-
return summary;
|
|
1056
|
-
}
|
|
1057
|
-
toJSON() {
|
|
1058
|
-
return JSON.stringify(Array.from(this.tasks.values()), null, 2);
|
|
1059
|
-
}
|
|
1060
|
-
static fromJSON(json2) {
|
|
1061
|
-
try {
|
|
1062
|
-
const tasks = JSON.parse(json2);
|
|
1063
|
-
return new _TaskGraph(tasks);
|
|
1064
|
-
} catch {
|
|
1065
|
-
return new _TaskGraph();
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
};
|
|
1069
|
-
|
|
1070
1008
|
// src/core/orchestrator/state.ts
|
|
1071
1009
|
var state = {
|
|
1072
1010
|
missionActive: false,
|
|
@@ -1806,10 +1744,10 @@ function mergeDefs(...defs) {
|
|
|
1806
1744
|
function cloneDef(schema) {
|
|
1807
1745
|
return mergeDefs(schema._zod.def);
|
|
1808
1746
|
}
|
|
1809
|
-
function getElementAtPath(obj,
|
|
1810
|
-
if (!
|
|
1747
|
+
function getElementAtPath(obj, path4) {
|
|
1748
|
+
if (!path4)
|
|
1811
1749
|
return obj;
|
|
1812
|
-
return
|
|
1750
|
+
return path4.reduce((acc, key) => acc?.[key], obj);
|
|
1813
1751
|
}
|
|
1814
1752
|
function promiseAllObject(promisesObj) {
|
|
1815
1753
|
const keys = Object.keys(promisesObj);
|
|
@@ -2170,11 +2108,11 @@ function aborted(x, startIndex = 0) {
|
|
|
2170
2108
|
}
|
|
2171
2109
|
return false;
|
|
2172
2110
|
}
|
|
2173
|
-
function prefixIssues(
|
|
2111
|
+
function prefixIssues(path4, issues) {
|
|
2174
2112
|
return issues.map((iss) => {
|
|
2175
2113
|
var _a;
|
|
2176
2114
|
(_a = iss).path ?? (_a.path = []);
|
|
2177
|
-
iss.path.unshift(
|
|
2115
|
+
iss.path.unshift(path4);
|
|
2178
2116
|
return iss;
|
|
2179
2117
|
});
|
|
2180
2118
|
}
|
|
@@ -2342,7 +2280,7 @@ function treeifyError(error45, _mapper) {
|
|
|
2342
2280
|
return issue2.message;
|
|
2343
2281
|
};
|
|
2344
2282
|
const result = { errors: [] };
|
|
2345
|
-
const processError = (error46,
|
|
2283
|
+
const processError = (error46, path4 = []) => {
|
|
2346
2284
|
var _a, _b;
|
|
2347
2285
|
for (const issue2 of error46.issues) {
|
|
2348
2286
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -2352,7 +2290,7 @@ function treeifyError(error45, _mapper) {
|
|
|
2352
2290
|
} else if (issue2.code === "invalid_element") {
|
|
2353
2291
|
processError({ issues: issue2.issues }, issue2.path);
|
|
2354
2292
|
} else {
|
|
2355
|
-
const fullpath = [...
|
|
2293
|
+
const fullpath = [...path4, ...issue2.path];
|
|
2356
2294
|
if (fullpath.length === 0) {
|
|
2357
2295
|
result.errors.push(mapper(issue2));
|
|
2358
2296
|
continue;
|
|
@@ -2384,8 +2322,8 @@ function treeifyError(error45, _mapper) {
|
|
|
2384
2322
|
}
|
|
2385
2323
|
function toDotPath(_path) {
|
|
2386
2324
|
const segs = [];
|
|
2387
|
-
const
|
|
2388
|
-
for (const seg of
|
|
2325
|
+
const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2326
|
+
for (const seg of path4) {
|
|
2389
2327
|
if (typeof seg === "number")
|
|
2390
2328
|
segs.push(`[${seg}]`);
|
|
2391
2329
|
else if (typeof seg === "symbol")
|
|
@@ -13504,7 +13442,7 @@ var callAgentTool = tool({
|
|
|
13504
13442
|
<agents>
|
|
13505
13443
|
| Agent | Role | When to Use |
|
|
13506
13444
|
|-------|------|-------------|
|
|
13507
|
-
| ${AGENT_NAMES.ARCHITECT} \u{1F3D7}\uFE0F | Planner | Complex task \u2192
|
|
13445
|
+
| ${AGENT_NAMES.ARCHITECT} \u{1F3D7}\uFE0F | Planner | Complex task \u2192 plan, OR 3+ failures \u2192 strategy |
|
|
13508
13446
|
| ${AGENT_NAMES.BUILDER} \u{1F528} | Developer | Any code implementation (logic + UI) |
|
|
13509
13447
|
| ${AGENT_NAMES.INSPECTOR} \u{1F50D} | Quality | Before completion, OR on errors (auto-fixes) |
|
|
13510
13448
|
| ${AGENT_NAMES.RECORDER} \u{1F4BE} | Context | After each task, OR at session start |
|
|
@@ -13565,321 +13503,30 @@ Never claim completion without proof.
|
|
|
13565
13503
|
});
|
|
13566
13504
|
|
|
13567
13505
|
// src/tools/slashCommand.ts
|
|
13568
|
-
var
|
|
13569
|
-
You are
|
|
13570
|
-
</role>
|
|
13571
|
-
|
|
13572
|
-
<core_rules>
|
|
13573
|
-
1. Never stop until "${MISSION.COMPLETE}"
|
|
13574
|
-
2. Never wait for user during execution
|
|
13575
|
-
3. Never stop because agent returned nothing
|
|
13576
|
-
4. Always survey environment & codebase BEFORE coding
|
|
13577
|
-
5. Always verify with evidence based on runtime context
|
|
13578
|
-
</core_rules>
|
|
13579
|
-
|
|
13580
|
-
<phase_0 name="TRIAGE">
|
|
13581
|
-
Evaluate the complexity of the request:
|
|
13582
|
-
|
|
13583
|
-
| Level | Signal | Track |
|
|
13584
|
-
|-------|--------|-------|
|
|
13585
|
-
| \u{1F7E2} L1: Simple | One file, clear fix, no dependencies | **FAST TRACK** |
|
|
13586
|
-
| \u{1F7E1} L2: Feature | New functionality, clear patterns | **NORMAL TRACK** |
|
|
13587
|
-
| \u{1F534} L3: Complex | Refactoring, infra change, unknown scope | **DEEP TRACK** |
|
|
13588
|
-
</phase_0>
|
|
13589
|
-
|
|
13590
|
-
<anti_hallucination>
|
|
13591
|
-
CRITICAL: ELIMINATE GUESSING. VERIFY EVERYTHING.
|
|
13592
|
-
|
|
13593
|
-
BEFORE ANY IMPLEMENTATION:
|
|
13594
|
-
1. If using unfamiliar API/library \u2192 RESEARCH FIRST
|
|
13595
|
-
2. If uncertain about patterns/syntax \u2192 SEARCH DOCUMENTATION
|
|
13596
|
-
3. NEVER assume - always verify from official sources
|
|
13597
|
-
|
|
13598
|
-
RESEARCH WORKFLOW:
|
|
13599
|
-
\`\`\`
|
|
13600
|
-
// Step 1: Search for documentation
|
|
13601
|
-
websearch({ query: "Next.js 14 app router official docs" })
|
|
13602
|
-
|
|
13603
|
-
// Step 2: Fetch specific documentation
|
|
13604
|
-
webfetch({ url: "https://nextjs.org/docs/app/..." })
|
|
13605
|
-
|
|
13606
|
-
// Step 3: Check cached docs
|
|
13607
|
-
cache_docs({ action: "list" })
|
|
13608
|
-
|
|
13609
|
-
// Step 4: For complex research, delegate to Librarian
|
|
13610
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13611
|
-
agent: "${AGENT_NAMES.LIBRARIAN}",
|
|
13612
|
-
description: "Research X API",
|
|
13613
|
-
prompt: "Find official documentation for...",
|
|
13614
|
-
background: false // Wait for research before implementing
|
|
13615
|
-
})
|
|
13616
|
-
\`\`\`
|
|
13617
|
-
|
|
13618
|
-
MANDATORY RESEARCH TRIGGERS:
|
|
13619
|
-
- New library/framework you haven't used in this session
|
|
13620
|
-
- API syntax you're not 100% sure about
|
|
13621
|
-
- Version-specific features (check version compatibility!)
|
|
13622
|
-
- Configuration patterns (check official examples)
|
|
13623
|
-
|
|
13624
|
-
WHEN CAUGHT GUESSING:
|
|
13625
|
-
1. STOP immediately
|
|
13626
|
-
2. Search for official documentation
|
|
13627
|
-
3. Cache important findings: webfetch({ url: "...", cache: true })
|
|
13628
|
-
4. Then proceed with verified information
|
|
13629
|
-
</anti_hallucination>
|
|
13630
|
-
|
|
13631
|
-
<phase_1 name="CONTEXT_GATHERING">
|
|
13632
|
-
IF FAST TRACK (L1):
|
|
13633
|
-
- Scan ONLY the target file and its immediate imports.
|
|
13634
|
-
- Skip broad infra/domain/doc scans unless an error occurs.
|
|
13635
|
-
- Proceed directly to execution.
|
|
13636
|
-
|
|
13637
|
-
IF NORMAL/DEEP TRACK (L2/L3):
|
|
13638
|
-
- **Deep Scan Required**: Execute the full "MANDATORY ENVIRONMENT SCAN".
|
|
13639
|
-
- 1. Infra check (Docker/OS)
|
|
13640
|
-
- 2. Domain & Stack check
|
|
13641
|
-
- 3. Pattern check
|
|
13506
|
+
var TASK_TRIGGER_TEMPLATE = `<mission_mode>
|
|
13507
|
+
You are now in MISSION MODE. Execute the following task autonomously until complete.
|
|
13642
13508
|
|
|
13643
|
-
|
|
13644
|
-
</phase_1>
|
|
13645
|
-
|
|
13646
|
-
<phase_2 name="TOOL_AGENT_SELECTION">
|
|
13647
|
-
| Track | Strategy |
|
|
13648
|
-
|-------|----------|
|
|
13649
|
-
| Fast | Use \`${AGENT_NAMES.BUILDER}\` directly. Skip \`${AGENT_NAMES.ARCHITECT}\`. |
|
|
13650
|
-
| Normal | Call \`${AGENT_NAMES.ARCHITECT}\` for lightweight plan. |
|
|
13651
|
-
| Deep | Full \`${AGENT_NAMES.ARCHITECT}\` DAG + \`${AGENT_NAMES.RECORDER}\` state tracking. |
|
|
13652
|
-
|
|
13653
|
-
AVAILABLE AGENTS:
|
|
13654
|
-
- \`${AGENT_NAMES.ARCHITECT}\`: Task decomposition and planning
|
|
13655
|
-
- \`${AGENT_NAMES.BUILDER}\`: Code implementation
|
|
13656
|
-
- \`${AGENT_NAMES.INSPECTOR}\`: Verification and bug fixing
|
|
13657
|
-
- \`${AGENT_NAMES.RECORDER}\`: State tracking (Deep Track only)
|
|
13658
|
-
- \`${AGENT_NAMES.LIBRARIAN}\`: Documentation research (Anti-Hallucination) \u2B50 NEW
|
|
13659
|
-
|
|
13660
|
-
WHEN TO USE LIBRARIAN:
|
|
13661
|
-
- Before using new APIs/libraries
|
|
13662
|
-
- When error messages are unclear
|
|
13663
|
-
- When implementing complex integrations
|
|
13664
|
-
- When official documentation is needed
|
|
13665
|
-
|
|
13666
|
-
DEFAULT to Deep Track if unsure to act safely.
|
|
13667
|
-
</phase_2>
|
|
13668
|
-
|
|
13669
|
-
<phase_3 name="DELEGATION">
|
|
13670
|
-
<agent_calling>
|
|
13671
|
-
CRITICAL: USE ${TOOL_NAMES.DELEGATE_TASK} FOR ALL DELEGATION
|
|
13672
|
-
|
|
13673
|
-
${TOOL_NAMES.DELEGATE_TASK} has THREE MODES:
|
|
13674
|
-
- background=true: Non-blocking, parallel execution
|
|
13675
|
-
- background=false: Blocking, waits for result
|
|
13676
|
-
- resume: Continue existing session
|
|
13677
|
-
|
|
13678
|
-
| Situation | How to Call |
|
|
13679
|
-
|-----------|-------------|
|
|
13680
|
-
| Multiple independent tasks | \`${TOOL_NAMES.DELEGATE_TASK}({ ..., background: true })\` for each |
|
|
13681
|
-
| Single task, continue working | \`${TOOL_NAMES.DELEGATE_TASK}({ ..., background: true })\` |
|
|
13682
|
-
| Need result for VERY next step | \`${TOOL_NAMES.DELEGATE_TASK}({ ..., background: false })\` |
|
|
13683
|
-
| Retry after failure | \`${TOOL_NAMES.DELEGATE_TASK}({ ..., resume: "session_id", ... })\` |
|
|
13684
|
-
| Follow-up question | \`${TOOL_NAMES.DELEGATE_TASK}({ ..., resume: "session_id", ... })\` |
|
|
13685
|
-
|
|
13686
|
-
PREFER background=true (PARALLEL):
|
|
13687
|
-
- Run multiple agents simultaneously
|
|
13688
|
-
- Continue analysis while they work
|
|
13689
|
-
- System notifies when ALL complete
|
|
13690
|
-
|
|
13691
|
-
EXAMPLE - PARALLEL:
|
|
13692
|
-
\`\`\`
|
|
13693
|
-
// Multiple tasks in parallel
|
|
13694
|
-
${TOOL_NAMES.DELEGATE_TASK}({ agent: "${AGENT_NAMES.BUILDER}", description: "Implement X", prompt: "...", background: true })
|
|
13695
|
-
${TOOL_NAMES.DELEGATE_TASK}({ agent: "${AGENT_NAMES.INSPECTOR}", description: "Review Y", prompt: "...", background: true })
|
|
13696
|
-
|
|
13697
|
-
// Continue other work (don't wait!)
|
|
13698
|
-
|
|
13699
|
-
// When notified "All Complete":
|
|
13700
|
-
${TOOL_NAMES.GET_TASK_RESULT}({ taskId: "${ID_PREFIX.TASK}xxx" })
|
|
13701
|
-
\`\`\`
|
|
13702
|
-
|
|
13703
|
-
EXAMPLE - SYNC (rare):
|
|
13704
|
-
\`\`\`
|
|
13705
|
-
// Only when you absolutely need the result now
|
|
13706
|
-
const result = ${TOOL_NAMES.DELEGATE_TASK}({ agent: "${AGENT_NAMES.BUILDER}", ..., background: false })
|
|
13707
|
-
// Result is immediately available
|
|
13708
|
-
\`\`\`
|
|
13709
|
-
|
|
13710
|
-
EXAMPLE - RESUME (for retry or follow-up):
|
|
13711
|
-
\`\`\`
|
|
13712
|
-
// Previous task output shows: Session: \`${ID_PREFIX.SESSION}abc123\` (save for resume)
|
|
13713
|
-
|
|
13714
|
-
// Retry after failure (keeps all context!)
|
|
13715
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13716
|
-
agent: "${AGENT_NAMES.BUILDER}",
|
|
13717
|
-
description: "Fix previous error",
|
|
13718
|
-
prompt: "The build failed with X. Please fix it.",
|
|
13719
|
-
background: true,
|
|
13720
|
-
resume: "${ID_PREFIX.SESSION}abc123" // \u2190 Continue existing session
|
|
13721
|
-
})
|
|
13722
|
-
|
|
13723
|
-
// Follow-up question (saves tokens!)
|
|
13724
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13725
|
-
agent: "${AGENT_NAMES.INSPECTOR}",
|
|
13726
|
-
description: "Additional check",
|
|
13727
|
-
prompt: "Also check for Y in the files you just reviewed.",
|
|
13728
|
-
background: true,
|
|
13729
|
-
resume: "${ID_PREFIX.SESSION}xyz789"
|
|
13730
|
-
})
|
|
13731
|
-
\`\`\`
|
|
13732
|
-
</agent_calling>
|
|
13733
|
-
|
|
13734
|
-
<delegation_template>
|
|
13735
|
-
AGENT: [name]
|
|
13736
|
-
TASK: [one atomic action]
|
|
13737
|
-
ENVIRONMENT:
|
|
13738
|
-
- Infra: [e.g. Docker + Volume mount]
|
|
13739
|
-
- Stack: [e.g. Next.js + PostgreSQL]
|
|
13740
|
-
- Patterns: [existing code conventions to follow]
|
|
13741
|
-
MUST: [Specific requirements]
|
|
13742
|
-
AVOID: [Restrictions]
|
|
13743
|
-
VERIFY: [Success criteria with evidence]
|
|
13744
|
-
</delegation_template>
|
|
13745
|
-
</phase_3>
|
|
13746
|
-
|
|
13747
|
-
<phase_4 name="EXECUTION_VERIFICATION">
|
|
13748
|
-
During implementation:
|
|
13749
|
-
- Match existing codebase style exactly
|
|
13750
|
-
- Run lsp_diagnostics after each change
|
|
13751
|
-
|
|
13752
|
-
<background_parallel_execution>
|
|
13753
|
-
PARALLEL EXECUTION SYSTEM:
|
|
13754
|
-
|
|
13755
|
-
You have access to a powerful parallel agent execution system.
|
|
13756
|
-
Up to 50 agents can run simultaneously with automatic resource management.
|
|
13757
|
-
|
|
13758
|
-
1. **${TOOL_NAMES.DELEGATE_TASK}** - Launch agents in parallel or sync mode
|
|
13759
|
-
\`\`\`
|
|
13760
|
-
// PARALLEL (recommended - non-blocking)
|
|
13761
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13762
|
-
agent: "${AGENT_NAMES.BUILDER}",
|
|
13763
|
-
description: "Implement X",
|
|
13764
|
-
prompt: "...",
|
|
13765
|
-
background: true
|
|
13766
|
-
})
|
|
13767
|
-
|
|
13768
|
-
// SYNC (blocking - wait for result)
|
|
13769
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13770
|
-
agent: "${AGENT_NAMES.LIBRARIAN}",
|
|
13771
|
-
description: "Research Y",
|
|
13772
|
-
prompt: "...",
|
|
13773
|
-
background: false
|
|
13774
|
-
})
|
|
13775
|
-
|
|
13776
|
-
// RESUME (continue previous session)
|
|
13777
|
-
${TOOL_NAMES.DELEGATE_TASK}({
|
|
13778
|
-
agent: "${AGENT_NAMES.BUILDER}",
|
|
13779
|
-
description: "Fix error",
|
|
13780
|
-
prompt: "...",
|
|
13781
|
-
background: true,
|
|
13782
|
-
resume: "${ID_PREFIX.SESSION}abc123" // From previous task output
|
|
13783
|
-
})
|
|
13784
|
-
\`\`\`
|
|
13785
|
-
|
|
13786
|
-
2. **${TOOL_NAMES.GET_TASK_RESULT}** - Retrieve completed task output
|
|
13787
|
-
\`\`\`
|
|
13788
|
-
${TOOL_NAMES.GET_TASK_RESULT}({ taskId: "${ID_PREFIX.TASK}xxx" })
|
|
13789
|
-
\`\`\`
|
|
13790
|
-
|
|
13791
|
-
3. **${TOOL_NAMES.LIST_TASKS}** - View all parallel tasks
|
|
13792
|
-
\`\`\`
|
|
13793
|
-
${TOOL_NAMES.LIST_TASKS}({})
|
|
13794
|
-
\`\`\`
|
|
13795
|
-
|
|
13796
|
-
4. **${TOOL_NAMES.CANCEL_TASK}** - Stop a running task
|
|
13797
|
-
\`\`\`
|
|
13798
|
-
${TOOL_NAMES.CANCEL_TASK}({ taskId: "${ID_PREFIX.TASK}xxx" })
|
|
13799
|
-
\`\`\`
|
|
13800
|
-
|
|
13801
|
-
CONCURRENCY LIMITS:
|
|
13802
|
-
- Max 10 tasks per agent type (queue automatically)
|
|
13803
|
-
- Max 50 total parallel sessions
|
|
13804
|
-
- Auto-timeout: 60 minutes
|
|
13805
|
-
- Auto-cleanup: 30 min after completion \u2192 archived to disk
|
|
13806
|
-
|
|
13807
|
-
SAFE PATTERNS:
|
|
13808
|
-
\u2705 Builder on file A + Inspector on file B (different files)
|
|
13809
|
-
\u2705 Multiple research agents (read-only)
|
|
13810
|
-
\u2705 Build command + Test command (independent)
|
|
13811
|
-
\u2705 Librarian research + Builder implementation (sequential deps)
|
|
13812
|
-
|
|
13813
|
-
UNSAFE PATTERNS:
|
|
13814
|
-
\u274C Multiple builders editing SAME FILE (conflict!)
|
|
13815
|
-
\u274C Waiting synchronously for many tasks (use background=true)
|
|
13816
|
-
|
|
13817
|
-
WORKFLOW:
|
|
13818
|
-
1. ${TOOL_NAMES.LIST_TASKS}: Check current status first
|
|
13819
|
-
2. ${TOOL_NAMES.DELEGATE_TASK} (background=true): Launch for INDEPENDENT tasks
|
|
13820
|
-
3. Continue working (NO WAITING)
|
|
13821
|
-
4. Wait for system notification "All Parallel Tasks Complete"
|
|
13822
|
-
5. ${TOOL_NAMES.GET_TASK_RESULT}: Retrieve each result
|
|
13823
|
-
</background_parallel_execution>
|
|
13824
|
-
|
|
13825
|
-
<verification_methods>
|
|
13826
|
-
| Infra | Proof Method |
|
|
13827
|
-
|-------|--------------|
|
|
13828
|
-
| OS-Native | npm run build, cargo build, specific test runs |
|
|
13829
|
-
| Container | Docker syntax check + config validation |
|
|
13830
|
-
| Live API | curl /health if reachable, check logs |
|
|
13831
|
-
| Generic | Manual audit by Inspector with logic summary |
|
|
13832
|
-
</verification_methods>
|
|
13833
|
-
</phase_4>
|
|
13834
|
-
|
|
13835
|
-
<failure_recovery>
|
|
13836
|
-
| Failures | Action |
|
|
13837
|
-
|----------|--------|
|
|
13838
|
-
| 1-2 | Adjust approach, retry |
|
|
13839
|
-
| 3+ | STOP. Call ${AGENT_NAMES.ARCHITECT} for new strategy |
|
|
13840
|
-
|
|
13841
|
-
<empty_responses>
|
|
13842
|
-
| Agent Empty (or Gibberish) | Action |
|
|
13843
|
-
|----------------------------|--------|
|
|
13844
|
-
| ${AGENT_NAMES.RECORDER} | Fresh start. Proceed to survey. |
|
|
13845
|
-
| ${AGENT_NAMES.ARCHITECT} | Try simpler plan yourself. |
|
|
13846
|
-
| ${AGENT_NAMES.BUILDER} | Call ${AGENT_NAMES.INSPECTOR} to diagnose. |
|
|
13847
|
-
| ${AGENT_NAMES.INSPECTOR} | Retry with more context. |
|
|
13848
|
-
</empty_responses>
|
|
13849
|
-
|
|
13850
|
-
STRICT RULE: If any agent output contains gibberish, mixed-language hallucinations, or fails the language rule, REJECT it immediately and trigger a "STRICT_CLEAN_START" retry.
|
|
13851
|
-
</failure_recovery>
|
|
13852
|
-
|
|
13853
|
-
<anti_patterns>
|
|
13854
|
-
\u274C Delegate without environment/codebase context
|
|
13855
|
-
\u274C Leave code broken or with LSP errors
|
|
13856
|
-
\u274C Make random changes without understanding root cause
|
|
13857
|
-
</anti_patterns>
|
|
13858
|
-
|
|
13859
|
-
<completion>
|
|
13860
|
-
Done when: Request fulfilled + lsp clean + build/test/audit pass.
|
|
13861
|
-
|
|
13862
|
-
<output_format>
|
|
13863
|
-
${MISSION.COMPLETE}
|
|
13864
|
-
Summary: [what was done]
|
|
13865
|
-
Evidence: [Specific build/test/audit results]
|
|
13866
|
-
</output_format>
|
|
13867
|
-
</completion>
|
|
13868
|
-
|
|
13869
|
-
<mission>
|
|
13509
|
+
<task>
|
|
13870
13510
|
$ARGUMENTS
|
|
13871
|
-
</
|
|
13511
|
+
</task>
|
|
13512
|
+
|
|
13513
|
+
<execution_rules>
|
|
13514
|
+
1. Complete this mission without user intervention
|
|
13515
|
+
2. Use your full capabilities: research, implement, verify
|
|
13516
|
+
3. Output "${MISSION.COMPLETE}" when done
|
|
13517
|
+
</execution_rules>
|
|
13518
|
+
</mission_mode>`;
|
|
13872
13519
|
var COMMANDS = {
|
|
13873
13520
|
"task": {
|
|
13874
|
-
description: "\u{1F680}
|
|
13875
|
-
template:
|
|
13521
|
+
description: "\u{1F680} MISSION MODE - Execute task autonomously until complete",
|
|
13522
|
+
template: TASK_TRIGGER_TEMPLATE,
|
|
13876
13523
|
argumentHint: '"mission goal"'
|
|
13877
13524
|
},
|
|
13878
13525
|
"plan": {
|
|
13879
|
-
description: "Create a
|
|
13526
|
+
description: "Create a task plan without executing",
|
|
13880
13527
|
template: `<delegate>
|
|
13881
13528
|
<agent>${AGENT_NAMES.ARCHITECT}</agent>
|
|
13882
|
-
<objective>Create parallel task
|
|
13529
|
+
<objective>Create parallel task plan for: $ARGUMENTS</objective>
|
|
13883
13530
|
<success>Valid JSON with tasks array, each having id, description, agent, parallel_group, dependencies, and success criteria</success>
|
|
13884
13531
|
<must_do>
|
|
13885
13532
|
- Maximize parallelism by grouping independent tasks
|
|
@@ -13904,7 +13551,7 @@ var COMMANDS = {
|
|
|
13904
13551
|
| Agent | Role | Responsibility |
|
|
13905
13552
|
|-------|------|----------------|
|
|
13906
13553
|
| Commander | Orchestrator | Relentless parallel execution until mission complete |
|
|
13907
|
-
| ${AGENT_NAMES.ARCHITECT} | Planner | Decomposes complex tasks into parallel
|
|
13554
|
+
| ${AGENT_NAMES.ARCHITECT} | Planner | Decomposes complex tasks into parallel subtasks |
|
|
13908
13555
|
| ${AGENT_NAMES.BUILDER} | Developer | Full-stack implementation (logic + UI combined) |
|
|
13909
13556
|
| ${AGENT_NAMES.INSPECTOR} | Quality | 5-point audit + automatic bug fixing |
|
|
13910
13557
|
| ${AGENT_NAMES.RECORDER} | Context | Persistent progress tracking across sessions |
|
|
@@ -13921,7 +13568,8 @@ THINK \u2192 ACT \u2192 OBSERVE \u2192 ADJUST \u2192 REPEAT
|
|
|
13921
13568
|
- Auto-fix: Inspector repairs problems automatically
|
|
13922
13569
|
|
|
13923
13570
|
## Usage
|
|
13924
|
-
|
|
13571
|
+
- Just select Commander agent and type your request
|
|
13572
|
+
- Or use \`/task "goal"\` for explicit mission mode`
|
|
13925
13573
|
}
|
|
13926
13574
|
};
|
|
13927
13575
|
function createSlashcommandTool() {
|
|
@@ -13961,19 +13609,19 @@ import { existsSync } from "fs";
|
|
|
13961
13609
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13962
13610
|
function getBinaryPath() {
|
|
13963
13611
|
const binDir = join(__dirname, "..", "..", "bin");
|
|
13964
|
-
const
|
|
13612
|
+
const os2 = platform();
|
|
13965
13613
|
const cpu = arch();
|
|
13966
13614
|
let binaryName;
|
|
13967
|
-
if (
|
|
13615
|
+
if (os2 === "win32") {
|
|
13968
13616
|
binaryName = "orchestrator-windows-x64.exe";
|
|
13969
|
-
} else if (
|
|
13617
|
+
} else if (os2 === "darwin") {
|
|
13970
13618
|
binaryName = cpu === "arm64" ? "orchestrator-macos-arm64" : "orchestrator-macos-x64";
|
|
13971
13619
|
} else {
|
|
13972
13620
|
binaryName = cpu === "arm64" ? "orchestrator-linux-arm64" : "orchestrator-linux-x64";
|
|
13973
13621
|
}
|
|
13974
13622
|
let binaryPath = join(binDir, binaryName);
|
|
13975
13623
|
if (!existsSync(binaryPath)) {
|
|
13976
|
-
binaryPath = join(binDir,
|
|
13624
|
+
binaryPath = join(binDir, os2 === "win32" ? "orchestrator.exe" : "orchestrator");
|
|
13977
13625
|
}
|
|
13978
13626
|
return binaryPath;
|
|
13979
13627
|
}
|
|
@@ -14600,10 +14248,25 @@ var TaskStore = class {
|
|
|
14600
14248
|
};
|
|
14601
14249
|
|
|
14602
14250
|
// src/core/agents/logger.ts
|
|
14251
|
+
import * as fs2 from "fs";
|
|
14252
|
+
import * as os from "os";
|
|
14253
|
+
import * as path2 from "path";
|
|
14603
14254
|
var DEBUG2 = process.env.DEBUG_PARALLEL_AGENT === "true";
|
|
14255
|
+
var LOG_FILE = path2.join(os.tmpdir(), "opencode-orchestrator.log");
|
|
14604
14256
|
function log2(...args) {
|
|
14257
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
14258
|
+
const message = `[${timestamp}] [parallel-agent] ${args.map(
|
|
14259
|
+
(a) => typeof a === "object" ? JSON.stringify(a) : String(a)
|
|
14260
|
+
).join(" ")}`;
|
|
14261
|
+
try {
|
|
14262
|
+
fs2.appendFileSync(LOG_FILE, message + "\n");
|
|
14263
|
+
} catch {
|
|
14264
|
+
}
|
|
14605
14265
|
if (DEBUG2) console.log("[parallel-agent]", ...args);
|
|
14606
14266
|
}
|
|
14267
|
+
function getLogPath() {
|
|
14268
|
+
return LOG_FILE;
|
|
14269
|
+
}
|
|
14607
14270
|
|
|
14608
14271
|
// src/core/agents/format.ts
|
|
14609
14272
|
function formatDuration(start, end) {
|
|
@@ -14638,8 +14301,10 @@ var TaskLauncher = class {
|
|
|
14638
14301
|
this.startPolling = startPolling;
|
|
14639
14302
|
}
|
|
14640
14303
|
async launch(input) {
|
|
14304
|
+
log2("[task-launcher.ts] launch() called", { agent: input.agent, description: input.description, parent: input.parentSessionID });
|
|
14641
14305
|
const concurrencyKey = input.agent;
|
|
14642
14306
|
await this.concurrency.acquire(concurrencyKey);
|
|
14307
|
+
log2("[task-launcher.ts] concurrency acquired for", concurrencyKey);
|
|
14643
14308
|
try {
|
|
14644
14309
|
const createResult = await this.client.session.create({
|
|
14645
14310
|
body: { parentID: input.parentSessionID, title: `Parallel: ${input.description}` },
|
|
@@ -14651,6 +14316,8 @@ var TaskLauncher = class {
|
|
|
14651
14316
|
}
|
|
14652
14317
|
const sessionID = createResult.data.id;
|
|
14653
14318
|
const taskId = `${ID_PREFIX.TASK}${crypto.randomUUID().slice(0, 8)}`;
|
|
14319
|
+
const depth = (input.depth ?? 0) + 1;
|
|
14320
|
+
log2("[task-launcher.ts] Creating task with depth", depth);
|
|
14654
14321
|
const task = {
|
|
14655
14322
|
id: taskId,
|
|
14656
14323
|
sessionID,
|
|
@@ -14660,14 +14327,25 @@ var TaskLauncher = class {
|
|
|
14660
14327
|
agent: input.agent,
|
|
14661
14328
|
status: TASK_STATUS.RUNNING,
|
|
14662
14329
|
startedAt: /* @__PURE__ */ new Date(),
|
|
14663
|
-
concurrencyKey
|
|
14330
|
+
concurrencyKey,
|
|
14331
|
+
depth
|
|
14664
14332
|
};
|
|
14665
14333
|
this.store.set(taskId, task);
|
|
14666
14334
|
this.store.trackPending(input.parentSessionID, taskId);
|
|
14667
14335
|
this.startPolling();
|
|
14668
14336
|
this.client.session.prompt({
|
|
14669
14337
|
path: { id: sessionID },
|
|
14670
|
-
body: {
|
|
14338
|
+
body: {
|
|
14339
|
+
agent: input.agent,
|
|
14340
|
+
tools: {
|
|
14341
|
+
// Prevent recursive task spawning from subagents
|
|
14342
|
+
delegate_task: false,
|
|
14343
|
+
get_task_result: false,
|
|
14344
|
+
list_tasks: false,
|
|
14345
|
+
cancel_task: false
|
|
14346
|
+
},
|
|
14347
|
+
parts: [{ type: PART_TYPES.TEXT, text: input.prompt }]
|
|
14348
|
+
}
|
|
14671
14349
|
}).catch((error45) => {
|
|
14672
14350
|
log2(`Prompt error for ${taskId}:`, error45);
|
|
14673
14351
|
this.onTaskError(taskId, error45);
|
|
@@ -14746,6 +14424,7 @@ var TaskPoller = class {
|
|
|
14746
14424
|
pollingInterval;
|
|
14747
14425
|
start() {
|
|
14748
14426
|
if (this.pollingInterval) return;
|
|
14427
|
+
log2("[task-poller.ts] start() - polling started");
|
|
14749
14428
|
this.pollingInterval = setInterval(() => this.poll(), CONFIG.POLL_INTERVAL_MS);
|
|
14750
14429
|
this.pollingInterval.unref();
|
|
14751
14430
|
}
|
|
@@ -14765,6 +14444,7 @@ var TaskPoller = class {
|
|
|
14765
14444
|
this.stop();
|
|
14766
14445
|
return;
|
|
14767
14446
|
}
|
|
14447
|
+
log2("[task-poller.ts] poll() checking", running.length, "running tasks");
|
|
14768
14448
|
try {
|
|
14769
14449
|
const statusResult = await this.client.session.status();
|
|
14770
14450
|
const allStatuses = statusResult.data ?? {};
|
|
@@ -14804,6 +14484,7 @@ var TaskPoller = class {
|
|
|
14804
14484
|
}
|
|
14805
14485
|
}
|
|
14806
14486
|
async completeTask(task) {
|
|
14487
|
+
log2("[task-poller.ts] completeTask() called for", task.id, task.agent);
|
|
14807
14488
|
task.status = TASK_STATUS.COMPLETED;
|
|
14808
14489
|
task.completedAt = /* @__PURE__ */ new Date();
|
|
14809
14490
|
if (task.concurrencyKey) {
|
|
@@ -15348,6 +15029,7 @@ var createDelegateTaskTool = (manager, client) => tool({
|
|
|
15348
15029
|
async execute(args, context) {
|
|
15349
15030
|
const { agent, description, prompt, background, resume } = args;
|
|
15350
15031
|
const ctx = context;
|
|
15032
|
+
log2("[delegate-task.ts] execute() called", { agent, description, background, resume, parentSession: ctx.sessionID });
|
|
15351
15033
|
const sessionClient = client;
|
|
15352
15034
|
if (background === void 0) {
|
|
15353
15035
|
return `\u274C 'background' parameter is REQUIRED.`;
|
|
@@ -15423,7 +15105,16 @@ Session: \`${task.sessionID}\` (save for resume)`;
|
|
|
15423
15105
|
const startTime = Date.now();
|
|
15424
15106
|
await session.prompt({
|
|
15425
15107
|
path: { id: sessionID },
|
|
15426
|
-
body: {
|
|
15108
|
+
body: {
|
|
15109
|
+
agent,
|
|
15110
|
+
tools: {
|
|
15111
|
+
delegate_task: false,
|
|
15112
|
+
get_task_result: false,
|
|
15113
|
+
list_tasks: false,
|
|
15114
|
+
cancel_task: false
|
|
15115
|
+
},
|
|
15116
|
+
parts: [{ type: PART_TYPES.TEXT, text: prompt }]
|
|
15117
|
+
}
|
|
15427
15118
|
});
|
|
15428
15119
|
let stablePolls = 0, lastMsgCount = 0;
|
|
15429
15120
|
while (Date.now() - startTime < 10 * 60 * 1e3) {
|
|
@@ -15677,15 +15368,15 @@ var METADATA_FILE = ".cache/docs/_metadata.json";
|
|
|
15677
15368
|
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15678
15369
|
|
|
15679
15370
|
// src/core/cache/operations.ts
|
|
15680
|
-
import * as
|
|
15681
|
-
import * as
|
|
15371
|
+
import * as fs4 from "node:fs/promises";
|
|
15372
|
+
import * as path3 from "node:path";
|
|
15682
15373
|
|
|
15683
15374
|
// src/core/cache/utils.ts
|
|
15684
|
-
import * as
|
|
15375
|
+
import * as fs3 from "node:fs/promises";
|
|
15685
15376
|
import { existsSync as existsSync3 } from "node:fs";
|
|
15686
15377
|
async function ensureCacheDir() {
|
|
15687
15378
|
if (!existsSync3(CACHE_DIR)) {
|
|
15688
|
-
await
|
|
15379
|
+
await fs3.mkdir(CACHE_DIR, { recursive: true });
|
|
15689
15380
|
}
|
|
15690
15381
|
}
|
|
15691
15382
|
function urlToFilename(url2) {
|
|
@@ -15700,7 +15391,7 @@ function urlToFilename(url2) {
|
|
|
15700
15391
|
}
|
|
15701
15392
|
async function readMetadata() {
|
|
15702
15393
|
try {
|
|
15703
|
-
const content = await
|
|
15394
|
+
const content = await fs3.readFile(METADATA_FILE, "utf-8");
|
|
15704
15395
|
return JSON.parse(content);
|
|
15705
15396
|
} catch {
|
|
15706
15397
|
return { documents: {}, lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
@@ -15709,7 +15400,7 @@ async function readMetadata() {
|
|
|
15709
15400
|
async function writeMetadata(metadata) {
|
|
15710
15401
|
await ensureCacheDir();
|
|
15711
15402
|
metadata.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
15712
|
-
await
|
|
15403
|
+
await fs3.writeFile(METADATA_FILE, JSON.stringify(metadata, null, 2));
|
|
15713
15404
|
}
|
|
15714
15405
|
|
|
15715
15406
|
// src/core/cache/operations.ts
|
|
@@ -15723,8 +15414,8 @@ async function get(url2) {
|
|
|
15723
15414
|
return null;
|
|
15724
15415
|
}
|
|
15725
15416
|
try {
|
|
15726
|
-
const filepath =
|
|
15727
|
-
const content = await
|
|
15417
|
+
const filepath = path3.join(CACHE_DIR, filename);
|
|
15418
|
+
const content = await fs4.readFile(filepath, "utf-8");
|
|
15728
15419
|
return { ...entry, content };
|
|
15729
15420
|
} catch {
|
|
15730
15421
|
return null;
|
|
@@ -15735,8 +15426,8 @@ async function getByFilename(filename) {
|
|
|
15735
15426
|
const entry = metadata.documents[filename];
|
|
15736
15427
|
if (!entry) return null;
|
|
15737
15428
|
try {
|
|
15738
|
-
const filepath =
|
|
15739
|
-
const content = await
|
|
15429
|
+
const filepath = path3.join(CACHE_DIR, filename);
|
|
15430
|
+
const content = await fs4.readFile(filepath, "utf-8");
|
|
15740
15431
|
return { ...entry, content };
|
|
15741
15432
|
} catch {
|
|
15742
15433
|
return null;
|
|
@@ -15745,7 +15436,7 @@ async function getByFilename(filename) {
|
|
|
15745
15436
|
async function set2(url2, content, title, ttlMs = DEFAULT_TTL_MS) {
|
|
15746
15437
|
await ensureCacheDir();
|
|
15747
15438
|
const filename = urlToFilename(url2);
|
|
15748
|
-
const filepath =
|
|
15439
|
+
const filepath = path3.join(CACHE_DIR, filename);
|
|
15749
15440
|
const now = /* @__PURE__ */ new Date();
|
|
15750
15441
|
const header = `# ${title}
|
|
15751
15442
|
|
|
@@ -15756,7 +15447,7 @@ async function set2(url2, content, title, ttlMs = DEFAULT_TTL_MS) {
|
|
|
15756
15447
|
|
|
15757
15448
|
`;
|
|
15758
15449
|
const fullContent = header + content;
|
|
15759
|
-
await
|
|
15450
|
+
await fs4.writeFile(filepath, fullContent);
|
|
15760
15451
|
const metadata = await readMetadata();
|
|
15761
15452
|
metadata.documents[filename] = {
|
|
15762
15453
|
url: url2,
|
|
@@ -15770,9 +15461,9 @@ async function set2(url2, content, title, ttlMs = DEFAULT_TTL_MS) {
|
|
|
15770
15461
|
}
|
|
15771
15462
|
async function remove(url2) {
|
|
15772
15463
|
const filename = urlToFilename(url2);
|
|
15773
|
-
const filepath =
|
|
15464
|
+
const filepath = path3.join(CACHE_DIR, filename);
|
|
15774
15465
|
try {
|
|
15775
|
-
await
|
|
15466
|
+
await fs4.unlink(filepath);
|
|
15776
15467
|
const metadata = await readMetadata();
|
|
15777
15468
|
delete metadata.documents[filename];
|
|
15778
15469
|
await writeMetadata(metadata);
|
|
@@ -15794,9 +15485,9 @@ async function clear() {
|
|
|
15794
15485
|
const metadata = await readMetadata();
|
|
15795
15486
|
const count = Object.keys(metadata.documents).length;
|
|
15796
15487
|
for (const filename of Object.keys(metadata.documents)) {
|
|
15797
|
-
const filepath =
|
|
15488
|
+
const filepath = path3.join(CACHE_DIR, filename);
|
|
15798
15489
|
try {
|
|
15799
|
-
await
|
|
15490
|
+
await fs4.unlink(filepath);
|
|
15800
15491
|
} catch {
|
|
15801
15492
|
}
|
|
15802
15493
|
}
|
|
@@ -16686,11 +16377,14 @@ Then output: \u2705 MISSION COMPLETE
|
|
|
16686
16377
|
var OrchestratorPlugin = async (input) => {
|
|
16687
16378
|
const { directory, client } = input;
|
|
16688
16379
|
console.log(`[orchestrator] v${PLUGIN_VERSION} loaded`);
|
|
16380
|
+
console.log(`[orchestrator] Log file: ${getLogPath()}`);
|
|
16381
|
+
log2("[index.ts] Plugin initialized", { version: PLUGIN_VERSION, directory });
|
|
16689
16382
|
const disableAutoToasts = enableAutoToasts();
|
|
16690
|
-
|
|
16383
|
+
log2("[index.ts] Toast notifications enabled");
|
|
16691
16384
|
const sessions = /* @__PURE__ */ new Map();
|
|
16692
16385
|
const parallelAgentManager2 = ParallelAgentManager.getInstance(client, directory);
|
|
16693
16386
|
const asyncAgentTools = createAsyncAgentTools(parallelAgentManager2, client);
|
|
16387
|
+
log2("[index.ts] ParallelAgentManager initialized");
|
|
16694
16388
|
return {
|
|
16695
16389
|
// -----------------------------------------------------------------
|
|
16696
16390
|
// Tools we expose to the LLM
|
|
@@ -16729,35 +16423,85 @@ var OrchestratorPlugin = async (input) => {
|
|
|
16729
16423
|
argumentHint: cmd.argumentHint
|
|
16730
16424
|
};
|
|
16731
16425
|
}
|
|
16426
|
+
const commanderPrompt = AGENTS[AGENT_NAMES.COMMANDER]?.systemPrompt || "";
|
|
16427
|
+
console.log(`[orchestrator] Commander prompt length: ${commanderPrompt.length} chars`);
|
|
16732
16428
|
const orchestratorAgents = {
|
|
16429
|
+
// Primary agent - the main orchestrator
|
|
16733
16430
|
[AGENT_NAMES.COMMANDER]: {
|
|
16734
|
-
name: AGENT_NAMES.COMMANDER,
|
|
16735
16431
|
description: "Autonomous orchestrator - executes until mission complete",
|
|
16736
16432
|
mode: "primary",
|
|
16737
|
-
prompt:
|
|
16433
|
+
prompt: commanderPrompt,
|
|
16738
16434
|
maxTokens: 64e3,
|
|
16739
16435
|
thinking: { type: "enabled", budgetTokens: 32e3 },
|
|
16740
16436
|
color: "#FF6B6B"
|
|
16741
16437
|
},
|
|
16438
|
+
// Subagents - invoked by Commander via Task tool
|
|
16439
|
+
[AGENT_NAMES.ARCHITECT]: {
|
|
16440
|
+
description: "Task decomposition and planning specialist",
|
|
16441
|
+
mode: "subagent",
|
|
16442
|
+
hidden: true,
|
|
16443
|
+
// Only invoked programmatically
|
|
16444
|
+
prompt: AGENTS[AGENT_NAMES.ARCHITECT]?.systemPrompt || "",
|
|
16445
|
+
maxTokens: 32e3,
|
|
16446
|
+
color: "#9B59B6"
|
|
16447
|
+
},
|
|
16448
|
+
[AGENT_NAMES.BUILDER]: {
|
|
16449
|
+
description: "Full-stack code implementation",
|
|
16450
|
+
mode: "subagent",
|
|
16451
|
+
hidden: true,
|
|
16452
|
+
prompt: AGENTS[AGENT_NAMES.BUILDER]?.systemPrompt || "",
|
|
16453
|
+
maxTokens: 32e3,
|
|
16454
|
+
color: "#E67E22"
|
|
16455
|
+
},
|
|
16456
|
+
[AGENT_NAMES.INSPECTOR]: {
|
|
16457
|
+
description: "Quality verification and bug fixing",
|
|
16458
|
+
mode: "subagent",
|
|
16459
|
+
hidden: true,
|
|
16460
|
+
prompt: AGENTS[AGENT_NAMES.INSPECTOR]?.systemPrompt || "",
|
|
16461
|
+
maxTokens: 32e3,
|
|
16462
|
+
color: "#27AE60"
|
|
16463
|
+
},
|
|
16464
|
+
[AGENT_NAMES.RECORDER]: {
|
|
16465
|
+
description: "Persistent progress tracking across sessions",
|
|
16466
|
+
mode: "subagent",
|
|
16467
|
+
hidden: true,
|
|
16468
|
+
prompt: AGENTS[AGENT_NAMES.RECORDER]?.systemPrompt || "",
|
|
16469
|
+
maxTokens: 16e3,
|
|
16470
|
+
color: "#3498DB"
|
|
16471
|
+
},
|
|
16742
16472
|
[AGENT_NAMES.LIBRARIAN]: {
|
|
16743
|
-
name: AGENT_NAMES.LIBRARIAN,
|
|
16744
16473
|
description: "Documentation research specialist - reduces hallucination",
|
|
16745
16474
|
mode: "subagent",
|
|
16475
|
+
hidden: true,
|
|
16746
16476
|
prompt: AGENTS[AGENT_NAMES.LIBRARIAN]?.systemPrompt || "",
|
|
16747
16477
|
maxTokens: 16e3,
|
|
16748
16478
|
color: "#4ECDC4"
|
|
16749
16479
|
},
|
|
16750
16480
|
[AGENT_NAMES.RESEARCHER]: {
|
|
16751
|
-
name: AGENT_NAMES.RESEARCHER,
|
|
16752
16481
|
description: "Pre-task investigation - gathers all info before implementation",
|
|
16753
16482
|
mode: "subagent",
|
|
16483
|
+
hidden: true,
|
|
16754
16484
|
prompt: AGENTS[AGENT_NAMES.RESEARCHER]?.systemPrompt || "",
|
|
16755
16485
|
maxTokens: 16e3,
|
|
16756
16486
|
color: "#45B7D1"
|
|
16757
16487
|
}
|
|
16758
16488
|
};
|
|
16489
|
+
const processedExistingAgents = { ...existingAgents };
|
|
16490
|
+
if (processedExistingAgents.build) {
|
|
16491
|
+
processedExistingAgents.build = {
|
|
16492
|
+
...processedExistingAgents.build,
|
|
16493
|
+
mode: "subagent",
|
|
16494
|
+
hidden: true
|
|
16495
|
+
};
|
|
16496
|
+
}
|
|
16497
|
+
if (processedExistingAgents.plan) {
|
|
16498
|
+
processedExistingAgents.plan = {
|
|
16499
|
+
...processedExistingAgents.plan,
|
|
16500
|
+
mode: "subagent"
|
|
16501
|
+
};
|
|
16502
|
+
}
|
|
16759
16503
|
config2.command = { ...existingCommands, ...orchestratorCommands };
|
|
16760
|
-
config2.agent = { ...
|
|
16504
|
+
config2.agent = { ...processedExistingAgents, ...orchestratorAgents };
|
|
16761
16505
|
config2.default_agent = AGENT_NAMES.COMMANDER;
|
|
16762
16506
|
console.log(`[orchestrator] Registered agents: ${Object.keys(orchestratorAgents).join(", ")}`);
|
|
16763
16507
|
console.log(`[orchestrator] Default agent: ${AGENT_NAMES.COMMANDER}`);
|
|
@@ -16850,7 +16594,6 @@ Anomaly count: ${stateSession.anomalyCount}
|
|
|
16850
16594
|
const taskIdMatch = toolInput.arguments.task.match(/\[(TASK-\d+)\]/i);
|
|
16851
16595
|
if (taskIdMatch) {
|
|
16852
16596
|
stateSession.currentTask = taskIdMatch[1].toUpperCase();
|
|
16853
|
-
stateSession.graph?.updateTask(stateSession.currentTask, { status: TASK_STATUS.RUNNING });
|
|
16854
16597
|
}
|
|
16855
16598
|
const agentName = toolInput.arguments.agent;
|
|
16856
16599
|
const emoji3 = AGENT_EMOJI[agentName] || "\u{1F916}";
|
|
@@ -16863,41 +16606,21 @@ Anomaly count: ${stateSession.anomalyCount}
|
|
|
16863
16606
|
state.missionActive = false;
|
|
16864
16607
|
return;
|
|
16865
16608
|
}
|
|
16866
|
-
if (
|
|
16867
|
-
const jsonMatch = toolOutput.output.match(/```json\n([\s\S]*?)\n```/) || toolOutput.output.match(/\[\s*\{[\s\S]*?\}\s*\]/);
|
|
16868
|
-
if (jsonMatch) {
|
|
16869
|
-
try {
|
|
16870
|
-
const tasks = JSON.parse(jsonMatch[1] || jsonMatch[0]);
|
|
16871
|
-
if (Array.isArray(tasks) && tasks.length > 0) {
|
|
16872
|
-
stateSession.graph = new TaskGraph(tasks);
|
|
16873
|
-
toolOutput.output += `
|
|
16874
|
-
|
|
16875
|
-
\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
16876
|
-
\u2705 INITIALIZED
|
|
16877
|
-
${stateSession.graph.getTaskSummary()}`;
|
|
16878
|
-
}
|
|
16879
|
-
} catch {
|
|
16880
|
-
}
|
|
16881
|
-
}
|
|
16882
|
-
}
|
|
16883
|
-
if (stateSession?.graph) {
|
|
16609
|
+
if (stateSession) {
|
|
16884
16610
|
const taskId = stateSession.currentTask;
|
|
16885
16611
|
if (toolOutput.output.includes("\u2705 PASS") || toolOutput.output.includes("AUDIT RESULT: PASS")) {
|
|
16886
16612
|
if (taskId) {
|
|
16887
|
-
stateSession.graph.updateTask(taskId, { status: TASK_STATUS.COMPLETED });
|
|
16888
16613
|
stateSession.taskRetries.clear();
|
|
16889
16614
|
toolOutput.output += `
|
|
16890
16615
|
|
|
16891
16616
|
\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
16892
|
-
\u2705 ${taskId} VERIFIED
|
|
16893
|
-
${stateSession.graph.getTaskSummary()}`;
|
|
16617
|
+
\u2705 ${taskId} VERIFIED`;
|
|
16894
16618
|
}
|
|
16895
16619
|
} else if (toolOutput.output.includes("\u274C FAIL") || toolOutput.output.includes("AUDIT RESULT: FAIL")) {
|
|
16896
16620
|
if (taskId) {
|
|
16897
16621
|
const retries = (stateSession.taskRetries.get(taskId) || 0) + 1;
|
|
16898
16622
|
stateSession.taskRetries.set(taskId, retries);
|
|
16899
16623
|
if (retries >= state.maxRetries) {
|
|
16900
|
-
stateSession.graph.updateTask(taskId, { status: TASK_STATUS.FAILED });
|
|
16901
16624
|
toolOutput.output += `
|
|
16902
16625
|
|
|
16903
16626
|
\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
@@ -16910,11 +16633,6 @@ ${stateSession.graph.getTaskSummary()}`;
|
|
|
16910
16633
|
}
|
|
16911
16634
|
}
|
|
16912
16635
|
}
|
|
16913
|
-
const readyTasks = stateSession.graph.getReadyTasks();
|
|
16914
|
-
if (readyTasks.length > 0) {
|
|
16915
|
-
toolOutput.output += `
|
|
16916
|
-
\u{1F449} NEXT: ${readyTasks.map((t) => `[${t.id}]`).join(", ")}`;
|
|
16917
|
-
}
|
|
16918
16636
|
}
|
|
16919
16637
|
const currentTime = formatTimestamp();
|
|
16920
16638
|
toolOutput.output += `
|