opencode-swarm-plugin 0.6.0 → 0.6.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/dist/index.js +335 -5
- package/dist/plugin.js +332 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23386,6 +23386,11 @@ var CriterionWeightSchema = exports_external.object({
|
|
|
23386
23386
|
last_validated: exports_external.string().optional(),
|
|
23387
23387
|
half_life_days: exports_external.number().positive().default(90)
|
|
23388
23388
|
});
|
|
23389
|
+
var DecompositionStrategySchema = exports_external.enum([
|
|
23390
|
+
"file-based",
|
|
23391
|
+
"feature-based",
|
|
23392
|
+
"risk-based"
|
|
23393
|
+
]);
|
|
23389
23394
|
var OutcomeSignalsSchema = exports_external.object({
|
|
23390
23395
|
bead_id: exports_external.string(),
|
|
23391
23396
|
duration_ms: exports_external.number().int().min(0),
|
|
@@ -23393,7 +23398,8 @@ var OutcomeSignalsSchema = exports_external.object({
|
|
|
23393
23398
|
retry_count: exports_external.number().int().min(0),
|
|
23394
23399
|
success: exports_external.boolean(),
|
|
23395
23400
|
files_touched: exports_external.array(exports_external.string()).default([]),
|
|
23396
|
-
timestamp: exports_external.string()
|
|
23401
|
+
timestamp: exports_external.string(),
|
|
23402
|
+
strategy: DecompositionStrategySchema.optional()
|
|
23397
23403
|
});
|
|
23398
23404
|
var ScoredOutcomeSchema = exports_external.object({
|
|
23399
23405
|
signals: OutcomeSignalsSchema,
|
|
@@ -23553,6 +23559,167 @@ function detectInstructionConflicts(subtasks) {
|
|
|
23553
23559
|
}
|
|
23554
23560
|
return conflicts;
|
|
23555
23561
|
}
|
|
23562
|
+
var STRATEGIES = {
|
|
23563
|
+
"file-based": {
|
|
23564
|
+
name: "file-based",
|
|
23565
|
+
description: "Group by file type or directory. Best for refactoring, migrations, and pattern changes across codebase.",
|
|
23566
|
+
keywords: [
|
|
23567
|
+
"refactor",
|
|
23568
|
+
"migrate",
|
|
23569
|
+
"update all",
|
|
23570
|
+
"rename",
|
|
23571
|
+
"replace",
|
|
23572
|
+
"convert",
|
|
23573
|
+
"upgrade",
|
|
23574
|
+
"deprecate",
|
|
23575
|
+
"remove",
|
|
23576
|
+
"cleanup",
|
|
23577
|
+
"lint",
|
|
23578
|
+
"format"
|
|
23579
|
+
],
|
|
23580
|
+
guidelines: [
|
|
23581
|
+
"Group files by directory or type (e.g., all components, all tests)",
|
|
23582
|
+
"Minimize cross-directory dependencies within a subtask",
|
|
23583
|
+
"Handle shared types/utilities first if they change",
|
|
23584
|
+
"Each subtask should be a complete transformation of its file set",
|
|
23585
|
+
"Consider import/export relationships when grouping"
|
|
23586
|
+
],
|
|
23587
|
+
antiPatterns: [
|
|
23588
|
+
"Don't split tightly coupled files across subtasks",
|
|
23589
|
+
"Don't group files that have no relationship",
|
|
23590
|
+
"Don't forget to update imports when moving/renaming"
|
|
23591
|
+
],
|
|
23592
|
+
examples: [
|
|
23593
|
+
"Migrate all components to new API \u2192 split by component directory",
|
|
23594
|
+
"Rename userId to accountId \u2192 split by module (types first, then consumers)",
|
|
23595
|
+
"Update all tests to use new matcher \u2192 split by test directory"
|
|
23596
|
+
]
|
|
23597
|
+
},
|
|
23598
|
+
"feature-based": {
|
|
23599
|
+
name: "feature-based",
|
|
23600
|
+
description: "Vertical slices with UI + API + data. Best for new features and adding functionality.",
|
|
23601
|
+
keywords: [
|
|
23602
|
+
"add",
|
|
23603
|
+
"implement",
|
|
23604
|
+
"build",
|
|
23605
|
+
"create",
|
|
23606
|
+
"feature",
|
|
23607
|
+
"new",
|
|
23608
|
+
"integrate",
|
|
23609
|
+
"connect",
|
|
23610
|
+
"enable",
|
|
23611
|
+
"support"
|
|
23612
|
+
],
|
|
23613
|
+
guidelines: [
|
|
23614
|
+
"Each subtask is a complete vertical slice (UI + logic + data)",
|
|
23615
|
+
"Start with data layer/types, then logic, then UI",
|
|
23616
|
+
"Keep related components together (form + validation + submission)",
|
|
23617
|
+
"Separate concerns that can be developed independently",
|
|
23618
|
+
"Consider user-facing features as natural boundaries"
|
|
23619
|
+
],
|
|
23620
|
+
antiPatterns: [
|
|
23621
|
+
"Don't split a single feature across multiple subtasks",
|
|
23622
|
+
"Don't create subtasks that can't be tested independently",
|
|
23623
|
+
"Don't forget integration points between features"
|
|
23624
|
+
],
|
|
23625
|
+
examples: [
|
|
23626
|
+
"Add user auth \u2192 [OAuth setup, Session management, Protected routes]",
|
|
23627
|
+
"Build dashboard \u2192 [Data fetching, Chart components, Layout/navigation]",
|
|
23628
|
+
"Add search \u2192 [Search API, Search UI, Results display]"
|
|
23629
|
+
]
|
|
23630
|
+
},
|
|
23631
|
+
"risk-based": {
|
|
23632
|
+
name: "risk-based",
|
|
23633
|
+
description: "Isolate high-risk changes, add tests first. Best for bug fixes, security issues, and critical changes.",
|
|
23634
|
+
keywords: [
|
|
23635
|
+
"fix",
|
|
23636
|
+
"bug",
|
|
23637
|
+
"security",
|
|
23638
|
+
"vulnerability",
|
|
23639
|
+
"critical",
|
|
23640
|
+
"urgent",
|
|
23641
|
+
"hotfix",
|
|
23642
|
+
"patch",
|
|
23643
|
+
"audit",
|
|
23644
|
+
"review",
|
|
23645
|
+
"investigate"
|
|
23646
|
+
],
|
|
23647
|
+
guidelines: [
|
|
23648
|
+
"Write tests FIRST to capture expected behavior",
|
|
23649
|
+
"Isolate the risky change to minimize blast radius",
|
|
23650
|
+
"Add monitoring/logging around the change",
|
|
23651
|
+
"Create rollback plan as part of the task",
|
|
23652
|
+
"Audit similar code for the same issue"
|
|
23653
|
+
],
|
|
23654
|
+
antiPatterns: [
|
|
23655
|
+
"Don't make multiple risky changes in one subtask",
|
|
23656
|
+
"Don't skip tests for 'simple' fixes",
|
|
23657
|
+
"Don't forget to check for similar issues elsewhere"
|
|
23658
|
+
],
|
|
23659
|
+
examples: [
|
|
23660
|
+
"Fix auth bypass \u2192 [Add regression test, Fix vulnerability, Audit similar endpoints]",
|
|
23661
|
+
"Fix race condition \u2192 [Add test reproducing issue, Implement fix, Add concurrency tests]",
|
|
23662
|
+
"Security audit \u2192 [Scan for vulnerabilities, Fix critical issues, Document remaining risks]"
|
|
23663
|
+
]
|
|
23664
|
+
}
|
|
23665
|
+
};
|
|
23666
|
+
function selectStrategy(task) {
|
|
23667
|
+
const taskLower = task.toLowerCase();
|
|
23668
|
+
const scores = {
|
|
23669
|
+
"file-based": 0,
|
|
23670
|
+
"feature-based": 0,
|
|
23671
|
+
"risk-based": 0
|
|
23672
|
+
};
|
|
23673
|
+
for (const [strategyName, definition] of Object.entries(STRATEGIES)) {
|
|
23674
|
+
const name = strategyName;
|
|
23675
|
+
for (const keyword of definition.keywords) {
|
|
23676
|
+
if (taskLower.includes(keyword)) {
|
|
23677
|
+
scores[name] += 1;
|
|
23678
|
+
}
|
|
23679
|
+
}
|
|
23680
|
+
}
|
|
23681
|
+
const entries = Object.entries(scores);
|
|
23682
|
+
entries.sort((a, b) => b[1] - a[1]);
|
|
23683
|
+
const [winner, winnerScore] = entries[0];
|
|
23684
|
+
const [runnerUp, runnerUpScore] = entries[1] || [null, 0];
|
|
23685
|
+
const totalScore = entries.reduce((sum, [, score]) => sum + score, 0);
|
|
23686
|
+
const confidence = totalScore > 0 ? Math.min(0.95, 0.5 + (winnerScore - runnerUpScore) / totalScore) : 0.5;
|
|
23687
|
+
let reasoning;
|
|
23688
|
+
if (winnerScore === 0) {
|
|
23689
|
+
reasoning = `No strong keyword signals. Defaulting to feature-based as it's most versatile.`;
|
|
23690
|
+
} else {
|
|
23691
|
+
const matchedKeywords = STRATEGIES[winner].keywords.filter((k) => taskLower.includes(k));
|
|
23692
|
+
reasoning = `Matched keywords: ${matchedKeywords.join(", ")}. ${STRATEGIES[winner].description}`;
|
|
23693
|
+
}
|
|
23694
|
+
const finalStrategy = winnerScore === 0 ? "feature-based" : winner;
|
|
23695
|
+
return {
|
|
23696
|
+
strategy: finalStrategy,
|
|
23697
|
+
confidence,
|
|
23698
|
+
reasoning,
|
|
23699
|
+
alternatives: entries.filter(([s]) => s !== finalStrategy).map(([strategy, score]) => ({ strategy, score }))
|
|
23700
|
+
};
|
|
23701
|
+
}
|
|
23702
|
+
function formatStrategyGuidelines(strategy) {
|
|
23703
|
+
const def = STRATEGIES[strategy];
|
|
23704
|
+
const guidelines = def.guidelines.map((g) => `- ${g}`).join(`
|
|
23705
|
+
`);
|
|
23706
|
+
const antiPatterns = def.antiPatterns.map((a) => `- ${a}`).join(`
|
|
23707
|
+
`);
|
|
23708
|
+
const examples = def.examples.map((e) => `- ${e}`).join(`
|
|
23709
|
+
`);
|
|
23710
|
+
return `## Strategy: ${strategy}
|
|
23711
|
+
|
|
23712
|
+
${def.description}
|
|
23713
|
+
|
|
23714
|
+
### Guidelines
|
|
23715
|
+
${guidelines}
|
|
23716
|
+
|
|
23717
|
+
### Anti-Patterns (Avoid These)
|
|
23718
|
+
${antiPatterns}
|
|
23719
|
+
|
|
23720
|
+
### Examples
|
|
23721
|
+
${examples}`;
|
|
23722
|
+
}
|
|
23556
23723
|
var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
23557
23724
|
|
|
23558
23725
|
## Task
|
|
@@ -23926,6 +24093,155 @@ function formatCassHistoryForPrompt(history) {
|
|
|
23926
24093
|
return lines.join(`
|
|
23927
24094
|
`);
|
|
23928
24095
|
}
|
|
24096
|
+
var swarm_select_strategy = tool({
|
|
24097
|
+
description: "Analyze task and recommend decomposition strategy (file-based, feature-based, or risk-based)",
|
|
24098
|
+
args: {
|
|
24099
|
+
task: tool.schema.string().min(1).describe("Task description to analyze"),
|
|
24100
|
+
codebase_context: tool.schema.string().optional().describe("Optional codebase context (file structure, tech stack, etc.)")
|
|
24101
|
+
},
|
|
24102
|
+
async execute(args) {
|
|
24103
|
+
const result = selectStrategy(args.task);
|
|
24104
|
+
let enhancedReasoning = result.reasoning;
|
|
24105
|
+
if (args.codebase_context) {
|
|
24106
|
+
enhancedReasoning += `
|
|
24107
|
+
|
|
24108
|
+
Codebase context considered: ${args.codebase_context.slice(0, 200)}...`;
|
|
24109
|
+
}
|
|
24110
|
+
return JSON.stringify({
|
|
24111
|
+
strategy: result.strategy,
|
|
24112
|
+
confidence: Math.round(result.confidence * 100) / 100,
|
|
24113
|
+
reasoning: enhancedReasoning,
|
|
24114
|
+
description: STRATEGIES[result.strategy].description,
|
|
24115
|
+
guidelines: STRATEGIES[result.strategy].guidelines,
|
|
24116
|
+
anti_patterns: STRATEGIES[result.strategy].antiPatterns,
|
|
24117
|
+
alternatives: result.alternatives.map((alt) => ({
|
|
24118
|
+
strategy: alt.strategy,
|
|
24119
|
+
description: STRATEGIES[alt.strategy].description,
|
|
24120
|
+
score: alt.score
|
|
24121
|
+
}))
|
|
24122
|
+
}, null, 2);
|
|
24123
|
+
}
|
|
24124
|
+
});
|
|
24125
|
+
var STRATEGY_DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
24126
|
+
|
|
24127
|
+
## Task
|
|
24128
|
+
{task}
|
|
24129
|
+
|
|
24130
|
+
{strategy_guidelines}
|
|
24131
|
+
|
|
24132
|
+
{context_section}
|
|
24133
|
+
|
|
24134
|
+
{cass_history}
|
|
24135
|
+
|
|
24136
|
+
## MANDATORY: Beads Issue Tracking
|
|
24137
|
+
|
|
24138
|
+
**Every subtask MUST become a bead.** This is non-negotiable.
|
|
24139
|
+
|
|
24140
|
+
After decomposition, the coordinator will:
|
|
24141
|
+
1. Create an epic bead for the overall task
|
|
24142
|
+
2. Create child beads for each subtask
|
|
24143
|
+
3. Track progress through bead status updates
|
|
24144
|
+
4. Close beads with summaries when complete
|
|
24145
|
+
|
|
24146
|
+
Agents MUST update their bead status as they work. No silent progress.
|
|
24147
|
+
|
|
24148
|
+
## Requirements
|
|
24149
|
+
|
|
24150
|
+
1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
|
|
24151
|
+
2. **Assign files** - each subtask must specify which files it will modify
|
|
24152
|
+
3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
|
|
24153
|
+
4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
|
|
24154
|
+
5. **Estimate complexity** - 1 (trivial) to 5 (complex)
|
|
24155
|
+
6. **Plan aggressively** - break down more than you think necessary, smaller is better
|
|
24156
|
+
|
|
24157
|
+
## Response Format
|
|
24158
|
+
|
|
24159
|
+
Respond with a JSON object matching this schema:
|
|
24160
|
+
|
|
24161
|
+
\`\`\`typescript
|
|
24162
|
+
{
|
|
24163
|
+
epic: {
|
|
24164
|
+
title: string, // Epic title for the beads tracker
|
|
24165
|
+
description?: string // Brief description of the overall goal
|
|
24166
|
+
},
|
|
24167
|
+
subtasks: [
|
|
24168
|
+
{
|
|
24169
|
+
title: string, // What this subtask accomplishes
|
|
24170
|
+
description?: string, // Detailed instructions for the agent
|
|
24171
|
+
files: string[], // Files this subtask will modify (globs allowed)
|
|
24172
|
+
dependencies: number[], // Indices of subtasks this depends on (0-indexed)
|
|
24173
|
+
estimated_complexity: 1-5 // Effort estimate
|
|
24174
|
+
},
|
|
24175
|
+
// ... more subtasks
|
|
24176
|
+
]
|
|
24177
|
+
}
|
|
24178
|
+
\`\`\`
|
|
24179
|
+
|
|
24180
|
+
Now decompose the task:`;
|
|
24181
|
+
var swarm_plan_prompt = tool({
|
|
24182
|
+
description: "Generate strategy-specific decomposition prompt. Auto-selects strategy or uses provided one. Queries CASS for similar tasks.",
|
|
24183
|
+
args: {
|
|
24184
|
+
task: tool.schema.string().min(1).describe("Task description to decompose"),
|
|
24185
|
+
strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
|
|
24186
|
+
max_subtasks: tool.schema.number().int().min(2).max(10).default(5).describe("Maximum number of subtasks (default: 5)"),
|
|
24187
|
+
context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
|
|
24188
|
+
query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
|
|
24189
|
+
cass_limit: tool.schema.number().int().min(1).max(10).optional().describe("Max CASS results to include (default: 3)")
|
|
24190
|
+
},
|
|
24191
|
+
async execute(args) {
|
|
24192
|
+
let selectedStrategy;
|
|
24193
|
+
let strategyReasoning;
|
|
24194
|
+
if (args.strategy && args.strategy !== "auto") {
|
|
24195
|
+
selectedStrategy = args.strategy;
|
|
24196
|
+
strategyReasoning = `User-specified strategy: ${selectedStrategy}`;
|
|
24197
|
+
} else {
|
|
24198
|
+
const selection = selectStrategy(args.task);
|
|
24199
|
+
selectedStrategy = selection.strategy;
|
|
24200
|
+
strategyReasoning = selection.reasoning;
|
|
24201
|
+
}
|
|
24202
|
+
let cassContext = "";
|
|
24203
|
+
let cassResult = null;
|
|
24204
|
+
if (args.query_cass !== false) {
|
|
24205
|
+
cassResult = await queryCassHistory(args.task, args.cass_limit ?? 3);
|
|
24206
|
+
if (cassResult && cassResult.results.length > 0) {
|
|
24207
|
+
cassContext = formatCassHistoryForPrompt(cassResult);
|
|
24208
|
+
}
|
|
24209
|
+
}
|
|
24210
|
+
const strategyGuidelines = formatStrategyGuidelines(selectedStrategy);
|
|
24211
|
+
const contextSection = args.context ? `## Additional Context
|
|
24212
|
+
${args.context}` : `## Additional Context
|
|
24213
|
+
(none provided)`;
|
|
24214
|
+
const prompt = STRATEGY_DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", cassContext || "").replace("{max_subtasks}", (args.max_subtasks ?? 5).toString());
|
|
24215
|
+
return JSON.stringify({
|
|
24216
|
+
prompt,
|
|
24217
|
+
strategy: {
|
|
24218
|
+
selected: selectedStrategy,
|
|
24219
|
+
reasoning: strategyReasoning,
|
|
24220
|
+
guidelines: STRATEGIES[selectedStrategy].guidelines,
|
|
24221
|
+
anti_patterns: STRATEGIES[selectedStrategy].antiPatterns
|
|
24222
|
+
},
|
|
24223
|
+
expected_schema: "BeadTree",
|
|
24224
|
+
schema_hint: {
|
|
24225
|
+
epic: { title: "string", description: "string?" },
|
|
24226
|
+
subtasks: [
|
|
24227
|
+
{
|
|
24228
|
+
title: "string",
|
|
24229
|
+
description: "string?",
|
|
24230
|
+
files: "string[]",
|
|
24231
|
+
dependencies: "number[]",
|
|
24232
|
+
estimated_complexity: "1-5"
|
|
24233
|
+
}
|
|
24234
|
+
]
|
|
24235
|
+
},
|
|
24236
|
+
validation_note: "Parse agent response as JSON and validate with swarm_validate_decomposition",
|
|
24237
|
+
cass_history: cassResult ? {
|
|
24238
|
+
queried: true,
|
|
24239
|
+
results_found: cassResult.results.length,
|
|
24240
|
+
included_in_context: cassResult.results.length > 0
|
|
24241
|
+
} : { queried: false, reason: "disabled or unavailable" }
|
|
24242
|
+
}, null, 2);
|
|
24243
|
+
}
|
|
24244
|
+
});
|
|
23929
24245
|
var swarm_decompose = tool({
|
|
23930
24246
|
description: "Generate decomposition prompt for breaking task into parallelizable subtasks. Optionally queries CASS for similar past tasks.",
|
|
23931
24247
|
args: {
|
|
@@ -24285,7 +24601,8 @@ var swarm_record_outcome = tool({
|
|
|
24285
24601
|
retry_count: tool.schema.number().int().min(0).default(0).describe("Number of retry attempts"),
|
|
24286
24602
|
success: tool.schema.boolean().describe("Whether the subtask succeeded"),
|
|
24287
24603
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files that were modified"),
|
|
24288
|
-
criteria: tool.schema.array(tool.schema.string()).optional().describe("Criteria to generate feedback for (default: all default criteria)")
|
|
24604
|
+
criteria: tool.schema.array(tool.schema.string()).optional().describe("Criteria to generate feedback for (default: all default criteria)"),
|
|
24605
|
+
strategy: tool.schema.enum(["file-based", "feature-based", "risk-based"]).optional().describe("Decomposition strategy used for this task")
|
|
24289
24606
|
},
|
|
24290
24607
|
async execute(args) {
|
|
24291
24608
|
const signals = {
|
|
@@ -24295,7 +24612,8 @@ var swarm_record_outcome = tool({
|
|
|
24295
24612
|
retry_count: args.retry_count ?? 0,
|
|
24296
24613
|
success: args.success,
|
|
24297
24614
|
files_touched: args.files_touched ?? [],
|
|
24298
|
-
timestamp: new Date().toISOString()
|
|
24615
|
+
timestamp: new Date().toISOString(),
|
|
24616
|
+
strategy: args.strategy
|
|
24299
24617
|
};
|
|
24300
24618
|
const validated = OutcomeSignalsSchema.parse(signals);
|
|
24301
24619
|
const scored = scoreImplicitFeedback(validated, DEFAULT_LEARNING_CONFIG);
|
|
@@ -24305,7 +24623,13 @@ var swarm_record_outcome = tool({
|
|
|
24305
24623
|
"patterns",
|
|
24306
24624
|
"readable"
|
|
24307
24625
|
];
|
|
24308
|
-
const feedbackEvents = criteriaToScore.map((criterion) =>
|
|
24626
|
+
const feedbackEvents = criteriaToScore.map((criterion) => {
|
|
24627
|
+
const event = outcomeToFeedback(scored, criterion);
|
|
24628
|
+
if (args.strategy) {
|
|
24629
|
+
event.context = `${event.context || ""} [strategy: ${args.strategy}]`.trim();
|
|
24630
|
+
}
|
|
24631
|
+
return event;
|
|
24632
|
+
});
|
|
24309
24633
|
return JSON.stringify({
|
|
24310
24634
|
success: true,
|
|
24311
24635
|
outcome: {
|
|
@@ -24322,7 +24646,8 @@ var swarm_record_outcome = tool({
|
|
|
24322
24646
|
duration_seconds: Math.round(args.duration_ms / 1000),
|
|
24323
24647
|
error_count: args.error_count ?? 0,
|
|
24324
24648
|
retry_count: args.retry_count ?? 0,
|
|
24325
|
-
success: args.success
|
|
24649
|
+
success: args.success,
|
|
24650
|
+
strategy: args.strategy
|
|
24326
24651
|
},
|
|
24327
24652
|
note: "Feedback events should be stored for criterion weight calculation. Use learning.ts functions to apply weights."
|
|
24328
24653
|
}, null, 2);
|
|
@@ -24542,6 +24867,8 @@ var swarm_init = tool({
|
|
|
24542
24867
|
});
|
|
24543
24868
|
var swarmTools = {
|
|
24544
24869
|
swarm_init,
|
|
24870
|
+
swarm_select_strategy,
|
|
24871
|
+
swarm_plan_prompt,
|
|
24545
24872
|
swarm_decompose,
|
|
24546
24873
|
swarm_validate_decomposition,
|
|
24547
24874
|
swarm_status,
|
|
@@ -25027,6 +25354,7 @@ export {
|
|
|
25027
25354
|
swarmTools,
|
|
25028
25355
|
structuredTools,
|
|
25029
25356
|
setStorage,
|
|
25357
|
+
selectStrategy,
|
|
25030
25358
|
resetToolCache,
|
|
25031
25359
|
resetStorage,
|
|
25032
25360
|
requireTool,
|
|
@@ -25040,6 +25368,7 @@ export {
|
|
|
25040
25368
|
formatToolAvailability,
|
|
25041
25369
|
formatSubtaskPromptV2,
|
|
25042
25370
|
formatSubtaskPrompt,
|
|
25371
|
+
formatStrategyGuidelines,
|
|
25043
25372
|
formatEvaluationPrompt,
|
|
25044
25373
|
extractJsonFromText,
|
|
25045
25374
|
src_default as default,
|
|
@@ -25072,6 +25401,7 @@ export {
|
|
|
25072
25401
|
SpawnedAgentSchema,
|
|
25073
25402
|
SemanticMemoryStorage,
|
|
25074
25403
|
SUBTASK_PROMPT_V2,
|
|
25404
|
+
STRATEGIES,
|
|
25075
25405
|
InMemoryStorage,
|
|
25076
25406
|
FileReservationConflictError,
|
|
25077
25407
|
EvaluationSchema,
|
package/dist/plugin.js
CHANGED
|
@@ -23360,6 +23360,11 @@ var CriterionWeightSchema = exports_external.object({
|
|
|
23360
23360
|
last_validated: exports_external.string().optional(),
|
|
23361
23361
|
half_life_days: exports_external.number().positive().default(90)
|
|
23362
23362
|
});
|
|
23363
|
+
var DecompositionStrategySchema = exports_external.enum([
|
|
23364
|
+
"file-based",
|
|
23365
|
+
"feature-based",
|
|
23366
|
+
"risk-based"
|
|
23367
|
+
]);
|
|
23363
23368
|
var OutcomeSignalsSchema = exports_external.object({
|
|
23364
23369
|
bead_id: exports_external.string(),
|
|
23365
23370
|
duration_ms: exports_external.number().int().min(0),
|
|
@@ -23367,7 +23372,8 @@ var OutcomeSignalsSchema = exports_external.object({
|
|
|
23367
23372
|
retry_count: exports_external.number().int().min(0),
|
|
23368
23373
|
success: exports_external.boolean(),
|
|
23369
23374
|
files_touched: exports_external.array(exports_external.string()).default([]),
|
|
23370
|
-
timestamp: exports_external.string()
|
|
23375
|
+
timestamp: exports_external.string(),
|
|
23376
|
+
strategy: DecompositionStrategySchema.optional()
|
|
23371
23377
|
});
|
|
23372
23378
|
var ScoredOutcomeSchema = exports_external.object({
|
|
23373
23379
|
signals: OutcomeSignalsSchema,
|
|
@@ -23512,6 +23518,167 @@ function detectInstructionConflicts(subtasks) {
|
|
|
23512
23518
|
}
|
|
23513
23519
|
return conflicts;
|
|
23514
23520
|
}
|
|
23521
|
+
var STRATEGIES = {
|
|
23522
|
+
"file-based": {
|
|
23523
|
+
name: "file-based",
|
|
23524
|
+
description: "Group by file type or directory. Best for refactoring, migrations, and pattern changes across codebase.",
|
|
23525
|
+
keywords: [
|
|
23526
|
+
"refactor",
|
|
23527
|
+
"migrate",
|
|
23528
|
+
"update all",
|
|
23529
|
+
"rename",
|
|
23530
|
+
"replace",
|
|
23531
|
+
"convert",
|
|
23532
|
+
"upgrade",
|
|
23533
|
+
"deprecate",
|
|
23534
|
+
"remove",
|
|
23535
|
+
"cleanup",
|
|
23536
|
+
"lint",
|
|
23537
|
+
"format"
|
|
23538
|
+
],
|
|
23539
|
+
guidelines: [
|
|
23540
|
+
"Group files by directory or type (e.g., all components, all tests)",
|
|
23541
|
+
"Minimize cross-directory dependencies within a subtask",
|
|
23542
|
+
"Handle shared types/utilities first if they change",
|
|
23543
|
+
"Each subtask should be a complete transformation of its file set",
|
|
23544
|
+
"Consider import/export relationships when grouping"
|
|
23545
|
+
],
|
|
23546
|
+
antiPatterns: [
|
|
23547
|
+
"Don't split tightly coupled files across subtasks",
|
|
23548
|
+
"Don't group files that have no relationship",
|
|
23549
|
+
"Don't forget to update imports when moving/renaming"
|
|
23550
|
+
],
|
|
23551
|
+
examples: [
|
|
23552
|
+
"Migrate all components to new API \u2192 split by component directory",
|
|
23553
|
+
"Rename userId to accountId \u2192 split by module (types first, then consumers)",
|
|
23554
|
+
"Update all tests to use new matcher \u2192 split by test directory"
|
|
23555
|
+
]
|
|
23556
|
+
},
|
|
23557
|
+
"feature-based": {
|
|
23558
|
+
name: "feature-based",
|
|
23559
|
+
description: "Vertical slices with UI + API + data. Best for new features and adding functionality.",
|
|
23560
|
+
keywords: [
|
|
23561
|
+
"add",
|
|
23562
|
+
"implement",
|
|
23563
|
+
"build",
|
|
23564
|
+
"create",
|
|
23565
|
+
"feature",
|
|
23566
|
+
"new",
|
|
23567
|
+
"integrate",
|
|
23568
|
+
"connect",
|
|
23569
|
+
"enable",
|
|
23570
|
+
"support"
|
|
23571
|
+
],
|
|
23572
|
+
guidelines: [
|
|
23573
|
+
"Each subtask is a complete vertical slice (UI + logic + data)",
|
|
23574
|
+
"Start with data layer/types, then logic, then UI",
|
|
23575
|
+
"Keep related components together (form + validation + submission)",
|
|
23576
|
+
"Separate concerns that can be developed independently",
|
|
23577
|
+
"Consider user-facing features as natural boundaries"
|
|
23578
|
+
],
|
|
23579
|
+
antiPatterns: [
|
|
23580
|
+
"Don't split a single feature across multiple subtasks",
|
|
23581
|
+
"Don't create subtasks that can't be tested independently",
|
|
23582
|
+
"Don't forget integration points between features"
|
|
23583
|
+
],
|
|
23584
|
+
examples: [
|
|
23585
|
+
"Add user auth \u2192 [OAuth setup, Session management, Protected routes]",
|
|
23586
|
+
"Build dashboard \u2192 [Data fetching, Chart components, Layout/navigation]",
|
|
23587
|
+
"Add search \u2192 [Search API, Search UI, Results display]"
|
|
23588
|
+
]
|
|
23589
|
+
},
|
|
23590
|
+
"risk-based": {
|
|
23591
|
+
name: "risk-based",
|
|
23592
|
+
description: "Isolate high-risk changes, add tests first. Best for bug fixes, security issues, and critical changes.",
|
|
23593
|
+
keywords: [
|
|
23594
|
+
"fix",
|
|
23595
|
+
"bug",
|
|
23596
|
+
"security",
|
|
23597
|
+
"vulnerability",
|
|
23598
|
+
"critical",
|
|
23599
|
+
"urgent",
|
|
23600
|
+
"hotfix",
|
|
23601
|
+
"patch",
|
|
23602
|
+
"audit",
|
|
23603
|
+
"review",
|
|
23604
|
+
"investigate"
|
|
23605
|
+
],
|
|
23606
|
+
guidelines: [
|
|
23607
|
+
"Write tests FIRST to capture expected behavior",
|
|
23608
|
+
"Isolate the risky change to minimize blast radius",
|
|
23609
|
+
"Add monitoring/logging around the change",
|
|
23610
|
+
"Create rollback plan as part of the task",
|
|
23611
|
+
"Audit similar code for the same issue"
|
|
23612
|
+
],
|
|
23613
|
+
antiPatterns: [
|
|
23614
|
+
"Don't make multiple risky changes in one subtask",
|
|
23615
|
+
"Don't skip tests for 'simple' fixes",
|
|
23616
|
+
"Don't forget to check for similar issues elsewhere"
|
|
23617
|
+
],
|
|
23618
|
+
examples: [
|
|
23619
|
+
"Fix auth bypass \u2192 [Add regression test, Fix vulnerability, Audit similar endpoints]",
|
|
23620
|
+
"Fix race condition \u2192 [Add test reproducing issue, Implement fix, Add concurrency tests]",
|
|
23621
|
+
"Security audit \u2192 [Scan for vulnerabilities, Fix critical issues, Document remaining risks]"
|
|
23622
|
+
]
|
|
23623
|
+
}
|
|
23624
|
+
};
|
|
23625
|
+
function selectStrategy(task) {
|
|
23626
|
+
const taskLower = task.toLowerCase();
|
|
23627
|
+
const scores = {
|
|
23628
|
+
"file-based": 0,
|
|
23629
|
+
"feature-based": 0,
|
|
23630
|
+
"risk-based": 0
|
|
23631
|
+
};
|
|
23632
|
+
for (const [strategyName, definition] of Object.entries(STRATEGIES)) {
|
|
23633
|
+
const name = strategyName;
|
|
23634
|
+
for (const keyword of definition.keywords) {
|
|
23635
|
+
if (taskLower.includes(keyword)) {
|
|
23636
|
+
scores[name] += 1;
|
|
23637
|
+
}
|
|
23638
|
+
}
|
|
23639
|
+
}
|
|
23640
|
+
const entries = Object.entries(scores);
|
|
23641
|
+
entries.sort((a, b) => b[1] - a[1]);
|
|
23642
|
+
const [winner, winnerScore] = entries[0];
|
|
23643
|
+
const [runnerUp, runnerUpScore] = entries[1] || [null, 0];
|
|
23644
|
+
const totalScore = entries.reduce((sum, [, score]) => sum + score, 0);
|
|
23645
|
+
const confidence = totalScore > 0 ? Math.min(0.95, 0.5 + (winnerScore - runnerUpScore) / totalScore) : 0.5;
|
|
23646
|
+
let reasoning;
|
|
23647
|
+
if (winnerScore === 0) {
|
|
23648
|
+
reasoning = `No strong keyword signals. Defaulting to feature-based as it's most versatile.`;
|
|
23649
|
+
} else {
|
|
23650
|
+
const matchedKeywords = STRATEGIES[winner].keywords.filter((k) => taskLower.includes(k));
|
|
23651
|
+
reasoning = `Matched keywords: ${matchedKeywords.join(", ")}. ${STRATEGIES[winner].description}`;
|
|
23652
|
+
}
|
|
23653
|
+
const finalStrategy = winnerScore === 0 ? "feature-based" : winner;
|
|
23654
|
+
return {
|
|
23655
|
+
strategy: finalStrategy,
|
|
23656
|
+
confidence,
|
|
23657
|
+
reasoning,
|
|
23658
|
+
alternatives: entries.filter(([s]) => s !== finalStrategy).map(([strategy, score]) => ({ strategy, score }))
|
|
23659
|
+
};
|
|
23660
|
+
}
|
|
23661
|
+
function formatStrategyGuidelines(strategy) {
|
|
23662
|
+
const def = STRATEGIES[strategy];
|
|
23663
|
+
const guidelines = def.guidelines.map((g) => `- ${g}`).join(`
|
|
23664
|
+
`);
|
|
23665
|
+
const antiPatterns = def.antiPatterns.map((a) => `- ${a}`).join(`
|
|
23666
|
+
`);
|
|
23667
|
+
const examples = def.examples.map((e) => `- ${e}`).join(`
|
|
23668
|
+
`);
|
|
23669
|
+
return `## Strategy: ${strategy}
|
|
23670
|
+
|
|
23671
|
+
${def.description}
|
|
23672
|
+
|
|
23673
|
+
### Guidelines
|
|
23674
|
+
${guidelines}
|
|
23675
|
+
|
|
23676
|
+
### Anti-Patterns (Avoid These)
|
|
23677
|
+
${antiPatterns}
|
|
23678
|
+
|
|
23679
|
+
### Examples
|
|
23680
|
+
${examples}`;
|
|
23681
|
+
}
|
|
23515
23682
|
var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
23516
23683
|
|
|
23517
23684
|
## Task
|
|
@@ -23877,6 +24044,155 @@ function formatCassHistoryForPrompt(history) {
|
|
|
23877
24044
|
return lines.join(`
|
|
23878
24045
|
`);
|
|
23879
24046
|
}
|
|
24047
|
+
var swarm_select_strategy = tool({
|
|
24048
|
+
description: "Analyze task and recommend decomposition strategy (file-based, feature-based, or risk-based)",
|
|
24049
|
+
args: {
|
|
24050
|
+
task: tool.schema.string().min(1).describe("Task description to analyze"),
|
|
24051
|
+
codebase_context: tool.schema.string().optional().describe("Optional codebase context (file structure, tech stack, etc.)")
|
|
24052
|
+
},
|
|
24053
|
+
async execute(args) {
|
|
24054
|
+
const result = selectStrategy(args.task);
|
|
24055
|
+
let enhancedReasoning = result.reasoning;
|
|
24056
|
+
if (args.codebase_context) {
|
|
24057
|
+
enhancedReasoning += `
|
|
24058
|
+
|
|
24059
|
+
Codebase context considered: ${args.codebase_context.slice(0, 200)}...`;
|
|
24060
|
+
}
|
|
24061
|
+
return JSON.stringify({
|
|
24062
|
+
strategy: result.strategy,
|
|
24063
|
+
confidence: Math.round(result.confidence * 100) / 100,
|
|
24064
|
+
reasoning: enhancedReasoning,
|
|
24065
|
+
description: STRATEGIES[result.strategy].description,
|
|
24066
|
+
guidelines: STRATEGIES[result.strategy].guidelines,
|
|
24067
|
+
anti_patterns: STRATEGIES[result.strategy].antiPatterns,
|
|
24068
|
+
alternatives: result.alternatives.map((alt) => ({
|
|
24069
|
+
strategy: alt.strategy,
|
|
24070
|
+
description: STRATEGIES[alt.strategy].description,
|
|
24071
|
+
score: alt.score
|
|
24072
|
+
}))
|
|
24073
|
+
}, null, 2);
|
|
24074
|
+
}
|
|
24075
|
+
});
|
|
24076
|
+
var STRATEGY_DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
24077
|
+
|
|
24078
|
+
## Task
|
|
24079
|
+
{task}
|
|
24080
|
+
|
|
24081
|
+
{strategy_guidelines}
|
|
24082
|
+
|
|
24083
|
+
{context_section}
|
|
24084
|
+
|
|
24085
|
+
{cass_history}
|
|
24086
|
+
|
|
24087
|
+
## MANDATORY: Beads Issue Tracking
|
|
24088
|
+
|
|
24089
|
+
**Every subtask MUST become a bead.** This is non-negotiable.
|
|
24090
|
+
|
|
24091
|
+
After decomposition, the coordinator will:
|
|
24092
|
+
1. Create an epic bead for the overall task
|
|
24093
|
+
2. Create child beads for each subtask
|
|
24094
|
+
3. Track progress through bead status updates
|
|
24095
|
+
4. Close beads with summaries when complete
|
|
24096
|
+
|
|
24097
|
+
Agents MUST update their bead status as they work. No silent progress.
|
|
24098
|
+
|
|
24099
|
+
## Requirements
|
|
24100
|
+
|
|
24101
|
+
1. **Break into 2-{max_subtasks} independent subtasks** that can run in parallel
|
|
24102
|
+
2. **Assign files** - each subtask must specify which files it will modify
|
|
24103
|
+
3. **No file overlap** - files cannot appear in multiple subtasks (they get exclusive locks)
|
|
24104
|
+
4. **Order by dependency** - if subtask B needs subtask A's output, A must come first in the array
|
|
24105
|
+
5. **Estimate complexity** - 1 (trivial) to 5 (complex)
|
|
24106
|
+
6. **Plan aggressively** - break down more than you think necessary, smaller is better
|
|
24107
|
+
|
|
24108
|
+
## Response Format
|
|
24109
|
+
|
|
24110
|
+
Respond with a JSON object matching this schema:
|
|
24111
|
+
|
|
24112
|
+
\`\`\`typescript
|
|
24113
|
+
{
|
|
24114
|
+
epic: {
|
|
24115
|
+
title: string, // Epic title for the beads tracker
|
|
24116
|
+
description?: string // Brief description of the overall goal
|
|
24117
|
+
},
|
|
24118
|
+
subtasks: [
|
|
24119
|
+
{
|
|
24120
|
+
title: string, // What this subtask accomplishes
|
|
24121
|
+
description?: string, // Detailed instructions for the agent
|
|
24122
|
+
files: string[], // Files this subtask will modify (globs allowed)
|
|
24123
|
+
dependencies: number[], // Indices of subtasks this depends on (0-indexed)
|
|
24124
|
+
estimated_complexity: 1-5 // Effort estimate
|
|
24125
|
+
},
|
|
24126
|
+
// ... more subtasks
|
|
24127
|
+
]
|
|
24128
|
+
}
|
|
24129
|
+
\`\`\`
|
|
24130
|
+
|
|
24131
|
+
Now decompose the task:`;
|
|
24132
|
+
var swarm_plan_prompt = tool({
|
|
24133
|
+
description: "Generate strategy-specific decomposition prompt. Auto-selects strategy or uses provided one. Queries CASS for similar tasks.",
|
|
24134
|
+
args: {
|
|
24135
|
+
task: tool.schema.string().min(1).describe("Task description to decompose"),
|
|
24136
|
+
strategy: tool.schema.enum(["file-based", "feature-based", "risk-based", "auto"]).optional().describe("Decomposition strategy (default: auto-detect)"),
|
|
24137
|
+
max_subtasks: tool.schema.number().int().min(2).max(10).default(5).describe("Maximum number of subtasks (default: 5)"),
|
|
24138
|
+
context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
|
|
24139
|
+
query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
|
|
24140
|
+
cass_limit: tool.schema.number().int().min(1).max(10).optional().describe("Max CASS results to include (default: 3)")
|
|
24141
|
+
},
|
|
24142
|
+
async execute(args) {
|
|
24143
|
+
let selectedStrategy;
|
|
24144
|
+
let strategyReasoning;
|
|
24145
|
+
if (args.strategy && args.strategy !== "auto") {
|
|
24146
|
+
selectedStrategy = args.strategy;
|
|
24147
|
+
strategyReasoning = `User-specified strategy: ${selectedStrategy}`;
|
|
24148
|
+
} else {
|
|
24149
|
+
const selection = selectStrategy(args.task);
|
|
24150
|
+
selectedStrategy = selection.strategy;
|
|
24151
|
+
strategyReasoning = selection.reasoning;
|
|
24152
|
+
}
|
|
24153
|
+
let cassContext = "";
|
|
24154
|
+
let cassResult = null;
|
|
24155
|
+
if (args.query_cass !== false) {
|
|
24156
|
+
cassResult = await queryCassHistory(args.task, args.cass_limit ?? 3);
|
|
24157
|
+
if (cassResult && cassResult.results.length > 0) {
|
|
24158
|
+
cassContext = formatCassHistoryForPrompt(cassResult);
|
|
24159
|
+
}
|
|
24160
|
+
}
|
|
24161
|
+
const strategyGuidelines = formatStrategyGuidelines(selectedStrategy);
|
|
24162
|
+
const contextSection = args.context ? `## Additional Context
|
|
24163
|
+
${args.context}` : `## Additional Context
|
|
24164
|
+
(none provided)`;
|
|
24165
|
+
const prompt = STRATEGY_DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{strategy_guidelines}", strategyGuidelines).replace("{context_section}", contextSection).replace("{cass_history}", cassContext || "").replace("{max_subtasks}", (args.max_subtasks ?? 5).toString());
|
|
24166
|
+
return JSON.stringify({
|
|
24167
|
+
prompt,
|
|
24168
|
+
strategy: {
|
|
24169
|
+
selected: selectedStrategy,
|
|
24170
|
+
reasoning: strategyReasoning,
|
|
24171
|
+
guidelines: STRATEGIES[selectedStrategy].guidelines,
|
|
24172
|
+
anti_patterns: STRATEGIES[selectedStrategy].antiPatterns
|
|
24173
|
+
},
|
|
24174
|
+
expected_schema: "BeadTree",
|
|
24175
|
+
schema_hint: {
|
|
24176
|
+
epic: { title: "string", description: "string?" },
|
|
24177
|
+
subtasks: [
|
|
24178
|
+
{
|
|
24179
|
+
title: "string",
|
|
24180
|
+
description: "string?",
|
|
24181
|
+
files: "string[]",
|
|
24182
|
+
dependencies: "number[]",
|
|
24183
|
+
estimated_complexity: "1-5"
|
|
24184
|
+
}
|
|
24185
|
+
]
|
|
24186
|
+
},
|
|
24187
|
+
validation_note: "Parse agent response as JSON and validate with swarm_validate_decomposition",
|
|
24188
|
+
cass_history: cassResult ? {
|
|
24189
|
+
queried: true,
|
|
24190
|
+
results_found: cassResult.results.length,
|
|
24191
|
+
included_in_context: cassResult.results.length > 0
|
|
24192
|
+
} : { queried: false, reason: "disabled or unavailable" }
|
|
24193
|
+
}, null, 2);
|
|
24194
|
+
}
|
|
24195
|
+
});
|
|
23880
24196
|
var swarm_decompose = tool({
|
|
23881
24197
|
description: "Generate decomposition prompt for breaking task into parallelizable subtasks. Optionally queries CASS for similar past tasks.",
|
|
23882
24198
|
args: {
|
|
@@ -24236,7 +24552,8 @@ var swarm_record_outcome = tool({
|
|
|
24236
24552
|
retry_count: tool.schema.number().int().min(0).default(0).describe("Number of retry attempts"),
|
|
24237
24553
|
success: tool.schema.boolean().describe("Whether the subtask succeeded"),
|
|
24238
24554
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files that were modified"),
|
|
24239
|
-
criteria: tool.schema.array(tool.schema.string()).optional().describe("Criteria to generate feedback for (default: all default criteria)")
|
|
24555
|
+
criteria: tool.schema.array(tool.schema.string()).optional().describe("Criteria to generate feedback for (default: all default criteria)"),
|
|
24556
|
+
strategy: tool.schema.enum(["file-based", "feature-based", "risk-based"]).optional().describe("Decomposition strategy used for this task")
|
|
24240
24557
|
},
|
|
24241
24558
|
async execute(args) {
|
|
24242
24559
|
const signals = {
|
|
@@ -24246,7 +24563,8 @@ var swarm_record_outcome = tool({
|
|
|
24246
24563
|
retry_count: args.retry_count ?? 0,
|
|
24247
24564
|
success: args.success,
|
|
24248
24565
|
files_touched: args.files_touched ?? [],
|
|
24249
|
-
timestamp: new Date().toISOString()
|
|
24566
|
+
timestamp: new Date().toISOString(),
|
|
24567
|
+
strategy: args.strategy
|
|
24250
24568
|
};
|
|
24251
24569
|
const validated = OutcomeSignalsSchema.parse(signals);
|
|
24252
24570
|
const scored = scoreImplicitFeedback(validated, DEFAULT_LEARNING_CONFIG);
|
|
@@ -24256,7 +24574,13 @@ var swarm_record_outcome = tool({
|
|
|
24256
24574
|
"patterns",
|
|
24257
24575
|
"readable"
|
|
24258
24576
|
];
|
|
24259
|
-
const feedbackEvents = criteriaToScore.map((criterion) =>
|
|
24577
|
+
const feedbackEvents = criteriaToScore.map((criterion) => {
|
|
24578
|
+
const event = outcomeToFeedback(scored, criterion);
|
|
24579
|
+
if (args.strategy) {
|
|
24580
|
+
event.context = `${event.context || ""} [strategy: ${args.strategy}]`.trim();
|
|
24581
|
+
}
|
|
24582
|
+
return event;
|
|
24583
|
+
});
|
|
24260
24584
|
return JSON.stringify({
|
|
24261
24585
|
success: true,
|
|
24262
24586
|
outcome: {
|
|
@@ -24273,7 +24597,8 @@ var swarm_record_outcome = tool({
|
|
|
24273
24597
|
duration_seconds: Math.round(args.duration_ms / 1000),
|
|
24274
24598
|
error_count: args.error_count ?? 0,
|
|
24275
24599
|
retry_count: args.retry_count ?? 0,
|
|
24276
|
-
success: args.success
|
|
24600
|
+
success: args.success,
|
|
24601
|
+
strategy: args.strategy
|
|
24277
24602
|
},
|
|
24278
24603
|
note: "Feedback events should be stored for criterion weight calculation. Use learning.ts functions to apply weights."
|
|
24279
24604
|
}, null, 2);
|
|
@@ -24493,6 +24818,8 @@ var swarm_init = tool({
|
|
|
24493
24818
|
});
|
|
24494
24819
|
var swarmTools = {
|
|
24495
24820
|
swarm_init,
|
|
24821
|
+
swarm_select_strategy,
|
|
24822
|
+
swarm_plan_prompt,
|
|
24496
24823
|
swarm_decompose,
|
|
24497
24824
|
swarm_validate_decomposition,
|
|
24498
24825
|
swarm_status,
|
package/package.json
CHANGED