opencode-swarm 5.0.4 → 5.0.5

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.
@@ -45,7 +45,15 @@ export declare const GuardrailsProfileSchema: z.ZodObject<{
45
45
  warning_threshold: z.ZodOptional<z.ZodNumber>;
46
46
  }, z.core.$strip>;
47
47
  export type GuardrailsProfile = z.infer<typeof GuardrailsProfileSchema>;
48
- export declare const DEFAULT_ARCHITECT_PROFILE: GuardrailsProfile;
48
+ export declare const DEFAULT_AGENT_PROFILES: Record<string, GuardrailsProfile>;
49
+ /** @deprecated Use DEFAULT_AGENT_PROFILES.architect instead */
50
+ export declare const DEFAULT_ARCHITECT_PROFILE: {
51
+ max_tool_calls?: number | undefined;
52
+ max_duration_minutes?: number | undefined;
53
+ max_repetitions?: number | undefined;
54
+ max_consecutive_errors?: number | undefined;
55
+ warning_threshold?: number | undefined;
56
+ };
49
57
  export declare const GuardrailsConfigSchema: z.ZodObject<{
50
58
  enabled: z.ZodDefault<z.ZodBoolean>;
51
59
  max_tool_calls: z.ZodDefault<z.ZodNumber>;
@@ -76,7 +84,7 @@ export type GuardrailsConfig = z.infer<typeof GuardrailsConfigSchema>;
76
84
  export declare function stripKnownSwarmPrefix(name: string): string;
77
85
  /**
78
86
  * Resolve guardrails configuration for a specific agent.
79
- * Merges the base config with built-in defaults (for the architect) and
87
+ * Merges the base config with built-in agent-type defaults and
80
88
  * any per-agent profile overrides. Merge order: base < built-in < user profile.
81
89
  *
82
90
  * @param base - The base guardrails configuration
package/dist/index.js CHANGED
@@ -13623,19 +13623,52 @@ var GuardrailsProfileSchema = exports_external.object({
13623
13623
  max_consecutive_errors: exports_external.number().min(2).max(20).optional(),
13624
13624
  warning_threshold: exports_external.number().min(0.1).max(0.9).optional()
13625
13625
  });
13626
- var DEFAULT_ARCHITECT_PROFILE = {
13627
- max_tool_calls: 600,
13628
- max_duration_minutes: 90,
13629
- max_consecutive_errors: 8,
13630
- warning_threshold: 0.7
13626
+ var DEFAULT_AGENT_PROFILES = {
13627
+ architect: {
13628
+ max_tool_calls: 800,
13629
+ max_duration_minutes: 90,
13630
+ max_consecutive_errors: 8,
13631
+ warning_threshold: 0.75
13632
+ },
13633
+ coder: {
13634
+ max_tool_calls: 400,
13635
+ max_duration_minutes: 45,
13636
+ warning_threshold: 0.85
13637
+ },
13638
+ test_engineer: {
13639
+ max_tool_calls: 400,
13640
+ max_duration_minutes: 45,
13641
+ warning_threshold: 0.85
13642
+ },
13643
+ explorer: {
13644
+ max_tool_calls: 150,
13645
+ max_duration_minutes: 20,
13646
+ warning_threshold: 0.75
13647
+ },
13648
+ reviewer: {
13649
+ max_tool_calls: 200,
13650
+ max_duration_minutes: 30,
13651
+ warning_threshold: 0.65
13652
+ },
13653
+ critic: {
13654
+ max_tool_calls: 200,
13655
+ max_duration_minutes: 30,
13656
+ warning_threshold: 0.65
13657
+ },
13658
+ sme: {
13659
+ max_tool_calls: 200,
13660
+ max_duration_minutes: 30,
13661
+ warning_threshold: 0.65
13662
+ }
13631
13663
  };
13664
+ var DEFAULT_ARCHITECT_PROFILE = DEFAULT_AGENT_PROFILES.architect;
13632
13665
  var GuardrailsConfigSchema = exports_external.object({
13633
13666
  enabled: exports_external.boolean().default(true),
13634
13667
  max_tool_calls: exports_external.number().min(10).max(1000).default(200),
13635
13668
  max_duration_minutes: exports_external.number().min(1).max(120).default(30),
13636
13669
  max_repetitions: exports_external.number().min(3).max(50).default(10),
13637
13670
  max_consecutive_errors: exports_external.number().min(2).max(20).default(5),
13638
- warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.5),
13671
+ warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
13639
13672
  profiles: exports_external.record(exports_external.string(), GuardrailsProfileSchema).optional()
13640
13673
  });
13641
13674
  function stripKnownSwarmPrefix(name) {
@@ -13656,7 +13689,7 @@ function resolveGuardrailsConfig(base, agentName) {
13656
13689
  return base;
13657
13690
  }
13658
13691
  const baseName = stripKnownSwarmPrefix(agentName);
13659
- const builtIn = baseName === ORCHESTRATOR_NAME ? DEFAULT_ARCHITECT_PROFILE : undefined;
13692
+ const builtIn = DEFAULT_AGENT_PROFILES[baseName];
13660
13693
  const userProfile = base.profiles?.[baseName] ?? base.profiles?.[agentName];
13661
13694
  if (!builtIn && !userProfile) {
13662
13695
  return base;
@@ -15974,6 +16007,7 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000) {
15974
16007
  consecutiveErrors: 0,
15975
16008
  recentToolCalls: [],
15976
16009
  warningIssued: false,
16010
+ warningReason: "",
15977
16011
  hardLimitHit: false
15978
16012
  };
15979
16013
  swarmState.agentSessions.set(sessionId, sessionState);
@@ -16291,7 +16325,7 @@ function createGuardrailsHooks(config2) {
16291
16325
  resolvedMaxCalls: agentConfig.max_tool_calls,
16292
16326
  currentCalls: session.toolCallCount
16293
16327
  });
16294
- throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Tool call limit reached (${session.toolCallCount}/${agentConfig.max_tool_calls}). Stop making tool calls and return your progress summary.`);
16328
+ throw new Error(`\uD83D\uDED1 LIMIT REACHED: Tool calls exhausted (${session.toolCallCount}/${agentConfig.max_tool_calls}). Finish the current operation and return your progress summary.`);
16295
16329
  }
16296
16330
  if (elapsedMinutes >= agentConfig.max_duration_minutes) {
16297
16331
  session.hardLimitHit = true;
@@ -16301,23 +16335,37 @@ function createGuardrailsHooks(config2) {
16301
16335
  resolvedMaxMinutes: agentConfig.max_duration_minutes,
16302
16336
  elapsedMinutes: Math.floor(elapsedMinutes)
16303
16337
  });
16304
- throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Duration limit reached (${Math.floor(elapsedMinutes)} min). Stop making tool calls and return your progress summary.`);
16338
+ throw new Error(`\uD83D\uDED1 LIMIT REACHED: Duration exhausted (${Math.floor(elapsedMinutes)}/${agentConfig.max_duration_minutes} min). Finish the current operation and return your progress summary.`);
16305
16339
  }
16306
16340
  if (repetitionCount >= agentConfig.max_repetitions) {
16307
16341
  session.hardLimitHit = true;
16308
- throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Repetition detected (same call ${repetitionCount} times). Stop making tool calls and return your progress summary.`);
16342
+ throw new Error(`\uD83D\uDED1 LIMIT REACHED: Repeated the same tool call ${repetitionCount} times. This suggests a loop. Return your progress summary.`);
16309
16343
  }
16310
16344
  if (session.consecutiveErrors >= agentConfig.max_consecutive_errors) {
16311
16345
  session.hardLimitHit = true;
16312
- throw new Error(`\uD83D\uDED1 CIRCUIT BREAKER: Too many consecutive errors (${session.consecutiveErrors}). Stop making tool calls and return your progress summary.`);
16346
+ throw new Error(`\uD83D\uDED1 LIMIT REACHED: ${session.consecutiveErrors} consecutive tool errors detected. Return your progress summary with details of what went wrong.`);
16313
16347
  }
16314
16348
  if (!session.warningIssued) {
16315
- const toolWarning = session.toolCallCount >= agentConfig.max_tool_calls * agentConfig.warning_threshold;
16316
- const durationWarning = elapsedMinutes >= agentConfig.max_duration_minutes * agentConfig.warning_threshold;
16317
- const repetitionWarning = repetitionCount >= agentConfig.max_repetitions * agentConfig.warning_threshold;
16318
- const errorWarning = session.consecutiveErrors >= agentConfig.max_consecutive_errors * agentConfig.warning_threshold;
16319
- if (toolWarning || durationWarning || repetitionWarning || errorWarning) {
16349
+ const toolPct = session.toolCallCount / agentConfig.max_tool_calls;
16350
+ const durationPct = elapsedMinutes / agentConfig.max_duration_minutes;
16351
+ const repPct = repetitionCount / agentConfig.max_repetitions;
16352
+ const errorPct = session.consecutiveErrors / agentConfig.max_consecutive_errors;
16353
+ const reasons = [];
16354
+ if (toolPct >= agentConfig.warning_threshold) {
16355
+ reasons.push(`tool calls ${session.toolCallCount}/${agentConfig.max_tool_calls}`);
16356
+ }
16357
+ if (durationPct >= agentConfig.warning_threshold) {
16358
+ reasons.push(`duration ${Math.floor(elapsedMinutes)}/${agentConfig.max_duration_minutes} min`);
16359
+ }
16360
+ if (repPct >= agentConfig.warning_threshold) {
16361
+ reasons.push(`repetitions ${repetitionCount}/${agentConfig.max_repetitions}`);
16362
+ }
16363
+ if (errorPct >= agentConfig.warning_threshold) {
16364
+ reasons.push(`errors ${session.consecutiveErrors}/${agentConfig.max_consecutive_errors}`);
16365
+ }
16366
+ if (reasons.length > 0) {
16320
16367
  session.warningIssued = true;
16368
+ session.warningReason = reasons.join(", ");
16321
16369
  }
16322
16370
  }
16323
16371
  },
@@ -16360,11 +16408,12 @@ function createGuardrailsHooks(config2) {
16360
16408
  return;
16361
16409
  }
16362
16410
  if (session.hardLimitHit) {
16363
- textPart.text = `[\uD83D\uDED1 CIRCUIT BREAKER ACTIVE: You have exceeded your resource limits. Do NOT make any more tool calls. Immediately return a summary of your progress so far. Any further tool calls will be blocked.]
16411
+ textPart.text = `[\uD83D\uDED1 LIMIT REACHED: Your resource budget is exhausted. Do not make additional tool calls. Return a summary of your progress and any remaining work.]
16364
16412
 
16365
16413
  ` + textPart.text;
16366
16414
  } else if (session.warningIssued) {
16367
- textPart.text = `[\u26A0\uFE0F GUARDRAIL WARNING: You are approaching resource limits. Please wrap up your current task efficiently. Avoid unnecessary tool calls and prepare to return your results soon.]
16415
+ const reasonSuffix = session.warningReason ? ` (${session.warningReason})` : "";
16416
+ textPart.text = `[\u26A0\uFE0F APPROACHING LIMITS${reasonSuffix}: You still have capacity to finish your current step. Complete what you're working on, then return your results.]
16368
16417
 
16369
16418
  ` + textPart.text;
16370
16419
  }
package/dist/state.d.ts CHANGED
@@ -55,6 +55,8 @@ export interface AgentSessionState {
55
55
  }>;
56
56
  /** Whether a soft warning has been issued */
57
57
  warningIssued: boolean;
58
+ /** Human-readable warning reason (set when warningIssued = true) */
59
+ warningReason: string;
58
60
  /** Whether a hard limit has been triggered */
59
61
  hardLimitHit: boolean;
60
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "5.0.4",
3
+ "version": "5.0.5",
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",