opencode-swarm-plugin 0.12.6 → 0.12.7

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.
@@ -466,6 +466,13 @@
466
466
  {"id":"opencode-swarm-plugin-97yt8","title":"Query test bead","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-10T09:06:06.460876-08:00","updated_at":"2025-12-10T09:06:10.054925-08:00","closed_at":"2025-12-10T09:06:10.054925-08:00"}
467
467
  {"id":"opencode-swarm-plugin-98oh","title":"Thread link test bead","description":"[thread:test-thread-456]","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T09:09:32.231853-08:00","updated_at":"2025-12-08T09:09:33.887506-08:00","closed_at":"2025-12-08T09:09:33.887506-08:00"}
468
468
  {"id":"opencode-swarm-plugin-99kl","title":"Test bug with priority","description":"This is a critical bug","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-12-08T08:25:09.19481-08:00","updated_at":"2025-12-08T08:25:11.989888-08:00","closed_at":"2025-12-08T08:25:11.989888-08:00"}
469
+ {"id":"opencode-swarm-plugin-9bwp7","title":"Swarm Plugin Improvements from AI Agent Pattern Research","description":"Improvements derived from PDF library research (Patterns for Building AI Agents, Principles of Building AI Agents). Focus on context engineering, error handling, and coordination patterns.","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-10T10:02:46.552187-08:00","updated_at":"2025-12-10T10:02:46.552187-08:00"}
470
+ {"id":"opencode-swarm-plugin-9bwp7.1","title":"Add swarm_compress_context tool for inter-subtask context pruning","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-10T10:02:46.602046-08:00","updated_at":"2025-12-10T10:09:07.1119-08:00","closed_at":"2025-12-10T10:09:07.1119-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.1","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.603062-08:00","created_by":"daemon"}]}
471
+ {"id":"opencode-swarm-plugin-9bwp7.2","title":"Add error accumulator that feeds errors into retry prompts","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-10T10:02:46.646473-08:00","updated_at":"2025-12-10T10:14:05.802245-08:00","closed_at":"2025-12-10T10:14:05.802245-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.2","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.647689-08:00","created_by":"daemon"}]}
472
+ {"id":"opencode-swarm-plugin-9bwp7.3","title":"Add failure mode taxonomy to swarm_record_outcome","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-10T10:02:46.693562-08:00","updated_at":"2025-12-10T10:02:46.693562-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.3","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.695053-08:00","created_by":"daemon"}]}
473
+ {"id":"opencode-swarm-plugin-9bwp7.4","title":"Add swarm_broadcast for mid-task context sharing between agents","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-10T10:02:46.743428-08:00","updated_at":"2025-12-10T10:02:46.743428-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.4","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.744327-08:00","created_by":"daemon"}]}
474
+ {"id":"opencode-swarm-plugin-9bwp7.5","title":"Restructure SUBTASK_PROMPT with explicit context sections","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-10T10:02:46.790385-08:00","updated_at":"2025-12-10T10:02:46.790385-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.5","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.791322-08:00","created_by":"daemon"}]}
475
+ {"id":"opencode-swarm-plugin-9bwp7.6","title":"Audit tool descriptions for semantic clarity","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-10T10:02:46.835414-08:00","updated_at":"2025-12-10T10:02:46.835414-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-9bwp7.6","depends_on_id":"opencode-swarm-plugin-9bwp7","type":"parent-child","created_at":"2025-12-10T10:02:46.836428-08:00","created_by":"daemon"}]}
469
476
  {"id":"opencode-swarm-plugin-9c51","title":"Thread link test bead","description":"[thread:test-thread-456]","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T08:25:11.111119-08:00","updated_at":"2025-12-08T08:25:12.950452-08:00","closed_at":"2025-12-08T08:25:12.950452-08:00"}
470
477
  {"id":"opencode-swarm-plugin-9c6","title":"Cleanup task","description":"","status":"closed","priority":3,"issue_type":"chore","created_at":"2025-12-07T19:34:52.310497-08:00","updated_at":"2025-12-07T19:34:54.508737-08:00","closed_at":"2025-12-07T19:34:54.508737-08:00"}
