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,176 @@
|
|
|
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 { taskEventBus } from '../event/bus.js';
|
|
10
|
+
import { NotificationThrottle } from '../event/throttle.js';
|
|
11
|
+
import { getStreamVerbosity, } from './types.js';
|
|
12
|
+
export class GroupProgressCollector {
|
|
13
|
+
groupId;
|
|
14
|
+
sendProgress;
|
|
15
|
+
verbosity;
|
|
16
|
+
aliasMap = new Map(); // taskId → alias
|
|
17
|
+
unsubscribes = [];
|
|
18
|
+
throttle;
|
|
19
|
+
// Aggregate counters
|
|
20
|
+
commandsRun = 0;
|
|
21
|
+
filesChanged = 0;
|
|
22
|
+
errorCount = 0;
|
|
23
|
+
agentsDone = 0;
|
|
24
|
+
totalAgents = 0;
|
|
25
|
+
progressCount = 0;
|
|
26
|
+
constructor(groupId, sendProgress, totalAgents) {
|
|
27
|
+
this.groupId = groupId;
|
|
28
|
+
this.sendProgress = sendProgress;
|
|
29
|
+
this.totalAgents = totalAgents;
|
|
30
|
+
this.verbosity = getStreamVerbosity();
|
|
31
|
+
this.throttle = new NotificationThrottle({
|
|
32
|
+
intervalMs: 500,
|
|
33
|
+
send: async () => {
|
|
34
|
+
await this.emitSummary();
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register an agent and subscribe to its TaskEventBus events.
|
|
40
|
+
*/
|
|
41
|
+
registerAgent(taskId, alias) {
|
|
42
|
+
this.aliasMap.set(taskId, alias);
|
|
43
|
+
const unsub = taskEventBus.subscribe(taskId, (taskEvent) => {
|
|
44
|
+
this.onAgentEvent(taskId, taskEvent.event);
|
|
45
|
+
});
|
|
46
|
+
this.unsubscribes.push(unsub);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Send a group-level progress event (e.g., waiting, worktree created).
|
|
50
|
+
* Not throttled — sent immediately.
|
|
51
|
+
*/
|
|
52
|
+
async emitGroupEvent(type, detail) {
|
|
53
|
+
this.progressCount++;
|
|
54
|
+
const message = detail ? `${type}: ${detail}` : type;
|
|
55
|
+
await this.sendProgress(message, this.progressCount).catch(() => { });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Send the markdown agent mapping table.
|
|
59
|
+
*/
|
|
60
|
+
async emitAgentTable(group) {
|
|
61
|
+
const lines = [
|
|
62
|
+
`group.agent_table: ${group.id}`,
|
|
63
|
+
'',
|
|
64
|
+
'| Agent | Role | Status |',
|
|
65
|
+
'|-------|------|--------|',
|
|
66
|
+
];
|
|
67
|
+
for (const agent of group.agents) {
|
|
68
|
+
lines.push(`| ${agent.alias} | ${agent.role ?? '-'} | ${agent.state} |`);
|
|
69
|
+
}
|
|
70
|
+
this.progressCount++;
|
|
71
|
+
await this.sendProgress(lines.join('\n'), this.progressCount).catch(() => { });
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Notify that an agent completed (success or failure).
|
|
75
|
+
* Flushes the throttle immediately for state changes.
|
|
76
|
+
*/
|
|
77
|
+
agentCompleted(alias, success) {
|
|
78
|
+
this.agentsDone++;
|
|
79
|
+
if (!success)
|
|
80
|
+
this.errorCount++;
|
|
81
|
+
// Flush immediately on state changes
|
|
82
|
+
this.throttle.flush().catch(() => { });
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Clean up all subscriptions and the throttle timer.
|
|
86
|
+
*/
|
|
87
|
+
async dispose() {
|
|
88
|
+
for (const unsub of this.unsubscribes) {
|
|
89
|
+
unsub();
|
|
90
|
+
}
|
|
91
|
+
this.unsubscribes.length = 0;
|
|
92
|
+
await this.throttle.flush().catch(() => { });
|
|
93
|
+
this.throttle.dispose();
|
|
94
|
+
}
|
|
95
|
+
// -----------------------------------------------------------------------
|
|
96
|
+
// Private
|
|
97
|
+
// -----------------------------------------------------------------------
|
|
98
|
+
onAgentEvent(taskId, event) {
|
|
99
|
+
const alias = this.aliasMap.get(taskId) ?? taskId;
|
|
100
|
+
switch (event.type) {
|
|
101
|
+
case 'command_execution':
|
|
102
|
+
this.commandsRun++;
|
|
103
|
+
if (this.verbosity !== 'low') {
|
|
104
|
+
const cmd = truncate(String(event.command ?? ''), 100);
|
|
105
|
+
this.emitDetailEvent(`agent.tool_call: ${alias}: ${cmd}`);
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
case 'file_change': {
|
|
109
|
+
const changes = event.changes;
|
|
110
|
+
if (Array.isArray(changes)) {
|
|
111
|
+
this.filesChanged += changes.length;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.filesChanged++;
|
|
115
|
+
}
|
|
116
|
+
if (this.verbosity !== 'low') {
|
|
117
|
+
const path = truncate(String(event.file ?? ''), 100);
|
|
118
|
+
this.emitDetailEvent(`agent.file_change: ${alias}: ${path}`);
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case 'mcp_tool_call':
|
|
123
|
+
if (this.verbosity !== 'low') {
|
|
124
|
+
const tool = String(event.tool ?? '');
|
|
125
|
+
this.emitDetailEvent(`agent.tool_call: ${alias}: ${tool}`);
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
case 'error':
|
|
129
|
+
case 'turn_failed':
|
|
130
|
+
this.errorCount++;
|
|
131
|
+
if (this.verbosity !== 'low') {
|
|
132
|
+
const msg = truncate(String(event.message ?? ''), 100);
|
|
133
|
+
this.emitDetailEvent(`agent.error: ${alias}: ${msg}`);
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
case 'agent_message':
|
|
137
|
+
if (this.verbosity === 'high') {
|
|
138
|
+
const text = truncate(String(event.text ?? ''), 100);
|
|
139
|
+
this.emitDetailEvent(`agent.message: ${alias}: ${text}`);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case 'reasoning':
|
|
143
|
+
if (this.verbosity === 'high') {
|
|
144
|
+
const text = truncate(String(event.text ??
|
|
145
|
+
event.content ??
|
|
146
|
+
''), 100);
|
|
147
|
+
this.emitDetailEvent(`agent.reasoning: ${alias}: ${text}`);
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
// Trigger throttled summary
|
|
154
|
+
this.throttle.notify();
|
|
155
|
+
}
|
|
156
|
+
emitDetailEvent(message) {
|
|
157
|
+
this.progressCount++;
|
|
158
|
+
this.sendProgress(message, this.progressCount).catch(() => { });
|
|
159
|
+
}
|
|
160
|
+
async emitSummary() {
|
|
161
|
+
const running = this.totalAgents - this.agentsDone;
|
|
162
|
+
const aliases = [...this.aliasMap.values()];
|
|
163
|
+
const runningAliases = aliases.slice(0, 5).join(', ');
|
|
164
|
+
const more = aliases.length > 5 ? ` +${aliases.length - 5} more` : '';
|
|
165
|
+
const summary = `[${this.agentsDone}/${this.totalAgents} done] ` +
|
|
166
|
+
(running > 0 ? `running: ${runningAliases}${more} | ` : '') +
|
|
167
|
+
`${this.commandsRun} cmds, ${this.filesChanged} files` +
|
|
168
|
+
(this.errorCount > 0 ? ` | ${this.errorCount} errors` : '');
|
|
169
|
+
this.progressCount++;
|
|
170
|
+
await this.sendProgress(summary, this.progressCount).catch(() => { });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function truncate(s, maxLen) {
|
|
174
|
+
return s.length > maxLen ? s.slice(0, maxLen) + '...' : s;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/wave/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GroupRegistry — single authoritative source for group state.
|
|
3
|
+
*
|
|
4
|
+
* Module-level singleton with JSONL persistence at
|
|
5
|
+
* ~/.mcp-codex-subagent/groups/<groupId>.jsonl
|
|
6
|
+
*
|
|
7
|
+
* Mirrors TaskStore patterns: explicit state machine, bounded,
|
|
8
|
+
* deterministic transitions.
|
|
9
|
+
*/
|
|
10
|
+
import { type GroupState, type AgentState, type GroupRecord, type AgentRecord, type AgentSpec } from './types.js';
|
|
11
|
+
export interface CreateGroupOptions {
|
|
12
|
+
agents: AgentSpec[];
|
|
13
|
+
baseCwd: string;
|
|
14
|
+
dependsOn: string[];
|
|
15
|
+
groupName?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class GroupRegistry {
|
|
18
|
+
private readonly groups;
|
|
19
|
+
createGroup(opts: CreateGroupOptions): GroupRecord;
|
|
20
|
+
transitionGroup(id: string, newState: GroupState, opts?: {
|
|
21
|
+
error?: string;
|
|
22
|
+
commitSha?: string;
|
|
23
|
+
baseCommit?: string;
|
|
24
|
+
}): boolean;
|
|
25
|
+
transitionAgent(groupId: string, alias: string, newState: AgentState, opts?: {
|
|
26
|
+
error?: string;
|
|
27
|
+
taskId?: string;
|
|
28
|
+
pid?: number;
|
|
29
|
+
}): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Increment the attempt counter for an agent.
|
|
32
|
+
*/
|
|
33
|
+
incrementAttempts(groupId: string, alias: string): void;
|
|
34
|
+
getGroup(id: string): GroupRecord | undefined;
|
|
35
|
+
getAllGroups(): GroupRecord[];
|
|
36
|
+
getAllNonTerminal(): GroupRecord[];
|
|
37
|
+
getAgent(groupId: string, alias: string): AgentRecord | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Check if all agents in a group have reached terminal states.
|
|
40
|
+
*/
|
|
41
|
+
allAgentsTerminal(groupId: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Check whether all dependencies are met for a group.
|
|
44
|
+
* Returns 'met' if all dep groups are done_success,
|
|
45
|
+
* 'failed' if any dep group is done_failed or done_timeout,
|
|
46
|
+
* 'pending' if any dep group is still running.
|
|
47
|
+
*/
|
|
48
|
+
areDependenciesMet(dependsOn: string[]): 'met' | 'pending' | 'failed';
|
|
49
|
+
/**
|
|
50
|
+
* Check if all agents that completed successfully.
|
|
51
|
+
*/
|
|
52
|
+
allAgentsSucceeded(groupId: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Write the group record to disk as JSONL.
|
|
55
|
+
* Full rewrite (groups are small; simpler than append-only).
|
|
56
|
+
*/
|
|
57
|
+
persist(id: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Load all group records from disk on startup.
|
|
60
|
+
*/
|
|
61
|
+
loadAll(): void;
|
|
62
|
+
resetForTesting(): void;
|
|
63
|
+
private generateUniqueId;
|
|
64
|
+
}
|
|
65
|
+
export declare const groupRegistry: GroupRegistry;
|
|
66
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/wave/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EAMf,MAAM,YAAY,CAAC;AAoBpB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAMzD,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW;IA0ClD,eAAe,CACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,UAAU,EACpB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO;IAwBV,eAAe,CACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,UAAU,EACpB,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GACA,OAAO;IA2BV;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWvD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI7C,YAAY,IAAI,WAAW,EAAE;IAI7B,iBAAiB,IAAI,WAAW,EAAE;IAIlC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIjE;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAM3C;;;;;OAKG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ;IAgBrE;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAU5C;;;OAGG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAuDzB;;OAEG;IACH,OAAO,IAAI,IAAI;IA0Ef,eAAe,IAAI,IAAI;IASvB,OAAO,CAAC,gBAAgB;CAYzB;AAGD,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GroupRegistry — single authoritative source for group state.
|
|
3
|
+
*
|
|
4
|
+
* Module-level singleton with JSONL persistence at
|
|
5
|
+
* ~/.mcp-codex-subagent/groups/<groupId>.jsonl
|
|
6
|
+
*
|
|
7
|
+
* Mirrors TaskStore patterns: explicit state machine, bounded,
|
|
8
|
+
* deterministic transitions.
|
|
9
|
+
*/
|
|
10
|
+
import { mkdirSync, writeFileSync, readdirSync, readFileSync } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { CONFIG_HOME } from '../types.js';
|
|
13
|
+
import { generateTaskId, normalizeTaskId } from '../utils/task-id-generator.js';
|
|
14
|
+
import { isValidGroupTransition, isGroupTerminal, isValidAgentTransition, isAgentTerminal, DEFAULT_MAX_ATTEMPTS, } from './types.js';
|
|
15
|
+
const GROUPS_DIR = join(CONFIG_HOME, 'groups');
|
|
16
|
+
// Ensure groups directory exists
|
|
17
|
+
let groupsDirReady = false;
|
|
18
|
+
function ensureGroupsDir() {
|
|
19
|
+
if (groupsDirReady)
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
mkdirSync(GROUPS_DIR, { recursive: true });
|
|
23
|
+
groupsDirReady = true;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Best-effort
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// GroupRegistry Class
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
export class GroupRegistry {
|
|
33
|
+
groups = new Map();
|
|
34
|
+
// -----------------------------------------------------------------------
|
|
35
|
+
// Group creation
|
|
36
|
+
// -----------------------------------------------------------------------
|
|
37
|
+
createGroup(opts) {
|
|
38
|
+
const id = this.generateUniqueId();
|
|
39
|
+
const groupName = opts.groupName || id;
|
|
40
|
+
const branch = `sub-agent/${id}`;
|
|
41
|
+
const worktreePath = join(opts.baseCwd, '.worktree', `${id}-${groupName}`);
|
|
42
|
+
const agents = opts.agents.map((spec) => ({
|
|
43
|
+
alias: spec.alias,
|
|
44
|
+
state: 'pending',
|
|
45
|
+
prompt: spec.prompt.length > 200
|
|
46
|
+
? spec.prompt.slice(0, 200) + '...'
|
|
47
|
+
: spec.prompt,
|
|
48
|
+
role: spec.role,
|
|
49
|
+
specialization: spec.specialization,
|
|
50
|
+
dependsOn: spec.depends_on ?? [],
|
|
51
|
+
attempts: 0,
|
|
52
|
+
maxAttempts: spec.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,
|
|
53
|
+
}));
|
|
54
|
+
const group = {
|
|
55
|
+
id,
|
|
56
|
+
state: 'waiting_deps',
|
|
57
|
+
agents,
|
|
58
|
+
branch,
|
|
59
|
+
worktreePath,
|
|
60
|
+
baseCwd: opts.baseCwd,
|
|
61
|
+
baseCommit: '', // set during worktree creation
|
|
62
|
+
dependsOn: opts.dependsOn,
|
|
63
|
+
groupName,
|
|
64
|
+
createdAt: new Date().toISOString(),
|
|
65
|
+
};
|
|
66
|
+
this.groups.set(normalizeTaskId(id), group);
|
|
67
|
+
this.persist(id);
|
|
68
|
+
return group;
|
|
69
|
+
}
|
|
70
|
+
// -----------------------------------------------------------------------
|
|
71
|
+
// Group state transitions
|
|
72
|
+
// -----------------------------------------------------------------------
|
|
73
|
+
transitionGroup(id, newState, opts) {
|
|
74
|
+
const group = this.getGroup(id);
|
|
75
|
+
if (!group)
|
|
76
|
+
return false;
|
|
77
|
+
if (!isValidGroupTransition(group.state, newState))
|
|
78
|
+
return false;
|
|
79
|
+
group.state = newState;
|
|
80
|
+
if (opts?.error)
|
|
81
|
+
group.error = opts.error;
|
|
82
|
+
if (opts?.commitSha)
|
|
83
|
+
group.commitSha = opts.commitSha;
|
|
84
|
+
if (opts?.baseCommit)
|
|
85
|
+
group.baseCommit = opts.baseCommit;
|
|
86
|
+
if (isGroupTerminal(newState)) {
|
|
87
|
+
group.completedAt = new Date().toISOString();
|
|
88
|
+
}
|
|
89
|
+
this.persist(id);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
// -----------------------------------------------------------------------
|
|
93
|
+
// Agent state transitions
|
|
94
|
+
// -----------------------------------------------------------------------
|
|
95
|
+
transitionAgent(groupId, alias, newState, opts) {
|
|
96
|
+
const group = this.getGroup(groupId);
|
|
97
|
+
if (!group)
|
|
98
|
+
return false;
|
|
99
|
+
const agent = group.agents.find((a) => a.alias === alias);
|
|
100
|
+
if (!agent)
|
|
101
|
+
return false;
|
|
102
|
+
if (!isValidAgentTransition(agent.state, newState))
|
|
103
|
+
return false;
|
|
104
|
+
agent.state = newState;
|
|
105
|
+
if (opts?.error)
|
|
106
|
+
agent.error = opts.error;
|
|
107
|
+
if (opts?.taskId)
|
|
108
|
+
agent.taskId = opts.taskId;
|
|
109
|
+
if (opts?.pid)
|
|
110
|
+
agent.pid = opts.pid;
|
|
111
|
+
if (newState === 'running' && !agent.startedAt) {
|
|
112
|
+
agent.startedAt = new Date().toISOString();
|
|
113
|
+
}
|
|
114
|
+
if (isAgentTerminal(newState)) {
|
|
115
|
+
agent.completedAt = new Date().toISOString();
|
|
116
|
+
}
|
|
117
|
+
// Don't persist on every agent transition (too frequent)
|
|
118
|
+
// Caller can call persist() explicitly when needed
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Increment the attempt counter for an agent.
|
|
123
|
+
*/
|
|
124
|
+
incrementAttempts(groupId, alias) {
|
|
125
|
+
const group = this.getGroup(groupId);
|
|
126
|
+
if (!group)
|
|
127
|
+
return;
|
|
128
|
+
const agent = group.agents.find((a) => a.alias === alias);
|
|
129
|
+
if (agent)
|
|
130
|
+
agent.attempts++;
|
|
131
|
+
}
|
|
132
|
+
// -----------------------------------------------------------------------
|
|
133
|
+
// Queries
|
|
134
|
+
// -----------------------------------------------------------------------
|
|
135
|
+
getGroup(id) {
|
|
136
|
+
return this.groups.get(normalizeTaskId(id));
|
|
137
|
+
}
|
|
138
|
+
getAllGroups() {
|
|
139
|
+
return [...this.groups.values()];
|
|
140
|
+
}
|
|
141
|
+
getAllNonTerminal() {
|
|
142
|
+
return [...this.groups.values()].filter((g) => !isGroupTerminal(g.state));
|
|
143
|
+
}
|
|
144
|
+
getAgent(groupId, alias) {
|
|
145
|
+
return this.getGroup(groupId)?.agents.find((a) => a.alias === alias);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Check if all agents in a group have reached terminal states.
|
|
149
|
+
*/
|
|
150
|
+
allAgentsTerminal(groupId) {
|
|
151
|
+
const group = this.getGroup(groupId);
|
|
152
|
+
if (!group)
|
|
153
|
+
return true;
|
|
154
|
+
return group.agents.every((a) => isAgentTerminal(a.state));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check whether all dependencies are met for a group.
|
|
158
|
+
* Returns 'met' if all dep groups are done_success,
|
|
159
|
+
* 'failed' if any dep group is done_failed or done_timeout,
|
|
160
|
+
* 'pending' if any dep group is still running.
|
|
161
|
+
*/
|
|
162
|
+
areDependenciesMet(dependsOn) {
|
|
163
|
+
if (dependsOn.length === 0)
|
|
164
|
+
return 'met';
|
|
165
|
+
for (const depId of dependsOn) {
|
|
166
|
+
const dep = this.getGroup(depId);
|
|
167
|
+
if (!dep)
|
|
168
|
+
return 'failed'; // dep doesn't exist
|
|
169
|
+
if (dep.state === 'done_success')
|
|
170
|
+
continue;
|
|
171
|
+
if (dep.state === 'done_failed' || dep.state === 'done_timeout') {
|
|
172
|
+
return 'failed';
|
|
173
|
+
}
|
|
174
|
+
return 'pending'; // still running
|
|
175
|
+
}
|
|
176
|
+
return 'met';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if all agents that completed successfully.
|
|
180
|
+
*/
|
|
181
|
+
allAgentsSucceeded(groupId) {
|
|
182
|
+
const group = this.getGroup(groupId);
|
|
183
|
+
if (!group)
|
|
184
|
+
return false;
|
|
185
|
+
return group.agents.every((a) => a.state === 'done_success');
|
|
186
|
+
}
|
|
187
|
+
// -----------------------------------------------------------------------
|
|
188
|
+
// Persistence (JSONL)
|
|
189
|
+
// -----------------------------------------------------------------------
|
|
190
|
+
/**
|
|
191
|
+
* Write the group record to disk as JSONL.
|
|
192
|
+
* Full rewrite (groups are small; simpler than append-only).
|
|
193
|
+
*/
|
|
194
|
+
persist(id) {
|
|
195
|
+
const group = this.getGroup(id);
|
|
196
|
+
if (!group)
|
|
197
|
+
return;
|
|
198
|
+
ensureGroupsDir();
|
|
199
|
+
const lines = [];
|
|
200
|
+
// Meta line (group-level state without agent details)
|
|
201
|
+
const meta = {
|
|
202
|
+
type: 'meta',
|
|
203
|
+
id: group.id,
|
|
204
|
+
state: group.state,
|
|
205
|
+
branch: group.branch,
|
|
206
|
+
worktreePath: group.worktreePath,
|
|
207
|
+
baseCwd: group.baseCwd,
|
|
208
|
+
baseCommit: group.baseCommit,
|
|
209
|
+
dependsOn: group.dependsOn,
|
|
210
|
+
groupName: group.groupName,
|
|
211
|
+
createdAt: group.createdAt,
|
|
212
|
+
completedAt: group.completedAt,
|
|
213
|
+
commitSha: group.commitSha,
|
|
214
|
+
error: group.error,
|
|
215
|
+
};
|
|
216
|
+
lines.push(JSON.stringify(meta));
|
|
217
|
+
// Agent lines
|
|
218
|
+
for (const agent of group.agents) {
|
|
219
|
+
const agentLine = {
|
|
220
|
+
type: 'agent',
|
|
221
|
+
alias: agent.alias,
|
|
222
|
+
state: agent.state,
|
|
223
|
+
taskId: agent.taskId,
|
|
224
|
+
prompt: agent.prompt,
|
|
225
|
+
role: agent.role,
|
|
226
|
+
specialization: agent.specialization,
|
|
227
|
+
dependsOn: agent.dependsOn,
|
|
228
|
+
attempts: agent.attempts,
|
|
229
|
+
maxAttempts: agent.maxAttempts,
|
|
230
|
+
error: agent.error,
|
|
231
|
+
startedAt: agent.startedAt,
|
|
232
|
+
completedAt: agent.completedAt,
|
|
233
|
+
pid: agent.pid,
|
|
234
|
+
};
|
|
235
|
+
lines.push(JSON.stringify(agentLine));
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const filePath = join(GROUPS_DIR, `${group.id}.jsonl`);
|
|
239
|
+
writeFileSync(filePath, lines.join('\n') + '\n', 'utf-8');
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Best-effort persistence
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Load all group records from disk on startup.
|
|
247
|
+
*/
|
|
248
|
+
loadAll() {
|
|
249
|
+
ensureGroupsDir();
|
|
250
|
+
let files;
|
|
251
|
+
try {
|
|
252
|
+
files = readdirSync(GROUPS_DIR).filter((f) => f.endsWith('.jsonl'));
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
for (const file of files) {
|
|
258
|
+
try {
|
|
259
|
+
const content = readFileSync(join(GROUPS_DIR, file), 'utf-8');
|
|
260
|
+
const lines = content.split('\n').filter((l) => l.trim());
|
|
261
|
+
let group = null;
|
|
262
|
+
const agents = [];
|
|
263
|
+
for (const line of lines) {
|
|
264
|
+
try {
|
|
265
|
+
const parsed = JSON.parse(line);
|
|
266
|
+
if (parsed.type === 'meta') {
|
|
267
|
+
group = {
|
|
268
|
+
id: parsed.id,
|
|
269
|
+
state: parsed.state,
|
|
270
|
+
agents: [], // filled below
|
|
271
|
+
branch: parsed.branch,
|
|
272
|
+
worktreePath: parsed.worktreePath,
|
|
273
|
+
baseCwd: parsed.baseCwd,
|
|
274
|
+
baseCommit: parsed.baseCommit ?? '',
|
|
275
|
+
dependsOn: parsed.dependsOn ?? [],
|
|
276
|
+
groupName: parsed.groupName,
|
|
277
|
+
createdAt: parsed.createdAt,
|
|
278
|
+
completedAt: parsed.completedAt,
|
|
279
|
+
commitSha: parsed.commitSha,
|
|
280
|
+
error: parsed.error,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
else if (parsed.type === 'agent') {
|
|
284
|
+
agents.push({
|
|
285
|
+
alias: parsed.alias,
|
|
286
|
+
state: parsed.state,
|
|
287
|
+
taskId: parsed.taskId,
|
|
288
|
+
prompt: parsed.prompt ?? '',
|
|
289
|
+
role: parsed.role,
|
|
290
|
+
specialization: parsed.specialization,
|
|
291
|
+
dependsOn: parsed.dependsOn ?? [],
|
|
292
|
+
attempts: parsed.attempts ?? 0,
|
|
293
|
+
maxAttempts: parsed.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,
|
|
294
|
+
error: parsed.error,
|
|
295
|
+
startedAt: parsed.startedAt,
|
|
296
|
+
completedAt: parsed.completedAt,
|
|
297
|
+
pid: parsed.pid,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Skip malformed lines
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (group) {
|
|
306
|
+
group.agents = agents;
|
|
307
|
+
this.groups.set(normalizeTaskId(group.id), group);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
// Skip unreadable files
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// -----------------------------------------------------------------------
|
|
316
|
+
// Testing
|
|
317
|
+
// -----------------------------------------------------------------------
|
|
318
|
+
resetForTesting() {
|
|
319
|
+
this.groups.clear();
|
|
320
|
+
groupsDirReady = false;
|
|
321
|
+
}
|
|
322
|
+
// -----------------------------------------------------------------------
|
|
323
|
+
// Private helpers
|
|
324
|
+
// -----------------------------------------------------------------------
|
|
325
|
+
generateUniqueId() {
|
|
326
|
+
let id = generateTaskId();
|
|
327
|
+
let attempts = 0;
|
|
328
|
+
while (this.groups.has(normalizeTaskId(id)) && attempts < 20) {
|
|
329
|
+
id = generateTaskId();
|
|
330
|
+
attempts++;
|
|
331
|
+
}
|
|
332
|
+
if (this.groups.has(normalizeTaskId(id))) {
|
|
333
|
+
id = `group-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
|
|
334
|
+
}
|
|
335
|
+
return id;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Module-level singleton
|
|
339
|
+
export const groupRegistry = new GroupRegistry();
|
|
340
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/wave/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async counting semaphore with FIFO fairness for global concurrency control.
|
|
3
|
+
*
|
|
4
|
+
* Module-level singleton shared across all groups.
|
|
5
|
+
* Supports AbortSignal for timeout/shutdown cancellation.
|
|
6
|
+
*/
|
|
7
|
+
export declare class AsyncSemaphore {
|
|
8
|
+
private permits;
|
|
9
|
+
readonly maxPermits: number;
|
|
10
|
+
private readonly queue;
|
|
11
|
+
private disposed;
|
|
12
|
+
constructor(maxPermits?: number);
|
|
13
|
+
/**
|
|
14
|
+
* Acquire a permit. Resolves immediately if available,
|
|
15
|
+
* otherwise FIFO-queues until a permit is released.
|
|
16
|
+
*
|
|
17
|
+
* Rejects if:
|
|
18
|
+
* - The semaphore has been disposed
|
|
19
|
+
* - The provided AbortSignal fires while queued
|
|
20
|
+
*/
|
|
21
|
+
acquire(signal?: AbortSignal): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Release a permit. Wakes the oldest queued waiter (FIFO)
|
|
24
|
+
* or increments the available permit count.
|
|
25
|
+
*/
|
|
26
|
+
release(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Dispose the semaphore: reject all queued waiters and prevent
|
|
29
|
+
* future acquisitions. Called on server shutdown.
|
|
30
|
+
*/
|
|
31
|
+
dispose(): void;
|
|
32
|
+
/** Number of permits currently available. */
|
|
33
|
+
get available(): number;
|
|
34
|
+
/** Number of waiters currently queued. */
|
|
35
|
+
get waiting(): number;
|
|
36
|
+
/** Whether the semaphore has been disposed. */
|
|
37
|
+
get isDisposed(): boolean;
|
|
38
|
+
/** Reset for testing. */
|
|
39
|
+
resetForTesting(): void;
|
|
40
|
+
}
|
|
41
|
+
export declare const concurrencySemaphore: AsyncSemaphore;
|
|
42
|
+
//# sourceMappingURL=semaphore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semaphore.d.ts","sourceRoot":"","sources":["../../src/wave/semaphore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAS;gBAEb,UAAU,CAAC,EAAE,MAAM;IAK/B;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC5C;;;OAGG;IACH,OAAO,IAAI,IAAI;IAef;;;OAGG;IACH,OAAO,IAAI,IAAI;IAYf,6CAA6C;IAC7C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0CAA0C;IAC1C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,+CAA+C;IAC/C,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,yBAAyB;IACzB,eAAe,IAAI,IAAI;CAWxB;AAGD,eAAO,MAAM,oBAAoB,gBAAuB,CAAC"}
|