opencode-orchestrator 0.1.8 β 0.1.9
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 +82 -97
- package/package.json +2 -14
- package/scripts/postinstall.ts +0 -73
- package/src/index.ts +0 -791
package/README.md
CHANGED
|
@@ -1,156 +1,141 @@
|
|
|
1
1
|
# OpenCode Orchestrator
|
|
2
2
|
|
|
3
|
-
> **Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
3
|
+
> **Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
|
+
[](https://www.npmjs.com/package/opencode-orchestrator)
|
|
8
9
|
[](https://opencode.ai)
|
|
9
10
|
|
|
10
11
|
</div>
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## What is this?
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
A 6-agent collaborative system that turns any LLM into a reliable coding team.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
**Core idea**: Break complex tasks into atomic units, verify each step, fix errors automatically.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Why Orchestrator?
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
| Traditional | With Orchestrator |
|
|
26
|
+
|-------------|-------------------|
|
|
27
|
+
| One big prompt β Hope it works | Atomic tasks β Verified every step |
|
|
28
|
+
| Expensive model required | Any model works |
|
|
29
|
+
| Errors compound silently | Self-correcting loop |
|
|
30
|
+
| Unpredictable results | Consistent quality |
|
|
25
31
|
|
|
26
32
|
---
|
|
27
33
|
|
|
28
|
-
##
|
|
34
|
+
## Features
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
- **π¦ Rust Core** β Fast, memory-safe search and analysis tools
|
|
37
|
+
- **π§ Micro-Task Architecture** β Atomic task decomposition for reliability
|
|
38
|
+
- **π Self-Correcting Loop** β Every change reviewed, errors auto-fixed
|
|
39
|
+
- **π₯ 6-Agent Team** β Specialized roles working together
|
|
40
|
+
- **π‘οΈ Circuit Breaker** β Stops after 3 same errors, prevents infinite loops
|
|
41
|
+
- **β‘ Full Autonomy** β `/auto` command handles everything
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## How It Works
|
|
31
46
|
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
```
|
|
48
|
+
User Request
|
|
49
|
+
β
|
|
50
|
+
βΌ
|
|
51
|
+
βββββββββββ
|
|
52
|
+
β PLANNER β β Break into atomic tasks
|
|
53
|
+
ββββββ¬βββββ
|
|
54
|
+
β
|
|
55
|
+
βΌ
|
|
56
|
+
ββββββββββββββββββββββββββββββββββββββββββββ
|
|
57
|
+
β For each task: β
|
|
58
|
+
β β
|
|
59
|
+
β Search β Code β Review β Fix β
|
|
60
|
+
β β β β
|
|
61
|
+
β ββββββββββββββββββββββββ β
|
|
62
|
+
β (until PASS) β
|
|
63
|
+
ββββββββββββββββββββββββββββββββββββββββββββ
|
|
64
|
+
β
|
|
65
|
+
βΌ
|
|
66
|
+
β
Done
|
|
36
67
|
```
|
|
37
68
|
|
|
38
|
-
|
|
69
|
+
---
|
|
39
70
|
|
|
40
|
-
|
|
71
|
+
## Install
|
|
41
72
|
|
|
42
|
-
```
|
|
43
|
-
|
|
73
|
+
```bash
|
|
74
|
+
npm install opencode-orchestrator
|
|
44
75
|
```
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
Auto-registers with OpenCode. Just restart.
|
|
47
78
|
|
|
48
79
|
---
|
|
49
80
|
|
|
50
|
-
##
|
|
81
|
+
## Usage
|
|
51
82
|
|
|
52
83
|
```
|
|
53
|
-
|
|
54
|
-
β SELF-CORRECTING LOOP β
|
|
55
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
56
|
-
β β
|
|
57
|
-
β User Request β
|
|
58
|
-
β β β
|
|
59
|
-
β βΌ β
|
|
60
|
-
β βββββββββββ βββββββββββββββββββββββββββββββββββββββ β
|
|
61
|
-
β β PLANNER ββββββΆβ Atomic Tasks: [T1] [T2] [T3] ... β β
|
|
62
|
-
β βββββββββββ βββββββββββββββββββββββββββββββββββββββ β
|
|
63
|
-
β β β
|
|
64
|
-
β βΌ β
|
|
65
|
-
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
|
66
|
-
β β FOR EACH TASK: β β
|
|
67
|
-
β β β β
|
|
68
|
-
β β SEARCHER ββΆ CODER ββΆ REVIEWER ββ¬ββΆ β
NEXT β β
|
|
69
|
-
β β β β β β
|
|
70
|
-
β β β FAIL β β β
|
|
71
|
-
β β β β β β
|
|
72
|
-
β β βΌ β β β
|
|
73
|
-
β β FIXER βββββ β β
|
|
74
|
-
β β (retry β€3) β β
|
|
75
|
-
β β β β
|
|
76
|
-
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
|
77
|
-
β β β
|
|
78
|
-
β βΌ β
|
|
79
|
-
β β
COMPLETE β
|
|
80
|
-
β β
|
|
81
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
84
|
+
/auto implement user authentication with JWT
|
|
82
85
|
```
|
|
83
86
|
|
|
84
|
-
### Agents
|
|
85
|
-
|
|
86
|
-
| Agent | Job |
|
|
87
|
-
|-------|-----|
|
|
88
|
-
| **Planner** | Decomposes complex tasks into atomic units |
|
|
89
|
-
| **Searcher** | Finds patterns and context in codebase |
|
|
90
|
-
| **Coder** | Implements one atomic task at a time |
|
|
91
|
-
| **Reviewer** | Quality gate β catches all errors |
|
|
92
|
-
| **Fixer** | Applies targeted fixes from reviewer feedback |
|
|
93
|
-
|
|
94
87
|
---
|
|
95
88
|
|
|
96
|
-
##
|
|
89
|
+
## Commands
|
|
97
90
|
|
|
98
91
|
| Command | Description |
|
|
99
92
|
|---------|-------------|
|
|
100
|
-
| `/auto
|
|
101
|
-
| `/plan
|
|
102
|
-
| `/review
|
|
103
|
-
| `/fix
|
|
104
|
-
| `/search
|
|
93
|
+
| `/auto` | Autonomous execution until complete |
|
|
94
|
+
| `/plan` | Decompose into atomic tasks |
|
|
95
|
+
| `/review` | Quality check |
|
|
96
|
+
| `/fix` | Fix specific error |
|
|
97
|
+
| `/search` | Find patterns in codebase |
|
|
105
98
|
|
|
106
99
|
---
|
|
107
100
|
|
|
108
|
-
##
|
|
101
|
+
## Agents
|
|
109
102
|
|
|
110
|
-
|
|
|
111
|
-
|
|
112
|
-
| **
|
|
113
|
-
| **
|
|
114
|
-
| **
|
|
115
|
-
| **
|
|
103
|
+
| Agent | Role |
|
|
104
|
+
|-------|------|
|
|
105
|
+
| **Orchestrator** | Team leader β coordinates, decides, adapts |
|
|
106
|
+
| **Planner** | Breaks work into atomic tasks |
|
|
107
|
+
| **Coder** | Implements one task at a time |
|
|
108
|
+
| **Reviewer** | Quality gate β catches all errors |
|
|
109
|
+
| **Fixer** | Targeted error resolution |
|
|
110
|
+
| **Searcher** | Finds context before coding |
|
|
116
111
|
|
|
117
112
|
---
|
|
118
113
|
|
|
119
|
-
##
|
|
120
|
-
|
|
121
|
-
### Traditional Approach
|
|
122
|
-
```
|
|
123
|
-
[Big Model] βββββββββββββββββββββββββββΆ [Hope it works?]
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Orchestrator Approach
|
|
127
|
-
```
|
|
128
|
-
[Any Model] βββΆ [Small Task] βββΆ [Verify] βββΆ [Fix if needed] βββΆ β
|
|
129
|
-
```
|
|
114
|
+
## Documentation
|
|
130
115
|
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
- π° **Lower cost**: Cheap models work fine
|
|
134
|
-
- π **Self-healing**: Errors get fixed automatically
|
|
135
|
-
- π **Predictable**: Clear progress tracking
|
|
116
|
+
- [Architecture](docs/ARCHITECTURE.md) β Detailed workflow
|
|
117
|
+
- [Configuration](examples/orchestrator.jsonc) β Customize settings
|
|
136
118
|
|
|
137
119
|
---
|
|
138
120
|
|
|
139
|
-
##
|
|
121
|
+
## Open Source
|
|
122
|
+
|
|
123
|
+
MIT License. No telemetry. No backdoors.
|
|
140
124
|
|
|
141
|
-
-
|
|
142
|
-
- **[Configuration](examples/orchestrator.jsonc)** β Customize agent settings
|
|
125
|
+
[github.com/agnusdei1207/opencode-orchestrator](https://github.com/agnusdei1207/opencode-orchestrator)
|
|
143
126
|
|
|
144
127
|
---
|
|
145
128
|
|
|
146
|
-
##
|
|
129
|
+
## Author's Note
|
|
147
130
|
|
|
148
|
-
|
|
131
|
+
> My goal is to prove that **affordable models like GLM-4.7** can produce results as good as expensive APIs β when you structure the work right.
|
|
132
|
+
>
|
|
133
|
+
> Break tasks down, verify every step, fix errors automatically. The model doesn't need to be smart. The process needs to be disciplined.
|
|
134
|
+
>
|
|
135
|
+
> β [@agnusdei1207](https://github.com/agnusdei1207)
|
|
149
136
|
|
|
150
137
|
---
|
|
151
138
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
**Built for [OpenCode](https://opencode.ai)** β’ Make cheap models work like expensive ones
|
|
139
|
+
## License
|
|
155
140
|
|
|
156
|
-
|
|
141
|
+
[MIT](LICENSE)
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-orchestrator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "6-Agent collaborative architecture for OpenCode - Make any model reliable",
|
|
5
5
|
"author": "agnusdei1207",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/agnusdei1207/opencode-orchestrator"
|
|
9
|
+
"url": "git+https://github.com/agnusdei1207/opencode-orchestrator.git"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://github.com/agnusdei1207/opencode-orchestrator#readme",
|
|
12
12
|
"bugs": {
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
"main": "dist/index.js",
|
|
26
26
|
"types": "dist/index.d.ts",
|
|
27
27
|
"type": "module",
|
|
28
|
-
"bin": {
|
|
29
|
-
"opencode-orchestrator": "./bin/orchestrator"
|
|
30
|
-
},
|
|
31
28
|
"exports": {
|
|
32
29
|
".": {
|
|
33
30
|
"types": "./dist/index.d.ts",
|
|
@@ -37,36 +34,27 @@
|
|
|
37
34
|
"files": [
|
|
38
35
|
"dist",
|
|
39
36
|
"bin",
|
|
40
|
-
"src",
|
|
41
|
-
"scripts",
|
|
42
37
|
"README.md",
|
|
43
38
|
"LICENSE"
|
|
44
39
|
],
|
|
45
40
|
"scripts": {
|
|
46
|
-
"// === BUILD: Individual Steps ===": "",
|
|
47
41
|
"build:rust": "docker compose run --rm dev",
|
|
48
42
|
"build:rust:copy": "docker compose run --rm dev sh -c 'cp /app/target/release/orchestrator /app/bin/' && chmod +x bin/orchestrator",
|
|
49
43
|
"build:ts": "bun build src/index.ts --outdir dist --target bun --format esm && tsc --emitDeclarationOnly",
|
|
50
44
|
"build:scripts": "mkdir -p dist/scripts && bun build scripts/postinstall.ts --outdir dist/scripts --target node",
|
|
51
|
-
"// === BUILD: Combined ===": "",
|
|
52
45
|
"build": "bun run build:ts && bun run build:scripts",
|
|
53
46
|
"build:full": "bun run build:rust && bun run build:rust:copy && bun run build",
|
|
54
|
-
"// === TEST ===": "",
|
|
55
47
|
"test": "docker compose run --rm test",
|
|
56
48
|
"test:local": "cargo test",
|
|
57
|
-
"// === PUBLISH: Steps ===": "",
|
|
58
49
|
"version:patch": "npm version patch --no-git-tag-version",
|
|
59
50
|
"version:minor": "npm version minor --no-git-tag-version",
|
|
60
51
|
"version:major": "npm version major --no-git-tag-version",
|
|
61
|
-
"// === PUBLISH: Combined ===": "",
|
|
62
52
|
"prepublishOnly": "bun run build",
|
|
63
53
|
"publish:npm": "npm publish --access public",
|
|
64
|
-
"// === RELEASE: Full Workflow ===": "",
|
|
65
54
|
"release:patch": "bun run build:full && bun run test && bun run version:patch && bun run publish:npm && bun run release:git",
|
|
66
55
|
"release:minor": "bun run build:full && bun run test && bun run version:minor && bun run publish:npm && bun run release:git",
|
|
67
56
|
"release:major": "bun run build:full && bun run test && bun run version:major && bun run publish:npm && bun run release:git",
|
|
68
57
|
"release:git": "git add -A && git commit -m \"Release v$(node -p \"require('./package.json').version\")\" && git tag \"v$(node -p \"require('./package.json').version\")\" && git push && git push --tags",
|
|
69
|
-
"// === INSTALL HOOKS ===": "",
|
|
70
58
|
"postinstall": "node dist/scripts/postinstall.js 2>/dev/null || true"
|
|
71
59
|
},
|
|
72
60
|
"dependencies": {
|
package/scripts/postinstall.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* OpenCode Orchestrator - Post-install script
|
|
5
|
-
* Automatically registers the plugin with OpenCode
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
|
-
import { join } from "path";
|
|
10
|
-
import { homedir } from "os";
|
|
11
|
-
|
|
12
|
-
const CONFIG_DIR = join(homedir(), ".config", "opencode");
|
|
13
|
-
const CONFIG_FILE = join(CONFIG_DIR, "opencode.json");
|
|
14
|
-
const PLUGIN_NAME = "opencode-orchestrator";
|
|
15
|
-
|
|
16
|
-
function getPluginPath() {
|
|
17
|
-
// Find where this package is installed
|
|
18
|
-
try {
|
|
19
|
-
const packagePath = new URL(".", import.meta.url).pathname;
|
|
20
|
-
return packagePath.replace(/\/$/, "");
|
|
21
|
-
} catch {
|
|
22
|
-
return PLUGIN_NAME;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function install() {
|
|
27
|
-
console.log("π¦ OpenCode Orchestrator - Installing...");
|
|
28
|
-
|
|
29
|
-
// Ensure config directory exists
|
|
30
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
31
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Load or create config
|
|
35
|
-
let config: Record<string, any> = {};
|
|
36
|
-
if (existsSync(CONFIG_FILE)) {
|
|
37
|
-
try {
|
|
38
|
-
config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
39
|
-
} catch {
|
|
40
|
-
config = {};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Add plugin if not already present
|
|
45
|
-
if (!config.plugin) {
|
|
46
|
-
config.plugin = [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const pluginPath = getPluginPath();
|
|
50
|
-
const hasPlugin = config.plugin.some((p: string) =>
|
|
51
|
-
p === PLUGIN_NAME || p === pluginPath || p.includes("opencode-orchestrator")
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
if (!hasPlugin) {
|
|
55
|
-
config.plugin.push(PLUGIN_NAME);
|
|
56
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
57
|
-
console.log("β
Plugin registered!");
|
|
58
|
-
console.log(` Config: ${CONFIG_FILE}`);
|
|
59
|
-
} else {
|
|
60
|
-
console.log("β
Plugin already registered.");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.log("");
|
|
64
|
-
console.log("π Ready! Restart OpenCode to use.");
|
|
65
|
-
console.log("");
|
|
66
|
-
console.log("Commands:");
|
|
67
|
-
console.log(" /auto \"task\" - Autonomous execution");
|
|
68
|
-
console.log(" /plan \"task\" - Decompose into atomic tasks");
|
|
69
|
-
console.log(" /review - Quality check");
|
|
70
|
-
console.log("");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
install();
|
package/src/index.ts
DELETED
|
@@ -1,791 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenCode Orchestrator Plugin
|
|
3
|
-
*
|
|
4
|
-
* 6-Agent Collaborative Architecture for OpenCode
|
|
5
|
-
*
|
|
6
|
-
* Philosophy: Cheap models (GLM-4.7, Gemma, Phi) can outperform
|
|
7
|
-
* expensive models through intelligent task decomposition and
|
|
8
|
-
* team collaboration with quality gates.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { spawn } from "child_process";
|
|
12
|
-
import { join, dirname } from "path";
|
|
13
|
-
import { fileURLToPath } from "url";
|
|
14
|
-
import { existsSync, writeFileSync, readFileSync, mkdirSync } from "fs";
|
|
15
|
-
import { platform, arch } from "os";
|
|
16
|
-
import { tool } from "@opencode-ai/plugin";
|
|
17
|
-
import type { PluginInput } from "@opencode-ai/plugin";
|
|
18
|
-
|
|
19
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
|
|
21
|
-
// ============================================================================
|
|
22
|
-
// 6-Agent Collaborative Architecture
|
|
23
|
-
// ============================================================================
|
|
24
|
-
|
|
25
|
-
interface AgentDefinition {
|
|
26
|
-
id: string;
|
|
27
|
-
description: string;
|
|
28
|
-
systemPrompt: string;
|
|
29
|
-
canWrite: boolean;
|
|
30
|
-
canBash: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const AGENTS: Record<string, AgentDefinition> = {
|
|
34
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
35
|
-
// ORCHESTRATOR - Team Leader & Decision Maker
|
|
36
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
37
|
-
orchestrator: {
|
|
38
|
-
id: "orchestrator",
|
|
39
|
-
description: "Team leader - delegates atomic tasks, tracks progress, adapts on failure",
|
|
40
|
-
systemPrompt: `You are the Orchestrator - the team leader.
|
|
41
|
-
|
|
42
|
-
## Mission
|
|
43
|
-
Coordinate agents to complete user tasks with ZERO errors.
|
|
44
|
-
Keep iterating until the task is 100% complete and working.
|
|
45
|
-
|
|
46
|
-
## Your Team
|
|
47
|
-
- **planner**: Decomposes complex tasks into atomic units
|
|
48
|
-
- **coder**: Implements single atomic task
|
|
49
|
-
- **reviewer**: Quality gate - catches ALL errors
|
|
50
|
-
- **fixer**: Repairs specific errors
|
|
51
|
-
- **searcher**: Finds context before coding
|
|
52
|
-
|
|
53
|
-
## Workflow (Self-Correcting Loop)
|
|
54
|
-
1. ANALYZE: Understand user request fully
|
|
55
|
-
2. PLAN: Call planner for complex tasks β get atomic task list
|
|
56
|
-
3. FOR EACH atomic task:
|
|
57
|
-
a. CONTEXT: Call searcher if context needed
|
|
58
|
-
b. CODE: Call coder with single atomic task
|
|
59
|
-
c. VERIFY: Call reviewer (MANDATORY after every code change)
|
|
60
|
-
d. FIX: If reviewer finds error β call fixer β verify again
|
|
61
|
-
e. LOOP: Repeat fix/verify until PASS (max 3 attempts)
|
|
62
|
-
4. NEXT: Move to next task only after current passes
|
|
63
|
-
5. COMPLETE: All tasks done with all reviews passed
|
|
64
|
-
|
|
65
|
-
## Atomic Task Examples
|
|
66
|
-
β
"Add validateEmail function to src/utils/validation.ts"
|
|
67
|
-
β
"Fix syntax error in LoginForm.tsx line 42"
|
|
68
|
-
β
"Update import statement in api/routes.ts"
|
|
69
|
-
β
"Add error handling to fetchUser function"
|
|
70
|
-
β "Refactor the entire auth module" (too big)
|
|
71
|
-
β "Fix all bugs" (not atomic)
|
|
72
|
-
|
|
73
|
-
## Error Recovery Protocol
|
|
74
|
-
- Error from reviewer β Call fixer with EXACT error details
|
|
75
|
-
- Same error 3 times β STOP, report to user, suggest alternatives
|
|
76
|
-
- Coder confused β Provide more context from searcher
|
|
77
|
-
- Stuck on approach β Try different strategy
|
|
78
|
-
|
|
79
|
-
## Progress Tracking (show after each step)
|
|
80
|
-
π Task: [current task]
|
|
81
|
-
β
Completed: [list]
|
|
82
|
-
β³ Remaining: [list]
|
|
83
|
-
π Retry: [X/3] if applicable
|
|
84
|
-
|
|
85
|
-
## Critical Rules
|
|
86
|
-
- NEVER skip reviewer after code changes
|
|
87
|
-
- One atomic task at a time
|
|
88
|
-
- Stop if same error persists 3 times
|
|
89
|
-
- Always show progress`,
|
|
90
|
-
canWrite: false,
|
|
91
|
-
canBash: false,
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
95
|
-
// PLANNER - Atomic Task Decomposition
|
|
96
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
97
|
-
planner: {
|
|
98
|
-
id: "planner",
|
|
99
|
-
description: "Task decomposition - creates atomic, verifiable units of work",
|
|
100
|
-
systemPrompt: `You are the Planner - atomic task decomposition expert.
|
|
101
|
-
|
|
102
|
-
## Your Job
|
|
103
|
-
Break complex tasks into the SMALLEST possible units that:
|
|
104
|
-
1. Can be completed independently
|
|
105
|
-
2. Can be verified by reviewer
|
|
106
|
-
3. Have clear success criteria
|
|
107
|
-
|
|
108
|
-
## Atomic Task Format
|
|
109
|
-
\`\`\`
|
|
110
|
-
[TASK-001] <action verb> + <specific target>
|
|
111
|
-
βββ File: <exact path>
|
|
112
|
-
βββ Action: <what to do>
|
|
113
|
-
βββ Success: <how to verify it worked>
|
|
114
|
-
βββ Depends: none | TASK-XXX
|
|
115
|
-
\`\`\`
|
|
116
|
-
|
|
117
|
-
## What Makes a Task "Atomic"
|
|
118
|
-
- Touches ONE file (or one specific location)
|
|
119
|
-
- Does ONE thing (add function, fix error, update import)
|
|
120
|
-
- Can be reviewed in isolation
|
|
121
|
-
- Has clear pass/fail criteria
|
|
122
|
-
|
|
123
|
-
## Good Atomic Tasks
|
|
124
|
-
β
"Add validateEmail function to utils/validation.ts"
|
|
125
|
-
β
"Import bcrypt in auth/password.ts"
|
|
126
|
-
β
"Fix missing closing brace in UserForm.tsx line 58"
|
|
127
|
-
β
"Add try-catch to fetchData function in api.ts"
|
|
128
|
-
β
"Update Button component props interface"
|
|
129
|
-
|
|
130
|
-
## Bad Tasks (too large/vague)
|
|
131
|
-
β "Implement authentication" β break into 5-10 atomic tasks
|
|
132
|
-
β "Fix all errors" β list specific errors as separate tasks
|
|
133
|
-
β "Refactor module" β identify specific changes needed
|
|
134
|
-
|
|
135
|
-
## Example Decomposition
|
|
136
|
-
Complex task: "Add user login feature"
|
|
137
|
-
|
|
138
|
-
[TASK-001] Create password hashing utility
|
|
139
|
-
βββ File: src/utils/password.ts
|
|
140
|
-
βββ Action: Add hashPassword and verifyPassword functions
|
|
141
|
-
βββ Success: Functions exported and callable
|
|
142
|
-
βββ Depends: none
|
|
143
|
-
|
|
144
|
-
[TASK-002] Create User type definition
|
|
145
|
-
βββ File: src/types/User.ts
|
|
146
|
-
βββ Action: Add User interface with id, email, passwordHash
|
|
147
|
-
βββ Success: Type exported and importable
|
|
148
|
-
βββ Depends: none
|
|
149
|
-
|
|
150
|
-
[TASK-003] Create login API handler
|
|
151
|
-
βββ File: src/api/login.ts
|
|
152
|
-
βββ Action: Add POST handler that validates credentials
|
|
153
|
-
βββ Success: Handler returns token on valid login
|
|
154
|
-
βββ Depends: TASK-001, TASK-002
|
|
155
|
-
|
|
156
|
-
## Output Format
|
|
157
|
-
List tasks in dependency order. Independent tasks first.`,
|
|
158
|
-
canWrite: false,
|
|
159
|
-
canBash: false,
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
163
|
-
// CODER - Single Task Implementation
|
|
164
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
165
|
-
coder: {
|
|
166
|
-
id: "coder",
|
|
167
|
-
description: "Implementation - executes one atomic task with complete, working code",
|
|
168
|
-
systemPrompt: `You are the Coder - implementation specialist.
|
|
169
|
-
|
|
170
|
-
## Your Job
|
|
171
|
-
Execute the ONE atomic task you're given. Produce complete, working code.
|
|
172
|
-
|
|
173
|
-
## Before Writing Code
|
|
174
|
-
- Understand exactly what the task asks
|
|
175
|
-
- Check context provided for patterns to follow
|
|
176
|
-
- Plan the implementation mentally first
|
|
177
|
-
|
|
178
|
-
## Code Quality Checklist
|
|
179
|
-
Before submitting, verify your code:
|
|
180
|
-
- [ ] All brackets { } ( ) [ ] properly paired
|
|
181
|
-
- [ ] All quotes " ' \` properly closed
|
|
182
|
-
- [ ] All statements terminated correctly
|
|
183
|
-
- [ ] All imports included at top
|
|
184
|
-
- [ ] No undefined variables
|
|
185
|
-
- [ ] Types match (if TypeScript)
|
|
186
|
-
- [ ] Follows existing code style
|
|
187
|
-
|
|
188
|
-
## Output Requirements
|
|
189
|
-
Provide COMPLETE code that:
|
|
190
|
-
1. Accomplishes the task fully
|
|
191
|
-
2. Compiles/runs without errors
|
|
192
|
-
3. Matches project style
|
|
193
|
-
4. Includes necessary imports
|
|
194
|
-
|
|
195
|
-
## Common Mistakes to Avoid
|
|
196
|
-
- Forgetting closing brackets
|
|
197
|
-
- Missing imports
|
|
198
|
-
- Using wrong variable names
|
|
199
|
-
- Type mismatches
|
|
200
|
-
- Breaking existing code
|
|
201
|
-
|
|
202
|
-
## If Unsure
|
|
203
|
-
- Ask for more context
|
|
204
|
-
- Request searcher to find patterns
|
|
205
|
-
- Keep implementation simple
|
|
206
|
-
|
|
207
|
-
## Output Format
|
|
208
|
-
\`\`\`<language>
|
|
209
|
-
// Full code implementation
|
|
210
|
-
\`\`\`
|
|
211
|
-
|
|
212
|
-
Brief explanation if needed.`,
|
|
213
|
-
canWrite: true,
|
|
214
|
-
canBash: true,
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
218
|
-
// REVIEWER - Quality Gate
|
|
219
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
220
|
-
reviewer: {
|
|
221
|
-
id: "reviewer",
|
|
222
|
-
description: "Quality gate - comprehensive error detection with specific fix instructions",
|
|
223
|
-
systemPrompt: `You are the Reviewer - quality assurance gate.
|
|
224
|
-
|
|
225
|
-
## Your Job
|
|
226
|
-
Find ALL issues in the code. Be thorough but specific.
|
|
227
|
-
|
|
228
|
-
## Review Checklist
|
|
229
|
-
|
|
230
|
-
### 1. Syntax (Critical)
|
|
231
|
-
- All brackets paired: { } ( ) [ ]
|
|
232
|
-
- All quotes closed: " ' \`
|
|
233
|
-
- All statements terminated
|
|
234
|
-
- Valid language syntax
|
|
235
|
-
|
|
236
|
-
### 2. Imports & Dependencies
|
|
237
|
-
- All used modules imported
|
|
238
|
-
- Import paths correct
|
|
239
|
-
- No unused imports (warning only)
|
|
240
|
-
|
|
241
|
-
### 3. Types (if applicable)
|
|
242
|
-
- Types match declarations
|
|
243
|
-
- No implicit any (warning)
|
|
244
|
-
- Generics correct
|
|
245
|
-
|
|
246
|
-
### 4. Logic
|
|
247
|
-
- Code does what task asked
|
|
248
|
-
- Edge cases handled
|
|
249
|
-
- No infinite loops possible
|
|
250
|
-
|
|
251
|
-
### 5. Style
|
|
252
|
-
- Matches project conventions
|
|
253
|
-
- Consistent naming
|
|
254
|
-
- Proper indentation
|
|
255
|
-
|
|
256
|
-
### 6. Security (if applicable)
|
|
257
|
-
- No hardcoded secrets
|
|
258
|
-
- Input validation present
|
|
259
|
-
|
|
260
|
-
## Output Format
|
|
261
|
-
|
|
262
|
-
### If NO errors:
|
|
263
|
-
\`\`\`
|
|
264
|
-
β
PASS
|
|
265
|
-
|
|
266
|
-
Reviewed: [what was checked]
|
|
267
|
-
Status: All checks passed
|
|
268
|
-
\`\`\`
|
|
269
|
-
|
|
270
|
-
### If errors found:
|
|
271
|
-
\`\`\`
|
|
272
|
-
β FAIL
|
|
273
|
-
|
|
274
|
-
[ERROR-001] <category>
|
|
275
|
-
βββ File: <path>
|
|
276
|
-
βββ Line: <number>
|
|
277
|
-
βββ Issue: <specific problem>
|
|
278
|
-
βββ Found: \`<problematic code>\`
|
|
279
|
-
βββ Expected: \`<correct code>\`
|
|
280
|
-
βββ Fix: <exact fix instruction>
|
|
281
|
-
|
|
282
|
-
[ERROR-002] ...
|
|
283
|
-
\`\`\`
|
|
284
|
-
|
|
285
|
-
## Rules
|
|
286
|
-
- List ALL errors found (not just first one)
|
|
287
|
-
- Be SPECIFIC about location and fix
|
|
288
|
-
- Prioritize: Syntax > Types > Logic > Style
|
|
289
|
-
- For each error, provide exact fix instruction`,
|
|
290
|
-
canWrite: false,
|
|
291
|
-
canBash: true,
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
295
|
-
// FIXER - Error Resolution
|
|
296
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
297
|
-
fixer: {
|
|
298
|
-
id: "fixer",
|
|
299
|
-
description: "Error resolution - applies targeted fixes based on reviewer feedback",
|
|
300
|
-
systemPrompt: `You are the Fixer - error resolution specialist.
|
|
301
|
-
|
|
302
|
-
## Your Job
|
|
303
|
-
Fix the SPECIFIC errors reported by reviewer.
|
|
304
|
-
|
|
305
|
-
## Input Format
|
|
306
|
-
You receive error reports like:
|
|
307
|
-
\`\`\`
|
|
308
|
-
[ERROR-001] <category>
|
|
309
|
-
βββ File: <path>
|
|
310
|
-
βββ Line: <number>
|
|
311
|
-
βββ Issue: <problem>
|
|
312
|
-
βββ Found: \`<bad code>\`
|
|
313
|
-
βββ Expected: \`<good code>\`
|
|
314
|
-
βββ Fix: <instruction>
|
|
315
|
-
\`\`\`
|
|
316
|
-
|
|
317
|
-
## Fixing Process
|
|
318
|
-
1. Read each error carefully
|
|
319
|
-
2. Understand root cause
|
|
320
|
-
3. Apply minimal fix
|
|
321
|
-
4. Verify fix addresses the issue
|
|
322
|
-
|
|
323
|
-
## Rules
|
|
324
|
-
- Fix ALL reported errors
|
|
325
|
-
- Make MINIMAL changes
|
|
326
|
-
- Don't "improve" unrelated code
|
|
327
|
-
- Don't refactor while fixing
|
|
328
|
-
- Keep existing style
|
|
329
|
-
|
|
330
|
-
## Output Format
|
|
331
|
-
\`\`\`<language>
|
|
332
|
-
// Fixed code with all errors addressed
|
|
333
|
-
\`\`\`
|
|
334
|
-
|
|
335
|
-
### Changes Made
|
|
336
|
-
- [ERROR-001]: <what was fixed>
|
|
337
|
-
- [ERROR-002]: <what was fixed>
|
|
338
|
-
|
|
339
|
-
## If Fix Unclear
|
|
340
|
-
- Ask for clarification
|
|
341
|
-
- Show what you understand
|
|
342
|
-
- Propose alternative fix`,
|
|
343
|
-
canWrite: true,
|
|
344
|
-
canBash: true,
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
348
|
-
// SEARCHER - Context Provider
|
|
349
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
350
|
-
searcher: {
|
|
351
|
-
id: "searcher",
|
|
352
|
-
description: "Context provider - finds patterns, examples, and project conventions",
|
|
353
|
-
systemPrompt: `You are the Searcher - context provider.
|
|
354
|
-
|
|
355
|
-
## Your Job
|
|
356
|
-
Find relevant patterns and context BEFORE coder starts working.
|
|
357
|
-
|
|
358
|
-
## Tools
|
|
359
|
-
- grep_search: Find text/code patterns
|
|
360
|
-
- glob_search: Find files by name
|
|
361
|
-
|
|
362
|
-
## What to Find
|
|
363
|
-
1. Similar implementations in codebase
|
|
364
|
-
2. Import patterns and style
|
|
365
|
-
3. Type definitions being used
|
|
366
|
-
4. Existing utility functions
|
|
367
|
-
5. Project conventions
|
|
368
|
-
|
|
369
|
-
## Output Format
|
|
370
|
-
\`\`\`
|
|
371
|
-
### Found Patterns
|
|
372
|
-
|
|
373
|
-
[PATTERN-1] <name>
|
|
374
|
-
File: <path>
|
|
375
|
-
Relevant code:
|
|
376
|
-
\`\`\`<lang>
|
|
377
|
-
<code snippet>
|
|
378
|
-
\`\`\`
|
|
379
|
-
|
|
380
|
-
[PATTERN-2] ...
|
|
381
|
-
|
|
382
|
-
### Recommendations for Coder
|
|
383
|
-
- Use <pattern> from <file>
|
|
384
|
-
- Follow <convention>
|
|
385
|
-
- Import from <path>
|
|
386
|
-
\`\`\`
|
|
387
|
-
|
|
388
|
-
## Guidelines
|
|
389
|
-
- Show actual code, not just file paths
|
|
390
|
-
- Focus on most relevant 3-5 findings
|
|
391
|
-
- Note project conventions
|
|
392
|
-
- Warn about gotchas`,
|
|
393
|
-
canWrite: false,
|
|
394
|
-
canBash: false,
|
|
395
|
-
},
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
// ============================================================================
|
|
399
|
-
// Binary Management
|
|
400
|
-
// ============================================================================
|
|
401
|
-
|
|
402
|
-
function getBinaryPath(): string {
|
|
403
|
-
const binDir = join(__dirname, "..", "bin");
|
|
404
|
-
const os = platform();
|
|
405
|
-
const cpu = arch();
|
|
406
|
-
|
|
407
|
-
let binaryName: string;
|
|
408
|
-
if (os === "win32") {
|
|
409
|
-
binaryName = "orchestrator-windows-x64.exe";
|
|
410
|
-
} else if (os === "darwin") {
|
|
411
|
-
binaryName = cpu === "arm64" ? "orchestrator-macos-arm64" : "orchestrator-macos-x64";
|
|
412
|
-
} else {
|
|
413
|
-
binaryName = cpu === "arm64" ? "orchestrator-linux-arm64" : "orchestrator-linux-x64";
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
let binaryPath = join(binDir, binaryName);
|
|
417
|
-
if (!existsSync(binaryPath)) {
|
|
418
|
-
binaryPath = join(binDir, os === "win32" ? "orchestrator.exe" : "orchestrator");
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
return binaryPath;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
async function callRustTool(name: string, args: Record<string, unknown>): Promise<string> {
|
|
425
|
-
const binary = getBinaryPath();
|
|
426
|
-
if (!existsSync(binary)) {
|
|
427
|
-
return JSON.stringify({ error: `Binary not found: ${binary}` });
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return new Promise((resolve) => {
|
|
431
|
-
const proc = spawn(binary, ["serve"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
432
|
-
let stdout = "";
|
|
433
|
-
|
|
434
|
-
proc.stdout.on("data", (data) => { stdout += data.toString(); });
|
|
435
|
-
|
|
436
|
-
const request = JSON.stringify({
|
|
437
|
-
jsonrpc: "2.0",
|
|
438
|
-
id: 1,
|
|
439
|
-
method: "tools/call",
|
|
440
|
-
params: { name, arguments: args },
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
proc.stdin.write(request + "\n");
|
|
444
|
-
proc.stdin.end();
|
|
445
|
-
|
|
446
|
-
const timeout = setTimeout(() => { proc.kill(); resolve(JSON.stringify({ error: "Timeout" })); }, 60000);
|
|
447
|
-
|
|
448
|
-
proc.on("close", () => {
|
|
449
|
-
clearTimeout(timeout);
|
|
450
|
-
try {
|
|
451
|
-
const lines = stdout.trim().split("\n");
|
|
452
|
-
const response = JSON.parse(lines[lines.length - 1]);
|
|
453
|
-
const text = response?.result?.content?.[0]?.text;
|
|
454
|
-
resolve(text || JSON.stringify(response.result));
|
|
455
|
-
} catch {
|
|
456
|
-
resolve(stdout || "No output");
|
|
457
|
-
}
|
|
458
|
-
});
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// ============================================================================
|
|
463
|
-
// State Management
|
|
464
|
-
// ============================================================================
|
|
465
|
-
|
|
466
|
-
const state = {
|
|
467
|
-
autoEnabled: false,
|
|
468
|
-
maxIterations: 100,
|
|
469
|
-
maxRetries: 3,
|
|
470
|
-
sessions: new Map<string, {
|
|
471
|
-
enabled: boolean;
|
|
472
|
-
iterations: number;
|
|
473
|
-
taskRetries: Map<string, number>;
|
|
474
|
-
currentTask: string;
|
|
475
|
-
}>(),
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
// ============================================================================
|
|
479
|
-
// call_agent Tool
|
|
480
|
-
// ============================================================================
|
|
481
|
-
|
|
482
|
-
const callAgentTool = tool({
|
|
483
|
-
description: `Call a team member to perform specific work.
|
|
484
|
-
|
|
485
|
-
## Team
|
|
486
|
-
- **planner**: Decompose complex task into atomic units
|
|
487
|
-
- **coder**: Implement single atomic task
|
|
488
|
-
- **reviewer**: Quality check (ALWAYS after coder)
|
|
489
|
-
- **fixer**: Fix specific errors from reviewer
|
|
490
|
-
- **searcher**: Find patterns and context
|
|
491
|
-
|
|
492
|
-
## Self-Correcting Workflow
|
|
493
|
-
1. planner β atomic tasks
|
|
494
|
-
2. For each task:
|
|
495
|
-
- searcher (if needed)
|
|
496
|
-
- coder
|
|
497
|
-
- reviewer (mandatory)
|
|
498
|
-
- fixer (if errors) β reviewer again
|
|
499
|
-
3. Continue until all pass`,
|
|
500
|
-
args: {
|
|
501
|
-
agent: tool.schema
|
|
502
|
-
.enum(["planner", "coder", "reviewer", "fixer", "searcher"])
|
|
503
|
-
.describe("Team member to call"),
|
|
504
|
-
task: tool.schema.string().describe("Atomic task or specific error to address"),
|
|
505
|
-
context: tool.schema.string().optional().describe("Relevant context from previous steps"),
|
|
506
|
-
},
|
|
507
|
-
async execute(args) {
|
|
508
|
-
const agentDef = AGENTS[args.agent];
|
|
509
|
-
if (!agentDef) {
|
|
510
|
-
return `Error: Unknown agent: ${args.agent}`;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
const prompt = `
|
|
514
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
515
|
-
${agentDef.id.toUpperCase()} AGENT
|
|
516
|
-
${agentDef.description}
|
|
517
|
-
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
518
|
-
|
|
519
|
-
<system>
|
|
520
|
-
${agentDef.systemPrompt}
|
|
521
|
-
</system>
|
|
522
|
-
|
|
523
|
-
<task>
|
|
524
|
-
${args.task}
|
|
525
|
-
</task>
|
|
526
|
-
|
|
527
|
-
${args.context ? `<context>\n${args.context}\n</context>` : ""}
|
|
528
|
-
|
|
529
|
-
Execute according to your role. Be thorough and precise.
|
|
530
|
-
`;
|
|
531
|
-
|
|
532
|
-
return prompt;
|
|
533
|
-
},
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
// ============================================================================
|
|
537
|
-
// Slash Commands
|
|
538
|
-
// ============================================================================
|
|
539
|
-
|
|
540
|
-
const COMMANDS: Record<string, { description: string; template: string; argumentHint?: string }> = {
|
|
541
|
-
"auto": {
|
|
542
|
-
description: "Autonomous execution with self-correcting loop",
|
|
543
|
-
template: `<command-instruction>
|
|
544
|
-
π AUTO MODE - Self-Correcting Agent Loop
|
|
545
|
-
|
|
546
|
-
## Protocol
|
|
547
|
-
1. Call planner to decompose into atomic tasks
|
|
548
|
-
2. For EACH atomic task:
|
|
549
|
-
- Call searcher if context needed
|
|
550
|
-
- Call coder to implement
|
|
551
|
-
- Call reviewer to verify (MANDATORY)
|
|
552
|
-
- If FAIL: Call fixer β reviewer again (max 3 retries)
|
|
553
|
-
- If PASS: Move to next task
|
|
554
|
-
3. Continue until all tasks complete with PASS
|
|
555
|
-
|
|
556
|
-
## Error Recovery
|
|
557
|
-
- Same error 3x β Stop and ask user
|
|
558
|
-
- New error β Apply fix and retry
|
|
559
|
-
- Stuck β Try different approach
|
|
560
|
-
|
|
561
|
-
## Goal
|
|
562
|
-
Complete "$ARGUMENTS" with zero errors.
|
|
563
|
-
Keep iterating until done.
|
|
564
|
-
</command-instruction>
|
|
565
|
-
|
|
566
|
-
<user-task>
|
|
567
|
-
$ARGUMENTS
|
|
568
|
-
</user-task>`,
|
|
569
|
-
argumentHint: '"task description"',
|
|
570
|
-
},
|
|
571
|
-
"plan": {
|
|
572
|
-
description: "Decompose task into atomic units",
|
|
573
|
-
template: `<agent-prompt agent="planner">
|
|
574
|
-
Decompose into atomic tasks:
|
|
575
|
-
$ARGUMENTS
|
|
576
|
-
</agent-prompt>`,
|
|
577
|
-
argumentHint: '"complex task"',
|
|
578
|
-
},
|
|
579
|
-
"review": {
|
|
580
|
-
description: "Quality check with error detection",
|
|
581
|
-
template: `<agent-prompt agent="reviewer">
|
|
582
|
-
Review for ALL issues:
|
|
583
|
-
$ARGUMENTS
|
|
584
|
-
</agent-prompt>`,
|
|
585
|
-
argumentHint: '"code to review"',
|
|
586
|
-
},
|
|
587
|
-
"fix": {
|
|
588
|
-
description: "Fix specific errors",
|
|
589
|
-
template: `<agent-prompt agent="fixer">
|
|
590
|
-
Fix these errors:
|
|
591
|
-
$ARGUMENTS
|
|
592
|
-
</agent-prompt>`,
|
|
593
|
-
argumentHint: '"error details"',
|
|
594
|
-
},
|
|
595
|
-
"search": {
|
|
596
|
-
description: "Find patterns and context",
|
|
597
|
-
template: `<agent-prompt agent="searcher">
|
|
598
|
-
Find patterns for:
|
|
599
|
-
$ARGUMENTS
|
|
600
|
-
</agent-prompt>`,
|
|
601
|
-
argumentHint: '"what to find"',
|
|
602
|
-
},
|
|
603
|
-
"agents": {
|
|
604
|
-
description: "Show agent team",
|
|
605
|
-
template: `## 6-Agent Collaborative Architecture
|
|
606
|
-
|
|
607
|
-
| Agent | Role |
|
|
608
|
-
|-------|------|
|
|
609
|
-
| planner | Decompose into atomic tasks |
|
|
610
|
-
| coder | Implement single task |
|
|
611
|
-
| reviewer | Quality gate (mandatory) |
|
|
612
|
-
| fixer | Apply specific fixes |
|
|
613
|
-
| searcher | Find context |
|
|
614
|
-
|
|
615
|
-
## Self-Correcting Loop
|
|
616
|
-
\`\`\`
|
|
617
|
-
plan β (search β code β review β fix?) β repeat
|
|
618
|
-
\`\`\``,
|
|
619
|
-
},
|
|
620
|
-
"cancel-auto": {
|
|
621
|
-
description: "Stop auto mode",
|
|
622
|
-
template: `Auto mode stopped.`,
|
|
623
|
-
},
|
|
624
|
-
};
|
|
625
|
-
|
|
626
|
-
// ============================================================================
|
|
627
|
-
// Slash Command Tool
|
|
628
|
-
// ============================================================================
|
|
629
|
-
|
|
630
|
-
function createSlashcommandTool() {
|
|
631
|
-
const commandList = Object.entries(COMMANDS)
|
|
632
|
-
.map(([name, cmd]) => {
|
|
633
|
-
const hint = cmd.argumentHint ? ` ${cmd.argumentHint}` : "";
|
|
634
|
-
return `- /${name}${hint}: ${cmd.description}`;
|
|
635
|
-
})
|
|
636
|
-
.join("\n");
|
|
637
|
-
|
|
638
|
-
return tool({
|
|
639
|
-
description: `Commands\n\n${commandList}`,
|
|
640
|
-
args: {
|
|
641
|
-
command: tool.schema.string().describe("Command (without slash)"),
|
|
642
|
-
},
|
|
643
|
-
async execute(args) {
|
|
644
|
-
const cmdName = (args.command || "").replace(/^\//, "").split(/\s+/)[0].toLowerCase();
|
|
645
|
-
const cmdArgs = (args.command || "").replace(/^\/?\\S+\s*/, "");
|
|
646
|
-
|
|
647
|
-
if (!cmdName) return `Commands:\n${commandList}`;
|
|
648
|
-
|
|
649
|
-
const command = COMMANDS[cmdName];
|
|
650
|
-
if (!command) return `Unknown: /${cmdName}\n\n${commandList}`;
|
|
651
|
-
|
|
652
|
-
return command.template.replace(/\$ARGUMENTS/g, cmdArgs || "continue");
|
|
653
|
-
},
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
// ============================================================================
|
|
658
|
-
// Search Tools
|
|
659
|
-
// ============================================================================
|
|
660
|
-
|
|
661
|
-
const grepSearchTool = (directory: string) => tool({
|
|
662
|
-
description: "Search code patterns",
|
|
663
|
-
args: {
|
|
664
|
-
pattern: tool.schema.string().describe("Regex pattern"),
|
|
665
|
-
dir: tool.schema.string().optional().describe("Directory"),
|
|
666
|
-
},
|
|
667
|
-
async execute(args) {
|
|
668
|
-
return callRustTool("grep_search", {
|
|
669
|
-
pattern: args.pattern,
|
|
670
|
-
directory: args.dir || directory,
|
|
671
|
-
});
|
|
672
|
-
},
|
|
673
|
-
});
|
|
674
|
-
|
|
675
|
-
const globSearchTool = (directory: string) => tool({
|
|
676
|
-
description: "Find files by pattern",
|
|
677
|
-
args: {
|
|
678
|
-
pattern: tool.schema.string().describe("Glob pattern"),
|
|
679
|
-
dir: tool.schema.string().optional().describe("Directory"),
|
|
680
|
-
},
|
|
681
|
-
async execute(args) {
|
|
682
|
-
return callRustTool("glob_search", {
|
|
683
|
-
pattern: args.pattern,
|
|
684
|
-
directory: args.dir || directory,
|
|
685
|
-
});
|
|
686
|
-
},
|
|
687
|
-
});
|
|
688
|
-
|
|
689
|
-
// ============================================================================
|
|
690
|
-
// Utilities
|
|
691
|
-
// ============================================================================
|
|
692
|
-
|
|
693
|
-
function detectSlashCommand(text: string): { command: string; args: string } | null {
|
|
694
|
-
const match = text.trim().match(/^\/([a-zA-Z0-9_-]+)(?:\s+(.*))?$/);
|
|
695
|
-
if (!match) return null;
|
|
696
|
-
return { command: match[1], args: match[2] || "" };
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
// ============================================================================
|
|
700
|
-
// Plugin
|
|
701
|
-
// ============================================================================
|
|
702
|
-
|
|
703
|
-
const OrchestratorPlugin = async (input: PluginInput) => {
|
|
704
|
-
const { directory } = input;
|
|
705
|
-
|
|
706
|
-
return {
|
|
707
|
-
tool: {
|
|
708
|
-
call_agent: callAgentTool,
|
|
709
|
-
slashcommand: createSlashcommandTool(),
|
|
710
|
-
grep_search: grepSearchTool(directory),
|
|
711
|
-
glob_search: globSearchTool(directory),
|
|
712
|
-
},
|
|
713
|
-
|
|
714
|
-
"chat.message": async (input: any, output: any) => {
|
|
715
|
-
const parts = output.parts as Array<{ type: string; text?: string }>;
|
|
716
|
-
const textPartIndex = parts.findIndex(p => p.type === "text" && p.text);
|
|
717
|
-
if (textPartIndex === -1) return;
|
|
718
|
-
|
|
719
|
-
const originalText = parts[textPartIndex].text || "";
|
|
720
|
-
const parsed = detectSlashCommand(originalText);
|
|
721
|
-
|
|
722
|
-
if (parsed) {
|
|
723
|
-
const command = COMMANDS[parsed.command];
|
|
724
|
-
if (command) {
|
|
725
|
-
parts[textPartIndex].text = command.template.replace(/\$ARGUMENTS/g, parsed.args || "continue");
|
|
726
|
-
|
|
727
|
-
if (parsed.command === "auto") {
|
|
728
|
-
const sessionID = input.sessionID;
|
|
729
|
-
state.sessions.set(sessionID, {
|
|
730
|
-
enabled: true,
|
|
731
|
-
iterations: 0,
|
|
732
|
-
taskRetries: new Map(),
|
|
733
|
-
currentTask: "",
|
|
734
|
-
});
|
|
735
|
-
state.autoEnabled = true;
|
|
736
|
-
} else if (parsed.command === "cancel-auto") {
|
|
737
|
-
state.sessions.delete(input.sessionID);
|
|
738
|
-
state.autoEnabled = false;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
},
|
|
743
|
-
|
|
744
|
-
"tool.execute.after": async (
|
|
745
|
-
input: { tool: string; sessionID: string; callID: string },
|
|
746
|
-
output: { title: string; output: string; metadata: any }
|
|
747
|
-
) => {
|
|
748
|
-
if (!state.autoEnabled) return;
|
|
749
|
-
|
|
750
|
-
const session = state.sessions.get(input.sessionID);
|
|
751
|
-
if (!session?.enabled) return;
|
|
752
|
-
|
|
753
|
-
session.iterations++;
|
|
754
|
-
|
|
755
|
-
// Circuit breaker: max iterations
|
|
756
|
-
if (session.iterations >= state.maxIterations) {
|
|
757
|
-
session.enabled = false;
|
|
758
|
-
output.output += `\n\nββββββββββββ\nβ οΈ ITERATION LIMIT (${state.maxIterations})\nReview progress and continue manually.`;
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// Detect errors and track retries
|
|
763
|
-
const errorMatch = output.output.match(/\[ERROR-(\d+)\]/);
|
|
764
|
-
if (errorMatch) {
|
|
765
|
-
const errorId = `error-${session.currentTask || 'unknown'}`;
|
|
766
|
-
const retries = (session.taskRetries.get(errorId) || 0) + 1;
|
|
767
|
-
session.taskRetries.set(errorId, retries);
|
|
768
|
-
|
|
769
|
-
if (retries >= state.maxRetries) {
|
|
770
|
-
session.enabled = false;
|
|
771
|
-
output.output += `\n\nββββββββββββ\nπ RETRY LIMIT (${state.maxRetries}x same error)\nReview manually or try different approach.`;
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
output.output += `\n\nββββββββββββ\nπ RETRY ${retries}/${state.maxRetries}\nApply fix and verify again.`;
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// Clear retries on PASS
|
|
780
|
-
if (output.output.includes("β
PASS")) {
|
|
781
|
-
session.taskRetries.clear();
|
|
782
|
-
output.output += `\n\nββββββββββββ\nβ
VERIFIED - Continue to next task\n[${session.iterations}/${state.maxIterations}]`;
|
|
783
|
-
return;
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
output.output += `\n\nββββββββββββ\n[${session.iterations}/${state.maxIterations}]`;
|
|
787
|
-
},
|
|
788
|
-
};
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
export default OrchestratorPlugin;
|