471
478
  {"id":"opencode-swarm-plugin-9csf","title":"Limit test bead 1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T08:11:39.347968-08:00","updated_at":"2025-12-08T08:11:41.877049-08:00","closed_at":"2025-12-08T08:11:41.877049-08:00"}
@@ -533,6 +540,7 @@
533
540
  {"id":"opencode-swarm-plugin-ai2p","title":"Update test bead","description":"Original description","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T08:22:17.302997-08:00","updated_at":"2025-12-08T08:22:19.488446-08:00","closed_at":"2025-12-08T08:22:19.488446-08:00"}
534
541
  {"id":"opencode-swarm-plugin-ajqu","title":"Query test bead","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T19:41:10.735824-08:00","updated_at":"2025-12-07T19:41:13.322607-08:00","closed_at":"2025-12-07T19:41:13.322607-08:00"}
535
542
  {"id":"opencode-swarm-plugin-am6b","title":"Single subtask epic","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-08T08:11:40.362506-08:00","updated_at":"2025-12-08T08:11:42.362957-08:00","closed_at":"2025-12-08T08:11:42.362957-08:00"}
543
+ {"id":"opencode-swarm-plugin-anlp2","title":"AI Agent Pattern Research: Plugin Improvement Analysis","description":"Research synthesis from PDF library (Patterns for Building AI Agents, Principles of Building AI Agents, Training Complex Cognitive Skills) applied to opencode-swarm-plugin improvements.\n\n## Key Patterns Identified\n\n### 1. Context Engineering (from Patterns for Building AI Agents)\n- **Current gap**: Our SUBTASK_PROMPT is verbose but lacks structured context sections\n- **Pattern**: \"Context engineering is both art and science\" - Karpathy\n- **Improvement**: Add explicit context sections: [IDENTITY] [TASK] [CONSTRAINTS] [TOOLS] [OUTPUT]\n\n### 2. Context Compression (p.37-39)\n- **Current gap**: No automatic context pruning between agent tasks\n- **Pattern**: \"Periodic context compression can prune irrelevant context\"\n- **Improvement**: Add `swarm_compress_context` tool that summarizes completed work\n\n### 3. Feed Errors Into Context (p.40)\n- **Current gap**: Errors are logged but not fed back into agent context\n- **Pattern**: \"Good agents examine and correct errors when something goes wrong\"\n- **Improvement**: Add error accumulator that feeds into retry prompts\n\n### 4. Parallelize Carefully (p.31)\n- **Current gap**: We spawn parallel agents but don't ensure context sharing\n- **Pattern**: \"Ensure subagents can share context along the way\"\n- **Improvement**: Add `swarm_broadcast` for mid-task context updates\n\n### 5. List Failure Modes (p.46)\n- **Current gap**: No classification of why agent failures occur\n- **Pattern**: \"Create classification process for agent failures\"\n- **Improvement**: Add failure taxonomy to swarm_record_outcome\n\n### 6. Tool Calling Best Practices (Principles p.36)\n- **Current gap**: Tool descriptions are functional but not semantic\n- **Pattern**: \"Use semantic naming that matches tool's purpose\"\n- **Improvement**: Audit all tool descriptions for semantic clarity\n\n### 7. Workflows as Tools (Principles p.109)\n- **Current gap**: Swarm is a command, not composable\n- **Pattern**: \"Multi-agent architecture = primitives + arrangement\"\n- **Improvement**: Make swarm_decompose callable from other workflows\n\n### 8. Implicit Feedback Scoring (already implemented)\n- **Current strength**: swarm_record_outcome tracks duration/errors/retries\n- **Enhancement**: Add strategy-specific scoring (file-based vs feature-based)\n\n## Recommended Improvements (Priority Order)\n\n1. **HIGH**: Context compression between subtasks\n2. **HIGH**: Error accumulator for retry prompts \n3. **MEDIUM**: Failure mode taxonomy\n4. **MEDIUM**: Mid-task context broadcast\n5. **LOW**: Semantic tool description audit\n6. **LOW**: Composable workflow primitives","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-10T10:02:37.4266-08:00","updated_at":"2025-12-10T10:02:37.4266-08:00"}
536
544
  {"id":"opencode-swarm-plugin-anuj","title":"New feature request","description":"","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-07T19:57:05.6861-08:00","updated_at":"2025-12-07T19:57:08.122037-08:00","closed_at":"2025-12-07T19:57:08.122037-08:00"}
