@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,161 @@
1
+ import type { ToolExecutionContext } from "@/tools/types";
2
+ import type { AISdkTool } from "@/tools/types";
3
+ import { type ToolResponse, createExpectedError } from "@/tools/utils";
4
+ import { extractAgentMcpServers } from "@/prompts/fragments/26-mcp-resources";
5
+ import { getProjectContext } from "@/services/projects";
6
+ import { tool } from "ai";
7
+ import { z } from "zod";
8
+
9
+ /**
10
+ * Schema for reading an MCP resource
11
+ */
12
+ const mcpResourceReadSchema = z.object({
13
+ serverName: z.string().describe('MCP server name (e.g., "nostr-provider")'),
14
+ resourceUri: z.string().describe('Resource URI to read (e.g., "file:///path/to/file")'),
15
+ templateParams: z
16
+ .record(z.string(), z.string())
17
+ .optional()
18
+ .describe('Parameters for template expansion (e.g., {"pubkey": "abc123"})'),
19
+ description: z.string().describe("Why you are reading this resource"),
20
+ });
21
+
22
+ /**
23
+ * Expand a resource URI template with parameters.
24
+ * Replaces {param} placeholders with actual values.
25
+ */
26
+ function expandUriTemplate(uriTemplate: string, params: Record<string, string>): string {
27
+ let expandedUri = uriTemplate;
28
+ for (const [key, value] of Object.entries(params)) {
29
+ expandedUri = expandedUri.replace(new RegExp(`\\{${key}\\}`, "g"), value);
30
+ }
31
+ return expandedUri;
32
+ }
33
+
34
+ /**
35
+ * Core implementation of reading an MCP resource
36
+ */
37
+ async function executeReadResource(
38
+ input: z.infer<typeof mcpResourceReadSchema>,
39
+ context: ToolExecutionContext
40
+ ): Promise<ToolResponse | ReturnType<typeof createExpectedError>> {
41
+ const { serverName, resourceUri, templateParams, description } = input;
42
+
43
+ // Get MCPManager from project context
44
+ const projectContext = getProjectContext();
45
+ const mcpManager = projectContext.mcpManager;
46
+
47
+ if (!mcpManager) {
48
+ throw new Error(
49
+ "MCP manager not available. This is a system error - MCP should be initialized."
50
+ );
51
+ }
52
+
53
+ // Validate agent has access to this server
54
+ const agentMcpServers = extractAgentMcpServers(context.agent.tools);
55
+
56
+ if (!agentMcpServers.includes(serverName)) {
57
+ return createExpectedError(
58
+ `You do not have access to MCP server '${serverName}'. ` +
59
+ `You can only read resources from servers you have tools from. ` +
60
+ `Your accessible servers: ${agentMcpServers.length > 0 ? agentMcpServers.join(", ") : "none"}`
61
+ );
62
+ }
63
+
64
+ // Check if server is running
65
+ const runningServers = mcpManager.getRunningServers();
66
+ if (!runningServers.includes(serverName)) {
67
+ return createExpectedError(
68
+ `MCP server '${serverName}' is not running. ` +
69
+ `Running servers: ${runningServers.length > 0 ? runningServers.join(", ") : "none"}`
70
+ );
71
+ }
72
+
73
+ // Expand template if params provided
74
+ const expandedUri = templateParams ? expandUriTemplate(resourceUri, templateParams) : resourceUri;
75
+
76
+ // Check if URI still has unfilled placeholders
77
+ if (expandedUri.includes("{") && expandedUri.includes("}")) {
78
+ return createExpectedError(
79
+ `Resource URI contains unfilled template parameters: ${expandedUri}. ` +
80
+ "Please provide all required parameters via templateParams."
81
+ );
82
+ }
83
+
84
+ try {
85
+ // Read the resource
86
+ const result = await mcpManager.readResource(serverName, expandedUri);
87
+
88
+ // Format the content for return
89
+ const formattedContents: string[] = [];
90
+
91
+ for (const content of result.contents) {
92
+ if ("text" in content && typeof content.text === "string") {
93
+ formattedContents.push(content.text);
94
+ } else if ("blob" in content && typeof content.blob === "string") {
95
+ formattedContents.push(
96
+ `[Binary content: ${content.blob.length} bytes, MIME type: ${content.mimeType || "unknown"}]`
97
+ );
98
+ }
99
+ }
100
+
101
+ return {
102
+ success: true,
103
+ message: `Successfully read resource from MCP server '${serverName}'`,
104
+ resourceUri: expandedUri,
105
+ serverName,
106
+ description,
107
+ content: formattedContents.join("\n\n"),
108
+ mimeType: result.contents[0]?.mimeType,
109
+ };
110
+ } catch (error) {
111
+ // MCP resource not found or other expected errors
112
+ const errorMessage = error instanceof Error ? error.message : String(error);
113
+
114
+ if (
115
+ errorMessage.toLowerCase().includes("not found") ||
116
+ errorMessage.toLowerCase().includes("does not exist")
117
+ ) {
118
+ return createExpectedError(
119
+ `Resource '${expandedUri}' not found on MCP server '${serverName}'. ` +
120
+ `Please verify the URI is correct.`
121
+ );
122
+ }
123
+
124
+ // Other MCP errors - return as expected error (user-facing)
125
+ return createExpectedError(
126
+ `Failed to read resource '${expandedUri}' from MCP server '${serverName}': ${errorMessage}`
127
+ );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Read content from an MCP resource on-demand.
133
+ *
134
+ * This tool provides immediate access to MCP resource content without setting up
135
+ * a persistent subscription. You can only read resources from MCP servers you have
136
+ * tools from (servers where you have mcp__serverName__* tools).
137
+ *
138
+ * Example use cases:
139
+ * - Read a configuration file from an MCP server
140
+ * - Fetch current state from a resource template
141
+ * - Access documentation or reference data
142
+ *
143
+ * For continuous updates, use rag_subscription_create instead.
144
+ */
145
+ export function createMcpResourceReadTool(context: ToolExecutionContext): AISdkTool {
146
+ return tool({
147
+ description:
148
+ "Read content from an MCP resource. You can only read resources from MCP servers you have tools from.",
149
+ inputSchema: mcpResourceReadSchema,
150
+ execute: async (input) => {
151
+ const result = await executeReadResource(input, context);
152
+
153
+ // Handle expected error results
154
+ if (typeof result === "object" && "type" in result && result.type === "error-text") {
155
+ return result;
156
+ }
157
+
158
+ return JSON.stringify(result, null, 2);
159
+ },
160
+ }) as AISdkTool;
161
+ }
@@ -0,0 +1,158 @@
1
+ import type { ConversationToolContext } from "@/tools/types";
2
+ import type { AISdkTool } from "@/tools/types";
3
+ import { type ToolResponse, createExpectedError } from "@/tools/utils";
4
+ import { extractAgentMcpServers } from "@/prompts/fragments/26-mcp-resources";
5
+ import { getProjectContext } from "@/services/projects";
6
+ import { McpSubscriptionService } from "@/services/mcp/McpSubscriptionService";
7
+ import { tool } from "ai";
8
+ import { z } from "zod";
9
+
10
+ /**
11
+ * Schema for creating an MCP resource subscription
12
+ */
13
+ const mcpSubscribeSchema = z.object({
14
+ serverName: z.string().describe('MCP server name (e.g., "nostr-provider")'),
15
+ resourceUri: z.string().describe('Resource URI to subscribe to (e.g., "nostr://feed/global")'),
16
+ description: z.string().describe("Human-readable description of what this subscription monitors"),
17
+ });
18
+
19
+ /**
20
+ * Validate that a resource URI has a scheme and non-empty path.
21
+ * MCP resource URIs follow standard URI format (e.g., "nostr://feed/global", "file:///path").
22
+ */
23
+ function isValidResourceUri(uri: string): boolean {
24
+ try {
25
+ // Check basic structure: must have a scheme (protocol) component
26
+ const schemeMatch = /^[a-zA-Z][a-zA-Z0-9+\-.]*:/.test(uri);
27
+ if (!schemeMatch) return false;
28
+ // Must have something after the scheme
29
+ const afterScheme = uri.indexOf(":") + 1;
30
+ return afterScheme < uri.length && uri.substring(afterScheme).trim().length > 0;
31
+ } catch {
32
+ return false;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Core implementation of MCP resource subscription
38
+ */
39
+ async function executeSubscribe(
40
+ input: z.infer<typeof mcpSubscribeSchema>,
41
+ context: ConversationToolContext
42
+ ): Promise<ToolResponse | ReturnType<typeof createExpectedError>> {
43
+ const { serverName, resourceUri, description } = input;
44
+
45
+ // Validate URI format upfront
46
+ if (!isValidResourceUri(resourceUri)) {
47
+ return createExpectedError(
48
+ `Invalid resource URI '${resourceUri}'. ` +
49
+ "Resource URIs must have a valid scheme (e.g., 'nostr://feed/global', 'file:///path')."
50
+ );
51
+ }
52
+
53
+ // Get MCPManager from project context
54
+ const projectContext = getProjectContext();
55
+ const mcpManager = projectContext.mcpManager;
56
+
57
+ if (!mcpManager) {
58
+ throw new Error(
59
+ "MCP manager not available. This is a system error - MCP should be initialized."
60
+ );
61
+ }
62
+
63
+ // Validate agent has access to this server
64
+ const agentMcpServers = extractAgentMcpServers(context.agent.tools);
65
+
66
+ if (!agentMcpServers.includes(serverName)) {
67
+ return createExpectedError(
68
+ `You do not have access to MCP server '${serverName}'. ` +
69
+ "You can only subscribe to resources from servers you have tools from. " +
70
+ `Your accessible servers: ${agentMcpServers.length > 0 ? agentMcpServers.join(", ") : "none"}`
71
+ );
72
+ }
73
+
74
+ // Check if server is running
75
+ const runningServers = mcpManager.getRunningServers();
76
+ if (!runningServers.includes(serverName)) {
77
+ return createExpectedError(
78
+ `MCP server '${serverName}' is not running. ` +
79
+ `Running servers: ${runningServers.length > 0 ? runningServers.join(", ") : "none"}`
80
+ );
81
+ }
82
+
83
+ // Get conversation details for subscription context
84
+ const conversationStore = context.conversationStore;
85
+ const rootEventId = conversationStore.getRootEventId();
86
+
87
+ if (!rootEventId) {
88
+ return createExpectedError(
89
+ "Cannot create subscription: conversation has no root event. " +
90
+ "This subscription must be created within an active conversation."
91
+ );
92
+ }
93
+
94
+ const projectId = projectContext.project.tagId();
95
+
96
+ try {
97
+ const subscriptionService = McpSubscriptionService.getInstance();
98
+
99
+ const subscription = await subscriptionService.createSubscription({
100
+ agentPubkey: context.agent.pubkey,
101
+ agentSlug: context.agent.slug,
102
+ serverName,
103
+ resourceUri,
104
+ conversationId: context.conversationId,
105
+ rootEventId,
106
+ projectId,
107
+ description,
108
+ });
109
+
110
+ return {
111
+ success: true,
112
+ message: `Successfully created MCP subscription '${subscription.id}'`,
113
+ subscription: {
114
+ id: subscription.id,
115
+ serverName: subscription.serverName,
116
+ resourceUri: subscription.resourceUri,
117
+ conversationId: subscription.conversationId,
118
+ status: subscription.status,
119
+ description: subscription.description,
120
+ },
121
+ hint: `Use mcp_subscription_stop('${subscription.id}') to cancel this subscription.`,
122
+ };
123
+ } catch (error) {
124
+ const errorMessage = error instanceof Error ? error.message : String(error);
125
+ return createExpectedError(
126
+ `Failed to create MCP subscription: ${errorMessage}`
127
+ );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Subscribe to MCP resource notifications within the current conversation.
133
+ *
134
+ * When the subscribed resource is updated, a notification will be delivered
135
+ * as a system-reminder message in this conversation, triggering a new
136
+ * agent execution to handle the update.
137
+ *
138
+ * Subscriptions persist across system restarts.
139
+ */
140
+ export function createMcpSubscribeTool(context: ConversationToolContext): AISdkTool {
141
+ return tool({
142
+ description:
143
+ "Subscribe to MCP resource update notifications. When the resource changes, " +
144
+ "a notification will be delivered to this conversation. " +
145
+ "You can only subscribe to resources from MCP servers you have tools from. " +
146
+ "Subscriptions persist across restarts.",
147
+ inputSchema: mcpSubscribeSchema,
148
+ execute: async (input) => {
149
+ const result = await executeSubscribe(input, context);
150
+
151
+ if (typeof result === "object" && "type" in result && result.type === "error-text") {
152
+ return result;
153
+ }
154
+
155
+ return JSON.stringify(result, null, 2);
156
+ },
157
+ }) as AISdkTool;
158
+ }
@@ -0,0 +1,85 @@
1
+ import type { ToolExecutionContext } from "@/tools/types";
2
+ import type { AISdkTool } from "@/tools/types";
3
+ import { type ToolResponse, createExpectedError } from "@/tools/utils";
4
+ import { McpSubscriptionService } from "@/services/mcp/McpSubscriptionService";
5
+ import { tool } from "ai";
6
+ import { z } from "zod";
7
+
8
+ /**
9
+ * Schema for stopping an MCP subscription
10
+ */
11
+ const mcpSubscriptionStopSchema = z.object({
12
+ subscriptionId: z.string().describe("The subscription ID to stop (returned by mcp_subscribe)"),
13
+ });
14
+
15
+ /**
16
+ * Core implementation of stopping an MCP subscription
17
+ */
18
+ async function executeStop(
19
+ input: z.infer<typeof mcpSubscriptionStopSchema>,
20
+ context: ToolExecutionContext
21
+ ): Promise<ToolResponse | ReturnType<typeof createExpectedError>> {
22
+ const { subscriptionId } = input;
23
+
24
+ const subscriptionService = McpSubscriptionService.getInstance();
25
+ const subscription = subscriptionService.getSubscription(subscriptionId);
26
+
27
+ if (!subscription) {
28
+ return createExpectedError(
29
+ `Subscription '${subscriptionId}' not found. ` +
30
+ "Please verify the subscription ID is correct."
31
+ );
32
+ }
33
+
34
+ // Authorization: only the agent that created the subscription can stop it
35
+ if (subscription.agentPubkey !== context.agent.pubkey) {
36
+ return createExpectedError(
37
+ `You are not authorized to stop subscription '${subscriptionId}'. ` +
38
+ "Only the agent that created the subscription can stop it."
39
+ );
40
+ }
41
+
42
+ const success = await subscriptionService.stopSubscription(subscriptionId, context.agent.pubkey);
43
+
44
+ if (!success) {
45
+ return createExpectedError(
46
+ `Failed to stop subscription '${subscriptionId}'.`
47
+ );
48
+ }
49
+
50
+ return {
51
+ success: true,
52
+ message: `Successfully stopped MCP subscription '${subscriptionId}'`,
53
+ subscription: {
54
+ id: subscription.id,
55
+ serverName: subscription.serverName,
56
+ resourceUri: subscription.resourceUri,
57
+ notificationsReceived: subscription.notificationsReceived,
58
+ },
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Stop an active MCP resource subscription.
64
+ *
65
+ * This cancels the subscription and cleans up all persisted state.
66
+ * The subscription will no longer deliver notifications.
67
+ */
68
+ export function createMcpSubscriptionStopTool(context: ToolExecutionContext): AISdkTool {
69
+ return tool({
70
+ description:
71
+ "Stop an active MCP resource subscription. " +
72
+ "Cancels the subscription and removes persisted state. " +
73
+ "No more notifications will be delivered.",
74
+ inputSchema: mcpSubscriptionStopSchema,
75
+ execute: async (input) => {
76
+ const result = await executeStop(input, context);
77
+
78
+ if (typeof result === "object" && "type" in result && result.type === "error-text") {
79
+ return result;
80
+ }
81
+
82
+ return JSON.stringify(result, null, 2);
83
+ },
84
+ }) as AISdkTool;
85
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Nostr Fetch Tool
3
+ *
4
+ * Fetches any nostr event by ID and returns formatted or raw output.
5
+ * Supports various ID formats: nevent, note, naddr, hex, with or without "nostr:" prefix.
6
+ */
7
+
8
+ import type { ToolExecutionContext } from "@/tools/types";
9
+ import { getNDK } from "@/nostr";
10
+ import { getPubkeyService } from "@/services/PubkeyService";
11
+ import type { AISdkTool } from "@/tools/types";
12
+ import { createExpectedError, isExpectedNotFoundError } from "@/tools/utils";
13
+ import { logger } from "@/utils/logger";
14
+ import { parseNostrEvent } from "@/utils/nostr-entity-parser";
15
+ import { tool } from "ai";
16
+ import { z } from "zod";
17
+
18
+ /**
19
+ * Schema for nostr_fetch tool input
20
+ */
21
+ const nostrFetchSchema = z.object({
22
+ eventId: z
23
+ .string()
24
+ .describe(
25
+ "The event ID to fetch. Supports nevent, note, naddr, hex format, with or without 'nostr:' prefix"
26
+ ),
27
+ format: z
28
+ .enum(["raw", "display"])
29
+ .default("display")
30
+ .describe(
31
+ "Output format: 'raw' returns the raw event JSON, 'display' returns human-readable format"
32
+ ),
33
+ });
34
+
35
+ type NostrFetchInput = z.infer<typeof nostrFetchSchema>;
36
+
37
+ /**
38
+ * Format a tag for display
39
+ */
40
+ function formatTag(tag: string[]): string {
41
+ if (tag.length === 0) return "";
42
+ if (tag.length === 1) return tag[0];
43
+ return `${tag[0]}=${tag.slice(1).join(",")}`;
44
+ }
45
+
46
+ /**
47
+ * Format timestamp to human-readable string
48
+ */
49
+ function formatTimestamp(unixTimestamp: number): string {
50
+ const date = new Date(unixTimestamp * 1000);
51
+ return date
52
+ .toISOString()
53
+ .replace("T", " ")
54
+ .replace(/\.\d{3}Z$/, " UTC");
55
+ }
56
+
57
+ /**
58
+ * Execute the nostr_fetch tool
59
+ * Returns null if event is not found (expected condition)
60
+ */
61
+ async function executeNostrFetch(input: NostrFetchInput): Promise<string | null> {
62
+ const { eventId, format } = input;
63
+
64
+ const ndk = getNDK();
65
+
66
+ // Use the existing parseNostrEvent utility which handles all formats
67
+ const event = await parseNostrEvent(eventId, ndk);
68
+
69
+ if (!event) {
70
+ // "Event not found" is an expected condition - return null to signal expected error
71
+ return null;
72
+ }
73
+
74
+ // Return raw event JSON if requested
75
+ if (format === "raw") {
76
+ return JSON.stringify(event.rawEvent(), null, 2);
77
+ }
78
+
79
+ // Build display format
80
+ const pubkeyService = getPubkeyService();
81
+ const authorName = await pubkeyService.getName(event.pubkey);
82
+ const timestamp = formatTimestamp(event.created_at || 0);
83
+
84
+ // Format tags with bullet points
85
+ const tagsSection =
86
+ event.tags.length > 0
87
+ ? `tags:\n${event.tags.map((tag) => ` * ${formatTag(tag)}`).join("\n")}`
88
+ : "tags: (none)";
89
+
90
+ const displayOutput = [
91
+ `Event ID: ${event.id}`,
92
+ `kind: ${event.kind}`,
93
+ `author: @${authorName}`,
94
+ `timestamp: ${timestamp}`,
95
+ "",
96
+ event.content,
97
+ "",
98
+ tagsSection,
99
+ ].join("\n");
100
+
101
+ return displayOutput;
102
+ }
103
+
104
+ /**
105
+ * Create the nostr_fetch AI SDK tool
106
+ */
107
+ export function createNostrFetchTool(_context: ToolExecutionContext): AISdkTool {
108
+ const toolInstance = tool({
109
+ description:
110
+ "Fetches any nostr event by ID. Supports nevent, note, naddr, hex format, " +
111
+ "with or without 'nostr:' prefix. Returns either raw JSON or a human-readable display format.",
112
+
113
+ inputSchema: nostrFetchSchema,
114
+
115
+ execute: async (input: NostrFetchInput) => {
116
+ try {
117
+ const result = await executeNostrFetch(input);
118
+
119
+ // "Event not found" is an expected condition - return error-text
120
+ if (result === null) {
121
+ return createExpectedError(`Event not found: ${input.eventId}`);
122
+ }
123
+
124
+ return result;
125
+ } catch (error) {
126
+ // Check if this is an expected "not found" error from a different code path
127
+ if (isExpectedNotFoundError(error)) {
128
+ return createExpectedError(`Event not found: ${input.eventId}`);
129
+ }
130
+
131
+ logger.error("Failed to fetch nostr event", { eventId: input.eventId, error });
132
+ throw new Error(
133
+ `Failed to fetch nostr event: ${error instanceof Error ? error.message : String(error)}`,
134
+ { cause: error }
135
+ );
136
+ }
137
+ },
138
+ });
139
+
140
+ Object.defineProperty(toolInstance, "getHumanReadableContent", {
141
+ value: ({ eventId, format }: NostrFetchInput) => {
142
+ return `Fetching nostr event ${eventId} (format: ${format || "display"})`;
143
+ },
144
+ enumerable: false,
145
+ configurable: true,
146
+ });
147
+
148
+ return toolInstance as AISdkTool;
149
+ }