@tenex-chat/backend 0.9.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 (427) hide show
  1. package/README.md +194 -0
  2. package/dist/backend-wrapper.cjs +3 -0
  3. package/dist/src/index.js +331928 -0
  4. package/package.json +103 -0
  5. package/src/agents/AgentRegistry.ts +418 -0
  6. package/src/agents/AgentStorage.ts +1133 -0
  7. package/src/agents/ConfigResolver.ts +229 -0
  8. package/src/agents/agent-installer.ts +236 -0
  9. package/src/agents/agent-loader.ts +241 -0
  10. package/src/agents/constants.ts +82 -0
  11. package/src/agents/errors.ts +48 -0
  12. package/src/agents/execution/AgentExecutor.ts +561 -0
  13. package/src/agents/execution/ExecutionContextFactory.ts +112 -0
  14. package/src/agents/execution/MessageCompiler.ts +597 -0
  15. package/src/agents/execution/MessageSyncer.ts +100 -0
  16. package/src/agents/execution/PostCompletionChecker.ts +278 -0
  17. package/src/agents/execution/ProgressMonitor.ts +50 -0
  18. package/src/agents/execution/RALResolver.ts +177 -0
  19. package/src/agents/execution/SessionManager.ts +181 -0
  20. package/src/agents/execution/StreamCallbacks.ts +312 -0
  21. package/src/agents/execution/StreamExecutionHandler.ts +579 -0
  22. package/src/agents/execution/StreamSetup.ts +313 -0
  23. package/src/agents/execution/ToolEventHandlers.ts +239 -0
  24. package/src/agents/execution/ToolExecutionTracker.ts +498 -0
  25. package/src/agents/execution/ToolResultUtils.ts +97 -0
  26. package/src/agents/execution/ToolSupervisionWrapper.ts +174 -0
  27. package/src/agents/execution/constants.ts +16 -0
  28. package/src/agents/execution/index.ts +3 -0
  29. package/src/agents/execution/types.ts +96 -0
  30. package/src/agents/execution/utils.ts +26 -0
  31. package/src/agents/index.ts +4 -0
  32. package/src/agents/script-installer.ts +266 -0
  33. package/src/agents/supervision/SupervisorLLMService.ts +253 -0
  34. package/src/agents/supervision/SupervisorOrchestrator.ts +471 -0
  35. package/src/agents/supervision/heuristics/ConsecutiveToolsWithoutTodoHeuristic.ts +73 -0
  36. package/src/agents/supervision/heuristics/DelegationClaimHeuristic.ts +80 -0
  37. package/src/agents/supervision/heuristics/HeuristicRegistry.ts +114 -0
  38. package/src/agents/supervision/heuristics/PendingTodosHeuristic.ts +93 -0
  39. package/src/agents/supervision/heuristics/SilentAgentHeuristic.ts +54 -0
  40. package/src/agents/supervision/heuristics/index.ts +5 -0
  41. package/src/agents/supervision/index.ts +28 -0
  42. package/src/agents/supervision/registerHeuristics.ts +110 -0
  43. package/src/agents/supervision/supervisionHealthCheck.ts +123 -0
  44. package/src/agents/supervision/types.ts +171 -0
  45. package/src/agents/tool-names.ts +46 -0
  46. package/src/agents/tool-normalization.ts +184 -0
  47. package/src/agents/types/index.ts +2 -0
  48. package/src/agents/types/runtime.ts +74 -0
  49. package/src/agents/types/storage.ts +145 -0
  50. package/src/commands/agent/import/index.ts +6 -0
  51. package/src/commands/agent/import/openclaw-distiller.ts +57 -0
  52. package/src/commands/agent/import/openclaw-reader.ts +141 -0
  53. package/src/commands/agent/import/openclaw.ts +154 -0
  54. package/src/commands/agent/index.ts +6 -0
  55. package/src/commands/agent.ts +215 -0
  56. package/src/commands/daemon.ts +198 -0
  57. package/src/commands/doctor.ts +134 -0
  58. package/src/commands/setup/embed.ts +228 -0
  59. package/src/commands/setup/global-system-prompt.ts +223 -0
  60. package/src/commands/setup/image.ts +179 -0
  61. package/src/commands/setup/index.ts +16 -0
  62. package/src/commands/setup/interactive.ts +95 -0
  63. package/src/commands/setup/llm.ts +38 -0
  64. package/src/commands/setup/onboarding.ts +294 -0
  65. package/src/commands/setup/providers.ts +27 -0
  66. package/src/constants.ts +34 -0
  67. package/src/conversations/ConversationDiskReader.ts +148 -0
  68. package/src/conversations/ConversationRegistry.ts +728 -0
  69. package/src/conversations/ConversationStore.ts +868 -0
  70. package/src/conversations/MessageBuilder.ts +866 -0
  71. package/src/conversations/executionTime.ts +62 -0
  72. package/src/conversations/formatters/DelegationXmlFormatter.ts +64 -0
  73. package/src/conversations/formatters/ThreadedConversationFormatter.ts +303 -0
  74. package/src/conversations/formatters/index.ts +9 -0
  75. package/src/conversations/formatters/utils/MessageFormatter.ts +46 -0
  76. package/src/conversations/formatters/utils/TimestampFormatter.ts +56 -0
  77. package/src/conversations/formatters/utils/TreeBuilder.ts +131 -0
  78. package/src/conversations/formatters/utils/TreeRenderer.ts +49 -0
  79. package/src/conversations/index.ts +2 -0
  80. package/src/conversations/persistence/ToolMessageStorage.ts +143 -0
  81. package/src/conversations/search/ConversationIndexManager.ts +393 -0
  82. package/src/conversations/search/QueryParser.ts +114 -0
  83. package/src/conversations/search/SearchEngine.ts +175 -0
  84. package/src/conversations/search/SnippetExtractor.ts +345 -0
  85. package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +484 -0
  86. package/src/conversations/search/embeddings/ConversationIndexingJob.ts +320 -0
  87. package/src/conversations/search/embeddings/IndexingStateManager.ts +338 -0
  88. package/src/conversations/search/embeddings/index.ts +18 -0
  89. package/src/conversations/search/index.ts +49 -0
  90. package/src/conversations/search/types.ts +124 -0
  91. package/src/conversations/services/CategoryManager.ts +160 -0
  92. package/src/conversations/services/ConversationResolver.ts +296 -0
  93. package/src/conversations/services/ConversationSummarizer.ts +234 -0
  94. package/src/conversations/services/MetadataDebounceManager.ts +188 -0
  95. package/src/conversations/services/index.ts +2 -0
  96. package/src/conversations/types.ts +148 -0
  97. package/src/conversations/utils/content-utils.ts +69 -0
  98. package/src/conversations/utils/image-placeholder.ts +281 -0
  99. package/src/conversations/utils/image-url-utils.ts +171 -0
  100. package/src/conversations/utils/multimodal-content.ts +90 -0
  101. package/src/conversations/utils/tool-result-truncator.ts +159 -0
  102. package/src/daemon/Daemon.ts +1883 -0
  103. package/src/daemon/ProjectRuntime.ts +657 -0
  104. package/src/daemon/RestartState.ts +152 -0
  105. package/src/daemon/RuntimeLifecycle.ts +268 -0
  106. package/src/daemon/SubscriptionManager.ts +305 -0
  107. package/src/daemon/UnixSocketTransport.ts +318 -0
  108. package/src/daemon/filters/SubscriptionFilterBuilder.ts +119 -0
  109. package/src/daemon/index.ts +9 -0
  110. package/src/daemon/routing/DaemonRouter.ts +491 -0
  111. package/src/daemon/types.ts +150 -0
  112. package/src/daemon/utils/routing-log.ts +76 -0
  113. package/src/daemon/utils/telemetry.ts +173 -0
  114. package/src/event-handler/agentDeletion.ts +383 -0
  115. package/src/event-handler/index.ts +749 -0
  116. package/src/event-handler/newConversation.ts +165 -0
  117. package/src/event-handler/project.ts +166 -0
  118. package/src/event-handler/reply.ts +18 -0
  119. package/src/events/NDKAgentDefinition.ts +292 -0
  120. package/src/events/NDKAgentLesson.ts +106 -0
  121. package/src/events/NDKEventMetadata.ts +34 -0
  122. package/src/events/NDKMCPTool.ts +60 -0
  123. package/src/events/NDKProjectStatus.ts +384 -0
  124. package/src/events/index.ts +4 -0
  125. package/src/index.ts +126 -0
  126. package/src/lib/agent-home.ts +334 -0
  127. package/src/lib/error-formatter.ts +200 -0
  128. package/src/lib/fs/filesystem.ts +128 -0
  129. package/src/lib/fs/index.ts +1 -0
  130. package/src/lib/json-parser.ts +30 -0
  131. package/src/lib/string.ts +15 -0
  132. package/src/lib/time.ts +74 -0
  133. package/src/llm/ChunkHandler.ts +277 -0
  134. package/src/llm/FinishHandler.ts +250 -0
  135. package/src/llm/LLMConfigEditor.ts +154 -0
  136. package/src/llm/LLMServiceFactory.ts +230 -0
  137. package/src/llm/MessageProcessor.ts +90 -0
  138. package/src/llm/RecordingState.ts +37 -0
  139. package/src/llm/StreamPublisher.ts +40 -0
  140. package/src/llm/TracingUtils.ts +77 -0
  141. package/src/llm/chunk-validators.ts +57 -0
  142. package/src/llm/constants.ts +6 -0
  143. package/src/llm/index.ts +12 -0
  144. package/src/llm/meta/MetaModelResolver.ts +352 -0
  145. package/src/llm/meta/index.ts +11 -0
  146. package/src/llm/middleware/flight-recorder.ts +188 -0
  147. package/src/llm/providers/MockProvider.ts +332 -0
  148. package/src/llm/providers/agent/ClaudeCodeProvider.ts +343 -0
  149. package/src/llm/providers/agent/ClaudeCodeToolsAdapter.ts +203 -0
  150. package/src/llm/providers/agent/CodexAppServerProvider.ts +214 -0
  151. package/src/llm/providers/agent/CodexAppServerToolsAdapter.ts +91 -0
  152. package/src/llm/providers/agent/index.ts +10 -0
  153. package/src/llm/providers/base/AgentProvider.ts +107 -0
  154. package/src/llm/providers/base/BaseProvider.ts +114 -0
  155. package/src/llm/providers/base/StandardProvider.ts +38 -0
  156. package/src/llm/providers/base/index.ts +9 -0
  157. package/src/llm/providers/index.ts +106 -0
  158. package/src/llm/providers/key-manager.ts +238 -0
  159. package/src/llm/providers/ollama-models.ts +105 -0
  160. package/src/llm/providers/openrouter-models.ts +102 -0
  161. package/src/llm/providers/provider-ids.ts +18 -0
  162. package/src/llm/providers/registry/ProviderRegistry.ts +414 -0
  163. package/src/llm/providers/registry/index.ts +7 -0
  164. package/src/llm/providers/standard/AnthropicProvider.ts +71 -0
  165. package/src/llm/providers/standard/OllamaProvider.ts +59 -0
  166. package/src/llm/providers/standard/OpenAIProvider.ts +44 -0
  167. package/src/llm/providers/standard/OpenRouterProvider.ts +103 -0
  168. package/src/llm/providers/standard/index.ts +10 -0
  169. package/src/llm/providers/types.ts +194 -0
  170. package/src/llm/providers/usage-metadata.ts +78 -0
  171. package/src/llm/service.ts +713 -0
  172. package/src/llm/types.ts +167 -0
  173. package/src/llm/utils/ConfigurationManager.ts +650 -0
  174. package/src/llm/utils/ConfigurationTester.ts +229 -0
  175. package/src/llm/utils/ModelSelector.ts +212 -0
  176. package/src/llm/utils/ProviderConfigUI.ts +177 -0
  177. package/src/llm/utils/claudeCodePromptCompiler.ts +141 -0
  178. package/src/llm/utils/codex-models.ts +53 -0
  179. package/src/llm/utils/context-window-cache.ts +30 -0
  180. package/src/llm/utils/models-dev-cache.ts +267 -0
  181. package/src/llm/utils/provider-setup.ts +50 -0
  182. package/src/llm/utils/tool-errors.ts +78 -0
  183. package/src/llm/utils/usage.ts +74 -0
  184. package/src/logging/EventRoutingLogger.ts +205 -0
  185. package/src/nostr/AgentEventDecoder.ts +357 -0
  186. package/src/nostr/AgentEventEncoder.ts +677 -0
  187. package/src/nostr/AgentProfilePublisher.ts +657 -0
  188. package/src/nostr/AgentPublisher.ts +437 -0
  189. package/src/nostr/BlossomService.ts +226 -0
  190. package/src/nostr/InterventionPublisher.ts +132 -0
  191. package/src/nostr/TagExtractor.ts +228 -0
  192. package/src/nostr/collectEvents.ts +83 -0
  193. package/src/nostr/constants.ts +38 -0
  194. package/src/nostr/encryption.ts +26 -0
  195. package/src/nostr/index.ts +31 -0
  196. package/src/nostr/keys.ts +17 -0
  197. package/src/nostr/kinds.ts +37 -0
  198. package/src/nostr/ndkClient.ts +72 -0
  199. package/src/nostr/relays.ts +43 -0
  200. package/src/nostr/trace-context.ts +39 -0
  201. package/src/nostr/types.ts +227 -0
  202. package/src/nostr/utils.ts +84 -0
  203. package/src/prompts/core/FragmentRegistry.ts +30 -0
  204. package/src/prompts/core/PromptBuilder.ts +98 -0
  205. package/src/prompts/core/index.ts +3 -0
  206. package/src/prompts/core/types.ts +13 -0
  207. package/src/prompts/fragments/00-global-system-prompt.ts +44 -0
  208. package/src/prompts/fragments/01-agent-identity.ts +69 -0
  209. package/src/prompts/fragments/02-agent-home-directory.ts +114 -0
  210. package/src/prompts/fragments/03-system-reminders-explanation.ts +14 -0
  211. package/src/prompts/fragments/04-relay-configuration.ts +38 -0
  212. package/src/prompts/fragments/05-delegation-chain.ts +45 -0
  213. package/src/prompts/fragments/06-agent-todos.ts +74 -0
  214. package/src/prompts/fragments/06-todo-usage-guidance.ts +34 -0
  215. package/src/prompts/fragments/07-meta-project-context.ts +234 -0
  216. package/src/prompts/fragments/08-active-conversations.ts +382 -0
  217. package/src/prompts/fragments/09-recent-conversations.ts +153 -0
  218. package/src/prompts/fragments/10-referenced-article.ts +21 -0
  219. package/src/prompts/fragments/11-nudges.ts +134 -0
  220. package/src/prompts/fragments/12-skills.ts +127 -0
  221. package/src/prompts/fragments/13-available-nudges.ts +122 -0
  222. package/src/prompts/fragments/15-available-agents.ts +53 -0
  223. package/src/prompts/fragments/16-stay-in-your-lane.ts +41 -0
  224. package/src/prompts/fragments/17-todo-before-delegation.ts +39 -0
  225. package/src/prompts/fragments/20-voice-mode.ts +62 -0
  226. package/src/prompts/fragments/22-scheduled-tasks.ts +175 -0
  227. package/src/prompts/fragments/24-retrieved-lessons.ts +26 -0
  228. package/src/prompts/fragments/25-rag-instructions.ts +333 -0
  229. package/src/prompts/fragments/26-mcp-resources.ts +237 -0
  230. package/src/prompts/fragments/27-memorized-reports.ts +77 -0
  231. package/src/prompts/fragments/28-agent-directed-monitoring.ts +32 -0
  232. package/src/prompts/fragments/29-rag-collections.ts +50 -0
  233. package/src/prompts/fragments/30-worktree-context.ts +98 -0
  234. package/src/prompts/fragments/31-agents-md-guidance.ts +96 -0
  235. package/src/prompts/fragments/32-process-metrics.ts +72 -0
  236. package/src/prompts/fragments/debug-mode.ts +48 -0
  237. package/src/prompts/fragments/delegation-completion.ts +44 -0
  238. package/src/prompts/fragments/index.ts +91 -0
  239. package/src/prompts/index.ts +21 -0
  240. package/src/prompts/utils/systemPromptBuilder.ts +777 -0
  241. package/src/scripts/migrate-prefix-index.ts +157 -0
  242. package/src/services/AgentDefinitionMonitor.ts +701 -0
  243. package/src/services/ConfigService.ts +723 -0
  244. package/src/services/CooldownRegistry.ts +199 -0
  245. package/src/services/LLMOperationsRegistry.ts +424 -0
  246. package/src/services/OwnerAgentListService.ts +354 -0
  247. package/src/services/PubkeyService.ts +308 -0
  248. package/src/services/agents/AgentMetadataStore.ts +72 -0
  249. package/src/services/agents/AgentResolution.ts +59 -0
  250. package/src/services/agents/EscalationService.ts +281 -0
  251. package/src/services/agents/NDKAgentDiscovery.ts +95 -0
  252. package/src/services/agents/index.ts +7 -0
  253. package/src/services/agents-md/AgentsMdService.ts +184 -0
  254. package/src/services/agents-md/SystemReminderInjector.ts +238 -0
  255. package/src/services/agents-md/index.ts +11 -0
  256. package/src/services/apns/APNsClient.ts +203 -0
  257. package/src/services/apns/APNsService.ts +358 -0
  258. package/src/services/apns/index.ts +11 -0
  259. package/src/services/apns/types.ts +80 -0
  260. package/src/services/compression/CompressionService.ts +445 -0
  261. package/src/services/compression/compression-schema.ts +28 -0
  262. package/src/services/compression/compression-types.ts +74 -0
  263. package/src/services/compression/compression-utils.ts +587 -0
  264. package/src/services/config/types.ts +394 -0
  265. package/src/services/dispatch/AgentDispatchService.ts +937 -0
  266. package/src/services/dispatch/AgentRouter.ts +181 -0
  267. package/src/services/dispatch/DelegationCompletionHandler.ts +232 -0
  268. package/src/services/embedding/EmbeddingProvider.ts +188 -0
  269. package/src/services/embedding/index.ts +5 -0
  270. package/src/services/event-context/EventContextService.ts +108 -0
  271. package/src/services/event-context/index.ts +2 -0
  272. package/src/services/heuristics/ContextBuilder.ts +106 -0
  273. package/src/services/heuristics/HeuristicEngine.ts +200 -0
  274. package/src/services/heuristics/formatters.ts +58 -0
  275. package/src/services/heuristics/index.ts +12 -0
  276. package/src/services/heuristics/rules/index.ts +25 -0
  277. package/src/services/heuristics/rules/todoBeforeDelegation.ts +69 -0
  278. package/src/services/heuristics/rules/todoReminderOnToolUse.ts +63 -0
  279. package/src/services/heuristics/types.ts +144 -0
  280. package/src/services/image/ImageGenerationService.ts +389 -0
  281. package/src/services/image/index.ts +12 -0
  282. package/src/services/intervention/InterventionService.ts +1352 -0
  283. package/src/services/intervention/index.ts +7 -0
  284. package/src/services/mcp/MCPManager.ts +683 -0
  285. package/src/services/mcp/McpNotificationDelivery.ts +139 -0
  286. package/src/services/mcp/McpSubscriptionService.ts +653 -0
  287. package/src/services/mcp/mcpInstaller.ts +130 -0
  288. package/src/services/nip46/Nip46SigningLog.ts +81 -0
  289. package/src/services/nip46/Nip46SigningService.ts +467 -0
  290. package/src/services/nip46/index.ts +4 -0
  291. package/src/services/nudge/NudgeService.ts +224 -0
  292. package/src/services/nudge/NudgeWhitelistService.ts +382 -0
  293. package/src/services/nudge/index.ts +5 -0
  294. package/src/services/nudge/types.ts +83 -0
  295. package/src/services/projects/ProjectContext.ts +672 -0
  296. package/src/services/projects/ProjectContextStore.ts +102 -0
  297. package/src/services/projects/index.ts +6 -0
  298. package/src/services/prompt-compiler/index.ts +15 -0
  299. package/src/services/prompt-compiler/prompt-compiler-service.ts +1143 -0
  300. package/src/services/pubkey-gate/PubkeyGateService.ts +93 -0
  301. package/src/services/pubkey-gate/index.ts +1 -0
  302. package/src/services/rag/EmbeddingProviderFactory.ts +292 -0
  303. package/src/services/rag/LanceDBMaintenanceService.ts +211 -0
  304. package/src/services/rag/RAGDatabaseService.ts +173 -0
  305. package/src/services/rag/RAGOperations.ts +682 -0
  306. package/src/services/rag/RAGService.ts +240 -0
  307. package/src/services/rag/RagSubscriptionService.ts +618 -0
  308. package/src/services/rag/rag-utils.ts +174 -0
  309. package/src/services/ral/PendingDelegationsRegistry.ts +168 -0
  310. package/src/services/ral/RALRegistry.ts +2782 -0
  311. package/src/services/ral/index.ts +4 -0
  312. package/src/services/ral/types.ts +292 -0
  313. package/src/services/reports/LocalReportStore.ts +380 -0
  314. package/src/services/reports/ReportEmbeddingService.ts +430 -0
  315. package/src/services/reports/ReportService.ts +440 -0
  316. package/src/services/reports/articleUtils.ts +52 -0
  317. package/src/services/reports/index.ts +7 -0
  318. package/src/services/scheduling/SchedulerService.ts +1057 -0
  319. package/src/services/scheduling/errors.ts +14 -0
  320. package/src/services/scheduling/index.ts +7 -0
  321. package/src/services/scheduling/utils.ts +77 -0
  322. package/src/services/search/SearchProviderRegistry.ts +78 -0
  323. package/src/services/search/UnifiedSearchService.ts +218 -0
  324. package/src/services/search/index.ts +47 -0
  325. package/src/services/search/projectFilter.ts +22 -0
  326. package/src/services/search/providers/ConversationSearchProvider.ts +48 -0
  327. package/src/services/search/providers/LessonSearchProvider.ts +75 -0
  328. package/src/services/search/providers/ReportSearchProvider.ts +49 -0
  329. package/src/services/search/types.ts +144 -0
  330. package/src/services/skill/SkillService.ts +482 -0
  331. package/src/services/skill/index.ts +2 -0
  332. package/src/services/skill/types.ts +70 -0
  333. package/src/services/status/OperationsStatusService.ts +276 -0
  334. package/src/services/status/ProjectStatusService.ts +522 -0
  335. package/src/services/status/index.ts +11 -0
  336. package/src/services/storage/PrefixKVStore.ts +242 -0
  337. package/src/services/storage/index.ts +1 -0
  338. package/src/services/system-reminder/SystemReminderUtils.ts +96 -0
  339. package/src/services/system-reminder/index.ts +7 -0
  340. package/src/services/trust-pubkeys/TrustPubkeyService.ts +325 -0
  341. package/src/services/trust-pubkeys/index.ts +2 -0
  342. package/src/telemetry/ConversationSpanManager.ts +111 -0
  343. package/src/telemetry/EventLoopMonitor.ts +206 -0
  344. package/src/telemetry/LLMSpanRegistry.ts +20 -0
  345. package/src/telemetry/NostrSpanProcessor.ts +89 -0
  346. package/src/telemetry/ToolCallSpanProcessor.ts +66 -0
  347. package/src/telemetry/diagnostics.ts +27 -0
  348. package/src/telemetry/setup.ts +120 -0
  349. package/src/tools/implementations/agents_discover.ts +121 -0
  350. package/src/tools/implementations/agents_hire.ts +127 -0
  351. package/src/tools/implementations/agents_list.ts +96 -0
  352. package/src/tools/implementations/agents_publish.ts +611 -0
  353. package/src/tools/implementations/agents_read.ts +173 -0
  354. package/src/tools/implementations/agents_write.ts +200 -0
  355. package/src/tools/implementations/ask.ts +411 -0
  356. package/src/tools/implementations/change_model.ts +141 -0
  357. package/src/tools/implementations/conversation_get.ts +661 -0
  358. package/src/tools/implementations/conversation_list.ts +377 -0
  359. package/src/tools/implementations/conversation_search.ts +370 -0
  360. package/src/tools/implementations/delegate.ts +327 -0
  361. package/src/tools/implementations/delegate_crossproject.ts +209 -0
  362. package/src/tools/implementations/delegate_followup.ts +300 -0
  363. package/src/tools/implementations/fs_edit.ts +162 -0
  364. package/src/tools/implementations/fs_glob.ts +182 -0
  365. package/src/tools/implementations/fs_grep.ts +513 -0
  366. package/src/tools/implementations/fs_read.ts +332 -0
  367. package/src/tools/implementations/fs_write.ts +113 -0
  368. package/src/tools/implementations/generate_image.ts +259 -0
  369. package/src/tools/implementations/home_fs.ts +515 -0
  370. package/src/tools/implementations/kill.ts +651 -0
  371. package/src/tools/implementations/learn.ts +166 -0
  372. package/src/tools/implementations/lesson-formatter.ts +38 -0
  373. package/src/tools/implementations/lesson_delete.ts +164 -0
  374. package/src/tools/implementations/lesson_get.ts +105 -0
  375. package/src/tools/implementations/lessons_list.ts +153 -0
  376. package/src/tools/implementations/mcp_resource_read.ts +161 -0
  377. package/src/tools/implementations/mcp_subscribe.ts +158 -0
  378. package/src/tools/implementations/mcp_subscription_stop.ts +85 -0
  379. package/src/tools/implementations/nostr_fetch.ts +149 -0
  380. package/src/tools/implementations/nostr_publish_as_user.ts +353 -0
  381. package/src/tools/implementations/project_list.ts +146 -0
  382. package/src/tools/implementations/rag_add_documents.ts +573 -0
  383. package/src/tools/implementations/rag_create_collection.ts +65 -0
  384. package/src/tools/implementations/rag_delete_collection.ts +68 -0
  385. package/src/tools/implementations/rag_list_collections.ts +77 -0
  386. package/src/tools/implementations/rag_query.ts +107 -0
  387. package/src/tools/implementations/rag_subscription_create.ts +105 -0
  388. package/src/tools/implementations/rag_subscription_delete.ts +80 -0
  389. package/src/tools/implementations/rag_subscription_get.ts +123 -0
  390. package/src/tools/implementations/rag_subscription_list.ts +128 -0
  391. package/src/tools/implementations/report_delete.ts +79 -0
  392. package/src/tools/implementations/report_read.ts +160 -0
  393. package/src/tools/implementations/report_write.ts +278 -0
  394. package/src/tools/implementations/reports_list.ts +77 -0
  395. package/src/tools/implementations/schedule_task.ts +104 -0
  396. package/src/tools/implementations/schedule_task_cancel.ts +62 -0
  397. package/src/tools/implementations/schedule_task_once.ts +128 -0
  398. package/src/tools/implementations/schedule_tasks_list.ts +79 -0
  399. package/src/tools/implementations/search.ts +160 -0
  400. package/src/tools/implementations/shell.ts +553 -0
  401. package/src/tools/implementations/todo.ts +260 -0
  402. package/src/tools/implementations/upload_blob.ts +381 -0
  403. package/src/tools/implementations/web_fetch.ts +153 -0
  404. package/src/tools/implementations/web_search.ts +250 -0
  405. package/src/tools/registry.ts +670 -0
  406. package/src/tools/types.ts +177 -0
  407. package/src/tools/utils.ts +256 -0
  408. package/src/types/event-ids.ts +320 -0
  409. package/src/types/index.ts +46 -0
  410. package/src/utils/agentFetcher.ts +107 -0
  411. package/src/utils/cli-error.ts +29 -0
  412. package/src/utils/conversation-id.ts +27 -0
  413. package/src/utils/conversation-utils.ts +1 -0
  414. package/src/utils/delegation-chain.ts +357 -0
  415. package/src/utils/error-handler.ts +42 -0
  416. package/src/utils/git/gitignore.ts +69 -0
  417. package/src/utils/git/index.ts +2 -0
  418. package/src/utils/git/initializeGitRepo.ts +204 -0
  419. package/src/utils/git/worktree.ts +260 -0
  420. package/src/utils/lessonFormatter.ts +70 -0
  421. package/src/utils/lessonTrust.ts +24 -0
  422. package/src/utils/lockfile.ts +123 -0
  423. package/src/utils/logger.ts +149 -0
  424. package/src/utils/nostr-entity-parser.ts +365 -0
  425. package/src/utils/process.ts +49 -0
  426. package/src/wrapper.ts +262 -0
  427. package/tsconfig.json +41 -0
