musubi-sdd 5.0.0 → 5.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.
Files changed (232) hide show
  1. package/README.ja.md +106 -48
  2. package/README.md +110 -32
  3. package/bin/musubi-analyze.js +74 -67
  4. package/bin/musubi-browser.js +27 -26
  5. package/bin/musubi-change.js +48 -47
  6. package/bin/musubi-checkpoint.js +10 -7
  7. package/bin/musubi-convert.js +25 -25
  8. package/bin/musubi-costs.js +27 -10
  9. package/bin/musubi-gui.js +52 -46
  10. package/bin/musubi-init.js +1952 -10
  11. package/bin/musubi-orchestrate.js +327 -239
  12. package/bin/musubi-remember.js +69 -56
  13. package/bin/musubi-resolve.js +53 -45
  14. package/bin/musubi-trace.js +51 -22
  15. package/bin/musubi-validate.js +39 -30
  16. package/bin/musubi-workflow.js +33 -34
  17. package/bin/musubi.js +39 -2
  18. package/package.json +1 -1
  19. package/src/agents/agent-loop.js +94 -95
  20. package/src/agents/agentic/code-generator.js +119 -109
  21. package/src/agents/agentic/code-reviewer.js +105 -108
  22. package/src/agents/agentic/index.js +4 -4
  23. package/src/agents/browser/action-executor.js +13 -13
  24. package/src/agents/browser/ai-comparator.js +11 -10
  25. package/src/agents/browser/context-manager.js +6 -6
  26. package/src/agents/browser/index.js +5 -5
  27. package/src/agents/browser/nl-parser.js +31 -46
  28. package/src/agents/browser/screenshot.js +2 -2
  29. package/src/agents/browser/test-generator.js +6 -4
  30. package/src/agents/function-tool.js +71 -65
  31. package/src/agents/index.js +7 -7
  32. package/src/agents/schema-generator.js +98 -94
  33. package/src/analyzers/ast-extractor.js +164 -145
  34. package/src/analyzers/codegraph-auto-update.js +858 -0
  35. package/src/analyzers/complexity-analyzer.js +536 -0
  36. package/src/analyzers/context-optimizer.js +247 -125
  37. package/src/analyzers/impact-analyzer.js +1 -1
  38. package/src/analyzers/large-project-analyzer.js +766 -0
  39. package/src/analyzers/repository-map.js +83 -80
  40. package/src/analyzers/security-analyzer.js +19 -11
  41. package/src/analyzers/stuck-detector.js +19 -17
  42. package/src/converters/index.js +78 -57
  43. package/src/converters/ir/types.js +12 -12
  44. package/src/converters/parsers/musubi-parser.js +134 -126
  45. package/src/converters/parsers/openapi-parser.js +70 -53
  46. package/src/converters/parsers/speckit-parser.js +239 -175
  47. package/src/converters/writers/musubi-writer.js +123 -118
  48. package/src/converters/writers/speckit-writer.js +124 -113
  49. package/src/generators/rust-migration-generator.js +512 -0
  50. package/src/gui/public/index.html +1365 -1211
  51. package/src/gui/server.js +41 -40
  52. package/src/gui/services/file-watcher.js +23 -8
  53. package/src/gui/services/project-scanner.js +26 -20
  54. package/src/gui/services/replanning-service.js +27 -23
  55. package/src/gui/services/traceability-service.js +8 -8
  56. package/src/gui/services/workflow-service.js +14 -7
  57. package/src/index.js +151 -0
  58. package/src/integrations/cicd.js +90 -104
  59. package/src/integrations/codegraph-mcp.js +643 -0
  60. package/src/integrations/documentation.js +142 -103
  61. package/src/integrations/examples.js +95 -80
  62. package/src/integrations/github-client.js +17 -17
  63. package/src/integrations/index.js +5 -5
  64. package/src/integrations/mcp/index.js +21 -21
  65. package/src/integrations/mcp/mcp-context-provider.js +76 -78
  66. package/src/integrations/mcp/mcp-discovery.js +74 -72
  67. package/src/integrations/mcp/mcp-tool-registry.js +99 -94
  68. package/src/integrations/mcp-connector.js +70 -66
  69. package/src/integrations/platforms.js +50 -49
  70. package/src/integrations/tool-discovery.js +37 -31
  71. package/src/llm-providers/anthropic-provider.js +11 -11
  72. package/src/llm-providers/base-provider.js +16 -18
  73. package/src/llm-providers/copilot-provider.js +22 -19
  74. package/src/llm-providers/index.js +26 -25
  75. package/src/llm-providers/ollama-provider.js +11 -11
  76. package/src/llm-providers/openai-provider.js +12 -12
  77. package/src/managers/agent-memory.js +36 -24
  78. package/src/managers/checkpoint-manager.js +4 -8
  79. package/src/managers/delta-spec.js +19 -19
  80. package/src/managers/index.js +13 -4
  81. package/src/managers/memory-condenser.js +35 -45
  82. package/src/managers/repo-skill-manager.js +57 -31
  83. package/src/managers/skill-loader.js +25 -22
  84. package/src/managers/skill-tools.js +36 -72
  85. package/src/managers/workflow.js +30 -22
  86. package/src/monitoring/cost-tracker.js +53 -44
  87. package/src/monitoring/incident-manager.js +123 -103
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +82 -59
  90. package/src/monitoring/quality-dashboard.js +51 -39
  91. package/src/monitoring/release-manager.js +70 -50
  92. package/src/orchestration/agent-skill-binding.js +39 -47
  93. package/src/orchestration/error-handler.js +65 -107
  94. package/src/orchestration/guardrails/base-guardrail.js +26 -24
  95. package/src/orchestration/guardrails/guardrail-rules.js +50 -64
  96. package/src/orchestration/guardrails/index.js +5 -5
  97. package/src/orchestration/guardrails/input-guardrail.js +58 -45
  98. package/src/orchestration/guardrails/output-guardrail.js +104 -81
  99. package/src/orchestration/guardrails/safety-check.js +79 -79
  100. package/src/orchestration/index.js +38 -55
  101. package/src/orchestration/mcp-tool-adapters.js +96 -99
  102. package/src/orchestration/orchestration-engine.js +21 -21
  103. package/src/orchestration/pattern-registry.js +60 -45
  104. package/src/orchestration/patterns/auto.js +34 -47
  105. package/src/orchestration/patterns/group-chat.js +59 -65
  106. package/src/orchestration/patterns/handoff.js +67 -65
  107. package/src/orchestration/patterns/human-in-loop.js +51 -72
  108. package/src/orchestration/patterns/nested.js +25 -40
  109. package/src/orchestration/patterns/sequential.js +35 -34
  110. package/src/orchestration/patterns/swarm.js +63 -56
  111. package/src/orchestration/patterns/triage.js +150 -109
  112. package/src/orchestration/reasoning/index.js +9 -9
  113. package/src/orchestration/reasoning/planning-engine.js +143 -140
  114. package/src/orchestration/reasoning/reasoning-engine.js +206 -144
  115. package/src/orchestration/reasoning/self-correction.js +121 -128
  116. package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
  117. package/src/orchestration/replanning/alternative-generator.js +37 -42
  118. package/src/orchestration/replanning/config.js +63 -59
  119. package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
  120. package/src/orchestration/replanning/index.js +24 -20
  121. package/src/orchestration/replanning/plan-evaluator.js +49 -50
  122. package/src/orchestration/replanning/plan-monitor.js +32 -28
  123. package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
  124. package/src/orchestration/replanning/replan-history.js +33 -26
  125. package/src/orchestration/replanning/replanning-engine.js +106 -108
  126. package/src/orchestration/skill-executor.js +107 -109
  127. package/src/orchestration/skill-registry.js +85 -89
  128. package/src/orchestration/workflow-examples.js +228 -231
  129. package/src/orchestration/workflow-executor.js +65 -68
  130. package/src/orchestration/workflow-orchestrator.js +72 -73
  131. package/src/phase4-integration.js +47 -40
  132. package/src/phase5-integration.js +89 -30
  133. package/src/reporters/coverage-report.js +82 -30
  134. package/src/reporters/hierarchical-reporter.js +498 -0
  135. package/src/reporters/traceability-matrix-report.js +29 -20
  136. package/src/resolvers/issue-resolver.js +43 -31
  137. package/src/steering/advanced-validation.js +133 -124
  138. package/src/steering/auto-updater.js +60 -73
  139. package/src/steering/index.js +6 -6
  140. package/src/steering/quality-metrics.js +41 -35
  141. package/src/steering/steering-auto-update.js +83 -86
  142. package/src/steering/steering-validator.js +98 -106
  143. package/src/steering/template-constraints.js +53 -54
  144. package/src/templates/agents/claude-code/CLAUDE.md +32 -32
  145. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
  146. package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
  147. package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
  148. package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
  149. package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
  150. package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
  151. package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
  152. package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
  153. package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
  154. package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
  155. package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
  156. package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
  157. package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
  158. package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
  159. package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
  160. package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
  161. package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
  162. package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
  163. package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
  164. package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
  165. package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
  166. package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
  167. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
  168. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
  169. package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
  170. package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
  171. package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
  172. package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
  173. package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
  174. package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
  175. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
  176. package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
  177. package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
  178. package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
  179. package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
  180. package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
  181. package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
  182. package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
  183. package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
  184. package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
  185. package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
  186. package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
  187. package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
  188. package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
  189. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
  190. package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
  191. package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
  192. package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
  193. package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
  194. package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
  195. package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
  196. package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
  197. package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
  198. package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
  199. package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
  200. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
  201. package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
  202. package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
  203. package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
  204. package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
  205. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
  206. package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
  207. package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
  208. package/src/templates/agents/codex/AGENTS.md +74 -42
  209. package/src/templates/agents/cursor/AGENTS.md +74 -42
  210. package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
  211. package/src/templates/agents/github-copilot/AGENTS.md +83 -51
  212. package/src/templates/agents/qwen-code/QWEN.md +74 -42
  213. package/src/templates/agents/windsurf/AGENTS.md +74 -42
  214. package/src/templates/architectures/README.md +41 -0
  215. package/src/templates/architectures/clean-architecture/README.md +113 -0
  216. package/src/templates/architectures/event-driven/README.md +162 -0
  217. package/src/templates/architectures/hexagonal/README.md +130 -0
  218. package/src/templates/index.js +6 -1
  219. package/src/templates/locale-manager.js +16 -16
  220. package/src/templates/shared/delta-spec-template.md +20 -13
  221. package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
  222. package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
  223. package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
  224. package/src/templates/shared/steering/structure.md +95 -0
  225. package/src/templates/skills/browser-agent.md +21 -16
  226. package/src/templates/skills/web-gui.md +8 -0
  227. package/src/templates/template-constraints.js +50 -53
  228. package/src/validators/advanced-validation.js +30 -36
  229. package/src/validators/constitutional-validator.js +77 -73
  230. package/src/validators/critic-system.js +49 -59
  231. package/src/validators/delta-format.js +59 -55
  232. package/src/validators/traceability-validator.js +7 -11
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * MUSUBI Agent Loop
3
- *
3
+ *
4
4
  * Implements agentic tool-calling loop inspired by OpenAI Agents SDK
