opencode-swarm 6.80.0 → 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.
package/dist/cli/index.js CHANGED
@@ -18738,6 +18738,15 @@ var ALL_AGENT_NAMES = [
18738
18738
  ORCHESTRATOR_NAME,
18739
18739
  ...ALL_SUBAGENT_NAMES
18740
18740
  ];
18741
+ var OPENCODE_NATIVE_AGENTS = new Set([
18742
+ "build",
18743
+ "plan",
18744
+ "general",
18745
+ "explore",
18746
+ "compaction",
18747
+ "title",
18748
+ "summary"
18749
+ ]);
18741
18750
  var AGENT_TOOL_MAP = {
18742
18751
  architect: [
18743
18752
  "checkpoint",
@@ -4,6 +4,7 @@ export declare const PIPELINE_AGENTS: readonly ["explorer", "coder", "test_engin
4
4
  export declare const ORCHESTRATOR_NAME: "architect";
5
5
  export declare const ALL_SUBAGENT_NAMES: readonly ["sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
6
6
  export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
7
+ export declare const OPENCODE_NATIVE_AGENTS: Set<"compaction" | "title" | "build" | "plan" | "general" | "explore" | "summary">;
7
8
  export type QAAgentName = (typeof QA_AGENTS)[number];
8
9
  export type PipelineAgentName = (typeof PIPELINE_AGENTS)[number];
9
10
  export type AgentName = (typeof ALL_AGENT_NAMES)[number];
@@ -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
@@ -129,7 +129,7 @@ function isLowCapabilityModel(modelId) {
129
129
  const lower = modelId.toLowerCase();
130
130
  return LOW_CAPABILITY_MODELS.some((substr) => lower.includes(substr));
131
131
  }
132
- var QA_AGENTS, PIPELINE_AGENTS, ORCHESTRATOR_NAME = "architect", ALL_SUBAGENT_NAMES, ALL_AGENT_NAMES, AGENT_TOOL_MAP, WRITE_TOOL_NAMES, TOOL_DESCRIPTIONS, DEFAULT_MODELS, DEFAULT_SCORING_CONFIG, LOW_CAPABILITY_MODELS, TURBO_MODE_BANNER = `## \uD83D\uDE80 TURBO MODE ACTIVE
132
+ var QA_AGENTS, PIPELINE_AGENTS, ORCHESTRATOR_NAME = "architect", ALL_SUBAGENT_NAMES, ALL_AGENT_NAMES, OPENCODE_NATIVE_AGENTS, AGENT_TOOL_MAP, WRITE_TOOL_NAMES, TOOL_DESCRIPTIONS, DEFAULT_MODELS, DEFAULT_SCORING_CONFIG, LOW_CAPABILITY_MODELS, TURBO_MODE_BANNER = `## \uD83D\uDE80 TURBO MODE ACTIVE
133
133
 
134
134
  **Speed optimization enabled for this session.**
135
135
 
@@ -177,6 +177,15 @@ var init_constants = __esm(() => {
177
177
  ORCHESTRATOR_NAME,
178
178
  ...ALL_SUBAGENT_NAMES
179
179
  ];
180
+ OPENCODE_NATIVE_AGENTS = new Set([
181
+ "build",
182
+ "plan",
183
+ "general",
184
+ "explore",
185
+ "compaction",
186
+ "title",
187
+ "summary"
188
+ ]);
180
189
  AGENT_TOOL_MAP = {
181
190
  architect: [
182
191
  "checkpoint",
@@ -22640,6 +22649,9 @@ function isWriteTool(toolName) {
22640
22649
  const normalized = normalizeToolName(toolName);
22641
22650
  return WRITE_TOOL_NAMES.includes(normalized);
22642
22651
  }
22652
+ function isNativeOpencodeAgent(agentName) {
22653
+ return OPENCODE_NATIVE_AGENTS.has(agentName.toLowerCase());
22654
+ }
22643
22655
  function isArchitect(sessionId) {
22644
22656
  const activeAgent = swarmState.activeAgent.get(sessionId);
22645
22657
  if (activeAgent) {
@@ -23538,17 +23550,23 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
23538
23550
  const strippedAgent = rawActiveAgent ? stripKnownSwarmPrefix(rawActiveAgent) : undefined;
23539
23551
  if (strippedAgent === ORCHESTRATOR_NAME)
23540
23552
  return null;
23553
+ if (strippedAgent && isNativeOpencodeAgent(strippedAgent))
23554
+ return null;
23541
23555
  const existingSession = swarmState.agentSessions.get(sessionID);
23542
23556
  if (existingSession) {
23543
23557
  const sessionAgent = stripKnownSwarmPrefix(existingSession.agentName);
23544
23558
  if (sessionAgent === ORCHESTRATOR_NAME)
23545
23559
  return null;
23560
+ if (isNativeOpencodeAgent(sessionAgent))
23561
+ return null;
23546
23562
  }
23547
23563
  const agentName = swarmState.activeAgent.get(sessionID) ?? ORCHESTRATOR_NAME;
23548
23564
  const session = ensureAgentSession(sessionID, agentName);
23549
23565
  const resolvedName = stripKnownSwarmPrefix(session.agentName);
23550
23566
  if (resolvedName === ORCHESTRATOR_NAME)
23551
23567
  return null;
23568
+ if (isNativeOpencodeAgent(resolvedName))
23569
+ return null;
23552
23570
  const agentConfig = resolveGuardrailsConfig(cfg, session.agentName);
23553
23571
  if (agentConfig.max_duration_minutes === 0 && agentConfig.max_tool_calls === 0) {
23554
23572
  return null;
@@ -24475,6 +24493,10 @@ var init_guardrails = __esm(() => {
24475
24493
  maxSize: 200
24476
24494
  });
24477
24495
  DEFAULT_AGENT_AUTHORITY_RULES = {
24496
+ build: {},
24497
+ plan: {},
24498
+ general: {},
24499
+ explore: {},
24478
24500
  architect: {
24479
24501
  blockedExact: [".swarm/plan.md", ".swarm/plan.json"],
24480
24502
  blockedZones: ["generated"]
@@ -65884,20 +65906,32 @@ Recommendation: Consider escalating to user or taking a different approach
65884
65906
  The current fix strategy appears to be cycling without progress`;
65885
65907
  return { eventLogged, checkpointCreated, message };
65886
65908
  }
65887
- var recentToolCalls = [];
65909
+ var recentToolCallsBySession = new Map;
65910
+ var lastSpiralTimestampBySession = new Map;
65888
65911
  var MAX_RECENT_CALLS = 20;
65889
65912
  var SPIRAL_THRESHOLD = 5;
65890
65913
  var SPIRAL_WINDOW_MS = 300000;
65891
- function recordToolCall(tool3, args2) {
65914
+ var SPIRAL_COOLDOWN_MS = 60000;
65915
+ var MAX_TRACKED_SESSIONS = 500;
65916
+ function recordToolCall(tool3, args2, sessionId) {
65892
65917
  const argsHash = typeof args2 === "string" ? args2.slice(0, 100) : JSON.stringify(args2 ?? "").slice(0, 100);
65893
- recentToolCalls.push({ tool: tool3, argsHash, timestamp: Date.now() });
65894
- if (recentToolCalls.length > MAX_RECENT_CALLS) {
65895
- 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();
65896
65926
  }
65897
65927
  }
65898
- async function detectDebuggingSpiral(_directory) {
65928
+ async function detectDebuggingSpiral(_directory, sessionId) {
65899
65929
  const now = Date.now();
65900
- 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);
65901
65935
  if (windowCalls.length < SPIRAL_THRESHOLD)
65902
65936
  return null;
65903
65937
  const lastN = windowCalls.slice(-SPIRAL_THRESHOLD);
@@ -65906,6 +65940,17 @@ async function detectDebuggingSpiral(_directory) {
65906
65940
  const allSameTool = lastN.every((c) => c.tool === firstTool);
65907
65941
  const allSimilarArgs = lastN.every((c) => c.argsHash === firstArgs);
65908
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
+ }
65909
65954
  return {
65910
65955
  pattern: "VELOCITY_RATIONALIZATION",
65911
65956
  severity: "HIGH",
@@ -67734,7 +67779,7 @@ var GUARD_KEYWORDS = [
67734
67779
  function isGuardKeyword(name2) {
67735
67780
  return GUARD_KEYWORDS.some((keyword) => {
67736
67781
  const ciKeyword = keyword.split("").map((c) => `[${c.toLowerCase()}${c.toUpperCase()}]`).join("");
67737
- const re = new RegExp("(?<![a-z])" + ciKeyword + "(?![a-z])");
67782
+ const re = new RegExp(`(?<![a-z])${ciKeyword}(?![a-z])`);
67738
67783
  return re.test(name2);
67739
67784
  });
67740
67785
  }
@@ -85875,12 +85920,12 @@ var OpenCodeSwarm = async (ctx) => {
85875
85920
  } catch {}
85876
85921
  }
85877
85922
  try {
85878
- recordToolCall(normalizedTool, input.args);
85923
+ recordToolCall(normalizedTool, input.args, input.sessionID);
85879
85924
  } catch {}
85880
85925
  try {
85881
- const spiralMatch = await detectDebuggingSpiral(ctx.directory);
85926
+ const spiralMatch = await detectDebuggingSpiral(ctx.directory, input.sessionID);
85882
85927
  if (spiralMatch) {
85883
- const taskId = swarmState.agentSessions.get(input.sessionID)?.currentTaskId ?? "unknown";
85928
+ const taskId = swarmState.agentSessions.get(input.sessionID)?.currentTaskId ?? `session-${input.sessionID.slice(0, 12)}`;
85884
85929
  const spiralResult = await handleDebuggingSpiral(spiralMatch, taskId, ctx.directory);
85885
85930
  const session = swarmState.agentSessions.get(input.sessionID);
85886
85931
  if (session) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.80.0",
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",