@backendkit-labs/agent-core 0.14.0

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 (533) hide show
  1. package/dist/agent-discovery/AgentPackageLoader.d.ts +14 -0
  2. package/dist/agent-discovery/AgentPackageLoader.d.ts.map +1 -0
  3. package/dist/agent-discovery/AgentPackageLoader.js +78 -0
  4. package/dist/agent-discovery/AgentPackageLoader.js.map +1 -0
  5. package/dist/agent-discovery/RemoteAgentRegistry.d.ts +31 -0
  6. package/dist/agent-discovery/RemoteAgentRegistry.d.ts.map +1 -0
  7. package/dist/agent-discovery/RemoteAgentRegistry.js +103 -0
  8. package/dist/agent-discovery/RemoteAgentRegistry.js.map +1 -0
  9. package/dist/agent-discovery/discoverAgents.d.ts +18 -0
  10. package/dist/agent-discovery/discoverAgents.d.ts.map +1 -0
  11. package/dist/agent-discovery/discoverAgents.js +59 -0
  12. package/dist/agent-discovery/discoverAgents.js.map +1 -0
  13. package/dist/agent-discovery/index.d.ts +5 -0
  14. package/dist/agent-discovery/index.d.ts.map +1 -0
  15. package/dist/agent-discovery/index.js +12 -0
  16. package/dist/agent-discovery/index.js.map +1 -0
  17. package/dist/agent-discovery/types.d.ts +42 -0
  18. package/dist/agent-discovery/types.d.ts.map +1 -0
  19. package/dist/agent-discovery/types.js +3 -0
  20. package/dist/agent-discovery/types.js.map +1 -0
  21. package/dist/agent-memory/EpisodicMemory.d.ts +26 -0
  22. package/dist/agent-memory/EpisodicMemory.d.ts.map +1 -0
  23. package/dist/agent-memory/EpisodicMemory.js +83 -0
  24. package/dist/agent-memory/EpisodicMemory.js.map +1 -0
  25. package/dist/agent-memory/MemorySystem.d.ts +40 -0
  26. package/dist/agent-memory/MemorySystem.d.ts.map +1 -0
  27. package/dist/agent-memory/MemorySystem.js +75 -0
  28. package/dist/agent-memory/MemorySystem.js.map +1 -0
  29. package/dist/agent-memory/ProceduralMemory.d.ts +26 -0
  30. package/dist/agent-memory/ProceduralMemory.d.ts.map +1 -0
  31. package/dist/agent-memory/ProceduralMemory.js +104 -0
  32. package/dist/agent-memory/ProceduralMemory.js.map +1 -0
  33. package/dist/agent-memory/SemanticMemory.d.ts +21 -0
  34. package/dist/agent-memory/SemanticMemory.d.ts.map +1 -0
  35. package/dist/agent-memory/SemanticMemory.js +68 -0
  36. package/dist/agent-memory/SemanticMemory.js.map +1 -0
  37. package/dist/agent-memory/index.d.ts +9 -0
  38. package/dist/agent-memory/index.d.ts.map +1 -0
  39. package/dist/agent-memory/index.js +19 -0
  40. package/dist/agent-memory/index.js.map +1 -0
  41. package/dist/agent-memory/scoring.d.ts +10 -0
  42. package/dist/agent-memory/scoring.d.ts.map +1 -0
  43. package/dist/agent-memory/scoring.js +32 -0
  44. package/dist/agent-memory/scoring.js.map +1 -0
  45. package/dist/agent-memory/stores/InMemoryStore.d.ts +10 -0
  46. package/dist/agent-memory/stores/InMemoryStore.d.ts.map +1 -0
  47. package/dist/agent-memory/stores/InMemoryStore.js +25 -0
  48. package/dist/agent-memory/stores/InMemoryStore.js.map +1 -0
  49. package/dist/agent-memory/stores/JsonFileStore.d.ts +18 -0
  50. package/dist/agent-memory/stores/JsonFileStore.d.ts.map +1 -0
  51. package/dist/agent-memory/stores/JsonFileStore.js +61 -0
  52. package/dist/agent-memory/stores/JsonFileStore.js.map +1 -0
  53. package/dist/agent-memory/tools.d.ts +6 -0
  54. package/dist/agent-memory/tools.d.ts.map +1 -0
  55. package/dist/agent-memory/tools.js +74 -0
  56. package/dist/agent-memory/tools.js.map +1 -0
  57. package/dist/agent-memory/types.d.ts +75 -0
  58. package/dist/agent-memory/types.d.ts.map +1 -0
  59. package/dist/agent-memory/types.js +4 -0
  60. package/dist/agent-memory/types.js.map +1 -0
  61. package/dist/bootstrap/GlobalSeed.d.ts +46 -0
  62. package/dist/bootstrap/GlobalSeed.d.ts.map +1 -0
  63. package/dist/bootstrap/GlobalSeed.js +285 -0
  64. package/dist/bootstrap/GlobalSeed.js.map +1 -0
  65. package/dist/bootstrap/config.d.ts +24 -0
  66. package/dist/bootstrap/config.d.ts.map +1 -0
  67. package/dist/bootstrap/config.js +71 -0
  68. package/dist/bootstrap/config.js.map +1 -0
  69. package/dist/checkpoint/index.d.ts +17 -0
  70. package/dist/checkpoint/index.d.ts.map +1 -0
  71. package/dist/checkpoint/index.js +207 -0
  72. package/dist/checkpoint/index.js.map +1 -0
  73. package/dist/commands/SlashCommandRegistry.d.ts +98 -0
  74. package/dist/commands/SlashCommandRegistry.d.ts.map +1 -0
  75. package/dist/commands/SlashCommandRegistry.js +41 -0
  76. package/dist/commands/SlashCommandRegistry.js.map +1 -0
  77. package/dist/commands/builtin.d.ts +7 -0
  78. package/dist/commands/builtin.d.ts.map +1 -0
  79. package/dist/commands/builtin.js +694 -0
  80. package/dist/commands/builtin.js.map +1 -0
  81. package/dist/commands/index.d.ts +4 -0
  82. package/dist/commands/index.d.ts.map +1 -0
  83. package/dist/commands/index.js +8 -0
  84. package/dist/commands/index.js.map +1 -0
  85. package/dist/context/index.d.ts +8 -0
  86. package/dist/context/index.d.ts.map +1 -0
  87. package/dist/context/index.js +8 -0
  88. package/dist/context/index.js.map +1 -0
  89. package/dist/context/pipeline.d.ts +46 -0
  90. package/dist/context/pipeline.d.ts.map +1 -0
  91. package/dist/context/pipeline.js +111 -0
  92. package/dist/context/pipeline.js.map +1 -0
  93. package/dist/context/stages/stage-instructions.d.ts +12 -0
  94. package/dist/context/stages/stage-instructions.d.ts.map +1 -0
  95. package/dist/context/stages/stage-instructions.js +76 -0
  96. package/dist/context/stages/stage-instructions.js.map +1 -0
  97. package/dist/context/stages/stage-lessons.d.ts +13 -0
  98. package/dist/context/stages/stage-lessons.d.ts.map +1 -0
  99. package/dist/context/stages/stage-lessons.js +83 -0
  100. package/dist/context/stages/stage-lessons.js.map +1 -0
  101. package/dist/context/stages/stage-manifest.d.ts +11 -0
  102. package/dist/context/stages/stage-manifest.d.ts.map +1 -0
  103. package/dist/context/stages/stage-manifest.js +62 -0
  104. package/dist/context/stages/stage-manifest.js.map +1 -0
  105. package/dist/context/stages/stage-project.d.ts +10 -0
  106. package/dist/context/stages/stage-project.d.ts.map +1 -0
  107. package/dist/context/stages/stage-project.js +55 -0
  108. package/dist/context/stages/stage-project.js.map +1 -0
  109. package/dist/context/stages/stage-session.d.ts +12 -0
  110. package/dist/context/stages/stage-session.d.ts.map +1 -0
  111. package/dist/context/stages/stage-session.js +69 -0
  112. package/dist/context/stages/stage-session.js.map +1 -0
  113. package/dist/delegation/DelegationBus.d.ts +40 -0
  114. package/dist/delegation/DelegationBus.d.ts.map +1 -0
  115. package/dist/delegation/DelegationBus.js +68 -0
  116. package/dist/delegation/DelegationBus.js.map +1 -0
  117. package/dist/engine/AgentEngine.d.ts +212 -0
  118. package/dist/engine/AgentEngine.d.ts.map +1 -0
  119. package/dist/engine/AgentEngine.js +1037 -0
  120. package/dist/engine/AgentEngine.js.map +1 -0
  121. package/dist/engine/AgentRegistry.d.ts +13 -0
  122. package/dist/engine/AgentRegistry.d.ts.map +1 -0
  123. package/dist/engine/AgentRegistry.js +37 -0
  124. package/dist/engine/AgentRegistry.js.map +1 -0
  125. package/dist/engine/IterationManager.d.ts +79 -0
  126. package/dist/engine/IterationManager.d.ts.map +1 -0
  127. package/dist/engine/IterationManager.js +103 -0
  128. package/dist/engine/IterationManager.js.map +1 -0
  129. package/dist/engine/ProviderRegistry.d.ts +10 -0
  130. package/dist/engine/ProviderRegistry.d.ts.map +1 -0
  131. package/dist/engine/ProviderRegistry.js +28 -0
  132. package/dist/engine/ProviderRegistry.js.map +1 -0
  133. package/dist/engine/ToolRegistry.d.ts +54 -0
  134. package/dist/engine/ToolRegistry.d.ts.map +1 -0
  135. package/dist/engine/ToolRegistry.js +75 -0
  136. package/dist/engine/ToolRegistry.js.map +1 -0
  137. package/dist/engine/createBaseEngine.d.ts +169 -0
  138. package/dist/engine/createBaseEngine.d.ts.map +1 -0
  139. package/dist/engine/createBaseEngine.js +91 -0
  140. package/dist/engine/createBaseEngine.js.map +1 -0
  141. package/dist/engine/qa-orchestrator.d.ts +56 -0
  142. package/dist/engine/qa-orchestrator.d.ts.map +1 -0
  143. package/dist/engine/qa-orchestrator.js +163 -0
  144. package/dist/engine/qa-orchestrator.js.map +1 -0
  145. package/dist/index.d.ts +83 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +163 -0
  148. package/dist/index.js.map +1 -0
  149. package/dist/mcp/MCPClientManager.d.ts +65 -0
  150. package/dist/mcp/MCPClientManager.d.ts.map +1 -0
  151. package/dist/mcp/MCPClientManager.js +211 -0
  152. package/dist/mcp/MCPClientManager.js.map +1 -0
  153. package/dist/mcp/index.d.ts +3 -0
  154. package/dist/mcp/index.d.ts.map +1 -0
  155. package/dist/mcp/index.js +6 -0
  156. package/dist/mcp/index.js.map +1 -0
  157. package/dist/mcp/types.d.ts +121 -0
  158. package/dist/mcp/types.d.ts.map +1 -0
  159. package/dist/mcp/types.js +3 -0
  160. package/dist/mcp/types.js.map +1 -0
  161. package/dist/memory/SessionMemory.d.ts +9 -0
  162. package/dist/memory/SessionMemory.d.ts.map +1 -0
  163. package/dist/memory/SessionMemory.js +20 -0
  164. package/dist/memory/SessionMemory.js.map +1 -0
  165. package/dist/observability/CostTracker.d.ts +19 -0
  166. package/dist/observability/CostTracker.d.ts.map +1 -0
  167. package/dist/observability/CostTracker.js +64 -0
  168. package/dist/observability/CostTracker.js.map +1 -0
  169. package/dist/observability/MetricsCollector.d.ts +17 -0
  170. package/dist/observability/MetricsCollector.d.ts.map +1 -0
  171. package/dist/observability/MetricsCollector.js +70 -0
  172. package/dist/observability/MetricsCollector.js.map +1 -0
  173. package/dist/observability/ObservabilityManager.d.ts +33 -0
  174. package/dist/observability/ObservabilityManager.d.ts.map +1 -0
  175. package/dist/observability/ObservabilityManager.js +107 -0
  176. package/dist/observability/ObservabilityManager.js.map +1 -0
  177. package/dist/observability/Tracer.d.ts +23 -0
  178. package/dist/observability/Tracer.d.ts.map +1 -0
  179. package/dist/observability/Tracer.js +65 -0
  180. package/dist/observability/Tracer.js.map +1 -0
  181. package/dist/observability/index.d.ts +7 -0
  182. package/dist/observability/index.d.ts.map +1 -0
  183. package/dist/observability/index.js +14 -0
  184. package/dist/observability/index.js.map +1 -0
  185. package/dist/observability/types.d.ts +77 -0
  186. package/dist/observability/types.d.ts.map +1 -0
  187. package/dist/observability/types.js +15 -0
  188. package/dist/observability/types.js.map +1 -0
  189. package/dist/orchestration/audit/audit-ci-blocker.d.ts +31 -0
  190. package/dist/orchestration/audit/audit-ci-blocker.d.ts.map +1 -0
  191. package/dist/orchestration/audit/audit-ci-blocker.js +120 -0
  192. package/dist/orchestration/audit/audit-ci-blocker.js.map +1 -0
  193. package/dist/orchestration/audit/audit-finding-tracer.d.ts +33 -0
  194. package/dist/orchestration/audit/audit-finding-tracer.d.ts.map +1 -0
  195. package/dist/orchestration/audit/audit-finding-tracer.js +126 -0
  196. package/dist/orchestration/audit/audit-finding-tracer.js.map +1 -0
  197. package/dist/orchestration/audit/audit-lessons-learned.d.ts +27 -0
  198. package/dist/orchestration/audit/audit-lessons-learned.d.ts.map +1 -0
  199. package/dist/orchestration/audit/audit-lessons-learned.js +155 -0
  200. package/dist/orchestration/audit/audit-lessons-learned.js.map +1 -0
  201. package/dist/orchestration/audit/audit-pending-issues.d.ts +21 -0
  202. package/dist/orchestration/audit/audit-pending-issues.d.ts.map +1 -0
  203. package/dist/orchestration/audit/audit-pending-issues.js +110 -0
  204. package/dist/orchestration/audit/audit-pending-issues.js.map +1 -0
  205. package/dist/orchestration/audit/audit-reflection-bridge.d.ts +39 -0
  206. package/dist/orchestration/audit/audit-reflection-bridge.d.ts.map +1 -0
  207. package/dist/orchestration/audit/audit-reflection-bridge.js +65 -0
  208. package/dist/orchestration/audit/audit-reflection-bridge.js.map +1 -0
  209. package/dist/orchestration/audit/audit-report-renderer.d.ts +30 -0
  210. package/dist/orchestration/audit/audit-report-renderer.d.ts.map +1 -0
  211. package/dist/orchestration/audit/audit-report-renderer.js +249 -0
  212. package/dist/orchestration/audit/audit-report-renderer.js.map +1 -0
  213. package/dist/orchestration/audit/audit-report-version-manager.d.ts +52 -0
  214. package/dist/orchestration/audit/audit-report-version-manager.d.ts.map +1 -0
  215. package/dist/orchestration/audit/audit-report-version-manager.js +144 -0
  216. package/dist/orchestration/audit/audit-report-version-manager.js.map +1 -0
  217. package/dist/orchestration/audit/audit-silent-gates-buffer.d.ts +37 -0
  218. package/dist/orchestration/audit/audit-silent-gates-buffer.d.ts.map +1 -0
  219. package/dist/orchestration/audit/audit-silent-gates-buffer.js +129 -0
  220. package/dist/orchestration/audit/audit-silent-gates-buffer.js.map +1 -0
  221. package/dist/orchestration/audit/index.d.ts +17 -0
  222. package/dist/orchestration/audit/index.d.ts.map +1 -0
  223. package/dist/orchestration/audit/index.js +26 -0
  224. package/dist/orchestration/audit/index.js.map +1 -0
  225. package/dist/orchestration/audit/types.d.ts +79 -0
  226. package/dist/orchestration/audit/types.d.ts.map +1 -0
  227. package/dist/orchestration/audit/types.js +10 -0
  228. package/dist/orchestration/audit/types.js.map +1 -0
  229. package/dist/orchestration/audit-reporter.d.ts +133 -0
  230. package/dist/orchestration/audit-reporter.d.ts.map +1 -0
  231. package/dist/orchestration/audit-reporter.js +322 -0
  232. package/dist/orchestration/audit-reporter.js.map +1 -0
  233. package/dist/orchestration/config-loader.d.ts +51 -0
  234. package/dist/orchestration/config-loader.d.ts.map +1 -0
  235. package/dist/orchestration/config-loader.js +215 -0
  236. package/dist/orchestration/config-loader.js.map +1 -0
  237. package/dist/orchestration/domain-detector.d.ts +36 -0
  238. package/dist/orchestration/domain-detector.d.ts.map +1 -0
  239. package/dist/orchestration/domain-detector.js +157 -0
  240. package/dist/orchestration/domain-detector.js.map +1 -0
  241. package/dist/orchestration/fsm.d.ts +86 -0
  242. package/dist/orchestration/fsm.d.ts.map +1 -0
  243. package/dist/orchestration/fsm.js +223 -0
  244. package/dist/orchestration/fsm.js.map +1 -0
  245. package/dist/orchestration/gate-resolver.d.ts +42 -0
  246. package/dist/orchestration/gate-resolver.d.ts.map +1 -0
  247. package/dist/orchestration/gate-resolver.js +94 -0
  248. package/dist/orchestration/gate-resolver.js.map +1 -0
  249. package/dist/orchestration/index.d.ts +15 -0
  250. package/dist/orchestration/index.d.ts.map +1 -0
  251. package/dist/orchestration/index.js +32 -0
  252. package/dist/orchestration/index.js.map +1 -0
  253. package/dist/orchestration/intent-detector.d.ts +43 -0
  254. package/dist/orchestration/intent-detector.d.ts.map +1 -0
  255. package/dist/orchestration/intent-detector.js +249 -0
  256. package/dist/orchestration/intent-detector.js.map +1 -0
  257. package/dist/orchestration/keyword-match.d.ts +17 -0
  258. package/dist/orchestration/keyword-match.d.ts.map +1 -0
  259. package/dist/orchestration/keyword-match.js +26 -0
  260. package/dist/orchestration/keyword-match.js.map +1 -0
  261. package/dist/orchestration/llm-client-adapter.d.ts +11 -0
  262. package/dist/orchestration/llm-client-adapter.d.ts.map +1 -0
  263. package/dist/orchestration/llm-client-adapter.js +30 -0
  264. package/dist/orchestration/llm-client-adapter.js.map +1 -0
  265. package/dist/orchestration/orchestrator.d.ts +153 -0
  266. package/dist/orchestration/orchestrator.d.ts.map +1 -0
  267. package/dist/orchestration/orchestrator.js +471 -0
  268. package/dist/orchestration/orchestrator.js.map +1 -0
  269. package/dist/orchestration/policy-engine.d.ts +47 -0
  270. package/dist/orchestration/policy-engine.d.ts.map +1 -0
  271. package/dist/orchestration/policy-engine.js +262 -0
  272. package/dist/orchestration/policy-engine.js.map +1 -0
  273. package/dist/orchestration/risk-scorer.d.ts +38 -0
  274. package/dist/orchestration/risk-scorer.d.ts.map +1 -0
  275. package/dist/orchestration/risk-scorer.js +145 -0
  276. package/dist/orchestration/risk-scorer.js.map +1 -0
  277. package/dist/orchestration/task-context.d.ts +195 -0
  278. package/dist/orchestration/task-context.d.ts.map +1 -0
  279. package/dist/orchestration/task-context.js +160 -0
  280. package/dist/orchestration/task-context.js.map +1 -0
  281. package/dist/orchestration/types.d.ts +111 -0
  282. package/dist/orchestration/types.d.ts.map +1 -0
  283. package/dist/orchestration/types.js +37 -0
  284. package/dist/orchestration/types.js.map +1 -0
  285. package/dist/qa/index.d.ts +3 -0
  286. package/dist/qa/index.d.ts.map +1 -0
  287. package/dist/qa/index.js +6 -0
  288. package/dist/qa/index.js.map +1 -0
  289. package/dist/qa/qa-service.d.ts +30 -0
  290. package/dist/qa/qa-service.d.ts.map +1 -0
  291. package/dist/qa/qa-service.js +200 -0
  292. package/dist/qa/qa-service.js.map +1 -0
  293. package/dist/reflection/commands/domain-commands.d.ts +78 -0
  294. package/dist/reflection/commands/domain-commands.d.ts.map +1 -0
  295. package/dist/reflection/commands/domain-commands.js +203 -0
  296. package/dist/reflection/commands/domain-commands.js.map +1 -0
  297. package/dist/reflection/domain-registry.d.ts +104 -0
  298. package/dist/reflection/domain-registry.d.ts.map +1 -0
  299. package/dist/reflection/domain-registry.js +279 -0
  300. package/dist/reflection/domain-registry.js.map +1 -0
  301. package/dist/reflection/domains/agent-domain.d.ts +40 -0
  302. package/dist/reflection/domains/agent-domain.d.ts.map +1 -0
  303. package/dist/reflection/domains/agent-domain.js +161 -0
  304. package/dist/reflection/domains/agent-domain.js.map +1 -0
  305. package/dist/reflection/domains/audit-domain.d.ts +46 -0
  306. package/dist/reflection/domains/audit-domain.d.ts.map +1 -0
  307. package/dist/reflection/domains/audit-domain.js +241 -0
  308. package/dist/reflection/domains/audit-domain.js.map +1 -0
  309. package/dist/reflection/domains/bootstrap-domain.d.ts +40 -0
  310. package/dist/reflection/domains/bootstrap-domain.d.ts.map +1 -0
  311. package/dist/reflection/domains/bootstrap-domain.js +156 -0
  312. package/dist/reflection/domains/bootstrap-domain.js.map +1 -0
  313. package/dist/reflection/domains/commit-domain.d.ts +40 -0
  314. package/dist/reflection/domains/commit-domain.d.ts.map +1 -0
  315. package/dist/reflection/domains/commit-domain.js +174 -0
  316. package/dist/reflection/domains/commit-domain.js.map +1 -0
  317. package/dist/reflection/domains/test-domain.d.ts +40 -0
  318. package/dist/reflection/domains/test-domain.d.ts.map +1 -0
  319. package/dist/reflection/domains/test-domain.js +194 -0
  320. package/dist/reflection/domains/test-domain.js.map +1 -0
  321. package/dist/reflection/failure-catalog.d.ts +100 -0
  322. package/dist/reflection/failure-catalog.d.ts.map +1 -0
  323. package/dist/reflection/failure-catalog.js +269 -0
  324. package/dist/reflection/failure-catalog.js.map +1 -0
  325. package/dist/reflection/historical-loader.d.ts +105 -0
  326. package/dist/reflection/historical-loader.d.ts.map +1 -0
  327. package/dist/reflection/historical-loader.js +462 -0
  328. package/dist/reflection/historical-loader.js.map +1 -0
  329. package/dist/reflection/hooks/agent-hook.d.ts +72 -0
  330. package/dist/reflection/hooks/agent-hook.d.ts.map +1 -0
  331. package/dist/reflection/hooks/agent-hook.js +98 -0
  332. package/dist/reflection/hooks/agent-hook.js.map +1 -0
  333. package/dist/reflection/hooks/audit-hook.d.ts +72 -0
  334. package/dist/reflection/hooks/audit-hook.d.ts.map +1 -0
  335. package/dist/reflection/hooks/audit-hook.js +112 -0
  336. package/dist/reflection/hooks/audit-hook.js.map +1 -0
  337. package/dist/reflection/hooks/bootstrap-hook.d.ts +71 -0
  338. package/dist/reflection/hooks/bootstrap-hook.d.ts.map +1 -0
  339. package/dist/reflection/hooks/bootstrap-hook.js +97 -0
  340. package/dist/reflection/hooks/bootstrap-hook.js.map +1 -0
  341. package/dist/reflection/hooks/commit-hook.d.ts +63 -0
  342. package/dist/reflection/hooks/commit-hook.d.ts.map +1 -0
  343. package/dist/reflection/hooks/commit-hook.js +90 -0
  344. package/dist/reflection/hooks/commit-hook.js.map +1 -0
  345. package/dist/reflection/hooks/test-hook.d.ts +65 -0
  346. package/dist/reflection/hooks/test-hook.d.ts.map +1 -0
  347. package/dist/reflection/hooks/test-hook.js +99 -0
  348. package/dist/reflection/hooks/test-hook.js.map +1 -0
  349. package/dist/reflection/index.d.ts +19 -0
  350. package/dist/reflection/index.d.ts.map +1 -0
  351. package/dist/reflection/index.js +40 -0
  352. package/dist/reflection/index.js.map +1 -0
  353. package/dist/reflection/lessons-memo-generator.d.ts +60 -0
  354. package/dist/reflection/lessons-memo-generator.d.ts.map +1 -0
  355. package/dist/reflection/lessons-memo-generator.js +286 -0
  356. package/dist/reflection/lessons-memo-generator.js.map +1 -0
  357. package/dist/reflection/pattern-detector.d.ts +55 -0
  358. package/dist/reflection/pattern-detector.d.ts.map +1 -0
  359. package/dist/reflection/pattern-detector.js +137 -0
  360. package/dist/reflection/pattern-detector.js.map +1 -0
  361. package/dist/reflection/policy-promoter.d.ts +86 -0
  362. package/dist/reflection/policy-promoter.d.ts.map +1 -0
  363. package/dist/reflection/policy-promoter.js +382 -0
  364. package/dist/reflection/policy-promoter.js.map +1 -0
  365. package/dist/reflection/reflection-engine.d.ts +160 -0
  366. package/dist/reflection/reflection-engine.d.ts.map +1 -0
  367. package/dist/reflection/reflection-engine.js +352 -0
  368. package/dist/reflection/reflection-engine.js.map +1 -0
  369. package/dist/reflection/types.d.ts +106 -0
  370. package/dist/reflection/types.d.ts.map +1 -0
  371. package/dist/reflection/types.js +64 -0
  372. package/dist/reflection/types.js.map +1 -0
  373. package/dist/shared/llm/resilient-client.d.ts +40 -0
  374. package/dist/shared/llm/resilient-client.d.ts.map +1 -0
  375. package/dist/shared/llm/resilient-client.js +60 -0
  376. package/dist/shared/llm/resilient-client.js.map +1 -0
  377. package/dist/shared/utils/atomic-write.d.ts +7 -0
  378. package/dist/shared/utils/atomic-write.d.ts.map +1 -0
  379. package/dist/shared/utils/atomic-write.js +52 -0
  380. package/dist/shared/utils/atomic-write.js.map +1 -0
  381. package/dist/shared/utils/git.d.ts +2 -0
  382. package/dist/shared/utils/git.d.ts.map +1 -0
  383. package/dist/shared/utils/git.js +17 -0
  384. package/dist/shared/utils/git.js.map +1 -0
  385. package/dist/shared/utils/project-key.d.ts +4 -0
  386. package/dist/shared/utils/project-key.d.ts.map +1 -0
  387. package/dist/shared/utils/project-key.js +54 -0
  388. package/dist/shared/utils/project-key.js.map +1 -0
  389. package/dist/shared/utils/string-utils.d.ts +17 -0
  390. package/dist/shared/utils/string-utils.d.ts.map +1 -0
  391. package/dist/shared/utils/string-utils.js +37 -0
  392. package/dist/shared/utils/string-utils.js.map +1 -0
  393. package/dist/skills/activator.d.ts +27 -0
  394. package/dist/skills/activator.d.ts.map +1 -0
  395. package/dist/skills/activator.js +127 -0
  396. package/dist/skills/activator.js.map +1 -0
  397. package/dist/skills/builtins/global.d.ts +7 -0
  398. package/dist/skills/builtins/global.d.ts.map +1 -0
  399. package/dist/skills/builtins/global.js +208 -0
  400. package/dist/skills/builtins/global.js.map +1 -0
  401. package/dist/skills/builtins/go-pack.d.ts +7 -0
  402. package/dist/skills/builtins/go-pack.d.ts.map +1 -0
  403. package/dist/skills/builtins/go-pack.js +263 -0
  404. package/dist/skills/builtins/go-pack.js.map +1 -0
  405. package/dist/skills/builtins/java-pack.d.ts +7 -0
  406. package/dist/skills/builtins/java-pack.d.ts.map +1 -0
  407. package/dist/skills/builtins/java-pack.js +272 -0
  408. package/dist/skills/builtins/java-pack.js.map +1 -0
  409. package/dist/skills/builtins/kotlin-pack.d.ts +9 -0
  410. package/dist/skills/builtins/kotlin-pack.d.ts.map +1 -0
  411. package/dist/skills/builtins/kotlin-pack.js +292 -0
  412. package/dist/skills/builtins/kotlin-pack.js.map +1 -0
  413. package/dist/skills/builtins/node-pack.d.ts +7 -0
  414. package/dist/skills/builtins/node-pack.d.ts.map +1 -0
  415. package/dist/skills/builtins/node-pack.js +750 -0
  416. package/dist/skills/builtins/node-pack.js.map +1 -0
  417. package/dist/skills/builtins/python-pack.d.ts +7 -0
  418. package/dist/skills/builtins/python-pack.d.ts.map +1 -0
  419. package/dist/skills/builtins/python-pack.js +303 -0
  420. package/dist/skills/builtins/python-pack.js.map +1 -0
  421. package/dist/skills/index.d.ts +11 -0
  422. package/dist/skills/index.d.ts.map +1 -0
  423. package/dist/skills/index.js +24 -0
  424. package/dist/skills/index.js.map +1 -0
  425. package/dist/skills/loader.d.ts +39 -0
  426. package/dist/skills/loader.d.ts.map +1 -0
  427. package/dist/skills/loader.js +152 -0
  428. package/dist/skills/loader.js.map +1 -0
  429. package/dist/skills/manager.d.ts +97 -0
  430. package/dist/skills/manager.d.ts.map +1 -0
  431. package/dist/skills/manager.js +296 -0
  432. package/dist/skills/manager.js.map +1 -0
  433. package/dist/skills/parse-md-skill.d.ts +14 -0
  434. package/dist/skills/parse-md-skill.d.ts.map +1 -0
  435. package/dist/skills/parse-md-skill.js +86 -0
  436. package/dist/skills/parse-md-skill.js.map +1 -0
  437. package/dist/skills/providers/github.d.ts +21 -0
  438. package/dist/skills/providers/github.d.ts.map +1 -0
  439. package/dist/skills/providers/github.js +146 -0
  440. package/dist/skills/providers/github.js.map +1 -0
  441. package/dist/skills/providers/index.d.ts +6 -0
  442. package/dist/skills/providers/index.d.ts.map +1 -0
  443. package/dist/skills/providers/index.js +12 -0
  444. package/dist/skills/providers/index.js.map +1 -0
  445. package/dist/skills/providers/local.d.ts +16 -0
  446. package/dist/skills/providers/local.d.ts.map +1 -0
  447. package/dist/skills/providers/local.js +91 -0
  448. package/dist/skills/providers/local.js.map +1 -0
  449. package/dist/skills/providers/obsidian.d.ts +31 -0
  450. package/dist/skills/providers/obsidian.d.ts.map +1 -0
  451. package/dist/skills/providers/obsidian.js +141 -0
  452. package/dist/skills/providers/obsidian.js.map +1 -0
  453. package/dist/skills/providers/skills-sh.d.ts +32 -0
  454. package/dist/skills/providers/skills-sh.d.ts.map +1 -0
  455. package/dist/skills/providers/skills-sh.js +53 -0
  456. package/dist/skills/providers/skills-sh.js.map +1 -0
  457. package/dist/skills/providers/types.d.ts +25 -0
  458. package/dist/skills/providers/types.d.ts.map +1 -0
  459. package/dist/skills/providers/types.js +3 -0
  460. package/dist/skills/providers/types.js.map +1 -0
  461. package/dist/skills/registry.d.ts +18 -0
  462. package/dist/skills/registry.d.ts.map +1 -0
  463. package/dist/skills/registry.js +45 -0
  464. package/dist/skills/registry.js.map +1 -0
  465. package/dist/skills/types.d.ts +66 -0
  466. package/dist/skills/types.d.ts.map +1 -0
  467. package/dist/skills/types.js +3 -0
  468. package/dist/skills/types.js.map +1 -0
  469. package/dist/tools/defineTool.d.ts +34 -0
  470. package/dist/tools/defineTool.d.ts.map +1 -0
  471. package/dist/tools/defineTool.js +63 -0
  472. package/dist/tools/defineTool.js.map +1 -0
  473. package/dist/transport/CallbackTransport.d.ts +12 -0
  474. package/dist/transport/CallbackTransport.d.ts.map +1 -0
  475. package/dist/transport/CallbackTransport.js +28 -0
  476. package/dist/transport/CallbackTransport.js.map +1 -0
  477. package/dist/transport/StdoutTransport.d.ts +9 -0
  478. package/dist/transport/StdoutTransport.d.ts.map +1 -0
  479. package/dist/transport/StdoutTransport.js +63 -0
  480. package/dist/transport/StdoutTransport.js.map +1 -0
  481. package/dist/transport/Transport.d.ts +8 -0
  482. package/dist/transport/Transport.d.ts.map +1 -0
  483. package/dist/transport/Transport.js +3 -0
  484. package/dist/transport/Transport.js.map +1 -0
  485. package/dist/triggers/EventBus.d.ts +14 -0
  486. package/dist/triggers/EventBus.d.ts.map +1 -0
  487. package/dist/triggers/EventBus.js +18 -0
  488. package/dist/triggers/EventBus.js.map +1 -0
  489. package/dist/triggers/TriggerManager.d.ts +28 -0
  490. package/dist/triggers/TriggerManager.d.ts.map +1 -0
  491. package/dist/triggers/TriggerManager.js +158 -0
  492. package/dist/triggers/TriggerManager.js.map +1 -0
  493. package/dist/triggers/WebhookServer.d.ts +23 -0
  494. package/dist/triggers/WebhookServer.d.ts.map +1 -0
  495. package/dist/triggers/WebhookServer.js +127 -0
  496. package/dist/triggers/WebhookServer.js.map +1 -0
  497. package/dist/triggers/createAutonomousAgent.d.ts +49 -0
  498. package/dist/triggers/createAutonomousAgent.d.ts.map +1 -0
  499. package/dist/triggers/createAutonomousAgent.js +42 -0
  500. package/dist/triggers/createAutonomousAgent.js.map +1 -0
  501. package/dist/triggers/index.d.ts +8 -0
  502. package/dist/triggers/index.d.ts.map +1 -0
  503. package/dist/triggers/index.js +12 -0
  504. package/dist/triggers/index.js.map +1 -0
  505. package/dist/triggers/types.d.ts +35 -0
  506. package/dist/triggers/types.d.ts.map +1 -0
  507. package/dist/triggers/types.js +3 -0
  508. package/dist/triggers/types.js.map +1 -0
  509. package/dist/types/index.d.ts +256 -0
  510. package/dist/types/index.d.ts.map +1 -0
  511. package/dist/types/index.js +4 -0
  512. package/dist/types/index.js.map +1 -0
  513. package/dist/workflow/WorkflowBuilder.d.ts +22 -0
  514. package/dist/workflow/WorkflowBuilder.d.ts.map +1 -0
  515. package/dist/workflow/WorkflowBuilder.js +67 -0
  516. package/dist/workflow/WorkflowBuilder.js.map +1 -0
  517. package/dist/workflow/WorkflowRunner.d.ts +22 -0
  518. package/dist/workflow/WorkflowRunner.d.ts.map +1 -0
  519. package/dist/workflow/WorkflowRunner.js +97 -0
  520. package/dist/workflow/WorkflowRunner.js.map +1 -0
  521. package/dist/workflow/index.d.ts +5 -0
  522. package/dist/workflow/index.d.ts.map +1 -0
  523. package/dist/workflow/index.js +10 -0
  524. package/dist/workflow/index.js.map +1 -0
  525. package/dist/workflow/types.d.ts +35 -0
  526. package/dist/workflow/types.d.ts.map +1 -0
  527. package/dist/workflow/types.js +3 -0
  528. package/dist/workflow/types.js.map +1 -0
  529. package/dist/workspace/index.d.ts +55 -0
  530. package/dist/workspace/index.d.ts.map +1 -0
  531. package/dist/workspace/index.js +189 -0
  532. package/dist/workspace/index.js.map +1 -0
  533. package/package.json +87 -0
