opencode-swarm 6.84.4 → 6.84.6
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 +2 -2
- package/dist/agents/index.d.ts +4 -0
- package/dist/cli/index.js +71 -8
- package/dist/index.js +81 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -173,7 +173,7 @@ No API key required. Excellent starting point:
|
|
|
173
173
|
"agents": {
|
|
174
174
|
"coder": { "model": "opencode/minimax-m2.5-free" },
|
|
175
175
|
"reviewer": { "model": "opencode/big-pickle" },
|
|
176
|
-
"explorer": { "model": "opencode/
|
|
176
|
+
"explorer": { "model": "opencode/big-pickle" }
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
```
|
|
@@ -195,7 +195,7 @@ For production, mix providers by role:
|
|
|
195
195
|
|
|
196
196
|
| Provider | Format | Example |
|
|
197
197
|
|---|---|---|
|
|
198
|
-
| OpenCode Zen | `opencode/<model>` | `opencode/
|
|
198
|
+
| OpenCode Zen | `opencode/<model>` | `opencode/big-pickle` |
|
|
199
199
|
| Anthropic | `anthropic/<model>` | `anthropic/claude-sonnet-4-20250514` |
|
|
200
200
|
| Google | `google/<model>` | `google/gemini-2.5-flash` |
|
|
201
201
|
| Z.ai | `zai-coding-plan/<model>` | `zai-coding-plan/glm-5` |
|
package/dist/agents/index.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export declare function stripSwarmPrefix(agentName: string, swarmPrefix?: string
|
|
|
11
11
|
/**
|
|
12
12
|
* Resolve the fallback model for an agent based on its config and fallback index.
|
|
13
13
|
* Called by guardrails at runtime when a transient model error is detected.
|
|
14
|
+
*
|
|
15
|
+
* Fallback inheritance:
|
|
16
|
+
* - curator_init/curator_phase inherit fallback_models from explorer if not explicitly configured
|
|
17
|
+
* - This matches the model inheritance: curator agents default to explorer's model
|
|
14
18
|
*/
|
|
15
19
|
export declare function resolveFallbackModel(agentBaseName: string, fallbackIndex: number, swarmAgents?: Record<string, {
|
|
16
20
|
model?: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -18976,6 +18976,13 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
18976
18976
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
18977
18977
|
disabled: exports_external.boolean().optional(),
|
|
18978
18978
|
fallback_models: exports_external.array(exports_external.string()).max(3).optional()
|
|
18979
|
+
}).refine((data) => {
|
|
18980
|
+
if (data.model && !data.fallback_models) {
|
|
18981
|
+
console.warn(`[opencode-swarm] WARNING: Agent configured with custom model "${data.model}" but no fallback_models. This means if the custom model fails, there is no fallback protection. Consider adding fallback_models for reliability.`);
|
|
18982
|
+
}
|
|
18983
|
+
return true;
|
|
18984
|
+
}, {
|
|
18985
|
+
message: "Agent configuration warning: Custom model without fallback protection"
|
|
18979
18986
|
});
|
|
18980
18987
|
var SwarmConfigSchema = exports_external.object({
|
|
18981
18988
|
name: exports_external.string().optional(),
|
|
@@ -45139,14 +45146,70 @@ async function install() {
|
|
|
45139
45146
|
if (!fs23.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
45140
45147
|
const defaultConfig = {
|
|
45141
45148
|
agents: {
|
|
45142
|
-
coder: {
|
|
45143
|
-
|
|
45144
|
-
|
|
45145
|
-
|
|
45146
|
-
|
|
45147
|
-
|
|
45148
|
-
|
|
45149
|
-
|
|
45149
|
+
coder: {
|
|
45150
|
+
model: "opencode/minimax-m2.5-free",
|
|
45151
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45152
|
+
},
|
|
45153
|
+
reviewer: {
|
|
45154
|
+
model: "opencode/big-pickle",
|
|
45155
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45156
|
+
},
|
|
45157
|
+
test_engineer: {
|
|
45158
|
+
model: "opencode/gpt-5-nano",
|
|
45159
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45160
|
+
},
|
|
45161
|
+
explorer: {
|
|
45162
|
+
model: "opencode/big-pickle",
|
|
45163
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45164
|
+
},
|
|
45165
|
+
sme: {
|
|
45166
|
+
model: "opencode/big-pickle",
|
|
45167
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45168
|
+
},
|
|
45169
|
+
critic: {
|
|
45170
|
+
model: "opencode/big-pickle",
|
|
45171
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45172
|
+
},
|
|
45173
|
+
docs: {
|
|
45174
|
+
model: "opencode/big-pickle",
|
|
45175
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45176
|
+
},
|
|
45177
|
+
designer: {
|
|
45178
|
+
model: "opencode/big-pickle",
|
|
45179
|
+
fallback_models: ["opencode/gpt-5-nano", "opencode/big-pickle"]
|
|
45180
|
+
},
|
|
45181
|
+
critic_sounding_board: {
|
|
45182
|
+
model: "opencode/gpt-5-nano",
|
|
45183
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45184
|
+
},
|
|
45185
|
+
critic_drift_verifier: {
|
|
45186
|
+
model: "opencode/gpt-5-nano",
|
|
45187
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45188
|
+
},
|
|
45189
|
+
critic_hallucination_verifier: {
|
|
45190
|
+
model: "opencode/gpt-5-nano",
|
|
45191
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45192
|
+
},
|
|
45193
|
+
critic_oversight: {
|
|
45194
|
+
model: "opencode/gpt-5-nano",
|
|
45195
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45196
|
+
},
|
|
45197
|
+
curator_init: {
|
|
45198
|
+
model: "opencode/gpt-5-nano",
|
|
45199
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45200
|
+
},
|
|
45201
|
+
curator_phase: {
|
|
45202
|
+
model: "opencode/gpt-5-nano",
|
|
45203
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45204
|
+
},
|
|
45205
|
+
council_member: {
|
|
45206
|
+
model: "opencode/gpt-5-nano",
|
|
45207
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45208
|
+
},
|
|
45209
|
+
council_moderator: {
|
|
45210
|
+
model: "opencode/gpt-5-nano",
|
|
45211
|
+
fallback_models: ["opencode/big-pickle"]
|
|
45212
|
+
}
|
|
45150
45213
|
},
|
|
45151
45214
|
max_iterations: 5
|
|
45152
45215
|
};
|
package/dist/index.js
CHANGED
|
@@ -478,23 +478,23 @@ var init_constants = __esm(() => {
|
|
|
478
478
|
}
|
|
479
479
|
}
|
|
480
480
|
DEFAULT_MODELS = {
|
|
481
|
-
explorer: "opencode/
|
|
481
|
+
explorer: "opencode/big-pickle",
|
|
482
482
|
coder: "opencode/minimax-m2.5-free",
|
|
483
483
|
reviewer: "opencode/big-pickle",
|
|
484
484
|
test_engineer: "opencode/gpt-5-nano",
|
|
485
|
-
sme: "opencode/
|
|
486
|
-
critic: "opencode/
|
|
487
|
-
critic_sounding_board: "opencode/
|
|
488
|
-
critic_drift_verifier: "opencode/
|
|
489
|
-
critic_hallucination_verifier: "opencode/
|
|
490
|
-
critic_oversight: "opencode/
|
|
491
|
-
docs: "opencode/
|
|
492
|
-
designer: "opencode/
|
|
493
|
-
curator_init: "opencode/
|
|
494
|
-
curator_phase: "opencode/
|
|
495
|
-
council_member: "opencode/
|
|
496
|
-
council_moderator: "opencode/
|
|
497
|
-
default: "opencode/
|
|
485
|
+
sme: "opencode/big-pickle",
|
|
486
|
+
critic: "opencode/big-pickle",
|
|
487
|
+
critic_sounding_board: "opencode/big-pickle",
|
|
488
|
+
critic_drift_verifier: "opencode/big-pickle",
|
|
489
|
+
critic_hallucination_verifier: "opencode/big-pickle",
|
|
490
|
+
critic_oversight: "opencode/big-pickle",
|
|
491
|
+
docs: "opencode/big-pickle",
|
|
492
|
+
designer: "opencode/big-pickle",
|
|
493
|
+
curator_init: "opencode/big-pickle",
|
|
494
|
+
curator_phase: "opencode/big-pickle",
|
|
495
|
+
council_member: "opencode/big-pickle",
|
|
496
|
+
council_moderator: "opencode/big-pickle",
|
|
497
|
+
default: "opencode/big-pickle"
|
|
498
498
|
};
|
|
499
499
|
DEFAULT_SCORING_CONFIG = {
|
|
500
500
|
enabled: false,
|
|
@@ -14724,6 +14724,13 @@ var init_schema = __esm(() => {
|
|
|
14724
14724
|
temperature: exports_external.number().min(0).max(2).optional(),
|
|
14725
14725
|
disabled: exports_external.boolean().optional(),
|
|
14726
14726
|
fallback_models: exports_external.array(exports_external.string()).max(3).optional()
|
|
14727
|
+
}).refine((data) => {
|
|
14728
|
+
if (data.model && !data.fallback_models) {
|
|
14729
|
+
console.warn(`[opencode-swarm] WARNING: Agent configured with custom model "${data.model}" but no fallback_models. This means if the custom model fails, there is no fallback protection. Consider adding fallback_models for reliability.`);
|
|
14730
|
+
}
|
|
14731
|
+
return true;
|
|
14732
|
+
}, {
|
|
14733
|
+
message: "Agent configuration warning: Custom model without fallback protection"
|
|
14727
14734
|
});
|
|
14728
14735
|
SwarmConfigSchema = exports_external.object({
|
|
14729
14736
|
name: exports_external.string().optional(),
|
|
@@ -57662,7 +57669,11 @@ function getModelForAgent(agentName, swarmAgents, swarmPrefix) {
|
|
|
57662
57669
|
return resolvedModel;
|
|
57663
57670
|
}
|
|
57664
57671
|
function resolveFallbackModel(agentBaseName, fallbackIndex, swarmAgents) {
|
|
57665
|
-
const
|
|
57672
|
+
const agentConfig = swarmAgents?.[agentBaseName];
|
|
57673
|
+
let fallbackModels = agentConfig?.fallback_models;
|
|
57674
|
+
if (fallbackModels === undefined && (agentBaseName === "curator_init" || agentBaseName === "curator_phase")) {
|
|
57675
|
+
fallbackModels = swarmAgents?.explorer?.fallback_models;
|
|
57676
|
+
}
|
|
57666
57677
|
if (!fallbackModels || fallbackModels.length === 0)
|
|
57667
57678
|
return null;
|
|
57668
57679
|
if (fallbackIndex < 1 || fallbackIndex > fallbackModels.length)
|
|
@@ -62132,7 +62143,7 @@ __export(exports_doc_scan, {
|
|
|
62132
62143
|
});
|
|
62133
62144
|
import * as crypto7 from "crypto";
|
|
62134
62145
|
import * as fs45 from "fs";
|
|
62135
|
-
import { mkdir as
|
|
62146
|
+
import { mkdir as mkdir9, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
|
|
62136
62147
|
import * as path59 from "path";
|
|
62137
62148
|
function normalizeSeparators(filePath) {
|
|
62138
62149
|
return filePath.replace(/\\/g, "/");
|
|
@@ -62304,7 +62315,7 @@ async function scanDocIndex(directory) {
|
|
|
62304
62315
|
files: discoveredFiles
|
|
62305
62316
|
};
|
|
62306
62317
|
try {
|
|
62307
|
-
await
|
|
62318
|
+
await mkdir9(path59.dirname(manifestPath), { recursive: true });
|
|
62308
62319
|
await writeFile8(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
62309
62320
|
} catch {}
|
|
62310
62321
|
return { manifest, cached: false };
|
|
@@ -65507,6 +65518,7 @@ async function saveGraph(workspace, graph, options) {
|
|
|
65507
65518
|
const graphPath = getGraphPath(workspace);
|
|
65508
65519
|
updateGraphMetadata(graph);
|
|
65509
65520
|
const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
65521
|
+
await fsPromises3.mkdir(path49.dirname(tempPath), { recursive: true });
|
|
65510
65522
|
let lastError = null;
|
|
65511
65523
|
try {
|
|
65512
65524
|
if (options?.createAtomic) {
|
|
@@ -65717,16 +65729,21 @@ function buildWorkspaceGraph(workspaceRoot, options) {
|
|
|
65717
65729
|
stats.filesScanned++;
|
|
65718
65730
|
const ext = path49.extname(filePath).toLowerCase();
|
|
65719
65731
|
let exports = [];
|
|
65720
|
-
|
|
65721
|
-
|
|
65722
|
-
|
|
65723
|
-
|
|
65724
|
-
|
|
65725
|
-
|
|
65726
|
-
|
|
65727
|
-
|
|
65732
|
+
let parsedImports = [];
|
|
65733
|
+
try {
|
|
65734
|
+
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
65735
|
+
const relativePath = path49.relative(absoluteRoot, filePath);
|
|
65736
|
+
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
65737
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
65738
|
+
} else if (ext === ".py") {
|
|
65739
|
+
const relativePath = path49.relative(absoluteRoot, filePath);
|
|
65740
|
+
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
65741
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
65742
|
+
}
|
|
65743
|
+
parsedImports = parseFileImports(content);
|
|
65744
|
+
} catch {
|
|
65745
|
+
continue;
|
|
65728
65746
|
}
|
|
65729
|
-
const parsedImports = parseFileImports(content);
|
|
65730
65747
|
const node = {
|
|
65731
65748
|
filePath,
|
|
65732
65749
|
moduleName: toModuleName(filePath, absoluteRoot),
|
|
@@ -65778,38 +65795,42 @@ function scanFile(filePath, absoluteRoot, maxFileSize) {
|
|
|
65778
65795
|
}
|
|
65779
65796
|
const ext = path49.extname(filePath).toLowerCase();
|
|
65780
65797
|
let exports = [];
|
|
65781
|
-
|
|
65782
|
-
|
|
65783
|
-
|
|
65784
|
-
|
|
65785
|
-
|
|
65786
|
-
|
|
65787
|
-
|
|
65788
|
-
|
|
65789
|
-
|
|
65790
|
-
|
|
65791
|
-
|
|
65792
|
-
|
|
65793
|
-
|
|
65794
|
-
|
|
65795
|
-
|
|
65796
|
-
|
|
65797
|
-
|
|
65798
|
-
|
|
65799
|
-
|
|
65800
|
-
|
|
65801
|
-
|
|
65802
|
-
const
|
|
65803
|
-
|
|
65804
|
-
|
|
65805
|
-
|
|
65806
|
-
|
|
65807
|
-
|
|
65808
|
-
|
|
65809
|
-
|
|
65798
|
+
try {
|
|
65799
|
+
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
65800
|
+
const relativePath = path49.relative(absoluteRoot, filePath);
|
|
65801
|
+
const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
|
|
65802
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
65803
|
+
} else if (ext === ".py") {
|
|
65804
|
+
const relativePath = path49.relative(absoluteRoot, filePath);
|
|
65805
|
+
const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
|
|
65806
|
+
exports = symbols2.filter((s) => s.exported).map((s) => s.name);
|
|
65807
|
+
}
|
|
65808
|
+
const parsedImports = parseFileImports(content);
|
|
65809
|
+
const node = {
|
|
65810
|
+
filePath,
|
|
65811
|
+
moduleName: toModuleName(filePath, absoluteRoot),
|
|
65812
|
+
exports,
|
|
65813
|
+
imports: parsedImports.map((p) => p.specifier),
|
|
65814
|
+
language: getLanguage(filePath),
|
|
65815
|
+
mtime: fileStats.mtime.toISOString()
|
|
65816
|
+
};
|
|
65817
|
+
const edges = [];
|
|
65818
|
+
const sortedImports = [...parsedImports].sort((a, b) => a.specifier.localeCompare(b.specifier));
|
|
65819
|
+
for (const parsed of sortedImports) {
|
|
65820
|
+
const resolvedTarget = resolveModuleSpecifier(absoluteRoot, filePath, parsed.specifier);
|
|
65821
|
+
if (resolvedTarget !== null) {
|
|
65822
|
+
edges.push({
|
|
65823
|
+
source: filePath,
|
|
65824
|
+
target: resolvedTarget,
|
|
65825
|
+
importSpecifier: parsed.specifier,
|
|
65826
|
+
importType: parsed.importType
|
|
65827
|
+
});
|
|
65828
|
+
}
|
|
65810
65829
|
}
|
|
65830
|
+
return { node, edges };
|
|
65831
|
+
} catch {
|
|
65832
|
+
return { node: null, edges: [] };
|
|
65811
65833
|
}
|
|
65812
|
-
return { node, edges };
|
|
65813
65834
|
}
|
|
65814
65835
|
async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
65815
65836
|
if (options?.forceRebuild) {
|
|
@@ -65907,7 +65928,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
65907
65928
|
if (message.includes("does not exist")) {
|
|
65908
65929
|
return;
|
|
65909
65930
|
}
|
|
65910
|
-
console.
|
|
65931
|
+
console.warn(`[repo-graph] Failed to build graph: ${message}`);
|
|
65911
65932
|
}
|
|
65912
65933
|
},
|
|
65913
65934
|
async toolAfter(input, _output) {
|
|
@@ -65947,7 +65968,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
|
|
|
65947
65968
|
console.log(`[repo-graph] Incremental update for ${path50.basename(filePath)}`);
|
|
65948
65969
|
} catch (error93) {
|
|
65949
65970
|
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
65950
|
-
console.
|
|
65971
|
+
console.warn(`[repo-graph] Incremental update failed: ${message}`);
|
|
65951
65972
|
}
|
|
65952
65973
|
}
|
|
65953
65974
|
};
|
|
@@ -81006,6 +81027,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
81006
81027
|
};
|
|
81007
81028
|
}
|
|
81008
81029
|
fs69.mkdirSync(path83.dirname(baselinePath), { recursive: true });
|
|
81030
|
+
fs69.mkdirSync(path83.dirname(tempPath), { recursive: true });
|
|
81009
81031
|
const releaseLock = await acquireLock(lockPath);
|
|
81010
81032
|
try {
|
|
81011
81033
|
let existing = null;
|
|
@@ -88107,9 +88129,9 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
88107
88129
|
swarmState.fullAutoEnabledInConfig = config3.full_auto?.enabled === true;
|
|
88108
88130
|
swarmState.opencodeClient = ctx.client;
|
|
88109
88131
|
await loadSnapshot(ctx.directory);
|
|
88132
|
+
initTelemetry(ctx.directory);
|
|
88110
88133
|
const repoGraphHook = createRepoGraphBuilderHook(ctx.directory);
|
|
88111
88134
|
repoGraphHook.init().catch(() => {});
|
|
88112
|
-
initTelemetry(ctx.directory);
|
|
88113
88135
|
const agents = getAgentConfigs(config3, ctx.directory);
|
|
88114
88136
|
const agentDefinitions = createAgents(config3);
|
|
88115
88137
|
swarmState.curatorInitAgentNames = Object.keys(agents).filter((k) => k === "curator_init" || k.endsWith("_curator_init"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.84.
|
|
3
|
+
"version": "6.84.6",
|
|
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",
|