opencode-orchestrator 0.5.16 → 0.5.18
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 +360 -24
- package/dist/agents/subagents/librarian.d.ts +10 -0
- package/dist/agents/subagents/researcher.d.ts +11 -0
- package/dist/core/agents/concurrency.d.ts +2 -6
- package/dist/core/agents/config.d.ts +1 -1
- package/dist/core/agents/consts/index.d.ts +4 -0
- package/dist/core/agents/consts/task-status.const.d.ts +12 -0
- package/dist/core/agents/interfaces/concurrency-config.interface.d.ts +9 -0
- package/dist/core/agents/interfaces/index.d.ts +6 -3
- package/dist/core/agents/interfaces/{parallel-task.d.ts → parallel-task.interface.d.ts} +4 -8
- package/dist/core/agents/interfaces/resume-input.interface.d.ts +17 -0
- package/dist/core/agents/interfaces/task-progress.interface.d.ts +9 -0
- package/dist/core/agents/manager/event-handler.d.ts +34 -0
- package/dist/core/agents/manager/index.d.ts +10 -0
- package/dist/core/agents/manager/task-cleaner.d.ts +17 -0
- package/dist/core/agents/manager/task-launcher.d.ts +20 -0
- package/dist/core/agents/manager/task-poller.d.ts +26 -0
- package/dist/core/agents/manager/task-resumer.d.ts +18 -0
- package/dist/core/agents/manager.d.ts +11 -29
- package/dist/core/agents/task-store.d.ts +29 -3
- package/dist/core/agents/types/index.d.ts +1 -1
- package/dist/core/agents/types/parallel-task-status.type.d.ts +4 -0
- package/dist/core/bus/event-bus.d.ts +53 -0
- package/dist/core/bus/index.d.ts +19 -0
- package/dist/core/bus/interfaces.d.ts +34 -0
- package/dist/core/bus/types.d.ts +12 -0
- package/dist/core/cache/constants.d.ts +6 -0
- package/dist/core/cache/document-cache.d.ts +6 -0
- package/dist/core/cache/index.d.ts +4 -0
- package/dist/core/cache/interfaces.d.ts +53 -0
- package/dist/core/cache/operations.d.ts +36 -0
- package/dist/core/cache/utils.d.ts +20 -0
- package/dist/core/loop/formatters.d.ts +16 -0
- package/dist/core/loop/interfaces.d.ts +34 -0
- package/dist/core/loop/parser.d.ts +8 -0
- package/dist/core/loop/stats.d.ts +24 -0
- package/dist/core/loop/todo-enforcer.d.ts +9 -0
- package/dist/core/notification/event-integration.d.ts +7 -0
- package/dist/core/notification/presets.d.ts +14 -0
- package/dist/core/notification/toast-core.d.ts +28 -0
- package/dist/core/notification/toast.d.ts +9 -0
- package/dist/core/notification/types.d.ts +19 -0
- package/dist/core/orchestrator/types/task-status.d.ts +2 -2
- package/dist/core/progress/calculator.d.ts +11 -0
- package/dist/core/progress/formatters.d.ts +20 -0
- package/dist/core/progress/interfaces.d.ts +54 -0
- package/dist/core/progress/store.d.ts +28 -0
- package/dist/core/progress/tracker.d.ts +11 -0
- package/dist/core/queue/async-queue.d.ts +46 -0
- package/dist/core/queue/async-utils.d.ts +20 -0
- package/dist/core/queue/index.d.ts +8 -0
- package/dist/core/queue/work-pool.d.ts +19 -0
- package/dist/core/recovery/auto-recovery.d.ts +9 -0
- package/dist/core/recovery/constants.d.ts +6 -0
- package/dist/core/recovery/handler.d.ts +27 -0
- package/dist/core/recovery/interfaces.d.ts +63 -0
- package/dist/core/recovery/patterns.d.ts +8 -0
- package/dist/core/session/interfaces.d.ts +53 -0
- package/dist/core/session/shared-context.d.ts +8 -0
- package/dist/core/session/store.d.ts +44 -0
- package/dist/core/session/summary.d.ts +7 -0
- package/dist/core/task/interfaces.d.ts +54 -0
- package/dist/core/task/parser.d.ts +8 -0
- package/dist/core/task/scheduler.d.ts +12 -0
- package/dist/core/task/store.d.ts +32 -0
- package/dist/core/task/summary.d.ts +7 -0
- package/dist/core/task/task-decomposer.d.ts +10 -0
- package/dist/index.d.ts +2 -133
- package/dist/index.js +2600 -675
- package/dist/shared/agent.d.ts +2 -0
- package/dist/shared/constants.d.ts +56 -3
- package/dist/shared/event-types.d.ts +77 -0
- package/dist/tools/background-cmd/list.d.ts +2 -2
- package/dist/tools/parallel/delegate-task.d.ts +3 -0
- package/dist/tools/web/cache-docs.d.ts +21 -0
- package/dist/tools/web/codesearch.d.ts +19 -0
- package/dist/tools/web/index.d.ts +9 -0
- package/dist/tools/web/webfetch.d.ts +19 -0
- package/dist/tools/web/websearch.d.ts +17 -0
- package/package.json +8 -7
- package/dist/core/agents/types/parallel-task-status.d.ts +0 -4
- /package/dist/core/agents/interfaces/{launch-input.d.ts → launch-input.interface.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -4,26 +4,312 @@
|
|
|
4
4
|
|
|
5
5
|
# OpenCode Orchestrator 🎯
|
|
6
6
|
|
|
7
|
-
> **Autonomous Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
7
|
+
> **Enterprise-Grade Autonomous Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
8
8
|
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://www.npmjs.com/package/opencode-orchestrator)
|
|
11
|
+
[]()
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## 🚀 What's New in v0.6.0
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
**Ultimate Agent Architecture** - Production-ready distributed agent orchestration!
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
| Feature | Description |
|
|
20
|
+
|---------|-------------|
|
|
21
|
+
| **♾️ Unlimited Mode** | No step limits - runs until mission complete |
|
|
22
|
+
| **🧠 Anti-Hallucination** | Research before coding, verify with docs |
|
|
23
|
+
| **⚡ 50x Parallel Sessions** | Massive concurrent task execution |
|
|
24
|
+
| **📊 Auto Memory Management** | GC, archiving, zero memory leaks |
|
|
25
|
+
| **🔄 Auto Recovery** | Handles rate limits, errors automatically |
|
|
26
|
+
| **📡 Event-Driven** | Real-time pub/sub across all components |
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 🏛️ System Architecture
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
34
|
+
│ │
|
|
35
|
+
│ USER REQUEST │
|
|
36
|
+
│ (OpenCode Terminal / UI) │
|
|
37
|
+
│ │ │
|
|
38
|
+
└──────────────────────────────────────────────┼────────────────────────────────────────────────────────┘
|
|
39
|
+
│
|
|
40
|
+
▼
|
|
41
|
+
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
42
|
+
│ │
|
|
43
|
+
│ ORCHESTRATOR PLUGIN (src/index.ts) │
|
|
44
|
+
│ │
|
|
45
|
+
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
|
|
46
|
+
│ │ Session State │ │ Agent Definitions │ │ Tools Registry │ │ Toast.enable │ │
|
|
47
|
+
│ │ Map<sessionId, │ │ (7 agents) │ │ (15+ tools) │ │ AutoToasts() │ │
|
|
48
|
+
│ │ {step, maxSteps, │ │ │ │ │ │ → EventBus sub │ │
|
|
49
|
+
│ │ timestamp}> │ │ • Commander 🎯 │ │ • call_agent │ │ │ │
|
|
50
|
+
│ │ │ │ • Architect 🏗️ │ │ • launch_parallel │ └─────────────────────┘ │
|
|
51
|
+
│ │ Cleanup: │ │ • Builder 🔨 │ │ • check_parallel │ │
|
|
52
|
+
│ │ session.deleted │ │ • Inspector 🔍 │ │ • webfetch │ ┌─────────────────────┐ │
|
|
53
|
+
│ │ → sessions.delete │ │ • Recorder 💾 │ │ • websearch │ │ ProgressTracker │ │
|
|
54
|
+
│ │ → Progress.clear │ │ • Librarian 📚 │ │ • grep_search │ │ .startSession() │ │
|
|
55
|
+
│ └─────────────────────┘ │ • Researcher 🔬 │ │ • run_background │ │ .recordSnapshot() │ │
|
|
56
|
+
│ └─────────────────────┘ └─────────────────────┘ │ .clearSession() │ │
|
|
57
|
+
│ └─────────────────────┘ │
|
|
58
|
+
│ │ │
|
|
59
|
+
│ ▼ │
|
|
60
|
+
│ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
61
|
+
│ │ │ │
|
|
62
|
+
│ │ PARENT SESSION (Main Execution Loop) │ │
|
|
63
|
+
│ │ │ │
|
|
64
|
+
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
|
65
|
+
│ │ │ Commander │───▶│ Architect │───▶│ Builder │───▶│ Inspector │───▶│ Recorder │ │ │
|
|
66
|
+
│ │ │ 🎯 │ │ 🏗️ │ │ 🔨 │ │ 🔍 │ │ 💾 │ │ │
|
|
67
|
+
│ │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
68
|
+
│ │ │ Orchestrate │ │ Decompose │ │ Implement │ │ Audit & │ │ Save │ │ │
|
|
69
|
+
│ │ │ & delegate │ │ into tasks │ │ code │ │ verify │ │ context │ │ │
|
|
70
|
+
│ │ └─────────────┘ └─────────────┘ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │
|
|
71
|
+
│ │ │ │ │
|
|
72
|
+
│ │ │ launch_parallel_agent() │ │
|
|
73
|
+
│ │ ▼ │ │
|
|
74
|
+
│ │ ┌──────────────────────────────────────────────────────────────────────────────────────────┐ │ │
|
|
75
|
+
│ │ │ │ │ │
|
|
76
|
+
│ │ │ hooks: "chat.message" / "tool.execute.after" / "handler" │ │ │
|
|
77
|
+
│ │ │ │ │ │
|
|
78
|
+
│ │ │ chat.message: │ │ │
|
|
79
|
+
│ │ │ • Parse /task, /plan slash commands │ │ │
|
|
80
|
+
│ │ │ • Auto-start session on Commander agent selection │ │ │
|
|
81
|
+
│ │ │ • emit(TASK_EVENTS.STARTED, { taskId, agent }) │ │ │
|
|
82
|
+
│ │ │ │ │ │
|
|
83
|
+
│ │ │ tool.execute.after: │ │ │
|
|
84
|
+
│ │ │ • Check "MISSION COMPLETE" → emit(MISSION_EVENTS.COMPLETE) │ │ │
|
|
85
|
+
│ │ │ • Check "/stop" or "/cancel" → emit(TASK_EVENTS.FAILED) │ │ │
|
|
86
|
+
│ │ │ • Record ProgressTracker.recordSnapshot() │ │ │
|
|
87
|
+
│ │ │ • Inject CONTINUE_INSTRUCTION → client.session.prompt() │ │ │
|
|
88
|
+
│ │ │ │ │ │
|
|
89
|
+
│ │ │ handler (event): │ │ │
|
|
90
|
+
│ │ │ • session.deleted → cleanup sessions, state, ProgressTracker │ │ │
|
|
91
|
+
│ │ │ • Pass to ParallelAgentManager.handleEvent() │ │ │
|
|
92
|
+
│ │ │ │ │ │
|
|
93
|
+
│ │ └──────────────────────────────────────────────────────────────────────────────────────────┘ │ │
|
|
94
|
+
│ │ │ │
|
|
95
|
+
│ └─────────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
|
96
|
+
│ │
|
|
97
|
+
└────────────────────────────────────────────────────┬───────────────────────────────────────────────────┘
|
|
98
|
+
│
|
|
99
|
+
▼
|
|
100
|
+
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
101
|
+
│ │
|
|
102
|
+
│ PARALLEL AGENT MANAGER (src/core/agents/manager.ts) │
|
|
103
|
+
│ │
|
|
104
|
+
│ ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
105
|
+
│ │ Component Composition │ │
|
|
106
|
+
│ │ │ │
|
|
107
|
+
│ │ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ │ │
|
|
108
|
+
│ │ │ TaskLauncher │ │ TaskResumer │ │ TaskPoller │ │ │
|
|
109
|
+
│ │ │ (task-launcher.ts) │ │ (task-resumer.ts) │ │ (task-poller.ts) │ │ │
|
|
110
|
+
│ │ │ ───────────────── │ │ ───────────────── │ │ ───────────────── │ │ │
|
|
111
|
+
│ │ │ │ │ │ │ │ │ │
|
|
112
|
+
│ │ │ async launch(): │ │ async resume(): │ │ poll() every 1s: │ │ │
|
|
113
|
+
│ │ │ 1. await acquire() │ │ 1. Find task │ │ 1. Get running │ │ │
|
|
114
|
+
│ │ │ 2. session.create()│ │ 2. session.message │ │ 2. Check events │ │ │
|
|
115
|
+
│ │ │ 3. store.set() │ │ 3. Notify parent │ │ 3. If idle+stable │ │ │
|
|
116
|
+
│ │ │ 4. emit(STARTED) │ │ │ │ → completed │ │ │
|
|
117
|
+
│ │ │ 5. session.message │ └───────────────────────┘ │ 4. emit(COMPLETED) │ │ │
|
|
118
|
+
│ │ │ 6. Start poller │ │ 5. scheduleCleanup │ │ │
|
|
119
|
+
│ │ │ │ │ │ │ │
|
|
120
|
+
│ │ └───────────┬───────────┘ └───────────┬───────────┘ │ │
|
|
121
|
+
│ │ │ │ │ │
|
|
122
|
+
│ │ ▼ ▼ │ │
|
|
123
|
+
│ │ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ │ │
|
|
124
|
+
│ │ │ TaskCleaner │ │ EventHandler │ │ ConcurrencyController │ │ │
|
|
125
|
+
│ │ │ (task-cleaner.ts) │ │ (event-handler.ts) │ │ (concurrency.ts) │ │ │
|
|
126
|
+
│ │ │ ───────────────── │ │ ───────────────── │ │ ───────────────── │ │ │
|
|
127
|
+
│ │ │ │ │ │ │ │ │ │
|
|
128
|
+
│ │ │ pruneExpiredTasks(): │ │ handle(event): │ │ acquire(key): │ │ │
|
|
129
|
+
│ │ │ • TTL > 60min │ │ │ │ • limit = 10 │ │ │
|
|
130
|
+
│ │ │ → status=timeout │ │ session.idle: │ │ • if < limit │ │ │
|
|
131
|
+
│ │ │ → release() │ │ • MIN_STABILITY │ │ → immediate │ │ │
|
|
132
|
+
│ │ │ → session.delete() │ │ • validateOutput │ │ • else queue.push │ │ │
|
|
133
|
+
│ │ │ │ │ → completed │ │ │ │ │
|
|
134
|
+
│ │ │ scheduleCleanup(): │ │ → release() │ │ release(key): │ │ │
|
|
135
|
+
│ │ │ • setTimeout 10min │ │ → scheduleClean │ │ • if queue.length │ │ │
|
|
136
|
+
│ │ │ → session.delete() │ │ │ │ → queue.shift() │ │ │
|
|
137
|
+
│ │ │ → store.delete() │ │ session.deleted: │ │ → next() │ │ │
|
|
138
|
+
│ │ │ │ │ → release() │ │ • else count-- │ │ │
|
|
139
|
+
│ │ │ notifyParent(): │ │ → store.delete() │ │ │ │ │
|
|
140
|
+
│ │ │ → session.prompt() │ │ │ │ getLimit(key): │ │ │
|
|
141
|
+
│ │ │ │ └───────────────────────┘ │ • MAX_TOTAL = 50 │ │ │
|
|
142
|
+
│ │ └───────────────────────┘ │ • PER_AGENT = 10 │ │ │
|
|
143
|
+
│ │ └───────────────────────┘ │ │
|
|
144
|
+
│ └────────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
|
145
|
+
│ │ │
|
|
146
|
+
│ ▼ │
|
|
147
|
+
│ ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
148
|
+
│ │ │ │
|
|
149
|
+
│ │ TaskStore (task-store.ts) │ │
|
|
150
|
+
│ │ │ │
|
|
151
|
+
│ │ ┌─────────────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │
|
|
152
|
+
│ │ │ tasks: Map<id, Task> │ │ pendingByParent: Map │ │ notifications: Map │ │ │
|
|
153
|
+
│ │ │ MAX: 1000 │ │ <parentId, Set<taskId>> │ │ <parentId, Task[]> │ │ │
|
|
154
|
+
│ │ │ │ │ │ │ MAX: 100/parent │ │ │
|
|
155
|
+
│ │ │ set() → auto gc() │ │ trackPending() │ │ │ │ │
|
|
156
|
+
│ │ │ getRunning() │ │ untrackPending() │ │ queueNotification() │ │ │
|
|
157
|
+
│ │ │ getByParent() │ │ hasPending() │ │ → FIFO eviction │ │ │
|
|
158
|
+
│ │ └─────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘ │ │
|
|
159
|
+
│ │ │ │
|
|
160
|
+
│ │ ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ │
|
|
161
|
+
│ │ │ │ │ │
|
|
162
|
+
│ │ │ async gc(): │ │ │
|
|
163
|
+
│ │ │ • completed > 30min → archiveTasks() → .cache/task-archive/tasks_YYYY-MM-DD.jsonl │ │ │
|
|
164
|
+
│ │ │ • error/cancelled > 10min → delete │ │ │
|
|
165
|
+
│ │ │ │ │ │
|
|
166
|
+
│ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ │ │
|
|
167
|
+
│ │ │ │
|
|
168
|
+
│ └────────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
|
169
|
+
│ │ │
|
|
170
|
+
│ ▼ │
|
|
171
|
+
│ ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
172
|
+
│ │ │ │
|
|
173
|
+
│ │ CHILD SESSIONS POOL (up to 50 concurrent) │ │
|
|
174
|
+
│ │ │ │
|
|
175
|
+
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
|
176
|
+
│ │ │Session 1 │ │Session 2 │ │Session 3 │ │Session 4 │ │Session 5 │ │Session 6 │ │ ... 50 │ │ │
|
|
177
|
+
│ │ │ Builder │ │Librarian │ │Researcher│ │Inspector │ │ Builder │ │ Builder │ │ │ │ │
|
|
178
|
+
│ │ │ 🔨 │ │ 📚 │ │ 🔬 │ │ 🔍 │ │ 🔨 │ │ 🔨 │ │ │ │ │
|
|
179
|
+
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
180
|
+
│ │ │ running │ │ running │ │completed │ │ running │ │ error │ │ pending │ │ │ │ │
|
|
181
|
+
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────────┘ │ │
|
|
182
|
+
│ │ │ │ │ │ │ │ │ │
|
|
183
|
+
│ │ └────────────┴────────────┴────────────┴────────────┴────────────┘ │ │
|
|
184
|
+
│ │ │ │ │
|
|
185
|
+
│ └─────────────────────────────────────────┼───────────────────────────────────────────────────────┘ │
|
|
186
|
+
│ │ │
|
|
187
|
+
└─────────────────────────────────────────────┼──────────────────────────────────────────────────────────┘
|
|
188
|
+
│
|
|
189
|
+
▼
|
|
190
|
+
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
191
|
+
│ │
|
|
192
|
+
│ EVENT BUS (src/core/bus/) │
|
|
193
|
+
│ │
|
|
194
|
+
│ ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
195
|
+
│ │ │ │
|
|
196
|
+
│ │ Event Types (Pub/Sub) │ │
|
|
197
|
+
│ │ │ │
|
|
198
|
+
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │
|
|
199
|
+
│ │ │task.started │ │task.completed│ │ task.failed │ │session.idle │ │ mission.complete │ │ │
|
|
200
|
+
│ │ │ │ │ │ │ │ │session.delete│ │ mission.all_complete│ │ │
|
|
201
|
+
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │ │
|
|
202
|
+
│ │ │ │ │ │ │ │ │
|
|
203
|
+
│ │ └────────────────┴────────────────┴────────────────┴────────────────────┘ │ │
|
|
204
|
+
│ │ │ │ │
|
|
205
|
+
│ │ ▼ │ │
|
|
206
|
+
│ │ ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ │
|
|
207
|
+
│ │ │ Subscribers │ │ │
|
|
208
|
+
│ │ │ │ │ │
|
|
209
|
+
│ │ │ Toast.enableAutoToasts(): EventHandler.handle(): │ │ │
|
|
210
|
+
│ │ │ • task.started → presets.taskStarted() • release concurrency │ │ │
|
|
211
|
+
│ │ │ • task.completed → presets.taskCompleted() • cleanup resources │ │ │
|
|
212
|
+
│ │ │ • task.failed → presets.taskFailed() │ │ │
|
|
213
|
+
│ │ │ • mission.complete → presets.missionComplete() │ │ │
|
|
214
|
+
│ │ │ • document.cached → presets.documentCached() │ │ │
|
|
215
|
+
│ │ │ │ │ │
|
|
216
|
+
│ │ │ Returns: () => void (unsubscribe function for cleanup) │ │ │
|
|
217
|
+
│ │ │ │ │ │
|
|
218
|
+
│ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ │ │
|
|
219
|
+
│ │ │ │
|
|
220
|
+
│ │ ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ │
|
|
221
|
+
│ │ │ EventBusImpl: │ │ │
|
|
222
|
+
│ │ │ • subscribe(type, handler) → unsubscribe fn │ │ │
|
|
223
|
+
│ │ │ • publish(type, properties) → Event │ │ │
|
|
224
|
+
│ │ │ • emit(type, properties) → void │ │ │
|
|
225
|
+
│ │ │ • once(type, handler) → unsubscribe fn │ │ │
|
|
226
|
+
│ │ │ • waitFor(type, timeout) → Promise<Event> │ │ │
|
|
227
|
+
│ │ │ • history: Event[] (max 100, FIFO) │ │ │
|
|
228
|
+
│ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ │ │
|
|
229
|
+
│ │ │ │
|
|
230
|
+
│ └────────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
|
231
|
+
│ │
|
|
232
|
+
└────────────────────────────────────────────────────┬───────────────────────────────────────────────────┘
|
|
233
|
+
│
|
|
234
|
+
▼
|
|
235
|
+
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
236
|
+
│ │
|
|
237
|
+
│ CORE SYSTEMS LAYER │
|
|
238
|
+
│ │
|
|
239
|
+
│ ┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐ │
|
|
240
|
+
│ │ Progress Tracker │ │ Auto Recovery │ │ Document Cache │ │
|
|
241
|
+
│ │ (src/core/progress/) │ │ (src/core/recovery/) │ │ (src/core/cache/) │ │
|
|
242
|
+
│ │ ────────────────── │ │ ────────────────── │ │ ────────────────── │ │
|
|
243
|
+
│ │ │ │ │ │ │ │
|
|
244
|
+
│ │ startSession(id) │ │ handleError(context) │ │ get(filename) │ │
|
|
245
|
+
│ │ recordSnapshot(id, { │ │ → match patterns │ │ set(filename, content) │ │
|
|
246
|
+
│ │ currentStep, │ │ → return action │ │ list() │ │
|
|
247
|
+
│ │ maxSteps │ │ │ │ clear(filename) │ │
|
|
248
|
+
│ │ }) │ │ Patterns: │ │ cleanExpired() │ │
|
|
249
|
+
│ │ formatCompact(id) │ │ • rate_limit │ │ │ │
|
|
250
|
+
│ │ clearSession(id) │ │ → retry+backoff │ │ Storage: │ │
|
|
251
|
+
│ │ │ │ • context_overflow │ │ .cache/docs/*.md │ │
|
|
252
|
+
│ │ Store: │ │ → compact │ │ │ │
|
|
253
|
+
│ │ sessions: Map<id, │ │ • network │ │ │ │
|
|
254
|
+
│ │ ProgressSnapshot[]> │ │ → retry 3x │ │ │ │
|
|
255
|
+
│ │ max 100/session │ │ • parse_error │ │ │ │
|
|
256
|
+
│ │ │ │ → skip │ │ │ │
|
|
257
|
+
│ └──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘ │
|
|
258
|
+
│ │
|
|
259
|
+
│ ┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐ │
|
|
260
|
+
│ │ Toast Notifier │ │ Async Queue │ │ Background Commands │ │
|
|
261
|
+
│ │ (src/core/notification)│ │ (src/core/queue/) │ │ (src/core/commands/) │ │
|
|
262
|
+
│ │ ────────────────── │ │ ────────────────── │ │ ────────────────── │ │
|
|
263
|
+
│ │ │ │ │ │ │ │
|
|
264
|
+
│ │ show({ title, msg }) │ │ workPool(items, fn, │ │ runBackground(cmd) │ │
|
|
265
|
+
│ │ │ │ concurrency) │ │ checkBackground(id) │ │
|
|
266
|
+
│ │ presets: │ │ workPoolWithResults() │ │ listBackground() │ │
|
|
267
|
+
│ │ • taskStarted() │ │ processBatches() │ │ killBackground(id) │ │
|
|
268
|
+
│ │ • taskCompleted() │ │ │ │ │ │
|
|
269
|
+
│ │ • taskFailed() │ │ retryWithBackoff(fn, │ │ Storage: │ │
|
|
270
|
+
│ │ • missionComplete() │ │ maxRetries, delay) │ │ backgroundJobs: Map │ │
|
|
271
|
+
│ │ • documentCached() │ │ withTimeout(fn, ms) │ │ <id, BackgroundTask> │ │
|
|
272
|
+
│ │ │ │ debounceAsync(fn, ms) │ │ │ │
|
|
273
|
+
│ │ enableAutoToasts() │ │ │ │ │ │
|
|
274
|
+
│ │ → EventBus.subscribe() │ │ AsyncQueue<T>: │ │ │ │
|
|
275
|
+
│ │ → returns disable fn │ │ async iterator │ │ │ │
|
|
276
|
+
│ │ │ │ │ │ │ │
|
|
277
|
+
│ └──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘ │
|
|
278
|
+
│ │
|
|
279
|
+
│ ┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐ │
|
|
280
|
+
│ │ Shared Context │ │ Task Decomposer │ │ Todo Enforcer │ │
|
|
281
|
+
│ │ (src/core/session/) │ │ (src/core/task/) │ │ (src/core/loop/) │ │
|
|
282
|
+
│ │ ────────────────── │ │ ────────────────── │ │ ────────────────── │ │
|
|
283
|
+
│ │ │ │ │ │ │ │
|
|
284
|
+
│ │ create(id, parentId) │ │ create(id, objective) │ │ parseTodos(data) │ │
|
|
285
|
+
│ │ get(id) │ │ addTask(id, { │ │ getIncompleteCount() │ │
|
|
286
|
+
│ │ getMerged(id) │ │ description, │ │ hasRemainingWork() │ │
|
|
287
|
+
│ │ → includes parent ctx │ │ level: 1|2|3, │ │ getNextPending() │ │
|
|
288
|
+
│ │ │ │ parallelGroup?, │ │ getStats() │ │
|
|
289
|
+
│ │ addDocument(id, doc) │ │ dependsOn? │ │ formatProgress() │ │
|
|
290
|
+
│ │ addFinding(id, find) │ │ }) │ │ isMissionComplete() │ │
|
|
291
|
+
│ │ addDecision(id, dec) │ │ updateStatus(id, task) │ │ │ │
|
|
292
|
+
│ │ │ │ getNextTasks(id) │ │ generateContinuation │ │
|
|
293
|
+
│ │ delete(id) │ │ getParallelBatch(id) │ │ Prompt() │ │
|
|
294
|
+
│ │ getStats(id) │ │ getSummary(id) │ │ generateCompletion │ │
|
|
295
|
+
│ │ │ │ │ │ Message() │ │
|
|
296
|
+
│ └──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘ │
|
|
297
|
+
│ │
|
|
298
|
+
└───────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 🎯 Key Differentiators
|
|
304
|
+
|
|
305
|
+
| Capability | OpenCode Orchestrator | Basic Plugins |
|
|
306
|
+
|------------|----------------------|---------------|
|
|
307
|
+
| **Parallel Sessions** | Up to 50 concurrent | Single session |
|
|
308
|
+
| **Memory Management** | Auto GC + disk archiving | Memory leaks |
|
|
309
|
+
| **Error Recovery** | Pattern-based auto retry | Crash |
|
|
310
|
+
| **Context Sharing** | Parent-child merge | Isolated |
|
|
311
|
+
| **Event System** | Real-time pub/sub | None |
|
|
312
|
+
| **Task Decomposition** | 3-level hierarchy | Flat |
|
|
27
313
|
|
|
28
314
|
---
|
|
29
315
|
|
|
@@ -55,25 +341,71 @@ Press `Tab` in OpenCode → Select **Commander** → Type your mission!
|
|
|
55
341
|
"Fix the login bug in the docker-compose environment"
|
|
56
342
|
```
|
|
57
343
|
|
|
58
|
-
|
|
344
|
+
> **💡 Recommended:** For complex missions, select **Commander** directly via `Tab` to use the full orchestration system with parallel processing, anti-hallucination, and auto-recovery features.
|
|
345
|
+
|
|
346
|
+
### 📋 Use /task Command (Simple Tasks)
|
|
347
|
+
|
|
348
|
+
For quick, simple tasks, you can use the `/task` command:
|
|
59
349
|
|
|
60
350
|
```bash
|
|
61
|
-
/task "
|
|
351
|
+
/task "Add a loading spinner to the button"
|
|
62
352
|
```
|
|
63
353
|
|
|
64
|
-
>
|
|
354
|
+
> **⚠️ Note:** `/task` uses a simplified prompt template. For complex multi-step missions, use **Commander** directly via `Tab` key.
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## The 7 Agents
|
|
359
|
+
|
|
360
|
+
| Agent | Role | Responsibility |
|
|
361
|
+
| :--------------- | :----------- | :--------------------------------- |
|
|
362
|
+
| **Commander** 🎯 | Orchestrator | Autonomous mission control |
|
|
363
|
+
| **Architect** 🏗️ | Planner | Hierarchical task decomposition |
|
|
364
|
+
| **Builder** 🔨 | Developer | Full-stack implementation |
|
|
365
|
+
| **Inspector** 🔍 | Quality | Audit, auto-fix & doc verification |
|
|
366
|
+
| **Recorder** 💾 | Context | Progress tracking |
|
|
367
|
+
| **Librarian** 📚 | Research | Documentation & API research |
|
|
368
|
+
| **Researcher** 🔬 | Investigation | Pre-task research & analysis |
|
|
65
369
|
|
|
66
370
|
---
|
|
67
371
|
|
|
68
|
-
##
|
|
372
|
+
## 🛠️ Available Tools
|
|
373
|
+
|
|
374
|
+
| Tool | Description |
|
|
375
|
+
|------|-------------|
|
|
376
|
+
| `call_agent` | Call another agent synchronously |
|
|
377
|
+
| `launch_parallel_agent` | Start parallel async session |
|
|
378
|
+
| `check_parallel_task` | Check task status |
|
|
379
|
+
| `collect_parallel_results` | Gather completed results |
|
|
380
|
+
| `webfetch` | Fetch URL content as Markdown |
|
|
381
|
+
| `websearch` | Search web (SearXNG → Brave → DuckDuckGo) |
|
|
382
|
+
| `codesearch` | Search open source code patterns |
|
|
383
|
+
| `cache_docs` | Manage cached documentation |
|
|
384
|
+
| `run_background` | Run command in background |
|
|
385
|
+
| `grep_search` / `glob_search` | Fast file search |
|
|
386
|
+
|
|
387
|
+
---
|
|
69
388
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
389
|
+
## 📊 Resource Guarantees
|
|
390
|
+
|
|
391
|
+
| Resource | Limit | Safety Mechanism |
|
|
392
|
+
|----------|-------|------------------|
|
|
393
|
+
| Parallel Sessions | 50 | Queue overflow protection |
|
|
394
|
+
| Tasks in Memory | 1,000 | Auto GC + disk archive |
|
|
395
|
+
| Notifications | 100/parent | FIFO eviction |
|
|
396
|
+
| Event History | 100 | Ring buffer |
|
|
397
|
+
| Session TTL | 60 min | Auto cleanup |
|
|
398
|
+
| Poll Interval | 1 second | Fast completion detection |
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## 🧪 Test Coverage
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
Test Files: 18 passed
|
|
406
|
+
Tests: 211 passed
|
|
407
|
+
Duration: ~4.3s
|
|
408
|
+
```
|
|
77
409
|
|
|
78
410
|
---
|
|
79
411
|
|
|
@@ -87,7 +419,9 @@ npm uninstall -g opencode-orchestrator
|
|
|
87
419
|
|
|
88
420
|
## Documentation
|
|
89
421
|
|
|
90
|
-
- [Architecture
|
|
422
|
+
- **[System Architecture](docs/SYSTEM_ARCHITECTURE.md)** — Detailed technical docs
|
|
423
|
+
- **[OpenCode SDK Reference](docs/OPENCODE_SDK_REFERENCE.md)** — API usage reference
|
|
424
|
+
- [Release Notes](docs/releases/) — Version history
|
|
91
425
|
- [Troubleshooting](docs/PLUGIN_TROUBLESHOOTING.md)
|
|
92
426
|
|
|
93
427
|
---
|
|
@@ -98,4 +432,6 @@ MIT License. [LICENSE](LICENSE)
|
|
|
98
432
|
|
|
99
433
|
---
|
|
100
434
|
|
|
101
|
-
|
|
435
|
+
<div align="center">
|
|
436
|
+
<b>Enterprise-scale. Memory-safe. Self-healing. Unlimited.</b>
|
|
437
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Librarian Agent - Documentation and API research specialist
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Reduce hallucination by researching before implementing
|
|
5
|
+
* - Searches official documentation
|
|
6
|
+
* - Caches important findings locally
|
|
7
|
+
* - Provides verified information with citations
|
|
8
|
+
*/
|
|
9
|
+
import { AgentDefinition } from "../../shared/agent.js";
|
|
10
|
+
export declare const librarian: AgentDefinition;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Researcher Agent - Pre-task investigation specialist
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Gather all necessary information BEFORE implementation begins
|
|
5
|
+
* - Analyzes task requirements
|
|
6
|
+
* - Searches for official documentation
|
|
7
|
+
* - Finds existing patterns in codebase
|
|
8
|
+
* - Caches important references
|
|
9
|
+
*/
|
|
10
|
+
import { AgentDefinition } from "../../shared/agent.js";
|
|
11
|
+
export declare const researcher: AgentDefinition;
|
|
@@ -6,12 +6,8 @@
|
|
|
6
6
|
* - Provider-specific limits (e.g., anthropic/*, openai/*)
|
|
7
7
|
* - Model-specific limits (e.g., anthropic/claude-3-5-sonnet)
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
agentConcurrency?: Record<string, number>;
|
|
12
|
-
providerConcurrency?: Record<string, number>;
|
|
13
|
-
modelConcurrency?: Record<string, number>;
|
|
14
|
-
}
|
|
9
|
+
import type { ConcurrencyConfig } from "./interfaces/concurrency-config.interface.js";
|
|
10
|
+
export type { ConcurrencyConfig } from "./interfaces/concurrency-config.interface.js";
|
|
15
11
|
export declare class ConcurrencyController {
|
|
16
12
|
private counts;
|
|
17
13
|
private queues;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TASK_STATUS - Task status constants
|
|
3
|
+
*/
|
|
4
|
+
export declare const TASK_STATUS: {
|
|
5
|
+
readonly PENDING: "pending";
|
|
6
|
+
readonly RUNNING: "running";
|
|
7
|
+
readonly COMPLETED: "completed";
|
|
8
|
+
readonly FAILED: "failed";
|
|
9
|
+
readonly ERROR: "error";
|
|
10
|
+
readonly TIMEOUT: "timeout";
|
|
11
|
+
readonly CANCELLED: "cancelled";
|
|
12
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Agents Interfaces Index
|
|
3
3
|
*/
|
|
4
|
-
export { ParallelTask } from "./parallel-task.js";
|
|
5
|
-
export {
|
|
4
|
+
export type { ParallelTask } from "./parallel-task.interface.js";
|
|
5
|
+
export type { TaskProgress } from "./task-progress.interface.js";
|
|
6
|
+
export type { LaunchInput } from "./launch-input.interface.js";
|
|
7
|
+
export type { ResumeInput } from "./resume-input.interface.js";
|
|
8
|
+
export type { ConcurrencyConfig } from "./concurrency-config.interface.js";
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ParallelTask - Represents a task running in a parallel session
|
|
2
|
+
* ParallelTask Interface - Represents a task running in a parallel session
|
|
3
3
|
*/
|
|
4
|
-
import { ParallelTaskStatus } from "../types/parallel-task-status.js";
|
|
5
|
-
|
|
6
|
-
toolCalls: number;
|
|
7
|
-
lastTool?: string;
|
|
8
|
-
lastMessage?: string;
|
|
9
|
-
lastUpdate: Date;
|
|
10
|
-
}
|
|
4
|
+
import type { ParallelTaskStatus } from "../types/parallel-task-status.type.js";
|
|
5
|
+
import type { TaskProgress } from "./task-progress.interface.js";
|
|
11
6
|
export interface ParallelTask {
|
|
12
7
|
id: string;
|
|
13
8
|
sessionID: string;
|
|
14
9
|
parentSessionID: string;
|
|
15
10
|
description: string;
|
|
11
|
+
prompt: string;
|
|
16
12
|
agent: string;
|
|
17
13
|
status: ParallelTaskStatus;
|
|
18
14
|
startedAt: Date;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResumeInput - Input for resuming an existing parallel task session
|
|
3
|
+
*
|
|
4
|
+
* This allows continuing work in an existing session, preserving all context.
|
|
5
|
+
* Useful for:
|
|
6
|
+
* - Retry after failure (don't start from scratch)
|
|
7
|
+
* - Follow-up questions to previous work
|
|
8
|
+
* - Token efficiency (reuse context)
|
|
9
|
+
*/
|
|
10
|
+
export interface ResumeInput {
|
|
11
|
+
/** Session ID to resume (from previous task.sessionID) */
|
|
12
|
+
sessionId: string;
|
|
13
|
+
/** New prompt to send to the resumed session */
|
|
14
|
+
prompt: string;
|
|
15
|
+
/** New parent session ID for notifications */
|
|
16
|
+
parentSessionID: string;
|
|
17
|
+
}
|