mcp-codex-subagent 2.0.9 → 2.0.11
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/dist/event/bus.d.ts +53 -0
- package/dist/event/bus.d.ts.map +1 -0
- package/dist/event/bus.js +94 -0
- package/dist/event/bus.js.map +1 -0
- package/dist/event/throttle.d.ts +36 -0
- package/dist/event/throttle.d.ts.map +1 -0
- package/dist/event/throttle.js +66 -0
- package/dist/event/throttle.js.map +1 -0
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/process/event-parser.d.ts +37 -0
- package/dist/process/event-parser.d.ts.map +1 -0
- package/dist/process/event-parser.js +141 -0
- package/dist/process/event-parser.js.map +1 -0
- package/dist/process/runner.d.ts +48 -0
- package/dist/process/runner.d.ts.map +1 -0
- package/dist/process/runner.js +227 -0
- package/dist/process/runner.js.map +1 -0
- package/dist/process/types.d.ts +74 -0
- package/dist/process/types.d.ts.map +1 -0
- package/dist/process/types.js +5 -0
- package/dist/process/types.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +128 -36
- package/dist/server.js.map +1 -1
- package/dist/services/account-rotator.d.ts +28 -0
- package/dist/services/account-rotator.d.ts.map +1 -0
- package/dist/services/account-rotator.js +216 -0
- package/dist/services/account-rotator.js.map +1 -0
- package/dist/services/output-file.d.ts.map +1 -1
- package/dist/services/output-file.js +80 -36
- package/dist/services/output-file.js.map +1 -1
- package/dist/services/template-init.d.ts +10 -0
- package/dist/services/template-init.d.ts.map +1 -0
- package/dist/services/template-init.js +41 -0
- package/dist/services/template-init.js.map +1 -0
- package/dist/session/file-storage.d.ts +27 -0
- package/dist/session/file-storage.d.ts.map +1 -0
- package/dist/session/file-storage.js +281 -0
- package/dist/session/file-storage.js.map +1 -0
- package/dist/session/storage.js +1 -1
- package/dist/session/storage.js.map +1 -1
- package/dist/task/state-machine.d.ts +27 -0
- package/dist/task/state-machine.d.ts.map +1 -0
- package/dist/task/state-machine.js +59 -0
- package/dist/task/state-machine.js.map +1 -0
- package/dist/task/store.d.ts +91 -0
- package/dist/task/store.d.ts.map +1 -0
- package/dist/task/store.js +317 -0
- package/dist/task/store.js.map +1 -0
- package/dist/task/types.d.ts +72 -0
- package/dist/task/types.d.ts.map +1 -0
- package/dist/task/types.js +13 -0
- package/dist/task/types.js.map +1 -0
- package/dist/templates/index.d.ts +16 -0
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +57 -5
- package/dist/templates/index.js.map +1 -1
- package/dist/tools/definitions.d.ts +5 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +253 -179
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/description-builder.d.ts +18 -0
- package/dist/tools/description-builder.d.ts.map +1 -0
- package/dist/tools/description-builder.js +88 -0
- package/dist/tools/description-builder.js.map +1 -0
- package/dist/tools/handlers.d.ts +19 -17
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +287 -341
- package/dist/tools/handlers.js.map +1 -1
- package/dist/types.d.ts +5 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -10
- package/dist/types.js.map +1 -1
- package/dist/utils/ring-buffer.d.ts +41 -0
- package/dist/utils/ring-buffer.d.ts.map +1 -0
- package/dist/utils/ring-buffer.js +83 -0
- package/dist/utils/ring-buffer.js.map +1 -0
- package/dist/wave/dag.d.ts +32 -0
- package/dist/wave/dag.d.ts.map +1 -0
- package/dist/wave/dag.js +186 -0
- package/dist/wave/dag.js.map +1 -0
- package/dist/wave/git.d.ts +57 -0
- package/dist/wave/git.d.ts.map +1 -0
- package/dist/wave/git.js +227 -0
- package/dist/wave/git.js.map +1 -0
- package/dist/wave/orchestrator.d.ts +15 -0
- package/dist/wave/orchestrator.d.ts.map +1 -0
- package/dist/wave/orchestrator.js +565 -0
- package/dist/wave/orchestrator.js.map +1 -0
- package/dist/wave/progress.d.ts +51 -0
- package/dist/wave/progress.d.ts.map +1 -0
- package/dist/wave/progress.js +176 -0
- package/dist/wave/progress.js.map +1 -0
- package/dist/wave/registry.d.ts +66 -0
- package/dist/wave/registry.d.ts.map +1 -0
- package/dist/wave/registry.js +340 -0
- package/dist/wave/registry.js.map +1 -0
- package/dist/wave/semaphore.d.ts +42 -0
- package/dist/wave/semaphore.d.ts.map +1 -0
- package/dist/wave/semaphore.js +119 -0
- package/dist/wave/semaphore.js.map +1 -0
- package/dist/wave/types.d.ts +197 -0
- package/dist/wave/types.d.ts.map +1 -0
- package/dist/wave/types.js +147 -0
- package/dist/wave/types.js.map +1 -0
- package/package.json +1 -1
- package/dist/services/task-manager.d.ts +0 -69
- package/dist/services/task-manager.d.ts.map +0 -1
- package/dist/services/task-manager.js +0 -173
- package/dist/services/task-manager.js.map +0 -1
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave group orchestrator — main scheduling loop.
|
|
3
|
+
*
|
|
4
|
+
* Synchronous from the MCP tool handler's perspective (blocks until
|
|
5
|
+
* all agents finish or the 30-minute timeout fires).
|
|
6
|
+
*
|
|
7
|
+
* Integrates with Phase 1 primitives:
|
|
8
|
+
* - CodexProcessRunner for spawning
|
|
9
|
+
* - taskStore for per-agent task records
|
|
10
|
+
* - taskEventBus for event routing
|
|
11
|
+
* - NotificationThrottle via progress collector
|
|
12
|
+
*/
|
|
13
|
+
import { readFile } from 'fs/promises';
|
|
14
|
+
import { PINNED_CODEX_MODEL, ROLE_TO_TASK_TYPE } from '../types.js';
|
|
15
|
+
import { CodexProcessRunner } from '../process/runner.js';
|
|
16
|
+
import { taskStore } from '../task/store.js';
|
|
17
|
+
import { taskEventBus } from '../event/bus.js';
|
|
18
|
+
import { getLastMessagePath } from '../services/output-file.js';
|
|
19
|
+
import { applyTemplate, isValidTaskType } from '../templates/index.js';
|
|
20
|
+
import { assemblePromptWithContext, } from '../utils/brief-validator.js';
|
|
21
|
+
import { groupRegistry } from './registry.js';
|
|
22
|
+
import { concurrencySemaphore } from './semaphore.js';
|
|
23
|
+
import { computeReadySet, computeBlockedSet } from './dag.js';
|
|
24
|
+
import { createWorktree, resolveBaseCommit, commitChanges, worktreeExists, } from './git.js';
|
|
25
|
+
import { GroupProgressCollector } from './progress.js';
|
|
26
|
+
import { RETRY_BACKOFF_MS, DEP_POLL_INTERVAL_MS, isAgentTerminal, } from './types.js';
|
|
27
|
+
import { notifyResourceChanged } from '../tools/handlers.js';
|
|
28
|
+
import { rotateAccount } from '../services/account-rotator.js';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Main entry point
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
export async function orchestrate(opts) {
|
|
33
|
+
const startTime = Date.now();
|
|
34
|
+
const { groupId, baseCwd, agents, commonContext, commonContextFiles, dependsOn, append, callbackUri, timeoutMs, sendProgress, } = opts;
|
|
35
|
+
const group = groupRegistry.getGroup(groupId);
|
|
36
|
+
const progress = new GroupProgressCollector(groupId, sendProgress, agents.length);
|
|
37
|
+
// Timeout via AbortController
|
|
38
|
+
const abortController = new AbortController();
|
|
39
|
+
const timeoutTimer = setTimeout(() => abortController.abort(), timeoutMs);
|
|
40
|
+
// Track runners for cleanup
|
|
41
|
+
const runners = new Map(); // alias → runner
|
|
42
|
+
// Track completion promises
|
|
43
|
+
const completionPromises = new Map(); // alias → promise
|
|
44
|
+
// Track in-flight spawn operations to prevent post-timeout late spawns
|
|
45
|
+
const inFlightSpawns = new Set();
|
|
46
|
+
try {
|
|
47
|
+
// ----- Step 1: Wait for group dependencies -----
|
|
48
|
+
// Group already starts in 'waiting_deps' state from registry.createGroup()
|
|
49
|
+
if (dependsOn.length > 0) {
|
|
50
|
+
await waitForDependencies(groupId, dependsOn, abortController.signal, progress);
|
|
51
|
+
// Check if we timed out or deps failed
|
|
52
|
+
const g = groupRegistry.getGroup(groupId);
|
|
53
|
+
if (g.state === 'done_failed' || g.state === 'done_timeout') {
|
|
54
|
+
return buildResult(groupId, startTime);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ----- Step 2: Create worktree (or reuse for append) -----
|
|
58
|
+
groupRegistry.transitionGroup(groupId, 'creating_worktree');
|
|
59
|
+
await progress.emitGroupEvent('group.creating_worktree');
|
|
60
|
+
let worktreePath;
|
|
61
|
+
let baseCommit;
|
|
62
|
+
if (append) {
|
|
63
|
+
// Reuse existing worktree
|
|
64
|
+
worktreePath = group.worktreePath;
|
|
65
|
+
baseCommit = group.baseCommit;
|
|
66
|
+
if (!worktreeExists(baseCwd, groupId, group.groupName ?? groupId)) {
|
|
67
|
+
throw new Error(`Worktree for group "${groupId}" no longer exists on disk`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Resolve base commit
|
|
72
|
+
const depBranches = new Map();
|
|
73
|
+
for (const depId of dependsOn) {
|
|
74
|
+
const depGroup = groupRegistry.getGroup(depId);
|
|
75
|
+
if (depGroup) {
|
|
76
|
+
depBranches.set(depId, depGroup.branch);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
baseCommit = await resolveBaseCommit(baseCwd, dependsOn, depBranches);
|
|
80
|
+
worktreePath = await createWorktree(baseCwd, groupId, group.groupName ?? groupId, baseCommit);
|
|
81
|
+
}
|
|
82
|
+
// Update group record
|
|
83
|
+
groupRegistry.transitionGroup(groupId, 'running', { baseCommit });
|
|
84
|
+
await progress.emitGroupEvent('worktree.created', `path=${worktreePath} branch=${group.branch} base=${baseCommit.slice(0, 8)}`);
|
|
85
|
+
// ----- Step 3: Emit agent table -----
|
|
86
|
+
await progress.emitAgentTable(groupRegistry.getGroup(groupId));
|
|
87
|
+
// ----- Step 4: Scheduling loop -----
|
|
88
|
+
await schedulingLoop(groupId, worktreePath, agents, commonContext, commonContextFiles, callbackUri, abortController.signal, progress, runners, completionPromises, inFlightSpawns);
|
|
89
|
+
// Check timeout
|
|
90
|
+
const finalGroup = groupRegistry.getGroup(groupId);
|
|
91
|
+
if (finalGroup.state === 'done_timeout') {
|
|
92
|
+
return buildResult(groupId, startTime);
|
|
93
|
+
}
|
|
94
|
+
// ----- Step 5: Commit (if all agents succeeded) -----
|
|
95
|
+
if (groupRegistry.allAgentsSucceeded(groupId)) {
|
|
96
|
+
groupRegistry.transitionGroup(groupId, 'committing');
|
|
97
|
+
await progress.emitGroupEvent('group.committing');
|
|
98
|
+
try {
|
|
99
|
+
const successCount = agents.length;
|
|
100
|
+
const commitSha = await commitChanges(worktreePath, groupId, agents.length, successCount);
|
|
101
|
+
if (commitSha) {
|
|
102
|
+
groupRegistry.transitionGroup(groupId, 'done_success', {
|
|
103
|
+
commitSha,
|
|
104
|
+
});
|
|
105
|
+
await progress.emitGroupEvent('commit.created', commitSha.slice(0, 8));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
groupRegistry.transitionGroup(groupId, 'done_success');
|
|
109
|
+
await progress.emitGroupEvent('commit.skipped_no_changes');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
groupRegistry.transitionGroup(groupId, 'done_failed', {
|
|
114
|
+
error: `Commit failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Some agents failed/blocked
|
|
120
|
+
const failedAliases = groupRegistry
|
|
121
|
+
.getGroup(groupId)
|
|
122
|
+
.agents.filter((a) => a.state === 'done_failed' ||
|
|
123
|
+
a.state === 'blocked' ||
|
|
124
|
+
a.state === 'timed_out')
|
|
125
|
+
.map((a) => a.alias);
|
|
126
|
+
groupRegistry.transitionGroup(groupId, 'done_failed', {
|
|
127
|
+
error: `Agents failed: ${failedAliases.join(', ')}`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
await progress.emitGroupEvent('group.done', groupRegistry.getGroup(groupId).state);
|
|
131
|
+
return buildResult(groupId, startTime);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
// Unexpected error
|
|
135
|
+
const currentGroup = groupRegistry.getGroup(groupId);
|
|
136
|
+
if (currentGroup && !currentGroup.completedAt) {
|
|
137
|
+
groupRegistry.transitionGroup(groupId, 'done_failed', {
|
|
138
|
+
error: err instanceof Error ? err.message : String(err),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return buildResult(groupId, startTime);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
clearTimeout(timeoutTimer);
|
|
145
|
+
await Promise.allSettled([...inFlightSpawns]);
|
|
146
|
+
await cleanupRunners(groupId, runners, abortController.signal);
|
|
147
|
+
await progress.dispose();
|
|
148
|
+
groupRegistry.persist(groupId);
|
|
149
|
+
notifyResourceChanged();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Scheduling loop
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
async function schedulingLoop(groupId, worktreePath, agents, commonContext, commonContextFiles, callbackUri, signal, progress, runners, completionPromises, inFlightSpawns) {
|
|
156
|
+
// Track in-flight spawn calls to prevent double-spawn when
|
|
157
|
+
// semaphore acquisition blocks and the scheduling loop re-iterates.
|
|
158
|
+
const spawningAliases = new Set();
|
|
159
|
+
while (!groupRegistry.allAgentsTerminal(groupId)) {
|
|
160
|
+
if (signal.aborted) {
|
|
161
|
+
await handleTimeout(groupId, runners);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// 1. Compute blocked agents
|
|
165
|
+
const dagNodes = getDagNodes(groupId);
|
|
166
|
+
const blockedAliases = computeBlockedSet(dagNodes);
|
|
167
|
+
for (const alias of blockedAliases) {
|
|
168
|
+
const agent = groupRegistry.getAgent(groupId, alias);
|
|
169
|
+
if (agent && agent.state === 'pending') {
|
|
170
|
+
groupRegistry.transitionAgent(groupId, alias, 'blocked', {
|
|
171
|
+
error: 'Dependency failed',
|
|
172
|
+
});
|
|
173
|
+
progress.agentCompleted(alias, false);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// 2. Compute ready agents
|
|
177
|
+
const readyAliases = computeReadySet(getDagNodes(groupId));
|
|
178
|
+
for (const alias of readyAliases) {
|
|
179
|
+
groupRegistry.transitionAgent(groupId, alias, 'queued');
|
|
180
|
+
}
|
|
181
|
+
// 3. Spawn queued agents
|
|
182
|
+
const group = groupRegistry.getGroup(groupId);
|
|
183
|
+
const queuedAgents = group.agents.filter((a) => a.state === 'queued');
|
|
184
|
+
for (const agentRecord of queuedAgents) {
|
|
185
|
+
// Skip if already being spawned (waiting for semaphore)
|
|
186
|
+
if (spawningAliases.has(agentRecord.alias))
|
|
187
|
+
continue;
|
|
188
|
+
const agentSpec = agents.find((s) => s.alias === agentRecord.alias);
|
|
189
|
+
if (!agentSpec)
|
|
190
|
+
continue;
|
|
191
|
+
spawningAliases.add(agentRecord.alias);
|
|
192
|
+
const spawnPromise = spawnAgent(groupId, agentSpec, agentRecord, worktreePath, commonContext, commonContextFiles, callbackUri, signal, progress, runners, completionPromises);
|
|
193
|
+
inFlightSpawns.add(spawnPromise);
|
|
194
|
+
spawnPromise
|
|
195
|
+
.catch(() => { })
|
|
196
|
+
.finally(() => {
|
|
197
|
+
spawningAliases.delete(agentRecord.alias);
|
|
198
|
+
inFlightSpawns.delete(spawnPromise);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// 4. Wait for at least one running agent to complete (or timeout)
|
|
202
|
+
const activePromises = [...completionPromises.values()];
|
|
203
|
+
if (activePromises.length > 0) {
|
|
204
|
+
await waitForAnyCompletionOrAbort(activePromises, signal);
|
|
205
|
+
}
|
|
206
|
+
else if (!groupRegistry.allAgentsTerminal(groupId)) {
|
|
207
|
+
// No running agents and not all terminal — shouldn't happen in normal flow
|
|
208
|
+
// Safety: small delay to prevent tight loop
|
|
209
|
+
await sleep(100);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// Agent spawning
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
async function spawnAgent(groupId, agentSpec, agentRecord, worktreePath, commonContext, commonContextFiles, callbackUri, signal, progress, runners, completionPromises) {
|
|
217
|
+
let permitReleased = false;
|
|
218
|
+
const releasePermit = () => {
|
|
219
|
+
if (permitReleased)
|
|
220
|
+
return;
|
|
221
|
+
permitReleased = true;
|
|
222
|
+
concurrencySemaphore.release();
|
|
223
|
+
};
|
|
224
|
+
// Acquire semaphore slot
|
|
225
|
+
try {
|
|
226
|
+
await concurrencySemaphore.acquire(signal);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Aborted or disposed
|
|
230
|
+
if (signal.aborted) {
|
|
231
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (signal.aborted) {
|
|
236
|
+
releasePermit();
|
|
237
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// Rotate account before spawning this agent
|
|
241
|
+
try {
|
|
242
|
+
await rotateAccount();
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
releasePermit();
|
|
246
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
247
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'done_failed', {
|
|
248
|
+
error: `Account rotation failed: ${msg}`,
|
|
249
|
+
});
|
|
250
|
+
progress.agentCompleted(agentRecord.alias, false);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (signal.aborted) {
|
|
254
|
+
releasePermit();
|
|
255
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
// Build effective prompt (commonContext + agent prompt)
|
|
259
|
+
let effectivePrompt = agentSpec.prompt;
|
|
260
|
+
if (commonContext) {
|
|
261
|
+
effectivePrompt = commonContext + '\n\n---\n\n' + effectivePrompt;
|
|
262
|
+
}
|
|
263
|
+
// Merge context files
|
|
264
|
+
const mergedContextFiles = [
|
|
265
|
+
...(commonContextFiles ?? []),
|
|
266
|
+
...(agentSpec.context_files ?? []),
|
|
267
|
+
];
|
|
268
|
+
// Assemble prompt with context files
|
|
269
|
+
const briefFiles = mergedContextFiles.length > 0
|
|
270
|
+
? mergedContextFiles.map((f) => ({
|
|
271
|
+
path: f.path,
|
|
272
|
+
description: f.description,
|
|
273
|
+
}))
|
|
274
|
+
: undefined;
|
|
275
|
+
let enrichedPrompt = await assemblePromptWithContext(effectivePrompt, briefFiles);
|
|
276
|
+
if (signal.aborted) {
|
|
277
|
+
releasePermit();
|
|
278
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// Apply template if role specified
|
|
282
|
+
if (agentSpec.role) {
|
|
283
|
+
const taskType = ROLE_TO_TASK_TYPE[agentSpec.role];
|
|
284
|
+
if (taskType && isValidTaskType(taskType)) {
|
|
285
|
+
enrichedPrompt = applyTemplate(taskType, enrichedPrompt, agentSpec.specialization);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Increment attempts
|
|
289
|
+
groupRegistry.incrementAttempts(groupId, agentRecord.alias);
|
|
290
|
+
// Create task in TaskStore
|
|
291
|
+
const task = await taskStore.createTask({
|
|
292
|
+
prompt: agentSpec.prompt,
|
|
293
|
+
role: agentSpec.role,
|
|
294
|
+
specialization: agentSpec.specialization,
|
|
295
|
+
model: PINNED_CODEX_MODEL,
|
|
296
|
+
cwd: worktreePath,
|
|
297
|
+
});
|
|
298
|
+
if (signal.aborted) {
|
|
299
|
+
releasePermit();
|
|
300
|
+
await taskStore.transitionTo(task.id, 'timed_out', {
|
|
301
|
+
error: 'Group timed out before spawn',
|
|
302
|
+
});
|
|
303
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
304
|
+
notifyResourceChanged();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
// Register with progress collector before spawn to capture events
|
|
308
|
+
progress.registerAgent(task.id, agentRecord.alias);
|
|
309
|
+
// Build codex args (NO session resume) -- --yolo covers sandbox + approvals
|
|
310
|
+
const effort = agentSpec.reasoningEffort ?? 'xhigh';
|
|
311
|
+
const lastMessagePath = getLastMessagePath(worktreePath, task.id);
|
|
312
|
+
const cmdArgs = [
|
|
313
|
+
'exec',
|
|
314
|
+
'--yolo',
|
|
315
|
+
'--search',
|
|
316
|
+
'--json',
|
|
317
|
+
'-o',
|
|
318
|
+
lastMessagePath,
|
|
319
|
+
'--model',
|
|
320
|
+
PINNED_CODEX_MODEL,
|
|
321
|
+
'-c',
|
|
322
|
+
`model_reasoning_effort="${effort}"`,
|
|
323
|
+
'-C',
|
|
324
|
+
worktreePath,
|
|
325
|
+
'--skip-git-repo-check',
|
|
326
|
+
enrichedPrompt,
|
|
327
|
+
];
|
|
328
|
+
// Build env
|
|
329
|
+
const effectiveCallbackUri = callbackUri || process.env.CODEX_MCP_CALLBACK_URI;
|
|
330
|
+
const env = effectiveCallbackUri
|
|
331
|
+
? { ...process.env, CODEX_MCP_CALLBACK_URI: effectiveCallbackUri }
|
|
332
|
+
: undefined;
|
|
333
|
+
// Spawn
|
|
334
|
+
const completionPromise = new Promise((resolve) => {
|
|
335
|
+
const runner = new CodexProcessRunner({
|
|
336
|
+
onEvent: (processEvent) => {
|
|
337
|
+
taskStore.appendOutput(task.id, processEvent.raw);
|
|
338
|
+
taskEventBus.emit(task.id, processEvent.parsed);
|
|
339
|
+
},
|
|
340
|
+
onExit: async (exitInfo) => {
|
|
341
|
+
releasePermit();
|
|
342
|
+
runners.delete(agentRecord.alias);
|
|
343
|
+
// Read last-message file
|
|
344
|
+
let lastMessage;
|
|
345
|
+
try {
|
|
346
|
+
lastMessage = await readFile(lastMessagePath, 'utf-8');
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
// May not exist
|
|
350
|
+
}
|
|
351
|
+
const currentAgent = groupRegistry.getAgent(groupId, agentRecord.alias);
|
|
352
|
+
if (currentAgent?.state === 'timed_out') {
|
|
353
|
+
await taskStore.transitionTo(task.id, 'timed_out', {
|
|
354
|
+
error: 'Group timed out',
|
|
355
|
+
});
|
|
356
|
+
progress.agentCompleted(agentRecord.alias, false);
|
|
357
|
+
taskEventBus.removeTaskSubscriptions(task.id);
|
|
358
|
+
notifyResourceChanged();
|
|
359
|
+
resolve();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
// Determine success
|
|
363
|
+
const succeeded = exitInfo.exitCode === 0 || !!lastMessage;
|
|
364
|
+
if (succeeded) {
|
|
365
|
+
await taskStore.transitionTo(task.id, 'completed', {
|
|
366
|
+
metadata: {
|
|
367
|
+
exitCode: exitInfo.exitCode,
|
|
368
|
+
...(lastMessage && {
|
|
369
|
+
lastMessage: lastMessage.slice(0, 5000),
|
|
370
|
+
}),
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'done_success');
|
|
374
|
+
progress.agentCompleted(agentRecord.alias, true);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
// Failed
|
|
378
|
+
const currentAgent = groupRegistry.getAgent(groupId, agentRecord.alias);
|
|
379
|
+
const attempts = currentAgent?.attempts ?? 1;
|
|
380
|
+
const maxAttempts = currentAgent?.maxAttempts ?? 2;
|
|
381
|
+
await taskStore.transitionTo(task.id, 'failed', {
|
|
382
|
+
error: `Exit code ${exitInfo.exitCode}`,
|
|
383
|
+
});
|
|
384
|
+
if (attempts < maxAttempts) {
|
|
385
|
+
// Retry: transition back to queued
|
|
386
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'queued');
|
|
387
|
+
await progress.emitGroupEvent('agent.retrying', `${agentRecord.alias} (attempt ${attempts}/${maxAttempts})`);
|
|
388
|
+
// Backoff delay before re-entering the scheduling loop
|
|
389
|
+
await sleep(RETRY_BACKOFF_MS);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
// Permanently failed
|
|
393
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'done_failed', {
|
|
394
|
+
error: `Failed after ${attempts} attempts (exit code ${exitInfo.exitCode})`,
|
|
395
|
+
});
|
|
396
|
+
progress.agentCompleted(agentRecord.alias, false);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
taskEventBus.removeTaskSubscriptions(task.id);
|
|
400
|
+
notifyResourceChanged();
|
|
401
|
+
resolve();
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
if (signal.aborted) {
|
|
405
|
+
releasePermit();
|
|
406
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'timed_out');
|
|
407
|
+
void taskStore.transitionTo(task.id, 'timed_out', {
|
|
408
|
+
error: 'Group timed out before spawn',
|
|
409
|
+
}).finally(() => {
|
|
410
|
+
taskEventBus.removeTaskSubscriptions(task.id);
|
|
411
|
+
notifyResourceChanged();
|
|
412
|
+
resolve();
|
|
413
|
+
});
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const handle = runner.spawn({
|
|
417
|
+
args: cmdArgs,
|
|
418
|
+
cwd: worktreePath,
|
|
419
|
+
env,
|
|
420
|
+
});
|
|
421
|
+
taskStore.setProcess(task.id, handle.childProcess);
|
|
422
|
+
taskStore.transitionTo(task.id, 'running');
|
|
423
|
+
runners.set(agentRecord.alias, runner);
|
|
424
|
+
// Single transition: queued → running with taskId + pid
|
|
425
|
+
groupRegistry.transitionAgent(groupId, agentRecord.alias, 'running', {
|
|
426
|
+
taskId: task.id,
|
|
427
|
+
pid: handle.pid,
|
|
428
|
+
});
|
|
429
|
+
}).finally(() => {
|
|
430
|
+
completionPromises.delete(agentRecord.alias);
|
|
431
|
+
});
|
|
432
|
+
completionPromises.set(agentRecord.alias, completionPromise);
|
|
433
|
+
await progress.emitGroupEvent('agent.spawned', `${agentRecord.alias} (task=${task.id}, attempt=${agentRecord.attempts}/${agentRecord.maxAttempts})`);
|
|
434
|
+
}
|
|
435
|
+
// ---------------------------------------------------------------------------
|
|
436
|
+
// Dependency waiting
|
|
437
|
+
// ---------------------------------------------------------------------------
|
|
438
|
+
async function waitForDependencies(groupId, dependsOn, signal, progress) {
|
|
439
|
+
if (dependsOn.length === 0)
|
|
440
|
+
return;
|
|
441
|
+
let lastEmit = 0;
|
|
442
|
+
while (!signal.aborted) {
|
|
443
|
+
const status = groupRegistry.areDependenciesMet(dependsOn);
|
|
444
|
+
if (status === 'met')
|
|
445
|
+
return;
|
|
446
|
+
if (status === 'failed') {
|
|
447
|
+
groupRegistry.transitionGroup(groupId, 'done_failed', {
|
|
448
|
+
error: `Dependency group(s) failed: ${dependsOn.join(', ')}`,
|
|
449
|
+
});
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
// Emit waiting event every 5 seconds
|
|
453
|
+
const now = Date.now();
|
|
454
|
+
if (now - lastEmit >= 5000) {
|
|
455
|
+
await progress.emitGroupEvent('group.waiting_dependency', dependsOn.join(', '));
|
|
456
|
+
lastEmit = now;
|
|
457
|
+
}
|
|
458
|
+
await sleep(DEP_POLL_INTERVAL_MS);
|
|
459
|
+
}
|
|
460
|
+
// Timed out
|
|
461
|
+
groupRegistry.transitionGroup(groupId, 'done_timeout', {
|
|
462
|
+
error: 'Timed out waiting for dependencies',
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
// ---------------------------------------------------------------------------
|
|
466
|
+
// Timeout handling
|
|
467
|
+
// ---------------------------------------------------------------------------
|
|
468
|
+
async function handleTimeout(groupId, runners) {
|
|
469
|
+
// Kill all running agents
|
|
470
|
+
const killPromises = [];
|
|
471
|
+
for (const [_alias, runner] of runners) {
|
|
472
|
+
killPromises.push(runner.kill().catch(() => { }));
|
|
473
|
+
}
|
|
474
|
+
await Promise.allSettled(killPromises);
|
|
475
|
+
// Transition remaining non-terminal agents to timed_out
|
|
476
|
+
const group = groupRegistry.getGroup(groupId);
|
|
477
|
+
if (group) {
|
|
478
|
+
for (const agent of group.agents) {
|
|
479
|
+
if (!isAgentTerminal(agent.state)) {
|
|
480
|
+
groupRegistry.transitionAgent(groupId, agent.alias, 'timed_out');
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
groupRegistry.transitionGroup(groupId, 'done_timeout', {
|
|
485
|
+
error: 'Group timed out after 30 minutes',
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
// ---------------------------------------------------------------------------
|
|
489
|
+
// Cleanup
|
|
490
|
+
// ---------------------------------------------------------------------------
|
|
491
|
+
async function cleanupRunners(_groupId, runners, _signal) {
|
|
492
|
+
// Kill any still-running agents
|
|
493
|
+
const killPromises = [];
|
|
494
|
+
for (const [_, runner] of runners) {
|
|
495
|
+
killPromises.push(runner.kill().catch(() => { }));
|
|
496
|
+
}
|
|
497
|
+
await Promise.allSettled(killPromises);
|
|
498
|
+
runners.clear();
|
|
499
|
+
}
|
|
500
|
+
// ---------------------------------------------------------------------------
|
|
501
|
+
// DAG node helpers
|
|
502
|
+
// ---------------------------------------------------------------------------
|
|
503
|
+
function getDagNodes(groupId) {
|
|
504
|
+
const group = groupRegistry.getGroup(groupId);
|
|
505
|
+
if (!group)
|
|
506
|
+
return [];
|
|
507
|
+
return group.agents.map((a) => ({
|
|
508
|
+
alias: a.alias,
|
|
509
|
+
dependsOn: a.dependsOn,
|
|
510
|
+
state: a.state,
|
|
511
|
+
}));
|
|
512
|
+
}
|
|
513
|
+
// ---------------------------------------------------------------------------
|
|
514
|
+
// Result builder
|
|
515
|
+
// ---------------------------------------------------------------------------
|
|
516
|
+
function buildResult(groupId, startTime) {
|
|
517
|
+
const group = groupRegistry.getGroup(groupId);
|
|
518
|
+
const durationMs = Date.now() - startTime;
|
|
519
|
+
const agentResults = group.agents.map((a) => ({
|
|
520
|
+
alias: a.alias,
|
|
521
|
+
state: a.state,
|
|
522
|
+
taskId: a.taskId,
|
|
523
|
+
attempts: a.attempts,
|
|
524
|
+
durationMs: a.startedAt && a.completedAt
|
|
525
|
+
? new Date(a.completedAt).getTime() - new Date(a.startedAt).getTime()
|
|
526
|
+
: undefined,
|
|
527
|
+
error: a.error,
|
|
528
|
+
}));
|
|
529
|
+
return {
|
|
530
|
+
groupId: group.id,
|
|
531
|
+
groupName: group.groupName,
|
|
532
|
+
state: group.state,
|
|
533
|
+
branch: group.branch,
|
|
534
|
+
worktreePath: group.worktreePath,
|
|
535
|
+
baseCommit: group.baseCommit,
|
|
536
|
+
commitSha: group.commitSha,
|
|
537
|
+
agentResults,
|
|
538
|
+
durationMs,
|
|
539
|
+
error: group.error,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
// ---------------------------------------------------------------------------
|
|
543
|
+
// Utilities
|
|
544
|
+
// ---------------------------------------------------------------------------
|
|
545
|
+
async function waitForAnyCompletionOrAbort(activePromises, signal) {
|
|
546
|
+
if (signal.aborted)
|
|
547
|
+
return;
|
|
548
|
+
let onAbort = null;
|
|
549
|
+
const abortPromise = new Promise((resolve) => {
|
|
550
|
+
onAbort = () => resolve();
|
|
551
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
552
|
+
});
|
|
553
|
+
try {
|
|
554
|
+
await Promise.race([Promise.race(activePromises), abortPromise]);
|
|
555
|
+
}
|
|
556
|
+
finally {
|
|
557
|
+
if (onAbort) {
|
|
558
|
+
signal.removeEventListener('abort', onAbort);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
function sleep(ms) {
|
|
563
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
564
|
+
}
|
|
565
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/wave/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GroupProgressCollector — per-group event aggregation for streaming.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to TaskEventBus for each agent's taskId and sends
|
|
5
|
+
* throttled progress notifications to the MCP client.
|
|
6
|
+
*
|
|
7
|
+
* One instance per orchestrate() call (NOT a singleton).
|
|
8
|
+
*/
|
|
9
|
+
import type { ToolHandlerContext } from '../types.js';
|
|
10
|
+
import { type GroupRecord } from './types.js';
|
|
11
|
+
export declare class GroupProgressCollector {
|
|
12
|
+
private readonly groupId;
|
|
13
|
+
private readonly sendProgress;
|
|
14
|
+
private readonly verbosity;
|
|
15
|
+
private readonly aliasMap;
|
|
16
|
+
private readonly unsubscribes;
|
|
17
|
+
private readonly throttle;
|
|
18
|
+
private commandsRun;
|
|
19
|
+
private filesChanged;
|
|
20
|
+
private errorCount;
|
|
21
|
+
private agentsDone;
|
|
22
|
+
private totalAgents;
|
|
23
|
+
private progressCount;
|
|
24
|
+
constructor(groupId: string, sendProgress: ToolHandlerContext['sendProgress'], totalAgents: number);
|
|
25
|
+
/**
|
|
26
|
+
* Register an agent and subscribe to its TaskEventBus events.
|
|
27
|
+
*/
|
|
28
|
+
registerAgent(taskId: string, alias: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Send a group-level progress event (e.g., waiting, worktree created).
|
|
31
|
+
* Not throttled — sent immediately.
|
|
32
|
+
*/
|
|
33
|
+
emitGroupEvent(type: string, detail?: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Send the markdown agent mapping table.
|
|
36
|
+
*/
|
|
37
|
+
emitAgentTable(group: GroupRecord): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Notify that an agent completed (success or failure).
|
|
40
|
+
* Flushes the throttle immediately for state changes.
|
|
41
|
+
*/
|
|
42
|
+
agentCompleted(alias: string, success: boolean): void;
|
|
43
|
+
/**
|
|
44
|
+
* Clean up all subscriptions and the throttle timer.
|
|
45
|
+
*/
|
|
46
|
+
dispose(): Promise<void>;
|
|
47
|
+
private onAgentEvent;
|
|
48
|
+
private emitDetailEvent;
|
|
49
|
+
private emitSummary;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/wave/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AAIpB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAGhD,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAAK;gBAGxB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,kBAAkB,CAAC,cAAc,CAAC,EAChD,WAAW,EAAE,MAAM;IAerB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IASlD;;;OAGG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlE;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAOrD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B,OAAO,CAAC,YAAY;IAmFpB,OAAO,CAAC,eAAe;YAKT,WAAW;CAe1B"}
|