5
5
  * and AutoGen patterns. Executes tool calls, processes results, and
6
6
  * continues until completion or limit is reached.
7
- *
7
+ *
8
8
  * @module agents/agent-loop
9
9
  */
10
10
 
@@ -53,30 +53,30 @@ class AgentLoop extends EventEmitter {
53
53
  */
54
54
  constructor(config = {}) {
55
55
  super();
56
-
56
+
57
57
  this.maxIterations = config.maxIterations ?? 10;
58
58
  this.timeout = config.timeout ?? 60000;
59
59
  this.iterationTimeout = config.iterationTimeout ?? 30000;
60
60
  this.continueOnError = config.continueOnError ?? false;
61
61
  this.completionCheck = config.completionCheck ?? this.defaultCompletionCheck.bind(this);
62
62
  this.guardrails = config.guardrails ?? null;
63
-
63
+
64
64
  /** @type {Map<string, ToolDefinition>} */
65
65
  this.tools = new Map();
66
-
66
+
67
67
  /** @type {Array} */
68
68
  this.messages = [];
69
-
69
+
70
70
  /** @type {Array<ToolCall>} */
71
71
  this.toolCallHistory = [];
72
-
72
+
73
73
  /** @type {boolean} */
74
74
  this.isRunning = false;
75
-
75
+
76
76
  /** @type {AbortController|null} */
77
77
  this.abortController = null;
78
78
  }
79
-
79
+
80
80
  /**
81
81
  * Register a tool for the agent to use
82
82
  * @param {ToolDefinition} tool
@@ -85,18 +85,18 @@ class AgentLoop extends EventEmitter {
85
85
  if (!tool.name || typeof tool.handler !== 'function') {
86
86
  throw new Error('Tool must have name and handler function');
87
87
  }
88
-
88
+
89
89
  this.tools.set(tool.name, {
90
90
  name: tool.name,
91
91
  description: tool.description || '',
92
92
  parameters: tool.parameters || { type: 'object', properties: {} },
93
- handler: tool.handler
93
+ handler: tool.handler,
94
94
  });
95
-
95
+
96
96
  this.emit('tool:registered', { name: tool.name });
97
97
  return this;
98
98
  }
99
-
99
+
100
100
  /**
101
101
  * Register multiple tools at once
102
102
  * @param {ToolDefinition[]} tools
@@ -107,7 +107,7 @@ class AgentLoop extends EventEmitter {
107
107
  }
108
108
  return this;
109
109
  }
110
-
110
+
111
111
  /**
112
112
  * Unregister a tool
113
113
  * @param {string} name
@@ -119,7 +119,7 @@ class AgentLoop extends EventEmitter {
119
119
  }
120
120
  return deleted;
121
121
  }
122
-
122
+
123
123
  /**
124
124
  * Get all registered tools in OpenAI function format
125
125
  * @returns {Array}
@@ -130,11 +130,11 @@ class AgentLoop extends EventEmitter {
130
130
  function: {
131
131
  name: tool.name,
132
132
  description: tool.description,
133
- parameters: tool.parameters
134
- }
133
+ parameters: tool.parameters,
134
+ },
135
135
  }));
136
136
  }
137
-
137
+
138
138
  /**
139
139
  * Run the agent loop with an LLM provider
140
140
  * @param {Object} options
@@ -148,62 +148,62 @@ class AgentLoop extends EventEmitter {
148
148
  if (this.isRunning) {
149
149
  throw new Error('Agent loop is already running');
150
150
  }
151
-
151
+
152
152
  this.isRunning = true;
153
153
  this.abortController = new AbortController();
154
154
  this.messages = [];
155
155
  this.toolCallHistory = [];
156
-
156
+
157
157
  const startTime = Date.now();
158
158
  const timeoutId = setTimeout(() => this.abort('timeout'), this.timeout);
159
-
159
+
160
160
  const metrics = {
161
161
  iterations: 0,
162
162
  toolCalls: 0,
163
163
  startTime,
164
164
  endTime: null,
165
165
  duration: null,
166
- tokensUsed: 0
166
+ tokensUsed: 0,
167
167
  };
168
-
168
+
169
169
  try {
170
170
  // Initialize messages
171
171
  this.messages.push({ role: 'system', content: systemPrompt });
172
-
172
+
173
173
  // Apply input guardrails if configured
174
174
  const processedInput = await this.applyInputGuardrails(userMessage, context);
175
175
  this.messages.push({ role: 'user', content: processedInput });
176
-
176
+
177
177
  let iteration = 0;
178
178
  let completed = false;
179
179
  let finalOutput = null;
180
-
180
+
181
181
  while (iteration < this.maxIterations && !completed) {
182
182
  if (this.abortController.signal.aborted) {
183
183
  return this.createResult('aborted', finalOutput, metrics);
184
184
  }
185
-
185
+
186
186
  iteration++;
187
187
  metrics.iterations = iteration;
188
188
  this.emit('iteration:start', { iteration, maxIterations: this.maxIterations });
189
-
189
+
190
190
  // Call LLM
191
191
  const response = await this.callLLMWithTimeout(llmProvider, {
192
192
  messages: this.messages,
193
193
  tools: this.getToolSchemas(),
194
- context
194
+ context,
195
195
  });
196
-
196
+
197
197
  if (response.usage) {
198
198
  metrics.tokensUsed += response.usage.total_tokens || 0;
199
199
  }
200
-
200
+
201
201
  // Check for tool calls
202
202
  if (response.toolCalls && response.toolCalls.length > 0) {
203
203
  // Execute tool calls
204
204
  const toolResults = await this.executeToolCalls(response.toolCalls);
205
205
  metrics.toolCalls += response.toolCalls.length;
206
-
206
+
207
207
  // Add assistant message with tool calls
208
208
  this.messages.push({
209
209
  role: 'assistant',
@@ -213,68 +213,67 @@ class AgentLoop extends EventEmitter {
213
213
  type: 'function',
214
214
  function: {
215
215
  name: tc.tool || tc.name,
216
- arguments: JSON.stringify(tc.arguments)
217
- }
218
- }))
216
+ arguments: JSON.stringify(tc.arguments),
217
+ },
218
+ })),
219
219
  });
220
-
220
+
221
221
  // Add tool results
222
222
  for (const result of toolResults) {
223
223
  this.messages.push({
224
224
  role: 'tool',
225
225
  tool_call_id: result.callId,
226
- content: JSON.stringify(result.output)
226
+ content: JSON.stringify(result.output),
227
227
  });
228
228
  }
229
-
229
+
230
230
  this.emit('iteration:complete', {
231
231
  iteration,
232
232
  toolCalls: response.toolCalls.length,
233
- hasMore: true
233
+ hasMore: true,
234
234
  });
235
235
  } else {
236
236
  // No tool calls - LLM response is final
237
237
  finalOutput = response.content;
238
-
238
+
239
239
  // Apply output guardrails
240
240
  finalOutput = await this.applyOutputGuardrails(finalOutput, context);
241
-
241
+
242
242
  // Add final assistant message
243
243
  this.messages.push({
244
244
  role: 'assistant',
245
- content: finalOutput
245
+ content: finalOutput,
246
246
  });
247
-
247
+
248
248
  // Check completion
249
249
  completed = await this.completionCheck(finalOutput, this.messages, context);
250
-
250
+
251
251
  this.emit('iteration:complete', {
252
252
  iteration,
253
253
  toolCalls: 0,
254
- hasMore: !completed
254
+ hasMore: !completed,
255
255
  });
256
256
  }
257
257
  }
258
-
258
+
259
259
  metrics.endTime = Date.now();
260
260
  metrics.duration = metrics.endTime - startTime;
261
-
261
+
262
262
  if (iteration >= this.maxIterations && !completed) {
263
263
  return this.createResult('max_iterations', finalOutput, metrics);
264
264
  }
265
-
265
+
266
266
  return this.createResult('completed', finalOutput, metrics);
267
-
268
267
  } catch (error) {
269
268
  metrics.endTime = Date.now();
270
269
  metrics.duration = metrics.endTime - startTime;
271
-
270
+
272
271
  this.emit('error', error);
273
-
272
+
274
273
  if (error.message === 'timeout') {
275
274
  return this.createResult('timeout', null, metrics);
276
275
  }
277
-
276
+
278
277
  return this.createResult('error', null, metrics, error);
279
278
  } finally {
280
279
  clearTimeout(timeoutId);
@@ -282,7 +281,7 @@ class AgentLoop extends EventEmitter {
282
281
  this.abortController = null;
283
282
  }
284
283
  }
285
-
284
+
286
285
  /**
287
286
  * Call LLM with per-iteration timeout
288
287
  * @param {Object} llmProvider
@@ -294,8 +293,9 @@ class AgentLoop extends EventEmitter {
294
293
  const timeoutId = setTimeout(() => {
295
294
  reject(new Error('Iteration timeout'));
296
295
  }, this.iterationTimeout);
297
-
298
- llmProvider.chat(options)
296
+
297
+ llmProvider
298
+ .chat(options)
299
299
  .then(response => {
300
300
  clearTimeout(timeoutId);
301
301
  resolve(response);
@@ -306,7 +306,7 @@ class AgentLoop extends EventEmitter {
306
306
  });
307
307
  });
308
308
  }
309
-
309
+
310
310
  /**
311
311
  * Execute tool calls and collect results
312
312
  * @param {ToolCall[]} toolCalls
@@ -314,73 +314,72 @@ class AgentLoop extends EventEmitter {
314
314
  */
315
315
  async executeToolCalls(toolCalls) {
316
316
  const results = [];
317
-
317
+
318
318
  for (const call of toolCalls) {
319
319
  const toolName = call.tool || call.name;
320
320
  const callId = call.id || `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
321
-
321
+
322
322
  this.emit('tool:call', { name: toolName, arguments: call.arguments, id: callId });
323
-
323
+
324
324
  try {
325
325
  const tool = this.tools.get(toolName);
326
-
326
+
327
327
  if (!tool) {
328
328
  throw new Error(`Unknown tool: ${toolName}`);
329
329
  }
330
-
330
+
331
331
  const output = await tool.handler(call.arguments);
332
-
332
+
333
333
  this.toolCallHistory.push({
334
334
  id: callId,
335
335
  tool: toolName,
336
336
  arguments: call.arguments,
337
337
  output,
338
- status: 'success'
338
+ status: 'success',
339
339
  });
340
-
340
+
341
341
  results.push({
342
342
  callId,
343
343
  tool: toolName,
344
344
  output,
345
- status: 'success'
345
+ status: 'success',
346
346
  });
347
-
347
+
348
348
  this.emit('tool:result', { name: toolName, output, id: callId, status: 'success' });
349
-
350
349
  } catch (error) {
351
- const errorResult = {
350
+ const _errorResult = {
352
351
  callId,
353
352
  tool: toolName,
354
353
  error: error.message,
355
- status: 'error'
354
+ status: 'error',
356
355
  };
357
-
356
+
358
357
  this.toolCallHistory.push({
359
358
  id: callId,
360
359
  tool: toolName,
361
360
  arguments: call.arguments,
362
361
  error: error.message,
363
- status: 'error'
362
+ status: 'error',
364
363
  });
365
-
364
+
366
365
  this.emit('tool:error', { name: toolName, error: error.message, id: callId });
367
-
366
+
368
367
  if (this.continueOnError) {
369
368
  results.push({
370
369
  callId,
371
370
  tool: toolName,
372
371
  output: { error: error.message },
373
- status: 'error'
372
+ status: 'error',
374
373
  });
375
374
  } else {
376
375
  throw error;
377
376
  }
378
377
  }
379
378
  }
380
-
379
+
381
380
  return results;
382
381
  }
383
-
382
+
384
383
  /**
385
384
  * Default completion check - returns true when LLM provides final response
386
385
  * @param {*} output
@@ -388,11 +387,11 @@ class AgentLoop extends EventEmitter {
388
387
  * @param {Object} context
389
388
  * @returns {Promise<boolean>}
390
389
  */
391
- async defaultCompletionCheck(output, messages, context) {
390
+ async defaultCompletionCheck(_output, _messages, _context) {
392
391
  // By default, if we reach here (no tool calls), we're done
393
392
  return true;
394
393
  }
395
-
394
+
396
395
  /**
397
396
  * Apply input guardrails if configured
398
397
  * @param {string} input
@@ -403,7 +402,7 @@ class AgentLoop extends EventEmitter {
403
402
  if (!this.guardrails?.input) {
404
403
  return input;
405
404
  }
406
-
405
+
407
406
  try {
408
407
  const result = await this.guardrails.input.validate(input, context);
409
408
  if (!result.valid) {
@@ -415,7 +414,7 @@ class AgentLoop extends EventEmitter {
415
414
  throw error;
416
415
  }
417
416
  }
418
-
417
+
419
418
  /**
420
419
  * Apply output guardrails if configured
421
420
  * @param {string} output
@@ -426,7 +425,7 @@ class AgentLoop extends EventEmitter {
426
425
  if (!this.guardrails?.output) {
427
426
  return output;
428
427
  }
429
-
428
+
430
429
  try {
431
430
  const result = await this.guardrails.output.validate(output, context);
432
431
  if (!result.valid) {
@@ -439,7 +438,7 @@ class AgentLoop extends EventEmitter {
439
438
  return output;
440
439
  }
441
440
  }
442
-
441
+
443
442
  /**
444
443
  * Create standardized result object
445
444
  * @param {string} status
@@ -458,12 +457,12 @@ class AgentLoop extends EventEmitter {
458
457
  ...metrics,
459
458
  toolCallCount: this.toolCallHistory.length,
460
459
  successfulCalls: this.toolCallHistory.filter(tc => tc.status === 'success').length,
461
- failedCalls: this.toolCallHistory.filter(tc => tc.status === 'error').length
460
+ failedCalls: this.toolCallHistory.filter(tc => tc.status === 'error').length,
462
461
  },
463
- ...(error && { error: error.message })
462
+ ...(error && { error: error.message }),
464
463
  };
465
464
  }
466
-
465
+
467
466
  /**
468
467
  * Abort the running loop
469
468
  * @param {string} [reason='aborted']
@@ -474,7 +473,7 @@ class AgentLoop extends EventEmitter {
474
473
  this.emit('abort', { reason });
475
474
  }
476
475
  }
477
-
476
+
478
477
  /**
479
478
  * Get current loop state
480
479
  * @returns {Object}
@@ -484,10 +483,10 @@ class AgentLoop extends EventEmitter {
484
483
  isRunning: this.isRunning,
485
484
  messageCount: this.messages.length,
486
485
  toolCallCount: this.toolCallHistory.length,
487
- registeredTools: Array.from(this.tools.keys())
486
+ registeredTools: Array.from(this.tools.keys()),
488
487
  };
489
488
  }
490
-
489
+
491
490
  /**
492
491
  * Reset the loop state
493
492
  */
@@ -495,7 +494,7 @@ class AgentLoop extends EventEmitter {
495
494
  if (this.isRunning) {
496
495
  throw new Error('Cannot reset while loop is running');
497
496
  }
498
-
497
+
499
498
  this.messages = [];
500
499
  this.toolCallHistory = [];
501
500
  this.emit('reset');
@@ -509,24 +508,24 @@ class AgentLoop extends EventEmitter {
509
508
  */
510
509
  function createMockLLMProvider(responses) {
511
510
  let callIndex = 0;
512
-
511
+
513
512
  return {
514
- async chat(options) {
513
+ async chat(_options) {
515
514
  if (callIndex >= responses.length) {
516
515
  return { content: 'Done', toolCalls: [] };
517
516
  }
518
-
517
+
519
518
  const response = responses[callIndex++];
520
519
  return {
521
520
  content: response.content || null,
522
521
  toolCalls: response.toolCalls || [],
523
- usage: response.usage || { total_tokens: 100 }
522
+ usage: response.usage || { total_tokens: 100 },
524
523
  };
525
- }
524
+ },
526
525
  };
527
526
  }
528
527
 
529
528
  module.exports = {
530
529
  AgentLoop,
531
- createMockLLMProvider
530
+ createMockLLMProvider,
532
531
  };