opencode-swarm 6.84.0 → 6.84.1

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/README.md CHANGED
@@ -17,9 +17,11 @@
17
17
  OpenCode Swarm is a plugin for [OpenCode](https://opencode.ai) that turns a single AI coding session into an **architect-led team of 11 specialized agents**. One agent writes the code. A different agent reviews it. Another writes and runs tests. Another checks security. **Nothing ships until every required gate passes.**
18
18
 
19
19
  ```bash
20
- npm install -g opencode-swarm
20
+ bunx opencode-swarm install
21
21
  ```
22
22
 
23
+ > This single command installs the package, registers it as an OpenCode plugin, disables conflicting default agents, and creates a ready-to-edit config at `~/.config/opencode/opencode-swarm.json`. Requires [Bun](https://bun.sh) (`bun --version` to check). If you must use npm: `npm install -g opencode-swarm && opencode-swarm install`.
24
+
23
25
  ### Why Swarm?
24
26
 
25
27
  Most AI coding tools let one model write code and ask that same model whether the code is good. That misses too much. Swarm separates planning, implementation, review, testing, and documentation into specialized internal roles — and enforces gated execution so agents never mutate the codebase in parallel.
package/dist/cli/index.js CHANGED
@@ -19268,21 +19268,25 @@ var DEFAULT_AGENT_PROFILES = {
19268
19268
  coder: {
19269
19269
  max_tool_calls: 400,
19270
19270
  max_duration_minutes: 45,
19271
+ max_consecutive_errors: 8,
19271
19272
  warning_threshold: 0.85
19272
19273
  },
19273
19274
  test_engineer: {
19274
19275
  max_tool_calls: 400,
19275
19276
  max_duration_minutes: 45,
19277
+ max_consecutive_errors: 8,
19276
19278
  warning_threshold: 0.85
19277
19279
  },
19278
19280
  explorer: {
19279
19281
  max_tool_calls: 150,
19280
19282
  max_duration_minutes: 20,
19283
+ max_consecutive_errors: 8,
19281
19284
  warning_threshold: 0.75
19282
19285
  },
19283
19286
  reviewer: {
19284
19287
  max_tool_calls: 200,
19285
19288
  max_duration_minutes: 30,
19289
+ max_consecutive_errors: 8,
19286
19290
  warning_threshold: 0.65
19287
19291
  },
19288
19292
  critic: {
@@ -44320,7 +44324,7 @@ async function handleResetSessionCommand(directory, _args) {
44320
44324
  "",
44321
44325
  "Session state cleared. Plan, evidence, and knowledge preserved.",
44322
44326
  "",
44323
- "**Next step:** Start a new OpenCode session. The plugin will initialize fresh session state on startup."
44327
+ "**All circuit breakers and revision limits have been cleared.** You can continue in this session \u2014 fresh state will be initialized automatically on the next tool call."
44324
44328
  ].join(`
44325
44329
  `);
44326
44330
  }
package/dist/index.js CHANGED
@@ -15016,21 +15016,25 @@ var init_schema = __esm(() => {
15016
15016
  coder: {
15017
15017
  max_tool_calls: 400,
15018
15018
  max_duration_minutes: 45,
15019
+ max_consecutive_errors: 8,
15019
15020
  warning_threshold: 0.85
15020
15021
  },
15021
15022
  test_engineer: {
15022
15023
  max_tool_calls: 400,
15023
15024
  max_duration_minutes: 45,
15025
+ max_consecutive_errors: 8,
15024
15026
  warning_threshold: 0.85
15025
15027
  },
15026
15028
  explorer: {
15027
15029
  max_tool_calls: 150,
15028
15030
  max_duration_minutes: 20,
15031
+ max_consecutive_errors: 8,
15029
15032
  warning_threshold: 0.75
15030
15033
  },
15031
15034
  reviewer: {
15032
15035
  max_tool_calls: 200,
15033
15036
  max_duration_minutes: 30,
15037
+ max_consecutive_errors: 8,
15034
15038
  warning_threshold: 0.65
15035
15039
  },
15036
15040
  critic: {
@@ -23380,7 +23384,7 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
23380
23384
  if (window2.consecutiveErrors >= agentConfig.max_consecutive_errors) {
23381
23385
  window2.hardLimitHit = true;
23382
23386
  telemetry.hardLimitHit(sessionID, window2.agentName, "consecutive_errors", window2.consecutiveErrors);
23383
- throw new Error(`\uD83D\uDED1 LIMIT REACHED: ${window2.consecutiveErrors} consecutive tool errors detected. Return your progress summary with details of what went wrong.`);
23387
+ throw new Error(`\uD83D\uDED1 LIMIT REACHED: ${window2.consecutiveErrors} consecutive tool errors detected. Return your progress summary with details of what went wrong. Run /swarm reset-session to clear the circuit breaker without restarting your session.`);
23384
23388
  }
23385
23389
  const idleMinutes = (Date.now() - window2.lastSuccessTimeMs) / 60000;
23386
23390
  if (idleMinutes >= agentConfig.idle_timeout_minutes) {
@@ -23921,31 +23925,32 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
23921
23925
  return;
23922
23926
  const hasError = output.output === null || output.output === undefined;
23923
23927
  if (hasError) {
23924
- window2.consecutiveErrors++;
23925
- if (session) {
23926
- const outputStr = typeof output.output === "string" ? output.output : "";
23927
- const errorContent = output.error ?? outputStr;
23928
- if (typeof errorContent === "string" && TRANSIENT_MODEL_ERROR_PATTERN.test(errorContent) && !session.modelFallbackExhausted) {
23929
- session.model_fallback_index++;
23930
- const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
23931
- const swarmAgents = getSwarmAgents();
23932
- const fallbackModels = swarmAgents?.[baseAgentName]?.fallback_models;
23933
- session.modelFallbackExhausted = !fallbackModels || session.model_fallback_index > fallbackModels.length;
23934
- const fallbackModel = resolveFallbackModel(baseAgentName, session.model_fallback_index, swarmAgents);
23935
- const primaryModel = swarmAgents?.[baseAgentName]?.model ?? "default";
23936
- if (fallbackModel) {
23937
- if (swarmAgents?.[baseAgentName]) {
23938
- swarmAgents[baseAgentName].model = fallbackModel;
23939
- }
23940
- session.pendingAdvisoryMessages ??= [];
23941
- session.pendingAdvisoryMessages.push(`MODEL FALLBACK: Applied fallback model "${fallbackModel}" (attempt ${session.model_fallback_index}). ` + `Using /swarm handoff to reset to primary model.`);
23942
- } else {
23943
- session.pendingAdvisoryMessages ??= [];
23944
- session.pendingAdvisoryMessages.push(`MODEL FALLBACK: Transient model error detected (attempt ${session.model_fallback_index}). ` + `No fallback models configured for this agent. Add "fallback_models": ["model-a", "model-b"] ` + `to the agent's config in opencode-swarm.json.`);
23928
+ const outputStr = typeof output.output === "string" ? output.output : "";
23929
+ const errorContent = output.error ?? outputStr;
23930
+ const isTransient = !!session && !session.modelFallbackExhausted && typeof errorContent === "string" && TRANSIENT_MODEL_ERROR_PATTERN.test(errorContent);
23931
+ if (!isTransient) {
23932
+ window2.consecutiveErrors++;
23933
+ }
23934
+ if (session && isTransient) {
23935
+ session.model_fallback_index++;
23936
+ const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
23937
+ const swarmAgents = getSwarmAgents();
23938
+ const fallbackModels = swarmAgents?.[baseAgentName]?.fallback_models;
23939
+ session.modelFallbackExhausted = !fallbackModels || session.model_fallback_index > fallbackModels.length;
23940
+ const fallbackModel = resolveFallbackModel(baseAgentName, session.model_fallback_index, swarmAgents);
23941
+ const primaryModel = swarmAgents?.[baseAgentName]?.model ?? "default";
23942
+ if (fallbackModel) {
23943
+ if (swarmAgents?.[baseAgentName]) {
23944
+ swarmAgents[baseAgentName].model = fallbackModel;
23945
23945
  }
23946
- telemetry.modelFallback(input.sessionID, session.agentName, primaryModel, fallbackModel ?? "none", "transient_model_error");
23947
- swarmState.pendingEvents++;
23946
+ session.pendingAdvisoryMessages ??= [];
23947
+ session.pendingAdvisoryMessages.push(`MODEL FALLBACK: Applied fallback model "${fallbackModel}" (attempt ${session.model_fallback_index}). ` + `Using /swarm handoff to reset to primary model.`);
23948
+ } else {
23949
+ session.pendingAdvisoryMessages ??= [];
23950
+ session.pendingAdvisoryMessages.push(`MODEL FALLBACK: Transient model error detected (attempt ${session.model_fallback_index}). ` + `No fallback models configured for this agent. Add "fallback_models": ["model-a", "model-b"] ` + `to the agent's config in opencode-swarm.json.`);
23948
23951
  }
23952
+ telemetry.modelFallback(input.sessionID, session.agentName, primaryModel, fallbackModel ?? "none", "transient_model_error");
23953
+ swarmState.pendingEvents++;
23949
23954
  }
23950
23955
  } else {
23951
23956
  window2.consecutiveErrors = 0;
@@ -53076,7 +53081,7 @@ async function handleResetSessionCommand(directory, _args) {
53076
53081
  "",
53077
53082
  "Session state cleared. Plan, evidence, and knowledge preserved.",
53078
53083
  "",
53079
- "**Next step:** Start a new OpenCode session. The plugin will initialize fresh session state on startup."
53084
+ "**All circuit breakers and revision limits have been cleared.** You can continue in this session \u2014 fresh state will be initialized automatically on the next tool call."
53080
53085
  ].join(`
53081
53086
  `);
53082
53087
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.84.0",
3
+ "version": "6.84.1",
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",