@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,174 @@
1
+ /**
2
+ * Tool supervision wrapper for pre-tool execution checks.
3
+ *
4
+ * Intercepts tool execution to run heuristics before the tool executes.
5
+ * This allows the supervision system to block or modify tool calls based
6
+ * on configured policies (e.g., preventing certain actions without approval).
7
+ */
8
+ import {
9
+ supervisorOrchestrator,
10
+ type PreToolContext,
11
+ } from "@/agents/supervision";
12
+ import type { ToolExecutionOptions } from "@ai-sdk/provider-utils";
13
+ import type { Tool as CoreTool } from "ai";
14
+ import { AgentEventDecoder } from "@/nostr/AgentEventDecoder";
15
+ import { buildSystemPromptMessages } from "@/prompts/utils/systemPromptBuilder";
16
+ import { NudgeService } from "@/services/nudge";
17
+ import { getProjectContext } from "@/services/projects";
18
+ import { RALRegistry } from "@/services/ral";
19
+ import { getToolsObject } from "@/tools/registry";
20
+ import type { FullRuntimeContext } from "./types";
21
+ import { formatAnyError } from "@/lib/error-formatter";
22
+ import { logger } from "@/utils/logger";
23
+
24
+ /**
25
+ * Wrap tools with pre-tool supervision checks.
26
+ *
27
+ * This function intercepts each tool's execute method to run supervision
28
+ * heuristics before the tool actually executes. If a violation is detected,
29
+ * the tool execution is blocked and a message is returned to the agent.
30
+ *
31
+ * @param toolsObject - The original tools object from the tool registry
32
+ * @param context - The full runtime context for the execution
33
+ * @returns A new tools object with wrapped execute methods
34
+ */
35
+ export function wrapToolsWithSupervision(
36
+ toolsObject: Record<string, CoreTool<unknown, unknown>>,
37
+ context: FullRuntimeContext
38
+ ): Record<string, CoreTool<unknown, unknown>> {
39
+ const wrappedTools: Record<string, CoreTool<unknown, unknown>> = {};
40
+ const ralRegistry = RALRegistry.getInstance();
41
+
42
+ for (const [toolName, tool] of Object.entries(toolsObject)) {
43
+ // Skip tools without execute function
44
+ if (!tool.execute) {
45
+ wrappedTools[toolName] = tool;
46
+ continue;
47
+ }
48
+
49
+ // Preserve the original tool's properties
50
+ const originalExecute = tool.execute.bind(tool);
51
+
52
+ // Create wrapped tool
53
+ wrappedTools[toolName] = {
54
+ ...tool,
55
+ execute: async (input: unknown, options: ToolExecutionOptions) => {
56
+ try {
57
+ // Build PreToolContext for this tool
58
+ const conversation = context.getConversation();
59
+ const conversationStore = context.conversationStore;
60
+
61
+ // Get system prompt and conversation history
62
+ const projectContext = getProjectContext();
63
+
64
+ // Fetch nudge content if triggering event has nudge tags
65
+ const preToolNudgeEventIds = AgentEventDecoder.extractNudgeEventIds(context.triggeringEvent);
66
+ const preToolNudgeContent = preToolNudgeEventIds.length > 0
67
+ ? await NudgeService.getInstance().fetchNudges(preToolNudgeEventIds)
68
+ : "";
69
+
70
+ const systemPromptMessages = await buildSystemPromptMessages({
71
+ agent: context.agent,
72
+ project: projectContext.project,
73
+ conversation,
74
+ projectBasePath: context.projectBasePath,
75
+ workingDirectory: context.workingDirectory,
76
+ currentBranch: context.currentBranch,
77
+ availableAgents: Array.from(projectContext.agents.values()),
78
+ mcpManager: projectContext.mcpManager,
79
+ agentLessons: projectContext.agentLessons,
80
+ nudgeContent: preToolNudgeContent,
81
+ });
82
+ const systemPrompt = systemPromptMessages.map(m => m.message.content).join("\n\n");
83
+
84
+ // Build conversation history from ConversationStore
85
+ const conversationMessages = await conversationStore.buildMessagesForRal(context.agent.pubkey, context.ralNumber);
86
+
87
+ // Get available tools
88
+ const toolNames = context.agent.tools || [];
89
+ const toolsForContext = toolNames.length > 0 ? getToolsObject(toolNames, context) : {};
90
+
91
+ // Build PreToolContext
92
+ const preToolContext: PreToolContext = {
93
+ agentSlug: context.agent.slug,
94
+ agentPubkey: context.agent.pubkey,
95
+ toolName,
96
+ toolArgs: input,
97
+ systemPrompt,
98
+ conversationHistory: conversationMessages,
99
+ availableTools: toolsForContext,
100
+ };
101
+
102
+ // Run pre-tool supervision check
103
+ logger.debug(`[ToolSupervisionWrapper] Running pre-tool supervision for "${toolName}"`, {
104
+ agent: context.agent.slug,
105
+ });
106
+
107
+ // Build executionId for heuristic enforcement tracking
108
+ const preToolExecutionId = `${context.agent.pubkey}:${context.conversationId}:${context.ralNumber}`;
109
+ const supervisionResult = await supervisorOrchestrator.checkPreTool(preToolContext, preToolExecutionId);
110
+
111
+ // If supervision detected a violation, block the tool
112
+ if (supervisionResult.hasViolation && supervisionResult.correctionAction) {
113
+ logger.warn(
114
+ `[ToolSupervisionWrapper] Pre-tool supervision blocked "${toolName}" execution`,
115
+ {
116
+ agent: context.agent.slug,
117
+ heuristic: supervisionResult.heuristicId,
118
+ actionType: supervisionResult.correctionAction.type,
119
+ }
120
+ );
121
+
122
+ // Mark this heuristic as enforced so it won't fire again in this RAL
123
+ if (supervisionResult.heuristicId) {
124
+ supervisorOrchestrator.markHeuristicEnforced(preToolExecutionId, supervisionResult.heuristicId);
125
+ }
126
+
127
+ // Queue correction message if available (for both inject-message and block-tool)
128
+ if (
129
+ supervisionResult.correctionAction.message &&
130
+ supervisionResult.correctionAction.reEngage
131
+ ) {
132
+ ralRegistry.queueUserMessage(
133
+ context.agent.pubkey,
134
+ context.conversationId,
135
+ context.ralNumber,
136
+ supervisionResult.correctionAction.message
137
+ );
138
+ }
139
+
140
+ // Return a blocked execution message
141
+ return `Tool execution blocked: ${supervisionResult.correctionAction.message || "This tool cannot be executed at this time."}`;
142
+ }
143
+
144
+ // No violation - execute the original tool
145
+ logger.debug(`[ToolSupervisionWrapper] Pre-tool supervision passed for "${toolName}"`, {
146
+ agent: context.agent.slug,
147
+ });
148
+
149
+ return await originalExecute(input, options);
150
+ } catch (error) {
151
+ logger.error("[ToolSupervisionWrapper] Error during pre-tool supervision check", {
152
+ tool: toolName,
153
+ error: formatAnyError(error),
154
+ });
155
+ // On supervision error, allow tool to execute (fail-safe)
156
+ return await originalExecute(input, options);
157
+ }
158
+ },
159
+ };
160
+
161
+ // Preserve non-enumerable properties like getHumanReadableContent
162
+ const toolWithCustomProps = tool as CoreTool<unknown, unknown> & {
163
+ getHumanReadableContent?: (args: unknown) => string;
164
+ };
165
+ if (toolWithCustomProps.getHumanReadableContent) {
166
+ Object.defineProperty(wrappedTools[toolName], "getHumanReadableContent", {
167
+ value: toolWithCustomProps.getHumanReadableContent,
168
+ enumerable: false,
169
+ });
170
+ }
171
+ }
172
+
173
+ return wrappedTools;
174
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Configuration constants for agent execution
3
+ */
4
+ export const ExecutionConfig = {
5
+ /** Delay in milliseconds after publishing typing indicator */
6
+ TOOL_INDICATOR_DELAY_MS: 100,
7
+
8
+ /** Default duration for tool execution when not tracked */
9
+ DEFAULT_TOOL_DURATION_MS: 1000,
10
+
11
+ /** Default timeout for shell commands in milliseconds (30 seconds) */
12
+ DEFAULT_COMMAND_TIMEOUT_MS: 30000,
13
+
14
+ /** Threshold for considering a phase transition as recent in milliseconds (30 seconds) */
15
+ RECENT_TRANSITION_THRESHOLD_MS: 30000,
16
+ } as const;
@@ -0,0 +1,3 @@
1
+ export * from "./AgentExecutor";
2
+ export * from "./ExecutionContextFactory";
3
+ export * from "./types";
@@ -0,0 +1,96 @@
1
+ import type { Tool as CoreTool, ModelMessage } from "ai";
2
+ import type { AgentInstance } from "@/agents/types";
3
+ import type { MessageCompiler } from "@/agents/execution/MessageCompiler";
4
+ import type { ConversationStore } from "@/conversations/ConversationStore";
5
+ import type { CompleteEvent } from "@/llm/types";
6
+ import type { AgentPublisher } from "@/nostr/AgentPublisher";
7
+ import type { MCPManager } from "@/services/mcp/MCPManager";
8
+ import type { ToolRegistryContext } from "@/tools/types";
9
+ import type { NDKEvent } from "@nostr-dev-kit/ndk";
10
+
11
+ /**
12
+ * Execution context for agent runs.
13
+ *
14
+ * This is the context created by createExecutionContext and enriched during execution.
15
+ * Runtime dependencies (agentPublisher, ralNumber, conversationStore) may not be
16
+ * available at creation time - they are added by prepareExecution().
17
+ *
18
+ * When passing context to tools via getToolsObject(), ensure all required fields
19
+ * are present (use ToolRegistryContext type to enforce this).
20
+ */
21
+ export interface ExecutionContext {
22
+ agent: AgentInstance;
23
+ conversationId: string;
24
+ projectBasePath: string;
25
+ workingDirectory: string;
26
+ currentBranch: string;
27
+ triggeringEvent: NDKEvent;
28
+ getConversation: () => ConversationStore | undefined;
29
+
30
+ // Runtime dependencies - added by prepareExecution()
31
+ agentPublisher?: AgentPublisher;
32
+ ralNumber?: number;
33
+ conversationStore?: ConversationStore;
34
+
35
+ // Execution flags
36
+ isDelegationCompletion?: boolean;
37
+ hasPendingDelegations?: boolean;
38
+ debug?: boolean;
39
+ mcpManager?: MCPManager;
40
+ }
41
+
42
+
43
+ /**
44
+ * Result of executeStreaming - discriminated union for clear error handling.
45
+ * - 'complete': Stream finished successfully with a completion event
46
+ * - 'error-handled': Stream error occurred and was already published to user
47
+ */
48
+ export type StreamExecutionResult =
49
+ | {
50
+ kind: "complete";
51
+ event: CompleteEvent;
52
+ aborted?: boolean;
53
+ /** The reason the execution was aborted (if aborted=true) */
54
+ abortReason?: string;
55
+ messageCompiler: MessageCompiler;
56
+ /** Accumulated LLM runtime in milliseconds (captured before RAL cleanup) */
57
+ accumulatedRuntime: number;
58
+ }
59
+ | { kind: "error-handled" };
60
+
61
+ /**
62
+ * Mutable context for RAL execution state during streaming.
63
+ *
64
+ * Makes explicit the state that coordinates between prepareStep and onStopCheck
65
+ * callbacks. Previously this was implicit closure variables.
66
+ */
67
+ export interface RALExecutionContext {
68
+ /**
69
+ * Messages accumulated from prepareStep callbacks.
70
+ * Updated in prepareStep (before each LLM step), read in onStopCheck.
71
+ * Contains messages up to but not including the current step.
72
+ */
73
+ accumulatedMessages: ModelMessage[];
74
+ }
75
+
76
+ /**
77
+ * Full runtime context for executor methods.
78
+ * Extends ToolRegistryContext with:
79
+ * - agent: AgentInstance (full agent type, not just ToolAgentInfo)
80
+ * - Execution-specific flags from ExecutionContext
81
+ */
82
+ export type FullRuntimeContext = Omit<ToolRegistryContext, "agent"> & {
83
+ agent: AgentInstance;
84
+ isDelegationCompletion?: boolean;
85
+ hasPendingDelegations?: boolean;
86
+ };
87
+
88
+ /**
89
+ * Request object for LLM completion preparation.
90
+ * Created by prepareLLMRequest() for external callers that need to prepare
91
+ * an LLM request without executing it (e.g., schema extraction).
92
+ */
93
+ export interface LLMCompletionRequest {
94
+ messages: ModelMessage[];
95
+ tools?: Record<string, CoreTool>;
96
+ }
@@ -0,0 +1,26 @@
1
+ import type { ModelMessage } from "ai";
2
+
3
+ /**
4
+ * Extract the text content from the last user message in the conversation.
5
+ * Handles both simple string content and complex content arrays (with text parts).
6
+ */
7
+ export function extractLastUserMessage(messages: ModelMessage[]): string | undefined {
8
+ // Find the last user message
9
+ for (let i = messages.length - 1; i >= 0; i--) {
10
+ const msg = messages[i];
11
+ if (msg.role === "user") {
12
+ // Handle simple string content
13
+ if (typeof msg.content === "string") {
14
+ return msg.content;
15
+ }
16
+ // Handle complex content arrays (e.g., [{ type: "text", text: "hello" }])
17
+ if (Array.isArray(msg.content)) {
18
+ const textParts = msg.content
19
+ .filter((part): part is { type: "text"; text: string } => part.type === "text")
20
+ .map(part => part.text);
21
+ return textParts.join("\n");
22
+ }
23
+ }
24
+ }
25
+ return undefined;
26
+ }
@@ -0,0 +1,4 @@
1
+ export { AgentRegistry } from "./AgentRegistry";
2
+ export * from "./execution";
3
+ export type { AgentInstance, AgentSummary } from "./types/runtime";
4
+ export type { AgentConfig, AgentConfigOptionalNsec, StoredAgentData } from "./types/storage";
@@ -0,0 +1,266 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import type NDK from "@nostr-dev-kit/ndk";
4
+ import type { NDKEvent } from "@nostr-dev-kit/ndk";
5
+ import { getAgentHomeDirectory } from "@/lib/agent-home";
6
+ import { ensureDirectory } from "@/lib/fs";
7
+ import { logger } from "@/utils/logger";
8
+
9
+ /**
10
+ * Information about a script file from a NIP-94 (kind 1063) event
11
+ */
12
+ export interface ScriptFileInfo {
13
+ eventId: string;
14
+ url: string;
15
+ relativePath: string;
16
+ mimeType?: string;
17
+ sha256?: string;
18
+ }
19
+
20
+ /**
21
+ * Result of downloading and installing a script
22
+ */
23
+ export interface ScriptInstallResult {
24
+ eventId: string;
25
+ relativePath: string;
26
+ absolutePath: string;
27
+ success: boolean;
28
+ error?: string;
29
+ }
30
+
31
+ const DOWNLOAD_TIMEOUT_MS = 30_000;
32
+
33
+ /**
34
+ * Extract script file information from a kind 1063 (NIP-94 file metadata) event.
35
+ *
36
+ * Expected tags:
37
+ * - ["url", "https://blossom.server/sha256"] - Required: Blossom download URL
38
+ * - ["name", "scripts/research.py"] - Required: Relative filepath from agent's home
39
+ * - ["m", "text/x-python"] - Optional: MIME type
40
+ * - ["x", "sha256hash"] - Optional: SHA-256 hash for verification
41
+ *
42
+ * @param event - The kind 1063 event to extract info from
43
+ * @returns Script file info or null if required tags are missing
44
+ */
45
+ export function extractScriptFileInfo(event: NDKEvent): ScriptFileInfo | null {
46
+ if (event.kind !== 1063) {
47
+ logger.warn(`Expected kind 1063 event, got kind ${event.kind}`);
48
+ return null;
49
+ }
50
+
51
+ const url = event.tagValue("url");
52
+ const relativePath = event.tagValue("name");
53
+
54
+ if (!url || !relativePath) {
55
+ logger.warn(`Kind 1063 event ${event.id} missing required tags`, {
56
+ hasUrl: !!url,
57
+ hasName: !!relativePath,
58
+ });
59
+ return null;
60
+ }
61
+
62
+ return {
63
+ eventId: event.id,
64
+ url,
65
+ relativePath,
66
+ mimeType: event.tagValue("m") || undefined,
67
+ sha256: event.tagValue("x") || undefined,
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Download a file from a Blossom URL
73
+ *
74
+ * @param url - The Blossom URL to download from
75
+ * @returns The downloaded file content as a Buffer
76
+ */
77
+ async function downloadFile(url: string): Promise<Buffer> {
78
+ const controller = new AbortController();
79
+ const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
80
+
81
+ try {
82
+ const response = await fetch(url, {
83
+ headers: {
84
+ "User-Agent": "TENEX/1.0 (Script Installer)",
85
+ },
86
+ signal: controller.signal,
87
+ });
88
+
89
+ if (!response.ok) {
90
+ throw new Error(`Failed to download: ${response.status} ${response.statusText}`);
91
+ }
92
+
93
+ const arrayBuffer = await response.arrayBuffer();
94
+ return Buffer.from(arrayBuffer);
95
+ } catch (error) {
96
+ if (error instanceof Error && error.name === "AbortError") {
97
+ throw new Error(`Download timed out after ${DOWNLOAD_TIMEOUT_MS}ms`);
98
+ }
99
+ throw error;
100
+ } finally {
101
+ clearTimeout(timeout);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Install a single script file to the agent's home directory.
107
+ *
108
+ * @param scriptInfo - Information about the script to install
109
+ * @param agentPubkey - The agent's public key (determines home directory)
110
+ * @returns Result of the installation
111
+ */
112
+ export async function installScriptFile(
113
+ scriptInfo: ScriptFileInfo,
114
+ agentPubkey: string
115
+ ): Promise<ScriptInstallResult> {
116
+ const homeDir = getAgentHomeDirectory(agentPubkey);
117
+ const absolutePath = path.join(homeDir, scriptInfo.relativePath);
118
+
119
+ try {
120
+ // Security check: ensure the path doesn't escape the home directory
121
+ const normalizedPath = path.normalize(absolutePath);
122
+ const normalizedHome = path.normalize(homeDir);
123
+ if (!normalizedPath.startsWith(normalizedHome)) {
124
+ throw new Error(
125
+ `Security violation: path "${scriptInfo.relativePath}" would escape agent home directory`
126
+ );
127
+ }
128
+
129
+ // Create parent directories
130
+ const parentDir = path.dirname(absolutePath);
131
+ await ensureDirectory(parentDir);
132
+
133
+ // Download the file
134
+ logger.debug(`Downloading script from ${scriptInfo.url}`);
135
+ const content = await downloadFile(scriptInfo.url);
136
+
137
+ // TODO: Verify SHA-256 hash if provided
138
+ // if (scriptInfo.sha256) {
139
+ // const hash = crypto.createHash('sha256').update(content).digest('hex');
140
+ // if (hash !== scriptInfo.sha256) {
141
+ // throw new Error(`SHA-256 mismatch: expected ${scriptInfo.sha256}, got ${hash}`);
142
+ // }
143
+ // }
144
+
145
+ // Write the file
146
+ await fs.writeFile(absolutePath, content);
147
+
148
+ // Make script executable if it's a script file
149
+ const ext = path.extname(scriptInfo.relativePath).toLowerCase();
150
+ const scriptExtensions = [".sh", ".py", ".rb", ".pl", ".js", ".ts"];
151
+ if (scriptExtensions.includes(ext)) {
152
+ await fs.chmod(absolutePath, 0o755);
153
+ }
154
+
155
+ logger.info(`Installed script: ${scriptInfo.relativePath}`, {
156
+ eventId: scriptInfo.eventId,
157
+ absolutePath,
158
+ size: content.length,
159
+ });
160
+
161
+ return {
162
+ eventId: scriptInfo.eventId,
163
+ relativePath: scriptInfo.relativePath,
164
+ absolutePath,
165
+ success: true,
166
+ };
167
+ } catch (error) {
168
+ const errorMessage = error instanceof Error ? error.message : String(error);
169
+ logger.error(`Failed to install script: ${scriptInfo.relativePath}`, {
170
+ eventId: scriptInfo.eventId,
171
+ error: errorMessage,
172
+ });
173
+
174
+ return {
175
+ eventId: scriptInfo.eventId,
176
+ relativePath: scriptInfo.relativePath,
177
+ absolutePath,
178
+ success: false,
179
+ error: errorMessage,
180
+ };
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Fetch and install all scripts referenced by e-tags in an agent definition.
186
+ *
187
+ * @param scriptETags - Array of script e-tag references from the agent definition
188
+ * @param agentPubkey - The agent's public key
189
+ * @param ndk - NDK instance for fetching events
190
+ * @returns Array of installation results
191
+ */
192
+ export async function installAgentScripts(
193
+ scriptETags: Array<{ eventId: string; relayUrl?: string }>,
194
+ agentPubkey: string,
195
+ ndk: NDK
196
+ ): Promise<ScriptInstallResult[]> {
197
+ if (scriptETags.length === 0) {
198
+ return [];
199
+ }
200
+
201
+ logger.info(`Installing ${scriptETags.length} script(s) for agent`, {
202
+ agentPubkey: agentPubkey.substring(0, 8),
203
+ });
204
+
205
+ const results: ScriptInstallResult[] = [];
206
+
207
+ for (const scriptRef of scriptETags) {
208
+ try {
209
+ // Fetch the 1063 event
210
+ logger.debug(`Fetching script event ${scriptRef.eventId}`);
211
+ const event = await ndk.fetchEvent(scriptRef.eventId, { groupable: false });
212
+
213
+ if (!event) {
214
+ results.push({
215
+ eventId: scriptRef.eventId,
216
+ relativePath: "unknown",
217
+ absolutePath: "unknown",
218
+ success: false,
219
+ error: `Could not fetch event ${scriptRef.eventId}`,
220
+ });
221
+ continue;
222
+ }
223
+
224
+ // Extract script info
225
+ const scriptInfo = extractScriptFileInfo(event);
226
+ if (!scriptInfo) {
227
+ results.push({
228
+ eventId: scriptRef.eventId,
229
+ relativePath: "unknown",
230
+ absolutePath: "unknown",
231
+ success: false,
232
+ error: "Event is not a valid kind 1063 file metadata event",
233
+ });
234
+ continue;
235
+ }
236
+
237
+ // Install the script
238
+ const result = await installScriptFile(scriptInfo, agentPubkey);
239
+ results.push(result);
240
+ } catch (error) {
241
+ const errorMessage = error instanceof Error ? error.message : String(error);
242
+ results.push({
243
+ eventId: scriptRef.eventId,
244
+ relativePath: "unknown",
245
+ absolutePath: "unknown",
246
+ success: false,
247
+ error: errorMessage,
248
+ });
249
+ }
250
+ }
251
+
252
+ // Log summary
253
+ const successCount = results.filter((r) => r.success).length;
254
+ const failCount = results.filter((r) => !r.success).length;
255
+
256
+ if (failCount > 0) {
257
+ logger.warn(`Script installation completed with errors`, {
258
+ success: successCount,
259
+ failed: failCount,
260
+ });
261
+ } else {
262
+ logger.info(`All scripts installed successfully`, { count: successCount });
263
+ }
264
+
265
+ return results;
266
+ }