opencode-swarm 7.77.6 → 7.77.7
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/cli/index.js +1 -1
- package/dist/index.js +71 -18
- package/dist/tools/dispatch-lanes.d.ts +1 -0
- package/dist/turbo/lean/runner.d.ts +1 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.77.
|
|
55
|
+
version: "7.77.7",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.77.
|
|
72
|
+
version: "7.77.7",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -105641,7 +105641,9 @@ async function dispatchFullAutoOversight(input) {
|
|
|
105641
105641
|
const oversightAgent = createCriticAutonomousOversightAgent(input.criticModel, buildOversightPrompt(input));
|
|
105642
105642
|
log(`[full-auto/oversight] Dispatching ${oversightAgent.name} via ${input.oversightAgentName} (model=${input.criticModel}, trigger=${input.triggerSource})`);
|
|
105643
105643
|
let ephemeralSessionId;
|
|
105644
|
+
const promptController = new AbortController;
|
|
105644
105645
|
const cleanup = () => {
|
|
105646
|
+
promptController.abort();
|
|
105645
105647
|
if (ephemeralSessionId) {
|
|
105646
105648
|
const id = ephemeralSessionId;
|
|
105647
105649
|
ephemeralSessionId = undefined;
|
|
@@ -105670,7 +105672,8 @@ async function dispatchFullAutoOversight(input) {
|
|
|
105670
105672
|
agent: input.oversightAgentName,
|
|
105671
105673
|
tools: { write: false, edit: false, patch: false },
|
|
105672
105674
|
parts: [{ type: "text", text: buildOversightPrompt(input) }]
|
|
105673
|
-
}
|
|
105675
|
+
},
|
|
105676
|
+
signal: promptController.signal
|
|
105674
105677
|
});
|
|
105675
105678
|
if (!promptResult.data) {
|
|
105676
105679
|
throw new Error(`Critic prompt failed: ${JSON.stringify(promptResult.error)}`);
|
|
@@ -107582,7 +107585,9 @@ async function dispatchCriticAndWriteEvent(directory, architectOutput, criticCon
|
|
|
107582
107585
|
const oversightAgent = createCriticAutonomousOversightAgent(criticModel, criticContext);
|
|
107583
107586
|
log(`[full-auto-intercept] Dispatching critic: ${oversightAgent.name} using model ${criticModel}`);
|
|
107584
107587
|
let ephemeralSessionId;
|
|
107588
|
+
const promptController = new AbortController;
|
|
107585
107589
|
const cleanup = () => {
|
|
107590
|
+
promptController.abort();
|
|
107586
107591
|
if (ephemeralSessionId) {
|
|
107587
107592
|
const id = ephemeralSessionId;
|
|
107588
107593
|
ephemeralSessionId = undefined;
|
|
@@ -107608,7 +107613,8 @@ async function dispatchCriticAndWriteEvent(directory, architectOutput, criticCon
|
|
|
107608
107613
|
agent: oversightAgentName,
|
|
107609
107614
|
tools: { write: false, edit: false, patch: false },
|
|
107610
107615
|
parts: [{ type: "text", text: criticContext }]
|
|
107611
|
-
}
|
|
107616
|
+
},
|
|
107617
|
+
signal: promptController.signal
|
|
107612
107618
|
});
|
|
107613
107619
|
if (!promptResult.data) {
|
|
107614
107620
|
throw new Error(`Critic LLM prompt failed: ${JSON.stringify(promptResult.error)}`);
|
|
@@ -114189,6 +114195,8 @@ async function defaultDispatchReviewerAgent(directory, reviewPackage, agentName,
|
|
|
114189
114195
|
throw new Error("Failed to create reviewer session");
|
|
114190
114196
|
}
|
|
114191
114197
|
const sessionId = sessionResult.data.id;
|
|
114198
|
+
const promptController = new AbortController;
|
|
114199
|
+
let timeoutHandle;
|
|
114192
114200
|
try {
|
|
114193
114201
|
const promptText = `You are a read-only phase reviewer for Lean Turbo execution.
|
|
114194
114202
|
|
|
@@ -114233,16 +114241,23 @@ Be specific and evidence-based. Do not approve a phase with unresolved degraded
|
|
|
114233
114241
|
agent: agentName,
|
|
114234
114242
|
tools: { write: false, edit: false, patch: false },
|
|
114235
114243
|
parts: [{ type: "text", text: promptText }]
|
|
114236
|
-
}
|
|
114244
|
+
},
|
|
114245
|
+
signal: promptController.signal
|
|
114237
114246
|
}),
|
|
114238
|
-
new Promise((_, reject) =>
|
|
114247
|
+
new Promise((_, reject) => {
|
|
114248
|
+
timeoutHandle = setTimeout(() => {
|
|
114249
|
+
promptController.abort();
|
|
114250
|
+
reject(new Error(`Reviewer dispatch timed out after ${timeoutMs}ms`));
|
|
114251
|
+
}, timeoutMs);
|
|
114252
|
+
})
|
|
114239
114253
|
]) : await client.session.prompt({
|
|
114240
114254
|
path: { id: sessionId },
|
|
114241
114255
|
body: {
|
|
114242
114256
|
agent: agentName,
|
|
114243
114257
|
tools: { write: false, edit: false, patch: false },
|
|
114244
114258
|
parts: [{ type: "text", text: promptText }]
|
|
114245
|
-
}
|
|
114259
|
+
},
|
|
114260
|
+
signal: promptController.signal
|
|
114246
114261
|
});
|
|
114247
114262
|
if (!response.data) {
|
|
114248
114263
|
throw new Error("Reviewer session returned no data");
|
|
@@ -114251,6 +114266,9 @@ Be specific and evidence-based. Do not approve a phase with unresolved degraded
|
|
|
114251
114266
|
`);
|
|
114252
114267
|
return textParts;
|
|
114253
114268
|
} finally {
|
|
114269
|
+
if (timeoutHandle !== undefined)
|
|
114270
|
+
clearTimeout(timeoutHandle);
|
|
114271
|
+
promptController.abort();
|
|
114254
114272
|
client.session.delete({ path: { id: sessionId } }).catch(() => {});
|
|
114255
114273
|
}
|
|
114256
114274
|
}
|
|
@@ -114534,6 +114552,7 @@ async function dispatchReviewer(directory, prompt, agentName, timeoutMs) {
|
|
|
114534
114552
|
throw new Error("Failed to create auto-review session");
|
|
114535
114553
|
}
|
|
114536
114554
|
const sessionId = createResult.data.id;
|
|
114555
|
+
const promptController = new AbortController;
|
|
114537
114556
|
let timeoutHandle;
|
|
114538
114557
|
try {
|
|
114539
114558
|
const promptCall = client.session.prompt({
|
|
@@ -114542,12 +114561,16 @@ async function dispatchReviewer(directory, prompt, agentName, timeoutMs) {
|
|
|
114542
114561
|
agent: agentName,
|
|
114543
114562
|
tools: { write: false, edit: false, patch: false },
|
|
114544
114563
|
parts: [{ type: "text", text: prompt }]
|
|
114545
|
-
}
|
|
114564
|
+
},
|
|
114565
|
+
signal: promptController.signal
|
|
114546
114566
|
});
|
|
114547
114567
|
const response = await Promise.race([
|
|
114548
114568
|
promptCall,
|
|
114549
114569
|
new Promise((_, reject) => {
|
|
114550
|
-
timeoutHandle = setTimeout(() =>
|
|
114570
|
+
timeoutHandle = setTimeout(() => {
|
|
114571
|
+
promptController.abort();
|
|
114572
|
+
reject(new Error(`auto-review timed out after ${timeoutMs}ms`));
|
|
114573
|
+
}, timeoutMs);
|
|
114551
114574
|
})
|
|
114552
114575
|
]);
|
|
114553
114576
|
if (!response.data) {
|
|
@@ -114558,6 +114581,7 @@ async function dispatchReviewer(directory, prompt, agentName, timeoutMs) {
|
|
|
114558
114581
|
} finally {
|
|
114559
114582
|
if (timeoutHandle !== undefined)
|
|
114560
114583
|
clearTimeout(timeoutHandle);
|
|
114584
|
+
promptController.abort();
|
|
114561
114585
|
client.session.delete({ path: { id: sessionId } }).catch(() => {});
|
|
114562
114586
|
}
|
|
114563
114587
|
}
|
|
@@ -124901,6 +124925,7 @@ async function runLane(session, dispatcher, lane, directory, timeoutMs, context)
|
|
|
124901
124925
|
error: `dispatcher ${decision.action}: ${decision.reason}`
|
|
124902
124926
|
};
|
|
124903
124927
|
}
|
|
124928
|
+
const promptController = new AbortController;
|
|
124904
124929
|
let sessionId;
|
|
124905
124930
|
try {
|
|
124906
124931
|
const createTimeoutMessage = `Lane "${lane.id}" session.create timed out after ${timeoutMs}ms`;
|
|
@@ -124929,8 +124954,9 @@ async function runLane(session, dispatcher, lane, directory, timeoutMs, context)
|
|
|
124929
124954
|
agent: lane.agent,
|
|
124930
124955
|
tools: buildReadOnlyTools(),
|
|
124931
124956
|
parts: [{ type: "text", text: lane.prompt }]
|
|
124932
|
-
}
|
|
124933
|
-
|
|
124957
|
+
},
|
|
124958
|
+
signal: promptController.signal
|
|
124959
|
+
}), timeoutMs, `Lane "${lane.id}" session.prompt timed out after ${timeoutMs}ms`, promptController);
|
|
124934
124960
|
if (!promptResult.data) {
|
|
124935
124961
|
return failedLane(lane, role, startedAt, `session.prompt failed: ${formatError3(promptResult.error)}`, decision.slot.slotId, decision.slot.runId, sessionId);
|
|
124936
124962
|
}
|
|
@@ -124951,6 +124977,7 @@ async function runLane(session, dispatcher, lane, directory, timeoutMs, context)
|
|
|
124951
124977
|
return failedLane(lane, role, startedAt, formatError3(error93), decision.slot.slotId, decision.slot.runId, sessionId);
|
|
124952
124978
|
} finally {
|
|
124953
124979
|
dispatcher.releaseSlot(decision.slot.slotId);
|
|
124980
|
+
promptController.abort();
|
|
124954
124981
|
if (sessionId) {
|
|
124955
124982
|
scheduleSessionCleanup(session, sessionId);
|
|
124956
124983
|
}
|
|
@@ -125088,13 +125115,19 @@ function scheduleSessionCleanup(session, sessionId) {
|
|
|
125088
125115
|
return;
|
|
125089
125116
|
});
|
|
125090
125117
|
}
|
|
125091
|
-
async function withTimeout2(promise3, timeoutMs, message) {
|
|
125118
|
+
async function withTimeout2(promise3, timeoutMs, message, controller) {
|
|
125092
125119
|
let timeout;
|
|
125093
125120
|
try {
|
|
125094
125121
|
return await Promise.race([
|
|
125095
125122
|
promise3,
|
|
125096
125123
|
new Promise((_, reject) => {
|
|
125097
|
-
timeout = setTimeout(() =>
|
|
125124
|
+
timeout = setTimeout(() => {
|
|
125125
|
+
controller?.abort();
|
|
125126
|
+
reject(new Error(message));
|
|
125127
|
+
}, timeoutMs);
|
|
125128
|
+
if (typeof timeout.unref === "function") {
|
|
125129
|
+
timeout.unref();
|
|
125130
|
+
}
|
|
125098
125131
|
})
|
|
125099
125132
|
]);
|
|
125100
125133
|
} finally {
|
|
@@ -127367,7 +127400,9 @@ async function generateMutants(files, ctx) {
|
|
|
127367
127400
|
}
|
|
127368
127401
|
const directory = ctx.directory ?? process.cwd();
|
|
127369
127402
|
let ephemeralSessionId;
|
|
127403
|
+
const promptController = new AbortController;
|
|
127370
127404
|
const cleanup = () => {
|
|
127405
|
+
promptController.abort();
|
|
127371
127406
|
if (ephemeralSessionId) {
|
|
127372
127407
|
const id = ephemeralSessionId;
|
|
127373
127408
|
ephemeralSessionId = undefined;
|
|
@@ -127414,7 +127449,8 @@ Return ONLY a valid JSON array. No markdown, no code fences, no explanation. Sta
|
|
|
127414
127449
|
agent: undefined,
|
|
127415
127450
|
tools: { write: false, edit: false, patch: false },
|
|
127416
127451
|
parts: [{ type: "text", text: promptText }]
|
|
127417
|
-
}
|
|
127452
|
+
},
|
|
127453
|
+
signal: promptController.signal
|
|
127418
127454
|
});
|
|
127419
127455
|
if (!promptResult.data) {
|
|
127420
127456
|
console.warn(`[generateMutants] LLM prompt failed: ${JSON.stringify(promptResult.error)}; returning empty patch set`);
|
|
@@ -130342,10 +130378,17 @@ class LeanTurboRunner {
|
|
|
130342
130378
|
if (!session) {
|
|
130343
130379
|
return { ok: false, error: "NO_CLIENT" };
|
|
130344
130380
|
}
|
|
130345
|
-
const
|
|
130381
|
+
const promptController = new AbortController;
|
|
130382
|
+
const dispatchPromise = this._doDispatch(session, lane, agentName, worktreeDirectory, promptController);
|
|
130346
130383
|
const timeoutMs = LeanTurboRunner._internals.laneDispatchTimeoutMs;
|
|
130347
130384
|
if (timeoutMs !== undefined && timeoutMs > 0) {
|
|
130348
|
-
|
|
130385
|
+
let timeoutHandle;
|
|
130386
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
130387
|
+
timeoutHandle = setTimeout(() => {
|
|
130388
|
+
promptController.abort();
|
|
130389
|
+
reject(new Error(`Lane dispatch timed out after ${timeoutMs}ms`));
|
|
130390
|
+
}, timeoutMs);
|
|
130391
|
+
});
|
|
130349
130392
|
try {
|
|
130350
130393
|
return await Promise.race([dispatchPromise, timeoutPromise]);
|
|
130351
130394
|
} catch (err2) {
|
|
@@ -130369,11 +130412,15 @@ class LeanTurboRunner {
|
|
|
130369
130412
|
return { ok: false, error: err2.message };
|
|
130370
130413
|
}
|
|
130371
130414
|
throw err2;
|
|
130415
|
+
} finally {
|
|
130416
|
+
if (timeoutHandle !== undefined)
|
|
130417
|
+
clearTimeout(timeoutHandle);
|
|
130372
130418
|
}
|
|
130373
130419
|
}
|
|
130374
130420
|
return dispatchPromise;
|
|
130375
130421
|
}
|
|
130376
|
-
async _doDispatch(session, lane, agentName, worktreeDirectory) {
|
|
130422
|
+
async _doDispatch(session, lane, agentName, worktreeDirectory, abortController) {
|
|
130423
|
+
let sessionId;
|
|
130377
130424
|
try {
|
|
130378
130425
|
const effectiveDirectory = worktreeDirectory ?? this._directory;
|
|
130379
130426
|
const createResult = await session.create({
|
|
@@ -130391,7 +130438,7 @@ class LeanTurboRunner {
|
|
|
130391
130438
|
error: `session.create failed: ${typeof createResult.error === "string" ? createResult.error : JSON.stringify(createResult.error)}`
|
|
130392
130439
|
};
|
|
130393
130440
|
}
|
|
130394
|
-
|
|
130441
|
+
sessionId = createResult.data.id;
|
|
130395
130442
|
const promptText = this._buildLanePrompt(lane);
|
|
130396
130443
|
const promptResult = await session.prompt({
|
|
130397
130444
|
path: { id: sessionId },
|
|
@@ -130399,9 +130446,11 @@ class LeanTurboRunner {
|
|
|
130399
130446
|
agent: agentName,
|
|
130400
130447
|
tools: { write: true, edit: true, patch: true },
|
|
130401
130448
|
parts: [{ type: "text", text: promptText }]
|
|
130402
|
-
}
|
|
130449
|
+
},
|
|
130450
|
+
signal: abortController?.signal
|
|
130403
130451
|
});
|
|
130404
130452
|
if (!promptResult.data) {
|
|
130453
|
+
abortController?.abort();
|
|
130405
130454
|
session.delete({ path: { id: sessionId } }).catch(() => {});
|
|
130406
130455
|
return {
|
|
130407
130456
|
ok: false,
|
|
@@ -130410,6 +130459,10 @@ class LeanTurboRunner {
|
|
|
130410
130459
|
}
|
|
130411
130460
|
return { ok: true, sessionId };
|
|
130412
130461
|
} catch (err2) {
|
|
130462
|
+
if (sessionId) {
|
|
130463
|
+
abortController?.abort();
|
|
130464
|
+
session.delete({ path: { id: sessionId } }).catch(() => {});
|
|
130465
|
+
}
|
|
130413
130466
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
130414
130467
|
return { ok: false, error: msg };
|
|
130415
130468
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.77.
|
|
3
|
+
"version": "7.77.7",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|