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 +3 -1
- package/dist/cli/index.js +5 -1
- package/dist/index.js +30 -25
- package/package.json +1 -1
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
|
-
|
|
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
|
-
"**
|
|
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
|
-
|
|
23925
|
-
|
|
23926
|
-
|
|
23927
|
-
|
|
23928
|
-
|
|
23929
|
-
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
23934
|
-
|
|
23935
|
-
|
|
23936
|
-
|
|
23937
|
-
|
|
23938
|
-
|
|
23939
|
-
|
|
23940
|
-
|
|
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
|
-
|
|
23947
|
-
|
|
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
|
-
"**
|
|
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.
|
|
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",
|