@@ -0,0 +1,1037 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentEngine = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const atomic_write_1 = require("../shared/utils/atomic-write");
7
+ const DelegationBus_1 = require("../delegation/DelegationBus");
8
+ const SessionMemory_1 = require("../memory/SessionMemory");
9
+ const activator_1 = require("../skills/activator");
10
+ const WorkflowRunner_1 = require("../workflow/WorkflowRunner");
11
+ const IterationManager_1 = require("./IterationManager");
12
+ const qa_orchestrator_1 = require("./qa-orchestrator");
13
+ /**
14
+ * Remove messages that would cause a 400 from any OpenAI-compatible provider:
15
+ * - `tool` messages that are not part of an active assistant→tool chain
16
+ * - `assistant` messages that declare tool_calls but have no following tool results
17
+ * (only stripped when the next non-tool message is NOT another turn of the same chain)
18
+ *
19
+ * Walking forward: we track whether we're "inside" a tool_calls chain.
20
+ * A chain starts with assistant(tool_calls) and ends once all IDs have a result.
21
+ * Any `tool` result that arrives outside an open chain is dropped.
22
+ */
23
+ function sanitizeMessages(messages) {
24
+ const out = [];
25
+ // IDs still waiting for a tool result in the current chain
26
+ let pendingIds = new Set();
27
+ for (const msg of messages) {
28
+ if (msg.role === 'assistant') {
29
+ // A new assistant message closes any previous chain (even if incomplete)
30
+ // and optionally opens a new one.
31
+ pendingIds = new Set();
32
+ if (msg.tool_calls?.length) {
33
+ for (const tc of msg.tool_calls) {
34
+ if (tc.id)
35
+ pendingIds.add(tc.id);
36
+ }
37
+ }
38
+ out.push(msg);
39
+ }
40
+ else if (msg.role === 'tool') {
41
+ if (pendingIds.size === 0) {
42
+ // Orphaned tool result — no open chain. Drop it.
43
+ continue;
44
+ }
45
+ if (msg.tool_call_id)
46
+ pendingIds.delete(msg.tool_call_id);
47
+ out.push(msg);
48
+ }
49
+ else {
50
+ // user / system — close any open chain
51
+ pendingIds = new Set();
52
+ out.push(msg);
53
+ }
54
+ }
55
+ return out;
56
+ }
57
+ const MAX_INPUT_BYTES = 100_000; // Fix #17: 100 KB hard cap on user input
58
+ const ASK_AGENT_TOOL = {
59
+ name: 'ask_agent',
60
+ description: 'Invokes another AI agent in the system. Multiple ask_agent calls in the same response ' +
61
+ 'run concurrently (up to 6 at a time via a bulkhead). Use to split large independent ' +
62
+ 'tasks across 2-5 specialist agents per response.',
63
+ parameters: {
64
+ type: 'object',
65
+ properties: {
66
+ agent_id: { type: 'string', description: 'ID of the agent to invoke' },
67
+ question: { type: 'string', description: 'The task or question for the agent' },
68
+ context: { type: 'string', description: 'Additional context the agent needs' },
69
+ },
70
+ required: ['agent_id', 'question'],
71
+ },
72
+ execute: async () => '',
73
+ };
74
+ class AgentEngine {
75
+ opts;
76
+ memory;
77
+ bus;
78
+ skillActivator = new activator_1.SkillActivator();
79
+ currentAgentId;
80
+ messages = [];
81
+ aborted = false;
82
+ abortController = null;
83
+ allSkills;
84
+ iterationManager;
85
+ activeSkillAddition = '';
86
+ yamlSkillsLoaded = false;
87
+ mcpInitialized = false;
88
+ mcpInitAttempts = 0;
89
+ mcpRegisteredServers = new Set();
90
+ mcpTriggers = new Map(); // agentId → triggers
91
+ mcpToolTriggers = new Map(); // keyword → {agentId, tool}
92
+ approvalDisabled = false; // set to true after 'approve_all'
93
+ static WRITE_TOOLS = new Set(['write_file', 'edit_file', 'run_command']);
94
+ /** Tracks what each MCP server blocked/assigned so it can be fully reverted on disconnect. */
95
+ mcpAgentBlocks = new Map();
96
+ /**
97
+ * Commands that always require user approval regardless of iteration mode or
98
+ * approvalDisabled flag. These are irreversible or high-blast-radius operations:
99
+ * installing new packages, removing packages, running destructive npm scripts.
100
+ */
101
+ static ALWAYS_ASK_PATTERNS = [
102
+ /^\s*npm\s+(install|i|add)\s+[^-]/i, // npm install <pkg> — new package install
103
+ /^\s*npm\s+uninstall\b/i, // npm uninstall
104
+ /^\s*yarn\s+add\s+[^-]/i, // yarn add <pkg>
105
+ /^\s*pnpm\s+add\s+[^-]/i, // pnpm add <pkg>
106
+ /^\s*pip\s+install\b/i, // pip install
107
+ /^\s*pip3\s+install\b/i,
108
+ ];
109
+ agentsLoaded = false;
110
+ memoryContextBlock = '';
111
+ constructor(opts) {
112
+ this.opts = opts;
113
+ this.memory = opts.sessionMemory ?? new SessionMemory_1.SessionMemory();
114
+ this.currentAgentId = opts.defaultAgentId;
115
+ this.allSkills = opts.skills ?? [];
116
+ this.iterationManager = new IterationManager_1.IterationManager({
117
+ mode: opts.iterationMode ?? 'interactive',
118
+ maxIterations: opts.maxIterations ?? 100,
119
+ onLimitReached: opts.onIterationLimit,
120
+ onStep: opts.onStep,
121
+ });
122
+ if (opts.auditLog) {
123
+ try {
124
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(opts.auditLog), { recursive: true });
125
+ }
126
+ catch { }
127
+ }
128
+ if (opts.historyPath && (0, fs_1.existsSync)(opts.historyPath)) {
129
+ try {
130
+ const raw = JSON.parse((0, fs_1.readFileSync)(opts.historyPath, 'utf-8'));
131
+ this.messages = raw.filter(m => m.role !== 'system');
132
+ }
133
+ catch { /* corrupt or missing — start fresh */ }
134
+ }
135
+ this.bus = new DelegationBus_1.DelegationBus({
136
+ maxParallel: opts.maxParallelAgents ?? 6,
137
+ agents: opts.agents,
138
+ tools: opts.tools,
139
+ transport: opts.transport,
140
+ workingDir: opts.workingDir,
141
+ runAgent: (id, question, context) => this.runAgentInternal(id, question, context),
142
+ });
143
+ }
144
+ /** Access the observability manager when configured via createBaseEngine({ observability }). */
145
+ get observability() {
146
+ return this.opts.observabilityManager;
147
+ }
148
+ /** Access the MCP client manager to inspect connected servers and their tools. */
149
+ getMCPManager() {
150
+ return this.opts.mcpManager;
151
+ }
152
+ /**
153
+ * Updates the working directory used by tools and the system prompt.
154
+ * Call after a workspace/project switch so file operations target the new
155
+ * project root without recreating the entire engine.
156
+ * Also triggers a skill reload so project-scoped skills are refreshed.
157
+ */
158
+ updateWorkingDir(newCwd) {
159
+ this.opts.workingDir = newCwd;
160
+ this.reloadSkills();
161
+ }
162
+ /**
163
+ * Marks YAML skills as stale so the next run() reloads them from disk.
164
+ * Call after installing, creating, or generating skills so changes take effect
165
+ * without restarting the engine.
166
+ * Built-in (in-memory) skills are never affected — only the YAML layers are reloaded.
167
+ */
168
+ reloadSkills() {
169
+ const builtins = this.opts.skills ?? [];
170
+ this.allSkills = [...builtins];
171
+ this.yamlSkillsLoaded = false;
172
+ }
173
+ /**
174
+ * Direct single-turn LLM call — no tools, no conversation history, no transport events.
175
+ * Useful for slash commands that need AI-generated content (e.g. /skills generate).
176
+ * Uses the engine's default provider and model.
177
+ */
178
+ async callLLM(prompt) {
179
+ const provider = this.opts.providers.resolve(undefined, this.opts.defaultProvider);
180
+ return new Promise((resolve, reject) => {
181
+ const chunks = [];
182
+ provider.chat([{ role: 'user', content: prompt }], [], {
183
+ onChunk(delta) { chunks.push(delta); },
184
+ onDone() { resolve(chunks.join('')); },
185
+ onError(err) { reject(err); },
186
+ });
187
+ });
188
+ }
189
+ getProviderForProfile(profile) {
190
+ return this.opts.providers.resolve(profile.provider, this.opts.defaultProvider);
191
+ }
192
+ async run(input) {
193
+ this.aborted = false;
194
+ this.opts.transport.emit({ type: 'ready' });
195
+ // Fix #17: reject inputs that exceed the hard cap to prevent prompt injection via huge payloads
196
+ if (Buffer.byteLength(input, 'utf-8') > MAX_INPUT_BYTES) {
197
+ this.opts.transport.emit({
198
+ type: 'error',
199
+ message: `Input too large (${Buffer.byteLength(input, 'utf-8').toLocaleString()} bytes). Maximum is ${MAX_INPUT_BYTES.toLocaleString()} bytes.`,
200
+ });
201
+ this.opts.transport.emit({ type: 'done' });
202
+ return;
203
+ }
204
+ await this.ensureMCPInitialized();
205
+ await this.ensureAgentsLoaded();
206
+ // Direct MCP routing: bypass general when input matches a configured trigger
207
+ const mcpRoute = this.findMCPRoute(input);
208
+ if (mcpRoute) {
209
+ if (mcpRoute.tool) {
210
+ // Tool trigger: call the MCP tool directly — no intermediate LLM
211
+ const toolName = `mcp__${mcpRoute.agentId}__${mcpRoute.tool}`;
212
+ const toolDef = this.opts.tools.get(toolName);
213
+ if (toolDef) {
214
+ const required = toolDef.parameters.required;
215
+ const firstParam = required?.[0] ?? 'input';
216
+ const ctx = this.buildContext();
217
+ const profile = this.opts.agents.get(mcpRoute.agentId);
218
+ this.opts.transport.emit({
219
+ type: 'block_start',
220
+ agent_id: mcpRoute.agentId,
221
+ agent_name: profile?.name ?? mcpRoute.agentId,
222
+ agent_icon: profile?.icon ?? '◎',
223
+ });
224
+ const result = await toolDef.execute({ [firstParam]: input }, ctx);
225
+ this.opts.transport.emit({ type: 'token', content: result, agent_id: mcpRoute.agentId });
226
+ this.opts.transport.emit({ type: 'block_end', status: 'ok', agent_id: mcpRoute.agentId });
227
+ this.opts.transport.emit({ type: 'done' });
228
+ return;
229
+ }
230
+ }
231
+ // Agent trigger fallback: route to the agent's LLM session
232
+ await this.runAgentInternal(mcpRoute.agentId, input);
233
+ this.opts.transport.emit({ type: 'done' });
234
+ return;
235
+ }
236
+ // Pre-compute memory context block for this input
237
+ if (this.opts.memorySystem) {
238
+ this.memoryContextBlock = await this.opts.memorySystem.buildContextBlock(input).catch(() => '');
239
+ }
240
+ // Lazy-load user YAML skills (global + packs + project) on first call
241
+ if (!this.yamlSkillsLoaded && this.opts.loadSkills) {
242
+ try {
243
+ const yamlSkills = await this.opts.loadSkills();
244
+ this.allSkills = [...this.allSkills, ...yamlSkills];
245
+ }
246
+ catch { /* non-fatal: skip if filesystem skills unavailable */ }
247
+ this.yamlSkillsLoaded = true;
248
+ }
249
+ // Activate skills relevant to this specific input
250
+ if (this.allSkills.length > 0) {
251
+ const active = this.skillActivator.activate(input, this.allSkills, this.opts.detectedStack ?? []);
252
+ this.activeSkillAddition = this.skillActivator.buildSystemPromptAddition(active);
253
+ }
254
+ const profile = this.getCurrentProfile();
255
+ if (!profile)
256
+ throw new Error(`Default agent "${this.currentAgentId}" not registered`);
257
+ // Orquestar la tarea para obtener clasificacion, risk scoring y gates requeridos
258
+ let orchestrationResult;
259
+ if (this.opts.orchestrator) {
260
+ orchestrationResult = await this.opts.orchestrator.orchestrate(input).catch(() => undefined);
261
+ }
262
+ this.messages.push({ role: 'user', content: input });
263
+ await this.runLoop(profile, orchestrationResult);
264
+ this.saveHistory();
265
+ this.opts.transport.emit({ type: 'done' });
266
+ }
267
+ async runWorkflow(defOrBuilder, opts = {}) {
268
+ await this.ensureMCPInitialized();
269
+ await this.ensureAgentsLoaded();
270
+ const def = 'build' in defOrBuilder ? defOrBuilder.build() : defOrBuilder;
271
+ const runner = new WorkflowRunner_1.WorkflowRunner(def, {
272
+ ...opts,
273
+ runAgent: (agentId, input, context) => this.runAgentInternal(agentId, input, context),
274
+ transport: this.opts.transport,
275
+ });
276
+ return runner.run();
277
+ }
278
+ abort() {
279
+ this.aborted = true;
280
+ this.abortController?.abort();
281
+ this.abortController = null;
282
+ }
283
+ /** Change the iteration mode at runtime — takes effect on the next run(). */
284
+ setIterationMode(mode) {
285
+ this.iterationManager.setMode(mode);
286
+ }
287
+ /** Returns the current iteration mode. */
288
+ getIterationMode() {
289
+ return this.iterationManager.mode;
290
+ }
291
+ /** Delete persisted history file and reset in-memory conversation. */
292
+ clearHistory() {
293
+ this.messages = [];
294
+ if (!this.opts.historyPath)
295
+ return;
296
+ try {
297
+ (0, atomic_write_1.atomicWriteSync)(this.opts.historyPath, '[]');
298
+ }
299
+ catch { /* non-fatal */ }
300
+ }
301
+ /** Serialize current conversation to disk (called automatically after each run). */
302
+ saveHistory() {
303
+ if (!this.opts.historyPath)
304
+ return;
305
+ const cap = this.opts.maxContextMessages ?? 100;
306
+ const toSave = this.messages.filter(m => m.role !== 'system').slice(-cap);
307
+ try {
308
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(this.opts.historyPath), { recursive: true });
309
+ (0, atomic_write_1.atomicWriteSync)(this.opts.historyPath, JSON.stringify(toSave, null, 2));
310
+ }
311
+ catch { /* non-fatal — history loss is preferable to a crash */ }
312
+ }
313
+ /**
314
+ * Trim conversation history to maxContextMessages by dropping oldest messages
315
+ * at a user-turn boundary. Preserves all assistant↔tool pairs intact.
316
+ */
317
+ trimHistory() {
318
+ const max = this.opts.maxContextMessages;
319
+ if (!max || this.messages.length <= max)
320
+ return;
321
+ // Walk forward from the target offset to find the next 'user' message.
322
+ // Cutting there avoids orphaning assistant tool_calls / tool results.
323
+ const target = this.messages.length - max;
324
+ let cutAt = target;
325
+ while (cutAt < this.messages.length && this.messages[cutAt].role !== 'user') {
326
+ cutAt++;
327
+ }
328
+ if (cutAt > 0 && cutAt < this.messages.length) {
329
+ this.messages = this.messages.slice(cutAt);
330
+ this.opts.transport.emit({
331
+ type: 'system',
332
+ level: 'warn',
333
+ text: `[ContextWindow] Dropped ${cutAt} messages — history capped at ${max} (maxContextMessages)`,
334
+ });
335
+ }
336
+ }
337
+ async ensureAgentsLoaded() {
338
+ if (this.agentsLoaded || !this.opts.loadAgents)
339
+ return;
340
+ this.agentsLoaded = true; // set early to prevent concurrent double-loads
341
+ try {
342
+ const discovered = await this.opts.loadAgents();
343
+ for (const agent of discovered)
344
+ this.opts.agents.upsert(agent);
345
+ // If the current default agent still isn't registered, fall back to first available
346
+ if (!this.opts.agents.has(this.currentAgentId)) {
347
+ const all = this.opts.agents.getAll();
348
+ if (all.length > 0)
349
+ this.currentAgentId = all[0].id;
350
+ }
351
+ }
352
+ catch (err) {
353
+ this.opts.transport.emit({
354
+ type: 'system', level: 'warn',
355
+ text: `[AgentDiscovery] Failed to load agents: ${err.message}`,
356
+ });
357
+ }
358
+ }
359
+ async ensureMCPInitialized() {
360
+ if (!this.opts.mcpManager)
361
+ return;
362
+ try {
363
+ if (!this.mcpInitialized) {
364
+ await this.opts.mcpManager.initialize();
365
+ this.mcpInitialized = true;
366
+ }
367
+ else {
368
+ // Subsequent runs: retry only servers that are still offline — bounded by their own counter
369
+ const offline = this.opts.mcpManager.getConfiguredNames()
370
+ .filter(n => !this.mcpRegisteredServers.has(n));
371
+ if (offline.length > 0 && this.mcpInitAttempts < 3) {
372
+ this.mcpInitAttempts++;
373
+ await this.opts.mcpManager.reconnectFailed();
374
+ }
375
+ }
376
+ }
377
+ catch (err) {
378
+ this.opts.transport.emit({
379
+ type: 'system', level: 'warn',
380
+ text: `MCP initialization error: ${err.message}`,
381
+ });
382
+ }
383
+ // Always register any server that is now connected but not yet registered as agent.
384
+ // This runs regardless of the retry counter so late-starting servers get picked up.
385
+ for (const { name, toolCount } of this.opts.mcpManager.getServerInfo()) {
386
+ if (toolCount > 0 && !this.mcpRegisteredServers.has(name)) {
387
+ const tools = this.opts.mcpManager.getServerTools(name);
388
+ const config = this.opts.mcpManager.getConfig(name);
389
+ this.registerMCPAgent(config, tools);
390
+ this.mcpRegisteredServers.add(name);
391
+ }
392
+ }
393
+ // Warn about servers still offline (only while retries remain)
394
+ const stillOffline = this.opts.mcpManager.getConfiguredNames()
395
+ .filter(n => !this.mcpRegisteredServers.has(n));
396
+ if (stillOffline.length > 0) {
397
+ const retriesLeft = 3 - this.mcpInitAttempts;
398
+ const suffix = retriesLeft > 0
399
+ ? `Retrying on next message (${retriesLeft} attempts left).`
400
+ : `No more automatic retries — call engine.getMCPManager()?.reconnectFailed() to retry manually.`;
401
+ this.opts.transport.emit({
402
+ type: 'system', level: 'warn',
403
+ text: `MCP agents offline: ${stillOffline.join(', ')} — start their servers to enable them. ${suffix}`,
404
+ });
405
+ }
406
+ }
407
+ registerMCPAgent(config, tools) {
408
+ // safeName mirrors the sanitization done by MCPClientManager.wrapTool() so that
409
+ // tool lookup `mcp__${safeName}__${tool}` always resolves correctly.
410
+ const safeName = config.name.replace(/[^a-zA-Z0-9_-]/g, '_');
411
+ // Register tools in the ToolRegistry — skip already-registered ones
412
+ // (safe for reconnection scenarios; mcpRegisteredServers normally prevents duplicates)
413
+ for (const tool of tools) {
414
+ if (!this.opts.tools.has(tool.name)) {
415
+ this.opts.tools.register(tool);
416
+ }
417
+ }
418
+ // toolTriggers work in both modes — direct keyword → tool execution, zero LLM hops
419
+ if (config.toolTriggers) {
420
+ for (const [keyword, tool] of Object.entries(config.toolTriggers)) {
421
+ this.mcpToolTriggers.set(keyword.toLowerCase(), { agentId: safeName, tool });
422
+ }
423
+ }
424
+ const mode = config.mode ?? 'tools';
425
+ if (mode === 'tools') {
426
+ this.registerMCPToolPack(config, tools, safeName);
427
+ }
428
+ else {
429
+ this.registerMCPAgentWrapper(config, tools, safeName);
430
+ }
431
+ }
432
+ /**
433
+ * mode='tools' (default): assigns MCP tools directly to local agent allowedTools.
434
+ * Also applies blocksCommands to those agents while the server is connected —
435
+ * forcing them to use the MCP tools instead of equivalent shell commands.
436
+ * Both tool assignments and command blocks are tracked so they can be
437
+ * fully reverted when the server disconnects via unregisterMCPServer().
438
+ */
439
+ registerMCPToolPack(config, tools, safeName) {
440
+ const toolNames = tools.map(t => t.name);
441
+ const blocksCommands = config.blocksCommands ?? [];
442
+ // Resolve target agents: explicit assignTo list, or all registered agents
443
+ const assignTo = config.assignTo?.filter(id => id !== '*') ?? [];
444
+ const targets = assignTo.length > 0
445
+ ? assignTo
446
+ : this.opts.agents.getAll().map(a => a.id);
447
+ const blockRecord = [];
448
+ for (const agentId of targets) {
449
+ const agent = this.opts.agents.get(agentId);
450
+ if (!agent) {
451
+ this.opts.transport.emit({
452
+ type: 'system', level: 'warn',
453
+ text: `[MCP:${config.name}] assignTo agent "${agentId}" not found — skipped.`,
454
+ });
455
+ continue;
456
+ }
457
+ this.opts.agents.upsert({
458
+ ...agent,
459
+ allowedTools: [...new Set([...agent.allowedTools, ...toolNames])],
460
+ blockedCommands: [...new Set([...(agent.blockedCommands ?? []), ...blocksCommands])],
461
+ });
462
+ blockRecord.push({ agentId, toolNames, blockedCmds: blocksCommands });
463
+ }
464
+ this.mcpAgentBlocks.set(safeName, blockRecord);
465
+ if (config.triggers?.length) {
466
+ this.opts.transport.emit({
467
+ type: 'system', level: 'warn',
468
+ text: `[MCP:${config.name}] 'triggers' is ignored in mode='tools'. Use 'toolTriggers' for direct keyword routing.`,
469
+ });
470
+ }
471
+ const shortNames = tools.map(t => t.name.split('__')[2] ?? t.name).join(', ');
472
+ const agentList = targets.join(', ') || 'all agents';
473
+ const blockedLabel = blocksCommands.length ? ` blocked: [${blocksCommands.join(', ')}]` : '';
474
+ this.opts.transport.emit({
475
+ type: 'system', level: 'info',
476
+ text: `[MCP:${config.name}] tools [${shortNames}] assigned to: ${agentList}${blockedLabel}`,
477
+ });
478
+ }
479
+ /**
480
+ * mode='agent': wraps the MCP server as a delegatable agent in the roster.
481
+ * Use only when the remote service has its own reasoning layer or its output
482
+ * is so large it needs a dedicated summarization turn.
483
+ */
484
+ registerMCPAgentWrapper(config, tools, safeName) {
485
+ const toolList = tools
486
+ .map(t => {
487
+ const shortName = t.name.split('__')[2] ?? t.name;
488
+ const desc = t.description.replace(/^\[MCP:[^\]]+\]\s*/, '').slice(0, 80);
489
+ return `- ${shortName}: ${desc}`;
490
+ })
491
+ .join('\n');
492
+ const enrichedDesc = tools
493
+ .map(t => {
494
+ const shortName = t.name.split('__')[2] ?? t.name;
495
+ const desc = t.description.replace(/^\[MCP:[^\]]+\]\s*/, '').slice(0, 70);
496
+ return `${shortName}: ${desc}`;
497
+ })
498
+ .join(' | ');
499
+ this.opts.agents.upsert({
500
+ id: safeName,
501
+ name: config.agentName ?? toTitleCase(config.name),
502
+ icon: config.icon ?? '◎',
503
+ description: config.agentDescription ?? `External specialist — ${enrichedDesc}`,
504
+ systemPrompt: `You are a specialized remote agent: ${config.name}.\n` +
505
+ `Use ONLY your available tools to answer the request. ` +
506
+ `Do NOT use run_command, read_file, or other local tools.\n\n` +
507
+ `Your tools:\n${toolList}`,
508
+ allowedTools: tools.map(t => t.name),
509
+ source: 'mcp',
510
+ });
511
+ if (config.triggers?.length) {
512
+ this.mcpTriggers.set(safeName, config.triggers);
513
+ }
514
+ }
515
+ findMCPRoute(input) {
516
+ const lower = input.toLowerCase();
517
+ for (const [keyword, route] of this.mcpToolTriggers) {
518
+ if (lower.includes(keyword))
519
+ return route;
520
+ }
521
+ for (const [agentId, triggers] of this.mcpTriggers) {
522
+ if (triggers.some(t => lower.includes(t.toLowerCase())))
523
+ return { agentId };
524
+ }
525
+ return undefined;
526
+ }
527
+ switchAgent(agentId) {
528
+ if (!this.opts.agents.has(agentId))
529
+ throw new Error(`Agent "${agentId}" not found`);
530
+ this.currentAgentId = agentId;
531
+ }
532
+ getCurrentProfile() {
533
+ return this.opts.agents.get(this.currentAgentId);
534
+ }
535
+ buildAgentRoster(excludeId) {
536
+ const all = this.opts.agents.getAll().filter(a => a.id !== excludeId);
537
+ const mcp = all.filter(a => a.source === 'mcp');
538
+ const local = all.filter(a => a.source !== 'mcp');
539
+ const parts = [];
540
+ if (mcp.length > 0) {
541
+ parts.push('## External Agents [MCP] — CHECK FIRST. If the task matches any of these, you MUST delegate to them via ask_agent before considering local agents.');
542
+ for (const a of mcp) {
543
+ parts.push(`- ${a.id} (${a.icon}): ${a.description} [MCP]`);
544
+ }
545
+ }
546
+ parts.push('## Local Agents — use only when no [MCP] agent covers the task.');
547
+ for (const a of local) {
548
+ const tag = a.source === 'project' ? ' [PROJECT]' : a.source === 'global' ? ' [GLOBAL]' : '';
549
+ parts.push(`- ${a.id} (${a.icon}): ${a.description}${tag}`);
550
+ }
551
+ return parts.join('\n');
552
+ }
553
+ buildSystemPrompt(profile, orchestrationResult) {
554
+ const isOrchestrator = profile.id === this.opts.defaultAgentId;
555
+ const parts = [profile.systemPrompt];
556
+ if (isOrchestrator)
557
+ parts.push(this.buildAgentRoster(profile.id));
558
+ if (this.opts.workingDir) {
559
+ parts.push(`## Working Directory\n` +
560
+ `\`${this.opts.workingDir}\`\n\n` +
561
+ `ALWAYS use RELATIVE paths with tools (e.g. \`src/index.ts\`, \`package.json\`). ` +
562
+ `NEVER invent absolute paths like \`/workspace/...\` or \`/home/...\`.`);
563
+ }
564
+ if (this.opts.projectContext)
565
+ parts.push(this.opts.projectContext);
566
+ // Per-agent session notes (tool quirks, learnings routed by LearningRouter)
567
+ const agentNotes = this.opts.store?.getAgentNotes?.(profile.id);
568
+ if (agentNotes)
569
+ parts.push(`## Agent Session Notes\n${agentNotes}`);
570
+ if (this.memoryContextBlock)
571
+ parts.push(this.memoryContextBlock);
572
+ if (this.activeSkillAddition)
573
+ parts.push(this.activeSkillAddition);
574
+ if (isOrchestrator && orchestrationResult) {
575
+ parts.push(this.buildOrchestrationBrief(orchestrationResult));
576
+ }
577
+ return parts.join('\n\n');
578
+ }
579
+ /**
580
+ * Converts an OrchestrationResult into a system-prompt section that tells the
581
+ * default agent which specialists to use, in what order, and what gates apply.
582
+ * This closes the gap between the deterministic policy layer and the LLM layer.
583
+ */
584
+ buildOrchestrationBrief(result) {
585
+ const { task, selectedAgents, agentPipeline, requiredGates } = result;
586
+ const lines = ['## Orchestrator Analysis — Current Task'];
587
+ const domains = task.domains.length > 0 ? task.domains.join(', ') : 'general';
588
+ lines.push(`**Intent:** ${task.actionType} | **Risk:** ${task.riskLevel} | **Domains:** ${domains}`);
589
+ // Only surface non-trivial agent selections (skip sole-fallback case)
590
+ const nonFallback = selectedAgents.filter(a => !(a.agentId === 'general' && a.score <= 50));
591
+ if (nonFallback.length > 0) {
592
+ lines.push('\n**Recommended agents for this task (highest priority first):**');
593
+ for (const a of nonFallback) {
594
+ lines.push(`- ${a.agentId} — ${a.reason}`);
595
+ }
596
+ lines.push('\nWhen delegating via ask_agent, prioritize the agents listed above. ' +
597
+ 'Do not delegate to unlisted agents unless the task explicitly requires it.');
598
+ }
599
+ if (agentPipeline && agentPipeline.length > 0) {
600
+ lines.push('\n**Suggested execution pipeline (respect this order):**');
601
+ agentPipeline.forEach((phase, i) => {
602
+ lines.push(`${i + 1}. [${phase.phase}] ${phase.agentId} — ${phase.purpose}`);
603
+ });
604
+ }
605
+ if (requiredGates.length > 0) {
606
+ lines.push(`\n**Required gates before commit:** ${requiredGates.join(', ')}`);
607
+ lines.push('Ensure each gate is satisfied before considering the task complete.');
608
+ }
609
+ return lines.join('\n');
610
+ }
611
+ resolvesDelegateTo(profile) {
612
+ if (!profile.delegatesTo || profile.delegatesTo.length === 0)
613
+ return [];
614
+ if (profile.delegatesTo[0] === '*') {
615
+ return this.opts.agents.getAll()
616
+ .map(a => a.id)
617
+ .filter(id => id !== profile.id);
618
+ }
619
+ return profile.delegatesTo;
620
+ }
621
+ getToolsForAgent(profile) {
622
+ const tools = this.opts.tools.getForAgent(profile.allowedTools);
623
+ if (profile.id === this.opts.defaultAgentId) {
624
+ tools.push(ASK_AGENT_TOOL);
625
+ }
626
+ return tools;
627
+ }
628
+ /**
629
+ * Merges the orchestrator's current-turn analysis with the explicit context the
630
+ * LLM provided in the ask_agent call. The analysis (streamBuffer) gives specialists
631
+ * the reasoning and data the orchestrator gathered before delegating.
632
+ */
633
+ buildSubAgentContext(explicit, orchestratorAnalysis) {
634
+ const trimmed = orchestratorAnalysis.trim();
635
+ if (!explicit && !trimmed)
636
+ return undefined;
637
+ const parts = [];
638
+ if (explicit)
639
+ parts.push(explicit);
640
+ if (trimmed)
641
+ parts.push(`## Análisis del orquestador\n${trimmed}`);
642
+ return parts.join('\n\n');
643
+ }
644
+ async runLoop(profile, orchestrationResult) {
645
+ let currentProfile = profile;
646
+ this.iterationManager.reset();
647
+ const iterManager = this.iterationManager;
648
+ this.opts.transport.emit({
649
+ type: 'block_start',
650
+ agent_id: profile.id,
651
+ agent_name: profile.name,
652
+ agent_icon: profile.icon,
653
+ });
654
+ while (!this.aborted) {
655
+ const shouldContinue = await iterManager.advance();
656
+ if (!shouldContinue)
657
+ break;
658
+ this.trimHistory();
659
+ const systemMsg = { role: 'system', content: this.buildSystemPrompt(currentProfile, orchestrationResult) };
660
+ const tools = this.getToolsForAgent(currentProfile);
661
+ const safeHistory = sanitizeMessages(this.messages);
662
+ let streamBuffer = '';
663
+ const askAgentCalls = [];
664
+ const otherCalls = [];
665
+ let finalMessage = null;
666
+ this.abortController = new AbortController();
667
+ const signal = this.abortController.signal;
668
+ await this.getProviderForProfile(currentProfile).chat([systemMsg, ...safeHistory], tools, {
669
+ onChunk: (delta) => {
670
+ streamBuffer += delta;
671
+ this.opts.transport.emit({ type: 'token', content: delta, agent_id: currentProfile.id });
672
+ },
673
+ onToolCall: (name, args, id) => {
674
+ this.opts.transport.emit({ type: 'tool_call', name, args_preview: args.slice(0, 80) });
675
+ if (name === 'ask_agent') {
676
+ try {
677
+ const parsed = JSON.parse(args);
678
+ askAgentCalls.push({ id, agentId: parsed.agent_id, question: parsed.question, context: parsed.context });
679
+ }
680
+ catch {
681
+ otherCalls.push({ id, name, args });
682
+ }
683
+ }
684
+ else {
685
+ otherCalls.push({ id, name, args });
686
+ }
687
+ },
688
+ onDone: (msg) => { finalMessage = msg; },
689
+ onError: (err) => {
690
+ if (!this.aborted)
691
+ this.opts.transport.emit({ type: 'error', message: err.message });
692
+ },
693
+ onMetrics: (inputTokens, outputTokens) => {
694
+ this.opts.transport.emit({ type: 'metrics', input_tokens: inputTokens, output_tokens: outputTokens });
695
+ },
696
+ signal,
697
+ });
698
+ this.abortController = null;
699
+ if (this.aborted)
700
+ break;
701
+ if (!finalMessage)
702
+ break;
703
+ this.messages.push(finalMessage);
704
+ const toolResults = [];
705
+ // ── ask_agent: parallel if 2+ calls ──────────────────────────────
706
+ if (askAgentCalls.length > 0) {
707
+ const validCalls = askAgentCalls.filter(c => c.agentId !== currentProfile.id);
708
+ const selfCalls = askAgentCalls.filter(c => c.agentId === currentProfile.id);
709
+ for (const call of selfCalls) {
710
+ const msg = `Self-delegation blocked: agent "${currentProfile.id}" cannot delegate to itself. Execute the task directly.`;
711
+ this.opts.transport.emit({ type: 'tool_result', name: 'ask_agent', success: false, preview: msg });
712
+ toolResults.push({ role: 'tool', tool_call_id: call.id, content: msg });
713
+ }
714
+ if (validCalls.length > 0) {
715
+ const requests = validCalls.map(c => ({
716
+ agentId: c.agentId,
717
+ question: c.question,
718
+ context: this.buildSubAgentContext(c.context, streamBuffer),
719
+ }));
720
+ const results = validCalls.length >= 2
721
+ ? await this.bus.runParallel(requests)
722
+ : [await this.bus.runSingle(requests[0])];
723
+ for (let i = 0; i < validCalls.length; i++) {
724
+ const call = validCalls[i];
725
+ const result = results[i];
726
+ const content = result.error ? `Error: ${result.error}` : result.content;
727
+ this.opts.transport.emit({ type: 'tool_result', name: 'ask_agent', success: !result.error, preview: content.slice(0, 120) });
728
+ toolResults.push({ role: 'tool', tool_call_id: call.id, content });
729
+ }
730
+ }
731
+ }
732
+ // ── other tools: sequential ───────────────────────────────────────
733
+ for (const call of otherCalls) {
734
+ if (this.aborted)
735
+ break;
736
+ iterManager.recordToolCall();
737
+ const result = await this.executeToolCall(call, currentProfile);
738
+ toolResults.push({ role: 'tool', tool_call_id: call.id, content: result });
739
+ }
740
+ // ── QA orchestration: runs when response is final (no tool calls) ─
741
+ if (toolResults.length === 0 && this.opts.orchestrator && this.opts.qaService && orchestrationResult) {
742
+ const qaAgentId = this.opts.agents.has('qa-engineer') ? 'qa-engineer' : undefined;
743
+ const qaCtx = {
744
+ clean: streamBuffer,
745
+ orchestrationResult,
746
+ orchestrator: this.opts.orchestrator,
747
+ qaService: this.opts.qaService,
748
+ allAgents: this.opts.agents.getAll(),
749
+ messages: this.messages,
750
+ effectiveAgentId: currentProfile.id,
751
+ defaultAgentId: this.opts.defaultAgentId,
752
+ qaAgentId,
753
+ noQA: this.opts.noQA,
754
+ onQAReview: this.opts.onQAReview,
755
+ setEffectiveAgent: (agentId) => {
756
+ const p = this.opts.agents.get(agentId);
757
+ if (p)
758
+ currentProfile = p;
759
+ },
760
+ };
761
+ await (0, qa_orchestrator_1.advanceRequiredGates)(qaCtx);
762
+ const qaProfile = (0, qa_orchestrator_1.activateQaEngineerIfNeeded)(qaCtx);
763
+ if (qaProfile) {
764
+ currentProfile = qaProfile;
765
+ continue; // re-enter loop as qa-engineer
766
+ }
767
+ if (qaAgentId && currentProfile.id === qaAgentId) {
768
+ await (0, qa_orchestrator_1.processQaEngineerResponse)(qaCtx);
769
+ currentProfile = profile; // reset to original agent
770
+ }
771
+ else {
772
+ await (0, qa_orchestrator_1.processInlineQaReview)(qaCtx);
773
+ }
774
+ }
775
+ if (toolResults.length === 0)
776
+ break;
777
+ this.messages.push(...toolResults);
778
+ }
779
+ this.opts.transport.emit({ type: 'block_end', status: 'ok', agent_id: profile.id });
780
+ }
781
+ async runAgentInternal(agentId, question, context) {
782
+ const profile = this.opts.agents.get(agentId);
783
+ if (!profile)
784
+ throw new Error(`Agent "${agentId}" not registered`);
785
+ const start = Date.now();
786
+ // Inject recent history from the orchestrator's conversation so specialists
787
+ // can see previously gathered data (file reads, command outputs, etc.)
788
+ // without requiring the orchestrator to manually copy it into context.
789
+ let historySlice = [];
790
+ const maxCtxMsgs = this.opts.subAgentContextMessages;
791
+ if (maxCtxMsgs && maxCtxMsgs > 0 && this.messages.length > 0) {
792
+ historySlice = this.messages.slice(-maxCtxMsgs);
793
+ // Trim to the first user-turn boundary to avoid orphaning tool results.
794
+ const firstUser = historySlice.findIndex(m => m.role === 'user');
795
+ if (firstUser > 0)
796
+ historySlice = historySlice.slice(firstUser);
797
+ else if (firstUser < 0)
798
+ historySlice = [];
799
+ // Sanitize: drop any tool messages whose assistant(tool_calls) was cut off
800
+ historySlice = sanitizeMessages(historySlice);
801
+ }
802
+ const messages = [
803
+ { role: 'system', content: this.buildSystemPrompt(profile) },
804
+ ...historySlice,
805
+ { role: 'user', content: context ? `${question}\n\nContexto:\n${context}` : question },
806
+ ];
807
+ let finalContent = '';
808
+ let totalInputTokens = 0;
809
+ let totalOutputTokens = 0;
810
+ const maxIter = 30;
811
+ let iter = 0;
812
+ this.opts.transport.emit({ type: 'block_start', agent_id: profile.id, agent_name: profile.name, agent_icon: profile.icon });
813
+ while (iter < maxIter) {
814
+ iter++;
815
+ let streamContent = '';
816
+ const toolCalls = [];
817
+ let finalMessage = null;
818
+ await this.getProviderForProfile(profile).chat(messages, this.getToolsForAgent(profile), {
819
+ onChunk: (delta) => {
820
+ streamContent += delta;
821
+ this.opts.transport.emit({ type: 'token', content: delta, agent_id: profile.id });
822
+ },
823
+ onToolCall: (name, args, id) => {
824
+ this.opts.transport.emit({ type: 'tool_call', name, args_preview: args.slice(0, 80) });
825
+ toolCalls.push({ id, name, args });
826
+ },
827
+ onDone: (msg) => { finalMessage = msg; },
828
+ onError: (err) => { throw err; },
829
+ onMetrics: (inputTokens, outputTokens) => {
830
+ totalInputTokens += inputTokens;
831
+ totalOutputTokens += outputTokens;
832
+ this.opts.transport.emit({ type: 'metrics', input_tokens: inputTokens, output_tokens: outputTokens });
833
+ },
834
+ });
835
+ if (!finalMessage)
836
+ break;
837
+ if (streamContent)
838
+ finalContent = streamContent;
839
+ messages.push(finalMessage);
840
+ if (toolCalls.length === 0)
841
+ break;
842
+ const toolResults = [];
843
+ for (const call of toolCalls) {
844
+ const result = await this.executeToolCall(call, profile);
845
+ toolResults.push({ role: 'tool', tool_call_id: call.id, content: result });
846
+ }
847
+ messages.push(...toolResults);
848
+ }
849
+ this.opts.transport.emit({ type: 'block_end', status: 'ok', agent_id: profile.id });
850
+ return { agentId, content: finalContent, inputTokens: totalInputTokens, outputTokens: totalOutputTokens, elapsedMs: Date.now() - start };
851
+ }
852
+ /**
853
+ * Unified tool execution used by both runLoop (primary agent) and
854
+ * runAgentInternal (sub-agents via ask_agent).
855
+ * Handles: allowedTools authorization → onToolApproval gate → execute → audit → transport.
856
+ */
857
+ async executeToolCall(call, profile) {
858
+ const callStart = Date.now();
859
+ const toolDef = this.opts.tools.get(call.name);
860
+ let result;
861
+ if (!toolDef) {
862
+ result = `Tool "${call.name}" not found`;
863
+ }
864
+ else if (!profile.allowedTools.includes(call.name) &&
865
+ (profile.allowedTools.length > 0 || (profile.delegatesTo && profile.delegatesTo.length > 0))) {
866
+ result = `Tool "${call.name}" is not authorized for agent "${profile.id}". ` +
867
+ `Use ask_agent to delegate to a specialist.`;
868
+ }
869
+ else if (this.opts.onToolApproval && this.requiresAlwaysAsk(call)) {
870
+ // High-blast-radius operations (npm install, pip install, etc.) always
871
+ // require approval — cannot be bypassed by approve_all or auto mode.
872
+ const preview = call.args.slice(0, 200);
873
+ this.opts.transport.emit({
874
+ type: 'tool_approval_request',
875
+ tool_name: call.name,
876
+ agent_id: profile.id,
877
+ args_preview: preview,
878
+ });
879
+ const decision = await this.opts.onToolApproval(call.name, profile.id, preview);
880
+ result = decision === 'reject'
881
+ ? `Tool call "${call.name}" was rejected by the user.`
882
+ : await this.runToolDef(call, toolDef, profile.id);
883
+ }
884
+ else if (!this.approvalDisabled &&
885
+ this.opts.onToolApproval &&
886
+ AgentEngine.WRITE_TOOLS.has(call.name)) {
887
+ const preview = call.args.slice(0, 200);
888
+ this.opts.transport.emit({
889
+ type: 'tool_approval_request',
890
+ tool_name: call.name,
891
+ agent_id: profile.id,
892
+ args_preview: preview,
893
+ });
894
+ const decision = await this.opts.onToolApproval(call.name, profile.id, preview);
895
+ if (decision === 'approve_all')
896
+ this.approvalDisabled = true;
897
+ result = decision === 'reject'
898
+ ? `Tool call "${call.name}" was rejected by the user.`
899
+ : await this.runToolDef(call, toolDef, profile.id);
900
+ }
901
+ else {
902
+ result = await this.runToolDef(call, toolDef, profile.id);
903
+ }
904
+ const success = !result.startsWith('Error:');
905
+ this.writeAuditRecord(profile.id, call.name, call.args, success, Date.now() - callStart);
906
+ this.opts.transport.emit({ type: 'tool_result', name: call.name, success, preview: result.slice(0, 120) });
907
+ return result;
908
+ }
909
+ async runToolDef(call, toolDef, agentId) {
910
+ const ctx = this.buildContext(agentId);
911
+ try {
912
+ const args = JSON.parse(call.args);
913
+ return await toolDef.execute(args, ctx);
914
+ }
915
+ catch (err) {
916
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
917
+ }
918
+ }
919
+ /**
920
+ * Returns true when a tool call matches a high-blast-radius pattern that
921
+ * always requires explicit approval — cannot be bypassed by approve_all or
922
+ * auto iteration mode.
923
+ */
924
+ requiresAlwaysAsk(call) {
925
+ if (call.name !== 'run_command')
926
+ return false;
927
+ try {
928
+ const { command } = JSON.parse(call.args);
929
+ if (!command)
930
+ return false;
931
+ return AgentEngine.ALWAYS_ASK_PATTERNS.some(re => re.test(command));
932
+ }
933
+ catch {
934
+ return false;
935
+ }
936
+ }
937
+ /**
938
+ * Disconnects an MCP server at runtime — reverts all tool assignments and
939
+ * command blocks it applied to local agents. After calling this, agents that
940
+ * had tools from this server lose them from allowedTools, and any commands
941
+ * that were blocked via blocksCommands are unblocked.
942
+ *
943
+ * For mode='agent' servers, the wrapper agent is also removed from the roster.
944
+ * For mode='tools' servers, agents fall back to shell commands automatically.
945
+ */
946
+ unregisterMCPServer(serverName) {
947
+ const safeName = serverName.replace(/[^a-zA-Z0-9_-]/g, '_');
948
+ // Revert tool assignments and command blocks on affected agents
949
+ const records = this.mcpAgentBlocks.get(safeName) ?? [];
950
+ for (const { agentId, toolNames, blockedCmds } of records) {
951
+ const agent = this.opts.agents.get(agentId);
952
+ if (agent) {
953
+ this.opts.agents.upsert({
954
+ ...agent,
955
+ allowedTools: agent.allowedTools.filter(t => !toolNames.includes(t)),
956
+ blockedCommands: (agent.blockedCommands ?? []).filter(c => !blockedCmds.includes(c)),
957
+ });
958
+ }
959
+ for (const toolName of toolNames) {
960
+ this.opts.tools.unregister(toolName);
961
+ }
962
+ }
963
+ this.mcpAgentBlocks.delete(safeName);
964
+ // Remove wrapper agent if mode='agent'
965
+ this.opts.agents.delete(safeName);
966
+ // Clean up routing tables
967
+ this.mcpTriggers.delete(safeName);
968
+ for (const [keyword, route] of this.mcpToolTriggers) {
969
+ if (route.agentId === safeName)
970
+ this.mcpToolTriggers.delete(keyword);
971
+ }
972
+ this.mcpRegisteredServers.delete(serverName);
973
+ this.opts.transport.emit({
974
+ type: 'system', level: 'info',
975
+ text: `[MCP:${serverName}] unregistered — tools removed, commands unblocked.`,
976
+ });
977
+ }
978
+ /** Disable approval gate for the rest of this session (approve_all). */
979
+ disableToolApproval() { this.approvalDisabled = true; }
980
+ /** Re-enable approval gate (e.g. after /iteration manual). */
981
+ enableToolApproval() { this.approvalDisabled = false; }
982
+ writeAuditRecord(agentId, tool, inputPreview, success, durationMs) {
983
+ if (!this.opts.auditLog)
984
+ return;
985
+ const line = JSON.stringify({
986
+ ts: new Date().toISOString(),
987
+ session: this.opts.sessionId ?? 'default',
988
+ agent: agentId,
989
+ tool,
990
+ input: inputPreview.slice(0, 200),
991
+ success,
992
+ durationMs,
993
+ });
994
+ (0, fs_1.appendFileSync)(this.opts.auditLog, line + '\n');
995
+ }
996
+ buildContext(agentId) {
997
+ const id = agentId ?? this.currentAgentId;
998
+ const profile = this.opts.agents.get(id);
999
+ return {
1000
+ agentId: id,
1001
+ sessionId: this.opts.sessionId ?? 'default',
1002
+ workingDir: this.opts.workingDir,
1003
+ memory: this.memory,
1004
+ store: this.opts.store,
1005
+ advancedMemory: this.opts.memorySystem,
1006
+ ...(profile?.blockedCommands?.length ? { blockedCommands: profile.blockedCommands } : {}),
1007
+ askAgent: async (agentId, question, context) => {
1008
+ const result = await this.bus.runSingle({ agentId, question, context });
1009
+ return result.content;
1010
+ },
1011
+ emitCompacting: (phase, label) => {
1012
+ this.opts.transport.emit({ type: 'compacting', phase, label });
1013
+ },
1014
+ llmCall: async (prompt) => {
1015
+ const profile = this.opts.agents.get(this.currentAgentId);
1016
+ if (!profile)
1017
+ return '';
1018
+ const provider = this.getProviderForProfile(profile);
1019
+ let result = '';
1020
+ await provider.chat([{ role: 'user', content: prompt }], [], {
1021
+ onChunk: (d) => { result += d; },
1022
+ onToolCall: () => { },
1023
+ onDone: () => { },
1024
+ onError: () => { },
1025
+ });
1026
+ return result.trim();
1027
+ },
1028
+ };
1029
+ }
1030
+ }
1031
+ exports.AgentEngine = AgentEngine;
1032
+ function toTitleCase(s) {
1033
+ return s
1034
+ .replace(/[-_](.)/g, (_, c) => ' ' + c.toUpperCase())
1035
+ .replace(/^(.)/, (c) => c.toUpperCase());
1036
+ }
1037
+ //# sourceMappingURL=AgentEngine.js.map