537
545
  {"id":"opencode-swarm-plugin-aoed","title":"Workflow test epic","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-07T19:39:30.83873-08:00","updated_at":"2025-12-07T19:39:31.011277-08:00","closed_at":"2025-12-07T19:39:31.011277-08:00"}
538
546
  {"id":"opencode-swarm-plugin-aoed.1","title":"Step 1","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T19:39:30.870528-08:00","updated_at":"2025-12-07T19:39:30.943621-08:00","closed_at":"2025-12-07T19:39:30.943621-08:00","dependencies":[{"issue_id":"opencode-swarm-plugin-aoed.1","depends_on_id":"opencode-swarm-plugin-aoed","type":"parent-child","created_at":"2025-12-07T19:39:30.870831-08:00","created_by":"daemon"}]}
@@ -600,6 +608,7 @@
600
608
  {"id":"opencode-swarm-plugin-c3ut","title":"Single subtask epic","description":"","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-08T08:25:10.733148-08:00","updated_at":"2025-12-08T08:25:12.718944-08:00","closed_at":"2025-12-08T08:25:12.718944-08:00"}
601
609
  {"id":"opencode-swarm-plugin-c3x","title":"Limit test bead 3","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T19:37:34.169277-08:00","updated_at":"2025-12-07T19:37:36.225991-08:00","closed_at":"2025-12-07T19:37:36.225991-08:00"}
602
610
  {"id":"opencode-swarm-plugin-c40t","title":"Update test bead","description":"Blocked on dependency","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-08T11:11:23.290111-08:00","updated_at":"2025-12-08T11:11:25.615728-08:00","closed_at":"2025-12-08T11:11:25.615728-08:00"}
611
+ {"id":"opencode-swarm-plugin-c4zjn","title":"Make Agent Mail auto-restart more aggressive","description":"Agent Mail server frequently gets into bad state with \"Server encountered an unexpected error\" but auto-restart is too conservative.\n\nCurrent config:\n- failureThreshold: 2 (needs 2 failures before restart)\n- restartCooldownMs: 30000 (30 second cooldown)\n\nProblems:\n1. First failure doesn't trigger restart, just retries\n2. 30s cooldown is too long when server is truly broken\n3. After restart, availability cache isn't cleared aggressively enough\n\nProposed fix:\n1. Reduce failureThreshold to 1 (restart on first \"unexpected error\")\n2. Reduce restartCooldownMs to 10000 (10 seconds)\n3. Add proactive health check on agentmail_init that triggers restart if server is unhealthy\n4. Clear availability cache after any restart attempt\n5. Add `agentmail_restart` tool for manual restart\n\nFiles: src/agent-mail.ts","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-10T10:14:48.242736-08:00","updated_at":"2025-12-10T10:16:17.53306-08:00","closed_at":"2025-12-10T10:16:17.53306-08:00"}
603
612
  {"id":"opencode-swarm-plugin-c540","title":"Limit test bead 2","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-08T08:22:16.856145-08:00","updated_at":"2025-12-08T08:22:19.29045-08:00","closed_at":"2025-12-08T08:22:19.29045-08:00"}
604
613
  {"id":"opencode-swarm-plugin-c591c","title":"swarm.ts:1774-1777 - File reservation release without verification","description":"swarm.ts:1774-1777 - swarm_complete calls release_file_reservations but doesn't check if it succeeds. If release fails, reservations leak and block other agents. Suggested fix: Check mcpCall result and log/retry on failure.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-10T09:06:38.089086-08:00","updated_at":"2025-12-10T09:06:38.089086-08:00"}
