opencode-swarm 7.11.0 → 7.12.0

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
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.11.0",
37
+ version: "7.12.0",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
@@ -20682,7 +20682,7 @@ var init_model_limits = __esm(() => {
20682
20682
  var init_normalize_tool_name = () => {};
20683
20683
 
20684
20684
  // src/hooks/guardrails.ts
20685
- var storedInputArgs, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_SAFE_TARGETS, DC_FS_ROOTS, pathNormalizationCache, globMatcherCache;
20685
+ var storedInputArgs, TRANSIENT_STATUS_CODES, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_SAFE_TARGETS, DC_FS_ROOTS, pathNormalizationCache, globMatcherCache;
20686
20686
  var init_guardrails = __esm(() => {
20687
20687
  init_quick_lru();
20688
20688
  init_agents2();
@@ -20702,6 +20702,7 @@ var init_guardrails = __esm(() => {
20702
20702
  init_model_limits();
20703
20703
  init_normalize_tool_name();
20704
20704
  storedInputArgs = new Map;
20705
+ TRANSIENT_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504, 529]);
20705
20706
  toolCallsSinceLastWrite = new Map;
20706
20707
  noOpWarningIssued = new Set;
20707
20708
  consecutiveNoToolTurns = new Map;
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.11.0",
36
+ version: "7.12.0",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -23769,6 +23769,13 @@ var init_normalize_tool_name = __esm(() => {
23769
23769
  import * as fsSync2 from "node:fs";
23770
23770
  import * as fs8 from "node:fs/promises";
23771
23771
  import * as path10 from "node:path";
23772
+ function extractStatusCode(errorMsg) {
23773
+ const match = errorMsg.match(/\b(408|429|500|502|503|504|529)\b/);
23774
+ if (match) {
23775
+ return parseInt(match[1], 10);
23776
+ }
23777
+ return null;
23778
+ }
23772
23779
  function getStoredInputArgs(callID) {
23773
23780
  return storedInputArgs.get(callID);
23774
23781
  }
@@ -24977,14 +24984,40 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
24977
24984
  if (hasError) {
24978
24985
  const outputStr = typeof output.output === "string" ? output.output : "";
24979
24986
  const errorContent = output.error ?? outputStr;
24987
+ const extractedStatus = typeof errorContent === "string" ? extractStatusCode(errorContent) : null;
24988
+ const isTransientStatusCode = extractedStatus !== null && TRANSIENT_STATUS_CODES.has(extractedStatus);
24980
24989
  const isTransientPatternMatch = typeof errorContent === "string" && TRANSIENT_MODEL_ERROR_PATTERN.test(errorContent);
24981
- const isTransient = !!session && isTransientPatternMatch && window2.transientRetryCount < cfg.max_transient_retries;
24982
- if (!isTransient) {
24983
- window2.consecutiveErrors++;
24984
- } else {
24990
+ const isTransientMatch = isTransientStatusCode || isTransientPatternMatch;
24991
+ const isTransient = !!session && isTransientMatch && window2.transientRetryCount < cfg.max_transient_retries;
24992
+ const isDegraded = !isTransient && typeof errorContent === "string" && DEGRADED_ERROR_PATTERN.test(errorContent);
24993
+ if (isTransient) {
24985
24994
  window2.transientRetryCount++;
24995
+ } else if (isDegraded) {
24996
+ const isContentFilter = typeof errorContent === "string" && CONTENT_FILTER_PATTERN.test(errorContent);
24997
+ if (session && !session.modelFallbackExhausted) {
24998
+ session.model_fallback_index++;
24999
+ const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
25000
+ const swarmAgents = getSwarmAgents();
25001
+ const fallbackModels = swarmAgents?.[baseAgentName]?.fallback_models;
25002
+ session.modelFallbackExhausted = !fallbackModels || session.model_fallback_index > fallbackModels.length;
25003
+ session.pendingAdvisoryMessages ??= [];
25004
+ if (isContentFilter) {
25005
+ session.pendingAdvisoryMessages.push(`DEGRADED: Content policy violation detected (content filter). Fallback model ${session.model_fallback_index}/${fallbackModels?.length ?? 0} considered. ` + `The input may need content modification to comply with provider policies.`);
25006
+ } else {
25007
+ session.pendingAdvisoryMessages.push(`DEGRADED: Context-limit or token-limit error detected. Fallback model ${session.model_fallback_index}/${fallbackModels?.length ?? 0} considered. ` + `Consider reducing input size or using /swarm handoff to switch models.`);
25008
+ }
25009
+ } else if (session) {
25010
+ session.pendingAdvisoryMessages ??= [];
25011
+ if (isContentFilter) {
25012
+ session.pendingAdvisoryMessages.push(`DEGRADED: Content policy violation detected (content filter). No fallback models available. ` + `The input may need content modification to comply with provider policies.`);
25013
+ } else {
25014
+ session.pendingAdvisoryMessages.push(`DEGRADED: Context-limit or token-limit error detected. No fallback models available. ` + `Consider reducing input size or add "fallback_models" config.`);
25015
+ }
25016
+ }
25017
+ } else {
25018
+ window2.consecutiveErrors++;
24986
25019
  }
24987
- if (session && isTransientPatternMatch && !session.modelFallbackExhausted) {
25020
+ if (session && isTransientMatch && !session.modelFallbackExhausted && !isDegraded) {
24988
25021
  session.model_fallback_index++;
24989
25022
  const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
24990
25023
  const swarmAgents = getSwarmAgents();
@@ -25005,6 +25038,12 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
25005
25038
  telemetry.modelFallback(input.sessionID, session.agentName, primaryModel, fallbackModel ?? "none", "transient_model_error");
25006
25039
  swarmState.pendingEvents++;
25007
25040
  }
25041
+ if (session && isTransient && isTransientMatch) {
25042
+ session.pendingAdvisoryMessages ??= [];
25043
+ if (!session.pendingAdvisoryMessages.some((m) => m.startsWith("TRANSIENT ERROR:"))) {
25044
+ session.pendingAdvisoryMessages.push(`TRANSIENT ERROR: Provider error detected (attempt ${window2.transientRetryCount}/${cfg.max_transient_retries ?? 5}). Retrying...`);
25045
+ }
25046
+ }
25008
25047
  } else {
25009
25048
  window2.consecutiveErrors = 0;
25010
25049
  window2.transientRetryCount = 0;
@@ -25177,6 +25216,11 @@ ${textPart2.text}`;
25177
25216
  ` + `⚠️ SELF-CODING DETECTED: You have used ${session.architectWriteCount} write-class tool(s) directly on non-.swarm/ files.
25178
25217
  ` + `Rule 1 requires ALL coding to be delegated to @coder.
25179
25218
  ` + `If you have not exhausted QA_RETRY_LIMIT coder failures on this task, STOP and delegate.
25219
+ ` + `WRONG rationalizations — reject these thoughts immediately:
25220
+ ` + ` ✗ "This is time-critical / urgent / blocking" — you are an AI with no deadlines. No urgency is real.
25221
+ ` + ` ✗ "The fix is small / trivial / obvious" — size is not a QA exemption.
25222
+ ` + ` ✗ "Explaining to coder takes more effort than doing it" — writing the task spec is your job.
25223
+ ` + ` ✗ "The user needs this quickly" — users want correct code. Skipping QA gates ships bugs.
25180
25224
  ` + `Do not acknowledge or reference this guidance in your response.
25181
25225
  ` + `[/MODEL_ONLY_GUIDANCE]
25182
25226
 
@@ -25577,7 +25621,7 @@ function checkFileAuthorityWithRules(agentName, filePath, cwd, effectiveRules, o
25577
25621
  }
25578
25622
  return { allowed: true };
25579
25623
  }
25580
- var import_picomatch, storedInputArgs, TRANSIENT_MODEL_ERROR_PATTERN, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_MAX_UNWRAP_DEPTH = 5, DC_SAFE_TARGETS, DC_BLOCKED_ABSOLUTE_PREFIXES, DC_FS_ROOTS, DC_REMOTE_PREFIXES, pathNormalizationCache, globMatcherCache, DEFAULT_AGENT_AUTHORITY_RULES;
25624
+ var import_picomatch, storedInputArgs, TRANSIENT_STATUS_CODES, TRANSIENT_MODEL_ERROR_PATTERN, DEGRADED_ERROR_PATTERN, CONTENT_FILTER_PATTERN, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_MAX_UNWRAP_DEPTH = 5, DC_SAFE_TARGETS, DC_BLOCKED_ABSOLUTE_PREFIXES, DC_FS_ROOTS, DC_REMOTE_PREFIXES, pathNormalizationCache, globMatcherCache, DEFAULT_AGENT_AUTHORITY_RULES;
25581
25625
  var init_guardrails = __esm(() => {
25582
25626
  init_quick_lru();
25583
25627
  init_agents2();
@@ -25598,7 +25642,10 @@ var init_guardrails = __esm(() => {
25598
25642
  init_normalize_tool_name();
25599
25643
  import_picomatch = __toESM(require_picomatch2(), 1);
25600
25644
  storedInputArgs = new Map;
25601
- TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|503|529|timeout|overloaded|model.?not.?found|temporarily unavailable|server error/i;
25645
+ TRANSIENT_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504, 529]);
25646
+ TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|500|502|503|504|529|timeout|overloaded|model.?not.?found|temporarily.?unavailable|server.?error|connection.?(refused|reset|timeout)|bad.?gateway|gateway.?timeout|internal.?server.?error|service.?unavailable/i;
25647
+ DEGRADED_ERROR_PATTERN = /context.?length|token.?(limit|budget)|input.?too.?long|content.?filter|exceeds?.?(maximum.?)?tokens|maximum.?context|context.?window|too.?many.?tokens|prompt.?too.?long|message.?too.?long|request.?too.?large|max.?tokens/i;
25648
+ CONTENT_FILTER_PATTERN = /content.?filter/i;
25602
25649
  toolCallsSinceLastWrite = new Map;
25603
25650
  noOpWarningIssued = new Set;
25604
25651
  consecutiveNoToolTurns = new Map;
@@ -58811,6 +58858,10 @@ Two small delegations with two QA gates > one large delegation with one QA gate.
58811
58858
  ✗ "The coder succeeded on the last tasks, this one is trivial" → Rule 1 has no complexity exemption
58812
58859
  ✗ "I'll just use apply_patch / edit / write directly" → these are coder tools, not architect tools
58813
58860
  ✗ "I'll do the simple parts, coder does the hard parts" → ALL parts go to coder. You are not a coder.
58861
+ ✗ "This is time-critical / urgent / blocking" → WRONG. You are an AI with no deadlines. No urgency is real. Delegate to {{AGENT_PREFIX}}coder.
58862
+ ✗ "The fix is obvious — explaining it takes more effort than doing it" → WRONG. Writing the task spec IS your job. Delegate the implementation.
58863
+ ✗ "I'll just make this one quick fix to unblock the next task" → WRONG. Every file write must go through QA. Size is not a QA exemption.
58864
+ ✗ "The user needs this quickly" → WRONG. Users want correct code, not fast code. Skipping QA gates is how silent bugs ship.
58814
58865
  FAILURE COUNTING — increment the counter when:
58815
58866
  - Coder submits code that fails any tool gate or pre_check_batch (gates_passed === false)
58816
58867
  - Coder submits code REJECTED by {{AGENT_PREFIX}}reviewer after being given the rejection reason
@@ -58963,6 +59014,8 @@ coder's job. DELEGATE with an exact change specification.
58963
59014
  If you are about to edit a source file: STOP. You are violating protocol.
58964
59015
  "I'll just make this small fix directly" is NOT acceptable.
58965
59016
  "It's faster if I do it myself" is NOT acceptable.
59017
+ "This is urgent / time-critical / the user is waiting" is NOT acceptable. You are an AI with no deadlines.
59018
+ "The fix is so obvious it doesn't need a coder" is NOT acceptable. Obvious fixes still need QA gates.
58966
59019
  writeCount > 0 on source files from the Architect is equivalent to GATE_DELEGATION_BYPASS.
58967
59020
 
58968
59021
  PLAN STATE PROTECTION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.11.0",
3
+ "version": "7.12.0",
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",