opencode-swarm 6.80.1 → 6.80.2

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.
@@ -42,9 +42,9 @@ export declare function handleDebuggingSpiral(match: AdversarialPatternMatch, ta
42
42
  * Record a tool call for debugging spiral detection.
43
43
  * Call this from toolAfter to track repetitive patterns.
44
44
  */
45
- export declare function recordToolCall(tool: string, args: unknown): void;
45
+ export declare function recordToolCall(tool: string, args: unknown, sessionId: string): void;
46
46
  /**
47
47
  * Detect debugging spiral: same tool called 5+ times in a row with similar args
48
48
  * within a 5-minute window. Indicates the agent is stuck in a loop.
49
49
  */
50
- export declare function detectDebuggingSpiral(_directory: string): Promise<AdversarialPatternMatch | null>;
50
+ export declare function detectDebuggingSpiral(_directory: string, sessionId: string): Promise<AdversarialPatternMatch | null>;
package/dist/index.js CHANGED
@@ -65906,20 +65906,32 @@ Recommendation: Consider escalating to user or taking a different approach
65906
65906
  The current fix strategy appears to be cycling without progress`;
65907
65907
  return { eventLogged, checkpointCreated, message };
65908
65908
  }
65909
- var recentToolCalls = [];
65909
+ var recentToolCallsBySession = new Map;
65910
+ var lastSpiralTimestampBySession = new Map;
65910
65911
  var MAX_RECENT_CALLS = 20;
65911
65912
  var SPIRAL_THRESHOLD = 5;
65912
65913
  var SPIRAL_WINDOW_MS = 300000;
65913
- function recordToolCall(tool3, args2) {
65914
+ var SPIRAL_COOLDOWN_MS = 60000;
65915
+ var MAX_TRACKED_SESSIONS = 500;
65916
+ function recordToolCall(tool3, args2, sessionId) {
65914
65917
  const argsHash = typeof args2 === "string" ? args2.slice(0, 100) : JSON.stringify(args2 ?? "").slice(0, 100);
65915
- recentToolCalls.push({ tool: tool3, argsHash, timestamp: Date.now() });
65916
- if (recentToolCalls.length > MAX_RECENT_CALLS) {
65917
- recentToolCalls.shift();
65918
+ let calls = recentToolCallsBySession.get(sessionId);
65919
+ if (!calls) {
65920
+ calls = [];
65921
+ recentToolCallsBySession.set(sessionId, calls);
65922
+ }
65923
+ calls.push({ tool: tool3, argsHash, timestamp: Date.now() });
65924
+ if (calls.length > MAX_RECENT_CALLS) {
65925
+ calls.shift();
65918
65926
  }
65919
65927
  }
65920
- async function detectDebuggingSpiral(_directory) {
65928
+ async function detectDebuggingSpiral(_directory, sessionId) {
65921
65929
  const now = Date.now();
65922
- const windowCalls = recentToolCalls.filter((c) => now - c.timestamp < SPIRAL_WINDOW_MS);
65930
+ const lastTrigger = lastSpiralTimestampBySession.get(sessionId) ?? 0;
65931
+ if (now - lastTrigger < SPIRAL_COOLDOWN_MS)
65932
+ return null;
65933
+ const calls = recentToolCallsBySession.get(sessionId) ?? [];
65934
+ const windowCalls = calls.filter((c) => now - c.timestamp < SPIRAL_WINDOW_MS);
65923
65935
  if (windowCalls.length < SPIRAL_THRESHOLD)
65924
65936
  return null;
65925
65937
  const lastN = windowCalls.slice(-SPIRAL_THRESHOLD);
@@ -65928,6 +65940,17 @@ async function detectDebuggingSpiral(_directory) {
65928
65940
  const allSameTool = lastN.every((c) => c.tool === firstTool);
65929
65941
  const allSimilarArgs = lastN.every((c) => c.argsHash === firstArgs);
65930
65942
  if (allSameTool && allSimilarArgs) {
65943
+ lastSpiralTimestampBySession.set(sessionId, now);
65944
+ recentToolCallsBySession.delete(sessionId);
65945
+ if (lastSpiralTimestampBySession.size > MAX_TRACKED_SESSIONS) {
65946
+ for (const oldest of lastSpiralTimestampBySession.keys()) {
65947
+ if (oldest !== sessionId) {
65948
+ lastSpiralTimestampBySession.delete(oldest);
65949
+ recentToolCallsBySession.delete(oldest);
65950
+ break;
65951
+ }
65952
+ }
65953
+ }
65931
65954
  return {
65932
65955
  pattern: "VELOCITY_RATIONALIZATION",
65933
65956
  severity: "HIGH",
@@ -85897,12 +85920,12 @@ var OpenCodeSwarm = async (ctx) => {
85897
85920
  } catch {}
85898
85921
  }
85899
85922
  try {
85900
- recordToolCall(normalizedTool, input.args);
85923
+ recordToolCall(normalizedTool, input.args, input.sessionID);
85901
85924
  } catch {}
85902
85925
  try {
85903
- const spiralMatch = await detectDebuggingSpiral(ctx.directory);
85926
+ const spiralMatch = await detectDebuggingSpiral(ctx.directory, input.sessionID);
85904
85927
  if (spiralMatch) {
85905
- const taskId = swarmState.agentSessions.get(input.sessionID)?.currentTaskId ?? "unknown";
85928
+ const taskId = swarmState.agentSessions.get(input.sessionID)?.currentTaskId ?? `session-${input.sessionID.slice(0, 12)}`;
85906
85929
  const spiralResult = await handleDebuggingSpiral(spiralMatch, taskId, ctx.directory);
85907
85930
  const session = swarmState.agentSessions.get(input.sessionID);
85908
85931
  if (session) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.80.1",
3
+ "version": "6.80.2",
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",