605
614
  {"id":"opencode-swarm-plugin-c5l","title":"Bead to close","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T19:37:34.574305-08:00","updated_at":"2025-12-07T19:37:34.598352-08:00","closed_at":"2025-12-07T19:37:34.598352-08:00"}
package/dist/index.js CHANGED
@@ -22632,8 +22632,8 @@ var RETRY_CONFIG = {
22632
22632
  jitterPercent: 20
22633
22633
  };
22634
22634
  var RECOVERY_CONFIG = {
22635
- failureThreshold: 2,
22636
- restartCooldownMs: 30000,
22635
+ failureThreshold: 1,
22636
+ restartCooldownMs: 1e4,
22637
22637
  enabled: process.env.OPENCODE_AGENT_MAIL_AUTO_RESTART !== "false"
22638
22638
  };
22639
22639
  var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join2(tmpdir(), "swarm-sessions");
@@ -23007,24 +23007,57 @@ var agentmail_init = tool({
23007
23007
  fallback: "Swarm will continue without multi-agent coordination. File conflicts possible if multiple agents active."
23008
23008
  }, null, 2);
23009
23009
  }
23010
- const project = await mcpCall("ensure_project", {
23011
- human_key: args.project_path
23012
- });
23013
- const agent = await mcpCall("register_agent", {
23014
- project_key: args.project_path,
23015
- program: "opencode",
23016
- model: "claude-opus-4",
23017
- name: args.agent_name,
23018
- task_description: args.task_description || ""
23019
- });
23020
- const state = {
23021
- projectKey: args.project_path,
23022
- agentName: agent.name,
23023
- reservations: [],
23024
- startedAt: new Date().toISOString()
23025
- };
23026
- setState(ctx.sessionID, state);
23027
- return JSON.stringify({ project, agent, available: true }, null, 2);
23010
+ const MAX_INIT_RETRIES = 3;
23011
+ let lastError = null;
23012
+ for (let attempt = 1;attempt <= MAX_INIT_RETRIES; attempt++) {
23013
+ try {
23014
+ const project = await mcpCall("ensure_project", {
23015
+ human_key: args.project_path
23016
+ });
23017
+ const agent = await mcpCall("register_agent", {
23018
+ project_key: args.project_path,
23019
+ program: "opencode",
23020
+ model: "claude-opus-4",
23021
+ name: args.agent_name,
23022
+ task_description: args.task_description || ""
23023
+ });
23024
+ const state = {
23025
+ projectKey: args.project_path,
23026
+ agentName: agent.name,
23027
+ reservations: [],
23028
+ startedAt: new Date().toISOString()
23029
+ };
23030
+ setState(ctx.sessionID, state);
23031
+ if (attempt > 1) {
23032
+ console.warn(`[agent-mail] Init succeeded on attempt ${attempt} after restart`);
23033
+ }
23034
+ return JSON.stringify({ project, agent, available: true }, null, 2);
23035
+ } catch (error45) {
23036
+ lastError = error45 instanceof Error ? error45 : new Error(String(error45));
23037
+ const isUnexpectedError = lastError.message.toLowerCase().includes("unexpected error");
23038
+ console.warn(`[agent-mail] Init attempt ${attempt}/${MAX_INIT_RETRIES} failed: ${lastError.message}`);
23039
+ if (isUnexpectedError && attempt < MAX_INIT_RETRIES) {
23040
+ console.warn("[agent-mail] Detected 'unexpected error', restarting server...");
23041
+ const restarted = await restartServer();
23042
+ if (restarted) {
23043
+ agentMailAvailable = null;
23044
+ consecutiveFailures = 0;
23045
+ await new Promise((resolve) => setTimeout(resolve, 1000));
23046
+ continue;
23047
+ }
23048
+ }
23049
+ if (!isUnexpectedError) {
23050
+ break;
23051
+ }
23052
+ }
23053
+ }
23054
+ return JSON.stringify({
23055
+ error: `Agent Mail init failed after ${MAX_INIT_RETRIES} attempts`,
23056
+ available: false,
23057
+ lastError: lastError?.message,
23058
+ hint: "Manually restart Agent Mail: pkill -f agent-mail && agent-mail serve",
23059
+ fallback: "Swarm will continue without multi-agent coordination."
23060
+ }, null, 2);
23028
23061
  }
