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 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.6",
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.6",
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) => setTimeout(() => reject(new Error(`Reviewer dispatch timed out after ${timeoutMs}ms`)), timeoutMs))
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(() => reject(new Error(`auto-review timed out after ${timeoutMs}ms`)), timeoutMs);
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
- }), timeoutMs, `Lane "${lane.id}" session.prompt timed out after ${timeoutMs}ms`);
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(() => reject(new Error(message)), timeoutMs);
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 dispatchPromise = this._doDispatch(session, lane, agentName, worktreeDirectory);
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
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Lane dispatch timed out after ${timeoutMs}ms`)), timeoutMs));
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
- const sessionId = createResult.data.id;
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
  }
@@ -69,6 +69,7 @@ export interface SessionOps {
69
69
  text: string;
70
70
  }>;
71
71
  };
72
+ signal?: AbortSignal;
72
73
  }): Promise<{
73
74
  data?: {
74
75
  parts?: Array<{
@@ -63,6 +63,7 @@ interface SessionClient {
63
63
  text: string;
64
64
  }>;
65
65
  };
66
+ signal?: AbortSignal;
66
67
  }): Promise<{
67
68
  data: {
68
69
  parts: Array<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.77.6",
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",