opencode-swarm-plugin 0.12.6 → 0.12.8
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/.beads/issues.jsonl +9 -0
- package/dist/index.js +326 -26
- package/dist/plugin.js +325 -26
- package/package.json +1 -1
- package/src/agent-mail.ts +184 -32
- package/src/learning.ts +277 -0
- package/src/swarm.ts +176 -1
package/dist/plugin.js
CHANGED
|
@@ -22606,8 +22606,8 @@ var RETRY_CONFIG = {
|
|
|
22606
22606
|
jitterPercent: 20
|
|
22607
22607
|
};
|
|
22608
22608
|
var RECOVERY_CONFIG = {
|
|
22609
|
-
failureThreshold:
|
|
22610
|
-
restartCooldownMs:
|
|
22609
|
+
failureThreshold: 1,
|
|
22610
|
+
restartCooldownMs: 1e4,
|
|
22611
22611
|
enabled: process.env.OPENCODE_AGENT_MAIL_AUTO_RESTART !== "false"
|
|
22612
22612
|
};
|
|
22613
22613
|
var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join2(tmpdir(), "swarm-sessions");
|
|
@@ -22905,6 +22905,7 @@ async function mcpCallOnce(toolName, args) {
|
|
|
22905
22905
|
}
|
|
22906
22906
|
async function mcpCall(toolName, args) {
|
|
22907
22907
|
let lastError = null;
|
|
22908
|
+
let restartAttempted = false;
|
|
22908
22909
|
for (let attempt = 0;attempt <= RETRY_CONFIG.maxRetries; attempt++) {
|
|
22909
22910
|
if (attempt > 0) {
|
|
22910
22911
|
const delay = calculateBackoffDelay(attempt);
|
|
@@ -22917,13 +22918,28 @@ async function mcpCall(toolName, args) {
|
|
|
22917
22918
|
return result;
|
|
22918
22919
|
} catch (error45) {
|
|
22919
22920
|
lastError = error45 instanceof Error ? error45 : new Error(String(error45));
|
|
22921
|
+
const errorMessage = lastError.message.toLowerCase();
|
|
22920
22922
|
consecutiveFailures++;
|
|
22921
22923
|
const retryable = isRetryableError(error45);
|
|
22922
|
-
|
|
22924
|
+
const isUnexpectedError = errorMessage.includes("unexpected error");
|
|
22925
|
+
if (isUnexpectedError && !restartAttempted && RECOVERY_CONFIG.enabled) {
|
|
22926
|
+
console.warn(`[agent-mail] "${toolName}" got unexpected error, restarting server immediately...`);
|
|
22927
|
+
restartAttempted = true;
|
|
22928
|
+
const restarted = await restartServer();
|
|
22929
|
+
if (restarted) {
|
|
22930
|
+
agentMailAvailable = null;
|
|
22931
|
+
consecutiveFailures = 0;
|
|
22932
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
22933
|
+
attempt--;
|
|
22934
|
+
continue;
|
|
22935
|
+
}
|
|
22936
|
+
}
|
|
22937
|
+
if (!isUnexpectedError && consecutiveFailures >= RECOVERY_CONFIG.failureThreshold && RECOVERY_CONFIG.enabled && !restartAttempted) {
|
|
22923
22938
|
console.warn(`[agent-mail] ${consecutiveFailures} consecutive failures, checking server health...`);
|
|
22924
22939
|
const healthy = await isServerFunctional();
|
|
22925
22940
|
if (!healthy) {
|
|
22926
22941
|
console.warn("[agent-mail] Server unhealthy, attempting restart...");
|
|
22942
|
+
restartAttempted = true;
|
|
22927
22943
|
const restarted = await restartServer();
|
|
22928
22944
|
if (restarted) {
|
|
22929
22945
|
agentMailAvailable = null;
|
|
@@ -22981,24 +22997,57 @@ var agentmail_init = tool({
|
|
|
22981
22997
|
fallback: "Swarm will continue without multi-agent coordination. File conflicts possible if multiple agents active."
|
|
22982
22998
|
}, null, 2);
|
|
22983
22999
|
}
|
|
22984
|
-
const
|
|
22985
|
-
|
|
22986
|
-
|
|
22987
|
-
|
|
22988
|
-
|
|
22989
|
-
|
|
22990
|
-
|
|
22991
|
-
|
|
22992
|
-
|
|
22993
|
-
|
|
22994
|
-
|
|
22995
|
-
|
|
22996
|
-
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23000
|
-
|
|
23001
|
-
|
|
23000
|
+
const MAX_INIT_RETRIES = 3;
|
|
23001
|
+
let lastError = null;
|
|
23002
|
+
for (let attempt = 1;attempt <= MAX_INIT_RETRIES; attempt++) {
|
|
23003
|
+
try {
|
|
23004
|
+
const project = await mcpCall("ensure_project", {
|
|
23005
|
+
human_key: args.project_path
|
|
23006
|
+
});
|
|
23007
|
+
const agent = await mcpCall("register_agent", {
|
|
23008
|
+
project_key: args.project_path,
|
|
23009
|
+
program: "opencode",
|
|
23010
|
+
model: "claude-opus-4",
|
|
23011
|
+
name: args.agent_name,
|
|
23012
|
+
task_description: args.task_description || ""
|
|
23013
|
+
});
|
|
23014
|
+
const state = {
|
|
23015
|
+
projectKey: args.project_path,
|
|
23016
|
+
agentName: agent.name,
|
|
23017
|
+
reservations: [],
|
|
23018
|
+
startedAt: new Date().toISOString()
|
|
23019
|
+
};
|
|
23020
|
+
setState(ctx.sessionID, state);
|
|
23021
|
+
if (attempt > 1) {
|
|
23022
|
+
console.warn(`[agent-mail] Init succeeded on attempt ${attempt} after restart`);
|
|
23023
|
+
}
|
|
23024
|
+
return JSON.stringify({ project, agent, available: true }, null, 2);
|
|
23025
|
+
} catch (error45) {
|
|
23026
|
+
lastError = error45 instanceof Error ? error45 : new Error(String(error45));
|
|
23027
|
+
const isUnexpectedError = lastError.message.toLowerCase().includes("unexpected error");
|
|
23028
|
+
console.warn(`[agent-mail] Init attempt ${attempt}/${MAX_INIT_RETRIES} failed: ${lastError.message}`);
|
|
23029
|
+
if (isUnexpectedError && attempt < MAX_INIT_RETRIES) {
|
|
23030
|
+
console.warn("[agent-mail] Detected 'unexpected error', restarting server...");
|
|
23031
|
+
const restarted = await restartServer();
|
|
23032
|
+
if (restarted) {
|
|
23033
|
+
agentMailAvailable = null;
|
|
23034
|
+
consecutiveFailures = 0;
|
|
23035
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
23036
|
+
continue;
|
|
23037
|
+
}
|
|
23038
|
+
}
|
|
23039
|
+
if (!isUnexpectedError) {
|
|
23040
|
+
break;
|
|
23041
|
+
}
|
|
23042
|
+
}
|
|
23043
|
+
}
|
|
23044
|
+
return JSON.stringify({
|
|
23045
|
+
error: `Agent Mail init failed after ${MAX_INIT_RETRIES} attempts`,
|
|
23046
|
+
available: false,
|
|
23047
|
+
lastError: lastError?.message,
|
|
23048
|
+
hint: "Manually restart Agent Mail: pkill -f agent-mail && agent-mail serve",
|
|
23049
|
+
fallback: "Swarm will continue without multi-agent coordination."
|
|
23050
|
+
}, null, 2);
|
|
23002
23051
|
}
|
|
23003
23052
|
});
|
|
23004
23053
|
var agentmail_send = tool({
|
|
@@ -23204,7 +23253,11 @@ var agentmail_health = tool({
|
|
|
23204
23253
|
try {
|
|
23205
23254
|
const response = await fetch(`${AGENT_MAIL_URL}/health/liveness`);
|
|
23206
23255
|
if (response.ok) {
|
|
23207
|
-
|
|
23256
|
+
const functional = await isServerFunctional();
|
|
23257
|
+
if (functional) {
|
|
23258
|
+
return "Agent Mail is running and functional";
|
|
23259
|
+
}
|
|
23260
|
+
return "Agent Mail health OK but MCP not responding - consider restart";
|
|
23208
23261
|
}
|
|
23209
23262
|
return `Agent Mail returned status ${response.status}`;
|
|
23210
23263
|
} catch (error45) {
|
|
@@ -23212,6 +23265,41 @@ var agentmail_health = tool({
|
|
|
23212
23265
|
}
|
|
23213
23266
|
}
|
|
23214
23267
|
});
|
|
23268
|
+
var agentmail_restart = tool({
|
|
23269
|
+
description: "Manually restart Agent Mail server (use when getting 'unexpected error')",
|
|
23270
|
+
args: {
|
|
23271
|
+
force: tool.schema.boolean().optional().describe("Force restart even if server appears healthy (default: false)")
|
|
23272
|
+
},
|
|
23273
|
+
async execute(args) {
|
|
23274
|
+
if (!args.force) {
|
|
23275
|
+
const functional = await isServerFunctional();
|
|
23276
|
+
if (functional) {
|
|
23277
|
+
return JSON.stringify({
|
|
23278
|
+
restarted: false,
|
|
23279
|
+
reason: "Server is functional, no restart needed",
|
|
23280
|
+
hint: "Use force=true to restart anyway"
|
|
23281
|
+
}, null, 2);
|
|
23282
|
+
}
|
|
23283
|
+
}
|
|
23284
|
+
console.warn("[agent-mail] Manual restart requested...");
|
|
23285
|
+
const success2 = await restartServer();
|
|
23286
|
+
agentMailAvailable = null;
|
|
23287
|
+
consecutiveFailures = 0;
|
|
23288
|
+
if (success2) {
|
|
23289
|
+
return JSON.stringify({
|
|
23290
|
+
restarted: true,
|
|
23291
|
+
success: true,
|
|
23292
|
+
message: "Agent Mail server restarted successfully"
|
|
23293
|
+
}, null, 2);
|
|
23294
|
+
}
|
|
23295
|
+
return JSON.stringify({
|
|
23296
|
+
restarted: true,
|
|
23297
|
+
success: false,
|
|
23298
|
+
error: "Restart attempted but server did not come back up",
|
|
23299
|
+
hint: "Check server logs or manually start: agent-mail serve"
|
|
23300
|
+
}, null, 2);
|
|
23301
|
+
}
|
|
23302
|
+
});
|
|
23215
23303
|
var agentMailTools = {
|
|
23216
23304
|
agentmail_init,
|
|
23217
23305
|
agentmail_send,
|
|
@@ -23222,7 +23310,8 @@ var agentMailTools = {
|
|
|
23222
23310
|
agentmail_release,
|
|
23223
23311
|
agentmail_ack,
|
|
23224
23312
|
agentmail_search,
|
|
23225
|
-
agentmail_health
|
|
23313
|
+
agentmail_health,
|
|
23314
|
+
agentmail_restart
|
|
23226
23315
|
};
|
|
23227
23316
|
|
|
23228
23317
|
// src/structured.ts
|
|
@@ -23638,6 +23727,24 @@ var CriterionWeightSchema = exports_external.object({
|
|
|
23638
23727
|
last_validated: exports_external.string().optional(),
|
|
23639
23728
|
half_life_days: exports_external.number().positive().default(90)
|
|
23640
23729
|
});
|
|
23730
|
+
var ErrorTypeSchema = exports_external.enum([
|
|
23731
|
+
"validation",
|
|
23732
|
+
"timeout",
|
|
23733
|
+
"conflict",
|
|
23734
|
+
"tool_failure",
|
|
23735
|
+
"unknown"
|
|
23736
|
+
]);
|
|
23737
|
+
var ErrorEntrySchema = exports_external.object({
|
|
23738
|
+
id: exports_external.string(),
|
|
23739
|
+
bead_id: exports_external.string(),
|
|
23740
|
+
error_type: ErrorTypeSchema,
|
|
23741
|
+
message: exports_external.string(),
|
|
23742
|
+
stack_trace: exports_external.string().optional(),
|
|
23743
|
+
tool_name: exports_external.string().optional(),
|
|
23744
|
+
timestamp: exports_external.string(),
|
|
23745
|
+
resolved: exports_external.boolean().default(false),
|
|
23746
|
+
context: exports_external.string().optional()
|
|
23747
|
+
});
|
|
23641
23748
|
var DecompositionStrategySchema = exports_external.enum([
|
|
23642
23749
|
"file-based",
|
|
23643
23750
|
"feature-based",
|
|
@@ -23711,6 +23818,117 @@ function outcomeToFeedback(outcome, criterion) {
|
|
|
23711
23818
|
raw_value: outcome.decayed_value
|
|
23712
23819
|
};
|
|
23713
23820
|
}
|
|
23821
|
+
class InMemoryErrorStorage {
|
|
23822
|
+
errors = [];
|
|
23823
|
+
async store(entry) {
|
|
23824
|
+
this.errors.push(entry);
|
|
23825
|
+
}
|
|
23826
|
+
async getByBead(beadId) {
|
|
23827
|
+
return this.errors.filter((e) => e.bead_id === beadId);
|
|
23828
|
+
}
|
|
23829
|
+
async getUnresolvedByBead(beadId) {
|
|
23830
|
+
return this.errors.filter((e) => e.bead_id === beadId && !e.resolved);
|
|
23831
|
+
}
|
|
23832
|
+
async markResolved(id) {
|
|
23833
|
+
const error45 = this.errors.find((e) => e.id === id);
|
|
23834
|
+
if (error45) {
|
|
23835
|
+
error45.resolved = true;
|
|
23836
|
+
}
|
|
23837
|
+
}
|
|
23838
|
+
async getAll() {
|
|
23839
|
+
return [...this.errors];
|
|
23840
|
+
}
|
|
23841
|
+
}
|
|
23842
|
+
|
|
23843
|
+
class ErrorAccumulator {
|
|
23844
|
+
storage;
|
|
23845
|
+
constructor(storage) {
|
|
23846
|
+
this.storage = storage ?? new InMemoryErrorStorage;
|
|
23847
|
+
}
|
|
23848
|
+
async recordError(beadId, errorType, message, options) {
|
|
23849
|
+
const entry = {
|
|
23850
|
+
id: `${beadId}-${errorType}-${Date.now()}`,
|
|
23851
|
+
bead_id: beadId,
|
|
23852
|
+
error_type: errorType,
|
|
23853
|
+
message,
|
|
23854
|
+
stack_trace: options?.stack_trace,
|
|
23855
|
+
tool_name: options?.tool_name,
|
|
23856
|
+
timestamp: new Date().toISOString(),
|
|
23857
|
+
resolved: false,
|
|
23858
|
+
context: options?.context
|
|
23859
|
+
};
|
|
23860
|
+
const validated = ErrorEntrySchema.parse(entry);
|
|
23861
|
+
await this.storage.store(validated);
|
|
23862
|
+
return validated;
|
|
23863
|
+
}
|
|
23864
|
+
async getErrors(beadId) {
|
|
23865
|
+
return this.storage.getByBead(beadId);
|
|
23866
|
+
}
|
|
23867
|
+
async getUnresolvedErrors(beadId) {
|
|
23868
|
+
return this.storage.getUnresolvedByBead(beadId);
|
|
23869
|
+
}
|
|
23870
|
+
async resolveError(errorId) {
|
|
23871
|
+
await this.storage.markResolved(errorId);
|
|
23872
|
+
}
|
|
23873
|
+
async getErrorContext(beadId, includeResolved = false) {
|
|
23874
|
+
const errors3 = includeResolved ? await this.getErrors(beadId) : await this.getUnresolvedErrors(beadId);
|
|
23875
|
+
if (errors3.length === 0) {
|
|
23876
|
+
return "";
|
|
23877
|
+
}
|
|
23878
|
+
const byType = errors3.reduce((acc, err) => {
|
|
23879
|
+
const type = err.error_type;
|
|
23880
|
+
if (!acc[type]) {
|
|
23881
|
+
acc[type] = [];
|
|
23882
|
+
}
|
|
23883
|
+
acc[type].push(err);
|
|
23884
|
+
return acc;
|
|
23885
|
+
}, {});
|
|
23886
|
+
const lines = [
|
|
23887
|
+
"## Previous Errors",
|
|
23888
|
+
"",
|
|
23889
|
+
"The following errors were encountered during execution:",
|
|
23890
|
+
""
|
|
23891
|
+
];
|
|
23892
|
+
for (const [type, typeErrors] of Object.entries(byType)) {
|
|
23893
|
+
lines.push(`### ${type} (${typeErrors.length} error${typeErrors.length > 1 ? "s" : ""})`);
|
|
23894
|
+
lines.push("");
|
|
23895
|
+
for (const err of typeErrors) {
|
|
23896
|
+
lines.push(`- **${err.message}**`);
|
|
23897
|
+
if (err.context) {
|
|
23898
|
+
lines.push(` - Context: ${err.context}`);
|
|
23899
|
+
}
|
|
23900
|
+
if (err.tool_name) {
|
|
23901
|
+
lines.push(` - Tool: ${err.tool_name}`);
|
|
23902
|
+
}
|
|
23903
|
+
if (err.stack_trace) {
|
|
23904
|
+
lines.push(` - Stack: \`${err.stack_trace.slice(0, 100)}...\``);
|
|
23905
|
+
}
|
|
23906
|
+
lines.push(` - Time: ${new Date(err.timestamp).toLocaleString()}${err.resolved ? " (resolved)" : ""}`);
|
|
23907
|
+
lines.push("");
|
|
23908
|
+
}
|
|
23909
|
+
}
|
|
23910
|
+
lines.push("**Action Required**: Address these errors before proceeding. Consider:");
|
|
23911
|
+
lines.push("- What caused each error?");
|
|
23912
|
+
lines.push("- How can you prevent similar errors?");
|
|
23913
|
+
lines.push("- Are there patterns across error types?");
|
|
23914
|
+
lines.push("");
|
|
23915
|
+
return lines.join(`
|
|
23916
|
+
`);
|
|
23917
|
+
}
|
|
23918
|
+
async getErrorStats(beadId) {
|
|
23919
|
+
const allErrors = await this.getErrors(beadId);
|
|
23920
|
+
const unresolved = await this.getUnresolvedErrors(beadId);
|
|
23921
|
+
const byType = allErrors.reduce((acc, err) => {
|
|
23922
|
+
acc[err.error_type] = (acc[err.error_type] || 0) + 1;
|
|
23923
|
+
return acc;
|
|
23924
|
+
}, {});
|
|
23925
|
+
return {
|
|
23926
|
+
total: allErrors.length,
|
|
23927
|
+
unresolved: unresolved.length,
|
|
23928
|
+
by_type: byType
|
|
23929
|
+
};
|
|
23930
|
+
}
|
|
23931
|
+
}
|
|
23714
23932
|
|
|
23715
23933
|
// src/swarm.ts
|
|
23716
23934
|
var POSITIVE_MARKERS = [
|
|
@@ -24122,6 +24340,10 @@ Only modify these files. Need others? Message the coordinator.
|
|
|
24122
24340
|
## Context
|
|
24123
24341
|
{shared_context}
|
|
24124
24342
|
|
|
24343
|
+
{compressed_context}
|
|
24344
|
+
|
|
24345
|
+
{error_context}
|
|
24346
|
+
|
|
24125
24347
|
## MANDATORY: Use These Tools
|
|
24126
24348
|
|
|
24127
24349
|
### Agent Mail - communicate with the swarm
|
|
@@ -24155,7 +24377,9 @@ Begin now.`;
|
|
|
24155
24377
|
function formatSubtaskPromptV2(params) {
|
|
24156
24378
|
const fileList = params.files.length > 0 ? params.files.map((f) => `- \`${f}\``).join(`
|
|
24157
24379
|
`) : "(no specific files - use judgment)";
|
|
24158
|
-
|
|
24380
|
+
const compressedSection = params.compressed_context ? params.compressed_context : "";
|
|
24381
|
+
const errorSection = params.error_context ? params.error_context : "";
|
|
24382
|
+
return SUBTASK_PROMPT_V2.replace(/{bead_id}/g, params.bead_id).replace(/{epic_id}/g, params.epic_id).replace("{subtask_title}", params.subtask_title).replace("{subtask_description}", params.subtask_description || "(see title)").replace("{file_list}", fileList).replace("{shared_context}", params.shared_context || "(none)").replace("{compressed_context}", compressedSection).replace("{error_context}", errorSection);
|
|
24159
24383
|
}
|
|
24160
24384
|
var EVALUATION_PROMPT = `Evaluate the work completed for this subtask.
|
|
24161
24385
|
|
|
@@ -24853,6 +25077,7 @@ var swarm_record_outcome = tool({
|
|
|
24853
25077
|
};
|
|
24854
25078
|
const validated = OutcomeSignalsSchema.parse(signals);
|
|
24855
25079
|
const scored = scoreImplicitFeedback(validated, DEFAULT_LEARNING_CONFIG);
|
|
25080
|
+
const errorStats = await globalErrorAccumulator.getErrorStats(args.bead_id);
|
|
24856
25081
|
const criteriaToScore = args.criteria ?? [
|
|
24857
25082
|
"type_safe",
|
|
24858
25083
|
"no_bugs",
|
|
@@ -24864,6 +25089,10 @@ var swarm_record_outcome = tool({
|
|
|
24864
25089
|
if (args.strategy) {
|
|
24865
25090
|
event.context = `${event.context || ""} [strategy: ${args.strategy}]`.trim();
|
|
24866
25091
|
}
|
|
25092
|
+
if (errorStats.total > 0) {
|
|
25093
|
+
const errorSummary = Object.entries(errorStats.by_type).map(([type, count]) => `${type}:${count}`).join(", ");
|
|
25094
|
+
event.context = `${event.context || ""} [errors: ${errorSummary}]`.trim();
|
|
25095
|
+
}
|
|
24867
25096
|
return event;
|
|
24868
25097
|
});
|
|
24869
25098
|
return JSON.stringify({
|
|
@@ -24877,13 +25106,16 @@ var swarm_record_outcome = tool({
|
|
|
24877
25106
|
}
|
|
24878
25107
|
},
|
|
24879
25108
|
feedback_events: feedbackEvents,
|
|
25109
|
+
error_patterns: errorStats,
|
|
24880
25110
|
summary: {
|
|
24881
25111
|
feedback_type: scored.type,
|
|
24882
25112
|
duration_seconds: Math.round(args.duration_ms / 1000),
|
|
24883
25113
|
error_count: args.error_count ?? 0,
|
|
24884
25114
|
retry_count: args.retry_count ?? 0,
|
|
24885
25115
|
success: args.success,
|
|
24886
|
-
strategy: args.strategy
|
|
25116
|
+
strategy: args.strategy,
|
|
25117
|
+
accumulated_errors: errorStats.total,
|
|
25118
|
+
unresolved_errors: errorStats.unresolved
|
|
24887
25119
|
},
|
|
24888
25120
|
note: "Feedback events should be stored for criterion weight calculation. Use learning.ts functions to apply weights."
|
|
24889
25121
|
}, null, 2);
|
|
@@ -25053,6 +25285,70 @@ var swarm_evaluation_prompt = tool({
|
|
|
25053
25285
|
}, null, 2);
|
|
25054
25286
|
}
|
|
25055
25287
|
});
|
|
25288
|
+
var globalErrorAccumulator = new ErrorAccumulator;
|
|
25289
|
+
var swarm_accumulate_error = tool({
|
|
25290
|
+
description: "Record an error during subtask execution. Errors feed into retry prompts.",
|
|
25291
|
+
args: {
|
|
25292
|
+
bead_id: tool.schema.string().describe("Bead ID where error occurred"),
|
|
25293
|
+
error_type: tool.schema.enum(["validation", "timeout", "conflict", "tool_failure", "unknown"]).describe("Category of error"),
|
|
25294
|
+
message: tool.schema.string().describe("Human-readable error message"),
|
|
25295
|
+
stack_trace: tool.schema.string().optional().describe("Stack trace for debugging"),
|
|
25296
|
+
tool_name: tool.schema.string().optional().describe("Tool that failed"),
|
|
25297
|
+
context: tool.schema.string().optional().describe("What was happening when error occurred")
|
|
25298
|
+
},
|
|
25299
|
+
async execute(args) {
|
|
25300
|
+
const entry = await globalErrorAccumulator.recordError(args.bead_id, args.error_type, args.message, {
|
|
25301
|
+
stack_trace: args.stack_trace,
|
|
25302
|
+
tool_name: args.tool_name,
|
|
25303
|
+
context: args.context
|
|
25304
|
+
});
|
|
25305
|
+
return JSON.stringify({
|
|
25306
|
+
success: true,
|
|
25307
|
+
error_id: entry.id,
|
|
25308
|
+
bead_id: entry.bead_id,
|
|
25309
|
+
error_type: entry.error_type,
|
|
25310
|
+
message: entry.message,
|
|
25311
|
+
timestamp: entry.timestamp,
|
|
25312
|
+
note: "Error recorded for retry context. Use swarm_get_error_context to retrieve accumulated errors."
|
|
25313
|
+
}, null, 2);
|
|
25314
|
+
}
|
|
25315
|
+
});
|
|
25316
|
+
var swarm_get_error_context = tool({
|
|
25317
|
+
description: "Get accumulated errors for a bead. Returns formatted context for retry prompts.",
|
|
25318
|
+
args: {
|
|
25319
|
+
bead_id: tool.schema.string().describe("Bead ID to get errors for"),
|
|
25320
|
+
include_resolved: tool.schema.boolean().optional().describe("Include resolved errors (default: false)")
|
|
25321
|
+
},
|
|
25322
|
+
async execute(args) {
|
|
25323
|
+
const errorContext = await globalErrorAccumulator.getErrorContext(args.bead_id, args.include_resolved ?? false);
|
|
25324
|
+
const stats = await globalErrorAccumulator.getErrorStats(args.bead_id);
|
|
25325
|
+
return JSON.stringify({
|
|
25326
|
+
bead_id: args.bead_id,
|
|
25327
|
+
error_context: errorContext,
|
|
25328
|
+
stats: {
|
|
25329
|
+
total_errors: stats.total,
|
|
25330
|
+
unresolved: stats.unresolved,
|
|
25331
|
+
by_type: stats.by_type
|
|
25332
|
+
},
|
|
25333
|
+
has_errors: errorContext.length > 0,
|
|
25334
|
+
usage: "Inject error_context into retry prompt using {error_context} placeholder"
|
|
25335
|
+
}, null, 2);
|
|
25336
|
+
}
|
|
25337
|
+
});
|
|
25338
|
+
var swarm_resolve_error = tool({
|
|
25339
|
+
description: "Mark an error as resolved after fixing it. Updates error accumulator state.",
|
|
25340
|
+
args: {
|
|
25341
|
+
error_id: tool.schema.string().describe("Error ID to mark as resolved")
|
|
25342
|
+
},
|
|
25343
|
+
async execute(args) {
|
|
25344
|
+
await globalErrorAccumulator.resolveError(args.error_id);
|
|
25345
|
+
return JSON.stringify({
|
|
25346
|
+
success: true,
|
|
25347
|
+
error_id: args.error_id,
|
|
25348
|
+
resolved: true
|
|
25349
|
+
}, null, 2);
|
|
25350
|
+
}
|
|
25351
|
+
});
|
|
25056
25352
|
var swarm_init = tool({
|
|
25057
25353
|
description: "Initialize swarm session and check tool availability. Call at swarm start to see what features are available.",
|
|
25058
25354
|
args: {
|
|
@@ -25114,7 +25410,10 @@ var swarmTools = {
|
|
|
25114
25410
|
swarm_subtask_prompt,
|
|
25115
25411
|
swarm_spawn_subtask,
|
|
25116
25412
|
swarm_complete_subtask,
|
|
25117
|
-
swarm_evaluation_prompt
|
|
25413
|
+
swarm_evaluation_prompt,
|
|
25414
|
+
swarm_accumulate_error,
|
|
25415
|
+
swarm_get_error_context,
|
|
25416
|
+
swarm_resolve_error
|
|
25118
25417
|
};
|
|
25119
25418
|
// src/anti-patterns.ts
|
|
25120
25419
|
var PatternKindSchema = exports_external.enum(["pattern", "anti_pattern"]);
|
package/package.json
CHANGED