@@ -0,0 +1,313 @@
1
+ /**
2
+ * StreamSetup - Handles pre-stream setup for LLM execution
3
+ *
4
+ * This module contains the setup logic that prepares everything needed
5
+ * before streaming begins: tool wrapping, session management, injection processing,
6
+ * meta model resolution, and initial message compilation.
7
+ */
8
+
9
+ import { AgentEventDecoder } from "@/nostr/AgentEventDecoder";
10
+ import { config as configService } from "@/services/ConfigService";
11
+ import { llmOpsRegistry } from "@/services/LLMOperationsRegistry";
12
+ import { NudgeService, NudgeSkillWhitelistService, type NudgeToolPermissions, type NudgeData } from "@/services/nudge";
13
+ import { SkillService, type SkillData } from "@/services/skill";
14
+ import { getProjectContext } from "@/services/projects";
15
+ import { RALRegistry } from "@/services/ral";
16
+ import { getToolsObject } from "@/tools/registry";
17
+ import { logger } from "@/utils/logger";
18
+ import type { ModelMessage } from "ai";
19
+ import { trace } from "@opentelemetry/api";
20
+ import type { LLMService } from "@/llm/service";
21
+ import { llmServiceFactory } from "@/llm/LLMServiceFactory";
22
+ import { MessageCompiler } from "./MessageCompiler";
23
+ import { SessionManager } from "./SessionManager";
24
+ import type { ToolExecutionTracker } from "./ToolExecutionTracker";
25
+ import { wrapToolsWithSupervision } from "./ToolSupervisionWrapper";
26
+ import type { FullRuntimeContext } from "./types";
27
+ import type { AISdkTool } from "@/tools/types";
28
+
29
+ /**
30
+ * Result of stream setup
31
+ */
32
+ export interface StreamSetupResult {
33
+ toolsObject: Record<string, AISdkTool>;
34
+ sessionManager: SessionManager;
35
+ llmService: LLMService;
36
+ messageCompiler: MessageCompiler;
37
+ messages: ModelMessage[];
38
+ ephemeralMessages: Array<{ role: "user" | "system"; content: string }>;
39
+ nudgeContent: string;
40
+ /** Individual nudge data for system prompt rendering */
41
+ nudges: NudgeData[];
42
+ /** Tool permissions extracted from nudge events */
43
+ nudgeToolPermissions: NudgeToolPermissions;
44
+ /** Concatenated skill content */
45
+ skillContent: string;
46
+ /** Individual skill data for system prompt rendering */
47
+ skills: SkillData[];
48
+ abortSignal: AbortSignal;
49
+ metaModelSystemPrompt?: string;
50
+ variantSystemPrompt?: string;
51
+ /** Optional dedicated LLM service for compression operations */
52
+ compressionLlmService?: LLMService;
53
+ }
54
+
55
+ /**
56
+ * Interface for injection processing
57
+ */
58
+ export interface InjectionProcessor {
59
+ warmSenderPubkeys(injections: Array<{ senderPubkey?: string }>): void;
60
+ }
61
+
62
+ /**
63
+ * Set up everything needed for stream execution
64
+ */
65
+ export async function setupStreamExecution(
66
+ context: FullRuntimeContext,
67
+ _toolTracker: ToolExecutionTracker, // Reserved for future use
68
+ ralNumber: number,
69
+ injectionProcessor: InjectionProcessor
70
+ ): Promise<StreamSetupResult> {
71
+ // === FETCH NUDGES FIRST ===
72
+ // Must fetch nudges BEFORE getToolsObject because nudges can modify available tools
73
+ const nudgeEventIds = AgentEventDecoder.extractNudgeEventIds(context.triggeringEvent);
74
+ const nudgeResult = nudgeEventIds.length > 0
75
+ ? await NudgeService.getInstance().fetchNudgesWithPermissions(nudgeEventIds)
76
+ : { nudges: [], content: "", toolPermissions: {} };
77
+
78
+ // === FETCH SKILLS ===
79
+ // Skills do NOT affect tools, but we fetch them early to download attached files
80
+ const skillEventIds = AgentEventDecoder.extractSkillEventIds(context.triggeringEvent);
81
+ const skillResult = skillEventIds.length > 0
82
+ ? await SkillService.getInstance().fetchSkills(skillEventIds)
83
+ : { skills: [], content: "" };
84
+
85
+ // Now get tools with nudge permissions applied
86
+ // IMPORTANT: Always call getToolsObject even with empty base tools,
87
+ // because nudge permissions (allow-tool, only-tool) can grant tools
88
+ // to agents that have no default tools configured.
89
+ const toolNames = context.agent.tools || [];
90
+ let toolsObject = getToolsObject(toolNames, context, nudgeResult.toolPermissions);
91
+
92
+ // Wrap tools with pre-tool supervision checks
93
+ toolsObject = wrapToolsWithSupervision(toolsObject, context);
94
+
95
+ const sessionManager = new SessionManager(
96
+ context.agent,
97
+ context.conversationId,
98
+ context.workingDirectory
99
+ );
100
+ const { sessionId } = sessionManager.getSession();
101
+
102
+ const ralRegistry = RALRegistry.getInstance();
103
+ const conversationStore = context.conversationStore;
104
+
105
+ // Register RAL in ConversationStore
106
+ conversationStore.ensureRalActive(context.agent.pubkey, ralNumber);
107
+
108
+ // Consume any pending injections BEFORE building messages
109
+ const initialInjections = ralRegistry.getAndConsumeInjections(
110
+ context.agent.pubkey,
111
+ context.conversationId,
112
+ ralNumber
113
+ );
114
+
115
+ // Collect ephemeral messages to pass to MessageCompiler
116
+ const ephemeralMessages: Array<{ role: "user" | "system"; content: string }> = [];
117
+
118
+ if (initialInjections.length > 0) {
119
+ // Best-effort profile warming (non-blocking)
120
+ injectionProcessor.warmSenderPubkeys(initialInjections);
121
+
122
+ for (const injection of initialInjections) {
123
+ if (injection.ephemeral) {
124
+ ephemeralMessages.push({
125
+ role: injection.role,
126
+ content: injection.content,
127
+ });
128
+ } else {
129
+ conversationStore.addMessage({
130
+ pubkey: context.triggeringEvent.pubkey,
131
+ ral: ralNumber,
132
+ content: injection.content,
133
+ messageType: "text",
134
+ targetedPubkeys: [context.agent.pubkey],
135
+ senderPubkey: injection.senderPubkey,
136
+ eventId: injection.eventId,
137
+ });
138
+ }
139
+ }
140
+
141
+ trace.getActiveSpan()?.addEvent("executor.initial_injections_consumed", {
142
+ "ral.number": ralNumber,
143
+ "injection.count": initialInjections.length,
144
+ "injection.ephemeral_count": ephemeralMessages.length,
145
+ });
146
+ }
147
+
148
+ const projectContext = getProjectContext();
149
+ const conversation = context.getConversation();
150
+ if (!conversation) {
151
+ throw new Error(`Conversation ${context.conversationId} not found`);
152
+ }
153
+
154
+ // Build MCP config from project's running MCP servers
155
+ // This allows Claude Code-based agents to spawn their own instances of external MCP servers
156
+ const projectMcpServers = projectContext.mcpManager?.getServerConfigs() ?? {};
157
+ const mcpConfig = Object.keys(projectMcpServers).length > 0
158
+ ? { enabled: true, servers: projectMcpServers }
159
+ : undefined;
160
+
161
+ if (mcpConfig) {
162
+ trace.getActiveSpan()?.addEvent("executor.mcp_config_prepared", {
163
+ "mcp.server_count": Object.keys(projectMcpServers).length,
164
+ "mcp.servers": Object.keys(projectMcpServers).join(", "),
165
+ });
166
+ }
167
+
168
+ // Use already-fetched nudge content (fetched at the top of this function)
169
+ const nudgeContent = nudgeResult.content;
170
+
171
+ const abortSignal = llmOpsRegistry.registerOperation(context);
172
+
173
+ // === META MODEL RESOLUTION ===
174
+ let resolvedConfigName: string | undefined;
175
+ let metaModelSystemPrompt: string | undefined;
176
+ let variantSystemPrompt: string | undefined;
177
+
178
+ if (configService.isMetaModelConfig(context.agent.llmConfig)) {
179
+ const variantOverride = conversationStore.getMetaModelVariantOverride(context.agent.pubkey);
180
+ const firstUserMessage = conversationStore.getFirstUserMessage();
181
+
182
+ const resolution = configService.resolveMetaModel(
183
+ context.agent.llmConfig,
184
+ firstUserMessage?.content,
185
+ variantOverride
186
+ );
187
+
188
+ if (resolution.isMetaModel) {
189
+ resolvedConfigName = resolution.configName;
190
+ metaModelSystemPrompt = resolution.metaModelSystemPrompt;
191
+ variantSystemPrompt = resolution.variantSystemPrompt;
192
+
193
+ if (
194
+ !variantOverride &&
195
+ resolution.strippedMessage !== undefined &&
196
+ resolution.strippedMessage !== firstUserMessage?.content &&
197
+ firstUserMessage
198
+ ) {
199
+ conversationStore.updateMessageContent(firstUserMessage.id, resolution.strippedMessage);
200
+ }
201
+
202
+ trace.getActiveSpan()?.addEvent("executor.meta_model_resolved", {
203
+ "meta_model.original_config": context.agent.llmConfig,
204
+ "meta_model.resolved_config": resolvedConfigName,
205
+ "meta_model.variant": resolution.variantName || "default",
206
+ "meta_model.used_override": !!variantOverride,
207
+ });
208
+ }
209
+ }
210
+
211
+ const llmService = context.agent.createLLMService({
212
+ tools: toolsObject,
213
+ sessionId,
214
+ workingDirectory: context.workingDirectory,
215
+ conversationId: context.conversationId,
216
+ resolvedConfigName,
217
+ mcpConfig,
218
+ onStreamStart: (injector) => {
219
+ llmOpsRegistry.setMessageInjector(
220
+ context.agent.pubkey,
221
+ context.conversationId,
222
+ injector
223
+ );
224
+ logger.debug("[StreamSetup] Message injector registered", {
225
+ agent: context.agent.slug,
226
+ conversationId: context.conversationId.substring(0, 8),
227
+ });
228
+ },
229
+ });
230
+
231
+ // Resolve optional dedicated compression LLM service
232
+ let compressionLlmService: LLMService | undefined;
233
+ const { llms } = await configService.loadConfig();
234
+ if (llms.compression) {
235
+ const compressionConfig = configService.getLLMConfig(llms.compression);
236
+ compressionLlmService = llmServiceFactory.createService(compressionConfig, {
237
+ agentName: `${context.agent.slug}-compression`,
238
+ sessionId: `compression-${context.conversationId.substring(0, 8)}`,
239
+ });
240
+ }
241
+
242
+ const messageCompiler = new MessageCompiler(
243
+ llmService.provider,
244
+ sessionManager,
245
+ conversationStore,
246
+ llmService,
247
+ compressionLlmService
248
+ );
249
+
250
+ const pendingDelegations = ralRegistry.getConversationPendingDelegations(
251
+ context.agent.pubkey,
252
+ context.conversationId,
253
+ ralNumber
254
+ );
255
+ const completedDelegations = ralRegistry.getConversationCompletedDelegations(
256
+ context.agent.pubkey,
257
+ context.conversationId,
258
+ ralNumber
259
+ );
260
+
261
+ const { messages, counts, mode } = await messageCompiler.compile({
262
+ agent: context.agent,
263
+ project: projectContext.project,
264
+ conversation,
265
+ projectBasePath: context.projectBasePath,
266
+ workingDirectory: context.workingDirectory,
267
+ currentBranch: context.currentBranch,
268
+ availableAgents: Array.from(projectContext.agents.values()),
269
+ mcpManager: projectContext.mcpManager,
270
+ agentLessons: projectContext.agentLessons,
271
+ agentComments: projectContext.agentComments,
272
+ nudgeContent,
273
+ nudges: nudgeResult.nudges,
274
+ nudgeToolPermissions: nudgeResult.toolPermissions,
275
+ skillContent: skillResult.content,
276
+ skills: skillResult.skills,
277
+ respondingToPubkey: context.triggeringEvent.pubkey,
278
+ pendingDelegations,
279
+ completedDelegations,
280
+ ralNumber,
281
+ metaModelSystemPrompt,
282
+ variantSystemPrompt,
283
+ ephemeralMessages,
284
+ availableNudges: NudgeSkillWhitelistService.getInstance().getWhitelistedNudges(),
285
+ availableSkills: NudgeSkillWhitelistService.getInstance().getWhitelistedSkills(),
286
+ });
287
+
288
+ trace.getActiveSpan()?.addEvent("executor.messages_built_from_store", {
289
+ "ral.number": ralNumber,
290
+ "message.count": counts.total,
291
+ "system_prompt.count": counts.systemPrompt,
292
+ "conversation.count": counts.conversation,
293
+ "message.mode": mode,
294
+ });
295
+
296
+ return {
297
+ toolsObject,
298
+ sessionManager,
299
+ llmService,
300
+ messageCompiler,
301
+ messages,
302
+ ephemeralMessages,
303
+ nudgeContent,
304
+ nudges: nudgeResult.nudges,
305
+ nudgeToolPermissions: nudgeResult.toolPermissions,
306
+ skillContent: skillResult.content,
307
+ skills: skillResult.skills,
308
+ abortSignal,
309
+ metaModelSystemPrompt,
310
+ variantSystemPrompt,
311
+ compressionLlmService,
312
+ };
313
+ }
@@ -0,0 +1,239 @@
1
+ /**
2
+ * ToolEventHandlers - Handles tool-will-execute and tool-did-execute events
3
+ *
4
+ * This module provides setup functions for tool execution event handlers
5
+ * that manage RAL state, conversation store updates, and delegation tracking.
6
+ */
7
+
8
+ import { ConversationStore } from "@/conversations/ConversationStore";
9
+ import { RALRegistry, extractPendingDelegations } from "@/services/ral";
10
+ import type { AISdkTool } from "@/tools/types";
11
+ import { logger } from "@/utils/logger";
12
+ import { trace } from "@opentelemetry/api";
13
+ import type { ToolCallPart, ToolResultPart } from "ai";
14
+ import chalk from "chalk";
15
+ import type { ToolWillExecuteEvent, ToolDidExecuteEvent } from "@/llm/types";
16
+ import type { LLMService } from "@/llm/service";
17
+ import type { EventContext } from "@/nostr/types";
18
+ import type { ToolExecutionTracker } from "./ToolExecutionTracker";
19
+ import type { FullRuntimeContext } from "./types";
20
+ import { getHeuristicEngine } from "@/services/heuristics";
21
+ import { buildHeuristicContext } from "@/services/heuristics/ContextBuilder";
22
+
23
+ /**
24
+ * Configuration for setting up tool event handlers
25
+ */
26
+ export interface ToolEventHandlersConfig {
27
+ context: FullRuntimeContext;
28
+ llmService: LLMService;
29
+ toolTracker: ToolExecutionTracker;
30
+ toolsObject: Record<string, AISdkTool>;
31
+ eventContext: EventContext;
32
+ ralNumber: number;
33
+ }
34
+
35
+ /**
36
+ * Setup tool-will-execute and tool-did-execute event handlers
37
+ */
38
+ export function setupToolEventHandlers(config: ToolEventHandlersConfig): void {
39
+ const { context, llmService, toolTracker, toolsObject, eventContext, ralNumber } = config;
40
+ const conversationStore = context.conversationStore;
41
+ const agentPublisher = context.agentPublisher;
42
+ const ralRegistry = RALRegistry.getInstance();
43
+
44
+ llmService.on("tool-will-execute", async (event: ToolWillExecuteEvent) => {
45
+ const argsStr = event.args !== undefined ? JSON.stringify(event.args) : "";
46
+ const argsPreview = argsStr.substring(0, 50);
47
+ console.log(
48
+ chalk.yellow(`\n\u{1F527} ${event.toolName}(${argsPreview}${argsStr.length > 50 ? "..." : ""})`)
49
+ );
50
+
51
+ ralRegistry.setToolActive(
52
+ context.agent.pubkey,
53
+ context.conversationId,
54
+ ralNumber,
55
+ event.toolCallId,
56
+ true,
57
+ event.toolName
58
+ );
59
+
60
+ // === HEURISTIC: Store tool args for later retrieval ===
61
+ // This enables BLOCKER 2 fix: pass real args to heuristics, not result
62
+ ralRegistry.storeToolArgs(
63
+ context.agent.pubkey,
64
+ context.conversationId,
65
+ ralNumber,
66
+ event.toolCallId,
67
+ event.args
68
+ );
69
+
70
+ // === HEURISTIC: Update O(1) summary ===
71
+ // Track tool execution for heuristic evaluation (BLOCKER 1 fix)
72
+ ralRegistry.updateHeuristicSummary(
73
+ context.agent.pubkey,
74
+ context.conversationId,
75
+ ralNumber,
76
+ event.toolName,
77
+ event.args
78
+ );
79
+
80
+ conversationStore.addMessage({
81
+ pubkey: context.agent.pubkey,
82
+ ral: ralNumber,
83
+ content: "",
84
+ messageType: "tool-call",
85
+ toolData: [
86
+ {
87
+ type: "tool-call",
88
+ toolCallId: event.toolCallId,
89
+ toolName: event.toolName,
90
+ input: event.args ?? {},
91
+ },
92
+ ] as ToolCallPart[],
93
+ });
94
+
95
+ const toolEvent = await toolTracker.trackExecution({
96
+ toolCallId: event.toolCallId,
97
+ toolName: event.toolName,
98
+ args: event.args,
99
+ toolsObject,
100
+ agentPublisher,
101
+ eventContext,
102
+ usage: event.usage,
103
+ });
104
+
105
+ if (toolEvent) {
106
+ await ConversationStore.addEvent(context.conversationId, toolEvent);
107
+ }
108
+ });
109
+
110
+ llmService.on("tool-did-execute", async (event: ToolDidExecuteEvent) => {
111
+ const toolResultMessageIndex = conversationStore.addMessage({
112
+ pubkey: context.agent.pubkey,
113
+ ral: ralNumber,
114
+ content: "",
115
+ messageType: "tool-result",
116
+ toolData: [
117
+ {
118
+ type: "tool-result" as const,
119
+ toolCallId: event.toolCallId,
120
+ toolName: event.toolName,
121
+ output:
122
+ event.result !== undefined
123
+ ? { type: "json" as const, value: event.result }
124
+ : { type: "text" as const, value: "" },
125
+ },
126
+ ] as ToolResultPart[],
127
+ });
128
+
129
+ // Check for StopExecutionSignal in tool result
130
+ const delegationsFromResult = extractPendingDelegations(event.result);
131
+ if (delegationsFromResult && delegationsFromResult.length > 0) {
132
+ trace.getActiveSpan()?.addEvent("executor.delegation_detected_in_tool_result", {
133
+ "ral.number": ralNumber,
134
+ "tool.name": event.toolName,
135
+ "delegation.count": delegationsFromResult.length,
136
+ });
137
+
138
+ // Use atomic merge to safely handle concurrent tool executions
139
+ // that may each produce delegation results
140
+ const { insertedCount, mergedCount } = ralRegistry.mergePendingDelegations(
141
+ context.agent.pubkey,
142
+ context.conversationId,
143
+ ralNumber,
144
+ delegationsFromResult
145
+ );
146
+
147
+ const totalPending = ralRegistry.getConversationPendingDelegations(
148
+ context.agent.pubkey,
149
+ context.conversationId,
150
+ ralNumber
151
+ ).length;
152
+
153
+ logger.info("[ToolEventHandlers] Registered pending delegations from tool result", {
154
+ agent: context.agent.slug,
155
+ ralNumber,
156
+ toolName: event.toolName,
157
+ delegationCount: delegationsFromResult.length,
158
+ insertedCount,
159
+ mergedCount,
160
+ totalPending,
161
+ });
162
+ }
163
+
164
+ // === HEURISTIC EVALUATION POST-TOOL ===
165
+ // Evaluate heuristics after tool execution to detect pattern violations
166
+ try {
167
+ const heuristicEngine = getHeuristicEngine();
168
+
169
+ // Retrieve stored tool args (BLOCKER 2 fix: use real args, not result)
170
+ const storedArgs = ralRegistry.getToolArgs(
171
+ context.agent.pubkey,
172
+ context.conversationId,
173
+ ralNumber,
174
+ event.toolCallId
175
+ );
176
+
177
+ // Build O(1) context from current RAL state
178
+ const heuristicContext = buildHeuristicContext({
179
+ agentPubkey: context.agent.pubkey,
180
+ conversationId: context.conversationId,
181
+ ralNumber,
182
+ toolName: event.toolName,
183
+ toolCallId: event.toolCallId,
184
+ toolArgs: storedArgs ?? {}, // Use stored args (fallback to empty object)
185
+ toolResult: event.result,
186
+ ralRegistry,
187
+ conversationStore,
188
+ currentBranch: context.currentBranch,
189
+ });
190
+
191
+ // Evaluate all heuristics (with hard error boundaries)
192
+ const violations = heuristicEngine.evaluate(heuristicContext);
193
+
194
+ // Add violations to RAL state for injection in next LLM step
195
+ if (violations.length > 0) {
196
+ ralRegistry.addHeuristicViolations(
197
+ context.agent.pubkey,
198
+ context.conversationId,
199
+ ralNumber,
200
+ violations
201
+ );
202
+ }
203
+
204
+ // Clean up stored tool args to prevent memory leak
205
+ ralRegistry.clearToolArgs(
206
+ context.agent.pubkey,
207
+ context.conversationId,
208
+ ralNumber,
209
+ event.toolCallId
210
+ );
211
+ } catch (error) {
212
+ // HARD ERROR BOUNDARY: Never crash tool pipeline
213
+ logger.error("[ToolEventHandlers] Heuristic evaluation failed", {
214
+ error: error instanceof Error ? error.message : String(error),
215
+ toolName: event.toolName,
216
+ });
217
+ }
218
+
219
+ const toolEventId = await toolTracker.completeExecution({
220
+ toolCallId: event.toolCallId,
221
+ result: event.result,
222
+ error: event.error ?? false,
223
+ agentPubkey: context.agent.pubkey,
224
+ });
225
+
226
+ if (toolEventId) {
227
+ conversationStore.setEventId(toolResultMessageIndex, toolEventId);
228
+ }
229
+
230
+ ralRegistry.setToolActive(
231
+ context.agent.pubkey,
232
+ context.conversationId,
233
+ ralNumber,
234
+ event.toolCallId,
235
+ false,
236
+ event.toolName
237
+ );
238
+ });
239
+ }