23029
23062
  });
23030
23063
  var agentmail_send = tool({
@@ -23230,7 +23263,11 @@ var agentmail_health = tool({
23230
23263
  try {
23231
23264
  const response = await fetch(`${AGENT_MAIL_URL}/health/liveness`);
23232
23265
  if (response.ok) {
23233
- return "Agent Mail is running";
23266
+ const functional = await isServerFunctional();
23267
+ if (functional) {
23268
+ return "Agent Mail is running and functional";
23269
+ }
23270
+ return "Agent Mail health OK but MCP not responding - consider restart";
23234
23271
  }
23235
23272
  return `Agent Mail returned status ${response.status}`;
23236
23273
  } catch (error45) {
@@ -23238,6 +23275,41 @@ var agentmail_health = tool({
23238
23275
  }
23239
23276
  }
23240
23277
  });
23278
+ var agentmail_restart = tool({
23279
+ description: "Manually restart Agent Mail server (use when getting 'unexpected error')",
23280
+ args: {
23281
+ force: tool.schema.boolean().optional().describe("Force restart even if server appears healthy (default: false)")
23282
+ },
23283
+ async execute(args) {
23284
+ if (!args.force) {
23285
+ const functional = await isServerFunctional();
23286
+ if (functional) {
23287
+ return JSON.stringify({
23288
+ restarted: false,
23289
+ reason: "Server is functional, no restart needed",
23290
+ hint: "Use force=true to restart anyway"
23291
+ }, null, 2);
23292
+ }
23293
+ }
23294
+ console.warn("[agent-mail] Manual restart requested...");
23295
+ const success2 = await restartServer();
23296
+ agentMailAvailable = null;
23297
+ consecutiveFailures = 0;
23298
+ if (success2) {
23299
+ return JSON.stringify({
23300
+ restarted: true,
23301
+ success: true,
23302
+ message: "Agent Mail server restarted successfully"
23303
+ }, null, 2);
23304
+ }
23305
+ return JSON.stringify({
23306
+ restarted: true,
23307
+ success: false,
23308
+ error: "Restart attempted but server did not come back up",
23309
+ hint: "Check server logs or manually start: agent-mail serve"
23310
+ }, null, 2);
23311
+ }
23312
+ });
23241
23313
  var agentMailTools = {
23242
23314
  agentmail_init,
23243
23315
  agentmail_send,
@@ -23248,7 +23320,8 @@ var agentMailTools = {
23248
23320
  agentmail_release,
23249
23321
  agentmail_ack,
23250
23322
  agentmail_search,
23251
- agentmail_health
23323
+ agentmail_health,
23324
+ agentmail_restart
23252
23325
  };
23253
23326
 
23254
23327
  // src/structured.ts
@@ -23664,6 +23737,24 @@ var CriterionWeightSchema = exports_external.object({
23664
23737
  last_validated: exports_external.string().optional(),
23665
23738
  half_life_days: exports_external.number().positive().default(90)
23666
23739
  });
23740
+ var ErrorTypeSchema = exports_external.enum([
23741
+ "validation",
23742
+ "timeout",
23743
+ "conflict",
23744
+ "tool_failure",
23745
+ "unknown"
23746
+ ]);
23747
+ var ErrorEntrySchema = exports_external.object({
23748
+ id: exports_external.string(),
23749
+ bead_id: exports_external.string(),
23750
+ error_type: ErrorTypeSchema,
23751
+ message: exports_external.string(),
23752
+ stack_trace: exports_external.string().optional(),
23753
+ tool_name: exports_external.string().optional(),
23754
+ timestamp: exports_external.string(),
23755
+ resolved: exports_external.boolean().default(false),
23756
+ context: exports_external.string().optional()
23757
+ });
23667
23758
  var DecompositionStrategySchema = exports_external.enum([
23668
23759
  "file-based",
23669
23760
  "feature-based",
@@ -23753,6 +23844,118 @@ class InMemoryFeedbackStorage {
23753
23844
  }
23754
23845
  }
23755
23846
 
23847
+ class InMemoryErrorStorage {
23848
+ errors = [];
23849
+ async store(entry) {
23850
+ this.errors.push(entry);
23851
+ }
23852
+ async getByBead(beadId) {
23853
+ return this.errors.filter((e) => e.bead_id === beadId);
23854
+ }
23855
+ async getUnresolvedByBead(beadId) {
23856
+ return this.errors.filter((e) => e.bead_id === beadId && !e.resolved);
23857
+ }
23858
+ async markResolved(id) {
23859
+ const error45 = this.errors.find((e) => e.id === id);
23860
+ if (error45) {
23861
+ error45.resolved = true;
23862
+ }
23863
+ }
23864
+ async getAll() {
23865
+ return [...this.errors];
23866
+ }
23867
+ }
23868
+
23869
+ class ErrorAccumulator {
23870
+ storage;
23871
+ constructor(storage) {
23872
+ this.storage = storage ?? new InMemoryErrorStorage;
23873
+ }
23874
+ async recordError(beadId, errorType, message, options) {
23875
+ const entry = {
23876
+ id: `${beadId}-${errorType}-${Date.now()}`,
23877
+ bead_id: beadId,
23878
+ error_type: errorType,
23879
+ message,
23880
+ stack_trace: options?.stack_trace,
23881
+ tool_name: options?.tool_name,
23882
+ timestamp: new Date().toISOString(),
23883
+ resolved: false,
23884
+ context: options?.context
23885
+ };
23886
+ const validated = ErrorEntrySchema.parse(entry);
23887
+ await this.storage.store(validated);
23888
+ return validated;
23889
+ }
23890
+ async getErrors(beadId) {
23891
+ return this.storage.getByBead(beadId);
23892
+ }
23893
+ async getUnresolvedErrors(beadId) {
23894
+ return this.storage.getUnresolvedByBead(beadId);
23895
+ }
23896
+ async resolveError(errorId) {
23897
+ await this.storage.markResolved(errorId);
23898
+ }
23899
+ async getErrorContext(beadId, includeResolved = false) {
23900
+ const errors3 = includeResolved ? await this.getErrors(beadId) : await this.getUnresolvedErrors(beadId);
23901
+ if (errors3.length === 0) {
23902
+ return "";
23903
+ }
23904
+ const byType = errors3.reduce((acc, err) => {
23905
+ const type = err.error_type;
23906
+ if (!acc[type]) {
23907
+ acc[type] = [];
23908
+ }
23909
+ acc[type].push(err);
23910
+ return acc;
23911
+ }, {});
23912
+ const lines = [
23913
+ "## Previous Errors",
23914
+ "",
23915
+ "The following errors were encountered during execution:",
23916
+ ""
23917
+ ];
23918
+ for (const [type, typeErrors] of Object.entries(byType)) {
23919
+ lines.push(`### ${type} (${typeErrors.length} error${typeErrors.length > 1 ? "s" : ""})`);
23920
+ lines.push("");
23921
+ for (const err of typeErrors) {
23922
+ lines.push(`- **${err.message}**`);
23923
+ if (err.context) {
23924
+ lines.push(` - Context: ${err.context}`);
23925
+ }
23926
+ if (err.tool_name) {
23927
+ lines.push(` - Tool: ${err.tool_name}`);
23928
+ }
23929
+ if (err.stack_trace) {
23930
+ lines.push(` - Stack: \`${err.stack_trace.slice(0, 100)}...\``);
23931
+ }
23932
+ lines.push(` - Time: ${new Date(err.timestamp).toLocaleString()}${err.resolved ? " (resolved)" : ""}`);
23933
+ lines.push("");
23934
+ }
23935
+ }
23936
+ lines.push("**Action Required**: Address these errors before proceeding. Consider:");
23937
+ lines.push("- What caused each error?");
23938
+ lines.push("- How can you prevent similar errors?");
23939
+ lines.push("- Are there patterns across error types?");
23940
+ lines.push("");
23941
+ return lines.join(`
23942
+ `);
23943
+ }
23944
+ async getErrorStats(beadId) {
23945
+ const allErrors = await this.getErrors(beadId);
23946
+ const unresolved = await this.getUnresolvedErrors(beadId);
23947
+ const byType = allErrors.reduce((acc, err) => {
23948
+ acc[err.error_type] = (acc[err.error_type] || 0) + 1;
23949
+ return acc;
23950
+ }, {});
23951
+ return {
23952
+ total: allErrors.length,
23953
+ unresolved: unresolved.length,
23954
+ by_type: byType
23955
+ };
23956
+ }
23957
+ }
23958
+
23756
23959
  // src/swarm.ts
23757
23960
  var POSITIVE_MARKERS = [
23758
23961
  "always",
@@ -24163,6 +24366,10 @@ Only modify these files. Need others? Message the coordinator.
24163
24366
  ## Context
24164
24367
  {shared_context}
24165
24368
 
24369
+ {compressed_context}
24370
+
24371
+ {error_context}
24372
+
24166
24373
  ## MANDATORY: Use These Tools
24167
24374
 
24168
24375
  ### Agent Mail - communicate with the swarm
@@ -24196,7 +24403,9 @@ Begin now.`;
24196
24403
  function formatSubtaskPromptV2(params) {
24197
24404
  const fileList = params.files.length > 0 ? params.files.map((f) => `- \`${f}\``).join(`
24198
24405
  `) : "(no specific files - use judgment)";
24199
- 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)");
24406
+ const compressedSection = params.compressed_context ? params.compressed_context : "";
24407
+ const errorSection = params.error_context ? params.error_context : "";
24408
+ 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);
24200
24409
  }
24201
24410
  var EVALUATION_PROMPT = `Evaluate the work completed for this subtask.
24202
24411
 
@@ -24902,6 +25111,7 @@ var swarm_record_outcome = tool({
24902
25111
  };
24903
25112
  const validated = OutcomeSignalsSchema.parse(signals);
24904
25113
  const scored = scoreImplicitFeedback(validated, DEFAULT_LEARNING_CONFIG);
25114
+ const errorStats = await globalErrorAccumulator.getErrorStats(args.bead_id);
24905
25115
  const criteriaToScore = args.criteria ?? [
24906
25116
  "type_safe",
24907
25117
  "no_bugs",
@@ -24913,6 +25123,10 @@ var swarm_record_outcome = tool({
24913
25123
  if (args.strategy) {
24914
25124
  event.context = `${event.context || ""} [strategy: ${args.strategy}]`.trim();
24915
25125
  }
25126
+ if (errorStats.total > 0) {
25127
+ const errorSummary = Object.entries(errorStats.by_type).map(([type, count]) => `${type}:${count}`).join(", ");
25128
+ event.context = `${event.context || ""} [errors: ${errorSummary}]`.trim();
25129
+ }
24916
25130
  return event;
24917
25131
  });
24918
25132
  return JSON.stringify({
@@ -24926,13 +25140,16 @@ var swarm_record_outcome = tool({
24926
25140
  }
24927
25141
  },
24928
25142
  feedback_events: feedbackEvents,
25143
+ error_patterns: errorStats,
24929
25144
  summary: {
24930
25145
  feedback_type: scored.type,
24931
25146
  duration_seconds: Math.round(args.duration_ms / 1000),
24932
25147
  error_count: args.error_count ?? 0,
24933
25148
  retry_count: args.retry_count ?? 0,
24934
25149
  success: args.success,
24935
- strategy: args.strategy
25150
+ strategy: args.strategy,
25151
+ accumulated_errors: errorStats.total,
25152
+ unresolved_errors: errorStats.unresolved
24936
25153
  },
24937
25154
  note: "Feedback events should be stored for criterion weight calculation. Use learning.ts functions to apply weights."
24938
25155
  }, null, 2);
@@ -25102,6 +25319,70 @@ var swarm_evaluation_prompt = tool({
25102
25319
  }, null, 2);
25103
25320
  }
25104
25321
  });
25322
+ var globalErrorAccumulator = new ErrorAccumulator;
25323
+ var swarm_accumulate_error = tool({
25324
+ description: "Record an error during subtask execution. Errors feed into retry prompts.",
25325
+ args: {
25326
+ bead_id: tool.schema.string().describe("Bead ID where error occurred"),
25327
+ error_type: tool.schema.enum(["validation", "timeout", "conflict", "tool_failure", "unknown"]).describe("Category of error"),
25328
+ message: tool.schema.string().describe("Human-readable error message"),
25329
+ stack_trace: tool.schema.string().optional().describe("Stack trace for debugging"),
25330
+ tool_name: tool.schema.string().optional().describe("Tool that failed"),
25331
+ context: tool.schema.string().optional().describe("What was happening when error occurred")
25332
+ },
25333
+ async execute(args) {
25334
+ const entry = await globalErrorAccumulator.recordError(args.bead_id, args.error_type, args.message, {
25335
+ stack_trace: args.stack_trace,
25336
+ tool_name: args.tool_name,
25337
+ context: args.context
25338
+ });
25339
+ return JSON.stringify({
25340
+ success: true,
25341
+ error_id: entry.id,
25342
+ bead_id: entry.bead_id,
25343
+ error_type: entry.error_type,
25344
+ message: entry.message,
25345
+ timestamp: entry.timestamp,
25346
+ note: "Error recorded for retry context. Use swarm_get_error_context to retrieve accumulated errors."
25347
+ }, null, 2);
25348
+ }
25349
+ });
25350
+ var swarm_get_error_context = tool({
25351
+ description: "Get accumulated errors for a bead. Returns formatted context for retry prompts.",
25352
+ args: {
25353
+ bead_id: tool.schema.string().describe("Bead ID to get errors for"),
25354
+ include_resolved: tool.schema.boolean().optional().describe("Include resolved errors (default: false)")
25355
+ },
25356
+ async execute(args) {
25357
+ const errorContext = await globalErrorAccumulator.getErrorContext(args.bead_id, args.include_resolved ?? false);
25358
+ const stats = await globalErrorAccumulator.getErrorStats(args.bead_id);
25359
+ return JSON.stringify({
25360
+ bead_id: args.bead_id,
25361
+ error_context: errorContext,
25362
+ stats: {
25363
+ total_errors: stats.total,
25364
+ unresolved: stats.unresolved,
25365
+ by_type: stats.by_type
25366
+ },
25367
+ has_errors: errorContext.length > 0,
25368
+ usage: "Inject error_context into retry prompt using {error_context} placeholder"
25369
+ }, null, 2);
25370
+ }
25371
+ });
25372
+ var swarm_resolve_error = tool({
25373
+ description: "Mark an error as resolved after fixing it. Updates error accumulator state.",
25374
+ args: {
25375
+ error_id: tool.schema.string().describe("Error ID to mark as resolved")
25376
+ },
25377
+ async execute(args) {
25378
+ await globalErrorAccumulator.resolveError(args.error_id);
25379
+ return JSON.stringify({
25380
+ success: true,
25381
+ error_id: args.error_id,
25382
+ resolved: true
25383
+ }, null, 2);
25384
+ }
25385
+ });
25105
25386
  var swarm_init = tool({
25106
25387
  description: "Initialize swarm session and check tool availability. Call at swarm start to see what features are available.",
25107
25388
  args: {
@@ -25163,7 +25444,10 @@ var swarmTools = {
25163
25444
  swarm_subtask_prompt,
25164
25445
  swarm_spawn_subtask,
25165
25446
  swarm_complete_subtask,
25166
- swarm_evaluation_prompt
25447
+ swarm_evaluation_prompt,
25448
+ swarm_accumulate_error,
25449
+ swarm_get_error_context,
25450
+ swarm_resolve_error
25167
25451
  };
25168
25452
  // src/anti-patterns.ts
25169
25453
  var PatternKindSchema = exports_external.enum(["pattern", "anti_pattern"]);