@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,573 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { URL } from "node:url";
4
+ import type { ToolExecutionContext } from "@/tools/types";
5
+ import { type RAGDocument, RAGService } from "@/services/rag/RAGService";
6
+ import type { AISdkTool } from "@/tools/types";
7
+ import type { DocumentMetadata } from "@/services/rag/rag-utils";
8
+ import { type ToolResponse, executeToolWithErrorHandling, resolveAndValidatePath } from "@/tools/utils";
9
+ import { getProjectContext, isProjectContextInitialized } from "@/services/projects";
10
+ import { tool } from "ai";
11
+ import { z } from "zod";
12
+
13
+ // Protocol Constants
14
+ const PROTOCOL_FILE = "file:";
15
+ const PROTOCOL_HTTP = "http:";
16
+ const PROTOCOL_HTTPS = "https:";
17
+ const FILE_PROTOCOL_PREFIX = "file://";
18
+
19
+ // Size and Timeout Constants
20
+ const HTTP_TIMEOUT_MS = 30000; // 30 seconds
21
+ const MAX_FILE_SIZE_MB = 100; // 100MB max file size
22
+ const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
23
+
24
+ // User Agent for HTTP requests
25
+ const HTTP_USER_AGENT = "TENEX-RAG-Ingester/1.0";
26
+
27
+ // Type definitions for protocol handlers
28
+ type ProtocolHandler = (uri: string, context: { workingDirectory: string }) => Promise<string>;
29
+
30
+ /**
31
+ * Schema for RAG document input
32
+ */
33
+ const ragAddDocumentsSchema = z.object({
34
+ description: z
35
+ .string()
36
+ .trim()
37
+ .min(1, "Description is required and cannot be empty")
38
+ .describe(
39
+ "REQUIRED: A clear, concise description of why you're adding these documents (5-10 words). Helps provide human-readable context for the operation."
40
+ ),
41
+ collection: z.string().describe("Name of the collection to add documents to"),
42
+ documents: z
43
+ .array(
44
+ z.union([
45
+ // Option 1: Content with optional file_path
46
+ z.object({
47
+ content: z.string().nullable().describe("Text content of the document"),
48
+ file_path: z.string().nullable().describe("Path to file to read content from"),
49
+ metadata: z
50
+ .record(z.string(), z.unknown())
51
+ .nullable()
52
+ .describe("Optional metadata for the document"),
53
+ source: z.string().nullable().describe("Source identifier for the document"),
54
+ id: z
55
+ .string()
56
+ .nullable()
57
+ .describe("Optional unique identifier for the document"),
58
+ }),
59
+ // Option 2: URI-based
60
+ z.object({
61
+ uri: z.string().describe("URI to fetch content from (file://, https://, etc.)"),
62
+ metadata: z
63
+ .record(z.string(), z.unknown())
64
+ .nullable()
65
+ .describe("Optional metadata for the document"),
66
+ source: z.string().nullable().describe("Source identifier for the document"),
67
+ id: z
68
+ .string()
69
+ .nullable()
70
+ .describe("Optional unique identifier for the document"),
71
+ }),
72
+ ])
73
+ )
74
+ .describe("Array of documents to add to the collection"),
75
+ });
76
+
77
+ /**
78
+ * Validate URI format and return parsed URL
79
+ *
80
+ * Rationale: Early validation prevents downstream errors and provides clear feedback
81
+ * about malformed URIs before any network or file operations are attempted.
82
+ */
83
+ function validateURI(uri: string): URL {
84
+ try {
85
+ return new URL(uri);
86
+ } catch (error) {
87
+ throw new Error(
88
+ `Invalid URI format '${uri}': ${error instanceof Error ? error.message : "Unknown error"}`,
89
+ { cause: error }
90
+ );
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Validate content is not empty
96
+ *
97
+ * Rationale: Empty documents cannot be meaningfully embedded or searched,
98
+ * so we reject them early with a clear error message.
99
+ */
100
+ function validateContent(content: string, source: string): void {
101
+ if (!content || content.trim().length === 0) {
102
+ throw new Error(`Document from ${source} must have non-empty content`);
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Check if a size exceeds the maximum allowed
108
+ *
109
+ * Rationale: Large files can cause memory issues and slow processing.
110
+ * This validation ensures system stability and predictable performance.
111
+ */
112
+ function validateSize(sizeInBytes: number, sourceName: string): void {
113
+ if (sizeInBytes > MAX_FILE_SIZE_BYTES) {
114
+ const sizeMB = (sizeInBytes / 1024 / 1024).toFixed(2);
115
+ throw new Error(
116
+ `${sourceName} size (${sizeMB}MB) exceeds maximum allowed size of ${MAX_FILE_SIZE_MB}MB`
117
+ );
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Handle common fetch errors with context
123
+ *
124
+ * Rationale: Consistent error messages across protocol handlers
125
+ * make debugging easier and provide better user experience.
126
+ */
127
+ function handleFetchError(error: unknown, protocol: string): never {
128
+ if (error && typeof error === "object" && "name" in error && error.name === "AbortError") {
129
+ throw new Error(`Request timeout after ${HTTP_TIMEOUT_MS / 1000} seconds`);
130
+ }
131
+
132
+ const message = error instanceof Error ? error.message : "Unknown error";
133
+ throw new Error(`Failed to fetch from ${protocol} URI: ${message}`);
134
+ }
135
+
136
+ /**
137
+ * Type for document input - represents the union of possible document shapes
138
+ */
139
+ type DocumentInput = {
140
+ content?: string;
141
+ file_path?: string;
142
+ uri?: string;
143
+ metadata?: Record<string, unknown>;
144
+ source?: string;
145
+ id?: string;
146
+ };
147
+
148
+ /**
149
+ * Generate consistent source field based on input type
150
+ *
151
+ * Rationale: Consistent source identification helps with debugging
152
+ * and tracking document origins across different input methods.
153
+ */
154
+ function generateSourceField(doc: DocumentInput, resolvedPath?: string): string | undefined {
155
+ // Explicit source takes precedence
156
+ if (doc.source) {
157
+ return doc.source;
158
+ }
159
+
160
+ // URI-based document
161
+ if ("uri" in doc && doc.uri) {
162
+ return doc.uri;
163
+ }
164
+
165
+ // File path-based document
166
+ if (doc.file_path) {
167
+ return `${FILE_PROTOCOL_PREFIX}${resolvedPath || doc.file_path}`;
168
+ }
169
+
170
+ // Direct content has no default source
171
+ return undefined;
172
+ }
173
+
174
+ /**
175
+ * Parse file path from file:// URI
176
+ *
177
+ * Rationale: File URIs have various formats that need normalization
178
+ * for cross-platform compatibility.
179
+ */
180
+ function parseFilePathFromURI(uri: string): string {
181
+ // Remove 'file://' prefix
182
+ let filePath = uri.substring(FILE_PROTOCOL_PREFIX.length);
183
+
184
+ // Handle different file:// formats
185
+ if (filePath.startsWith("//")) {
186
+ // file:////absolute/path or file://host/path
187
+ filePath = filePath.substring(2);
188
+ } else if (filePath.startsWith("/./")) {
189
+ // file://./relative/path - explicit relative
190
+ filePath = filePath.substring(3);
191
+ } else if (filePath.startsWith("./")) {
192
+ // file://./relative/path - explicit relative
193
+ filePath = filePath.substring(2);
194
+ }
195
+
196
+ // On Windows, file:///C:/path becomes /C:/path, need to remove leading slash
197
+ if (process.platform === "win32" && filePath.match(/^\/[a-zA-Z]:[\\/]/)) {
198
+ filePath = filePath.slice(1);
199
+ }
200
+
201
+ return filePath;
202
+ }
203
+
204
+ /**
205
+ * Handle file:// protocol URIs
206
+ *
207
+ * Rationale: File URIs require special handling for path resolution,
208
+ * size validation, and cross-platform compatibility.
209
+ */
210
+ async function handleFileProtocolURI(
211
+ uri: string,
212
+ context: { workingDirectory: string }
213
+ ): Promise<string> {
214
+ try {
215
+ const filePath = parseFilePathFromURI(uri);
216
+
217
+ // Resolve the path (handles both absolute and relative paths)
218
+ const resolvedPath = path.resolve(context.workingDirectory, filePath);
219
+
220
+ // Check file size before reading
221
+ const stats = await stat(resolvedPath);
222
+ validateSize(stats.size, "File");
223
+
224
+ return await readFile(resolvedPath, "utf-8");
225
+ } catch (error) {
226
+ handleFetchError(error, PROTOCOL_FILE);
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Handle HTTP/HTTPS protocol URIs with timeout and size limits
232
+ *
233
+ * Rationale: HTTP requests need timeouts to prevent hanging,
234
+ * and size limits to prevent memory exhaustion from large responses.
235
+ */
236
+ async function handleHttpProtocolURI(
237
+ uri: string,
238
+ _context: { workingDirectory: string }
239
+ ): Promise<string> {
240
+ const controller = new AbortController();
241
+ const timeout = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS);
242
+
243
+ try {
244
+ const response = await fetch(uri, {
245
+ signal: controller.signal,
246
+ headers: {
247
+ "User-Agent": HTTP_USER_AGENT,
248
+ },
249
+ });
250
+
251
+ if (!response.ok) {
252
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
253
+ }
254
+
255
+ // Check content length before reading body
256
+ const contentLength = response.headers.get("content-length");
257
+ if (contentLength) {
258
+ const sizeInBytes = Number.parseInt(contentLength, 10);
259
+ validateSize(sizeInBytes, "Response");
260
+ }
261
+
262
+ // Read response body with streaming size check
263
+ const chunks: string[] = [];
264
+ let totalSize = 0;
265
+ const reader = response.body?.getReader();
266
+ const decoder = new TextDecoder();
267
+
268
+ if (!reader) {
269
+ throw new Error("Response body is not readable");
270
+ }
271
+
272
+ while (true) {
273
+ const { done, value } = await reader.read();
274
+ if (done) break;
275
+
276
+ totalSize += value.length;
277
+ validateSize(totalSize, "Response");
278
+
279
+ chunks.push(decoder.decode(value, { stream: true }));
280
+ }
281
+
282
+ return chunks.join("");
283
+ } catch (error) {
284
+ handleFetchError(error, uri.startsWith(PROTOCOL_HTTPS) ? PROTOCOL_HTTPS : PROTOCOL_HTTP);
285
+ } finally {
286
+ clearTimeout(timeout);
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Extensible protocol handler map
292
+ */
293
+ const PROTOCOL_HANDLERS: Map<string, ProtocolHandler> = new Map([
294
+ [PROTOCOL_FILE, handleFileProtocolURI],
295
+ [PROTOCOL_HTTP, handleHttpProtocolURI],
296
+ [PROTOCOL_HTTPS, handleHttpProtocolURI],
297
+ ]);
298
+
299
+ /**
300
+ * Register a new protocol handler
301
+ *
302
+ * Rationale: Extensibility allows adding support for new protocols
303
+ * without modifying the core implementation.
304
+ */
305
+ export function registerProtocolHandler(protocol: string, handler: ProtocolHandler): void {
306
+ PROTOCOL_HANDLERS.set(protocol, handler);
307
+ }
308
+
309
+ /**
310
+ * Fetch content from a URI using the appropriate protocol handler
311
+ */
312
+ async function fetchFromURI(uri: string, workingDirectory: string): Promise<string> {
313
+ // Validate URI first
314
+ const parsedUrl = validateURI(uri);
315
+
316
+ // Get protocol handler
317
+ const handler = PROTOCOL_HANDLERS.get(parsedUrl.protocol);
318
+ if (!handler) {
319
+ throw new Error(
320
+ `Unsupported URI protocol '${parsedUrl.protocol}'. ` +
321
+ `Supported protocols: ${Array.from(PROTOCOL_HANDLERS.keys()).join(", ")}`
322
+ );
323
+ }
324
+
325
+ // Execute handler
326
+ return await handler(uri, { workingDirectory });
327
+ }
328
+
329
+ /**
330
+ * Extract document content from various sources (renamed from processSingleDocument)
331
+ *
332
+ * Rationale: This function unifies content extraction from different input types,
333
+ * providing a consistent interface for document processing.
334
+ */
335
+ async function extractDocumentContentFromSource(
336
+ doc: DocumentInput,
337
+ workingDirectory: string
338
+ ): Promise<{ content: string; source: string | undefined }> {
339
+ let content: string;
340
+ let resolvedPath: string | undefined;
341
+
342
+ if ("uri" in doc && doc.uri) {
343
+ // URI-based document
344
+ content = await fetchFromURI(doc.uri, workingDirectory);
345
+ } else {
346
+ // Content/file_path based document
347
+ content = doc.content || "";
348
+
349
+ // Read from file if file_path is provided
350
+ if (doc.file_path) {
351
+ resolvedPath = resolveAndValidatePath(doc.file_path, workingDirectory);
352
+
353
+ // Check file size
354
+ const stats = await stat(resolvedPath);
355
+ validateSize(stats.size, "File");
356
+
357
+ try {
358
+ content = await readFile(resolvedPath, "utf-8");
359
+ } catch (error) {
360
+ if (!doc.content) {
361
+ throw new Error(
362
+ `Cannot read file '${doc.file_path}': ${error instanceof Error ? error.message : "Unknown error"}`,
363
+ { cause: error }
364
+ );
365
+ }
366
+ // Fall back to provided content if file read fails but content exists
367
+ }
368
+ }
369
+ }
370
+
371
+ // Generate source field
372
+ const source = generateSourceField(doc, resolvedPath);
373
+
374
+ return { content, source };
375
+ }
376
+
377
+ /**
378
+ * Compute base provenance metadata once per tool execution
379
+ *
380
+ * Rationale: Pre-computing provenance avoids repeated global context access
381
+ * per document. This is called once in executeAddDocuments and passed down.
382
+ */
383
+ function computeBaseProvenance(context: ToolExecutionContext): DocumentMetadata {
384
+ const provenance: DocumentMetadata = {};
385
+
386
+ // Auto-inject agent_pubkey if available
387
+ if (context.agent?.pubkey) {
388
+ provenance.agent_pubkey = context.agent.pubkey;
389
+ }
390
+
391
+ // Auto-inject project_id if available (uses NIP-33 address format)
392
+ if (isProjectContextInitialized()) {
393
+ try {
394
+ const projectCtx = getProjectContext();
395
+ const projectId = projectCtx.project.tagId();
396
+ if (projectId) {
397
+ provenance.project_id = projectId;
398
+ }
399
+ } catch {
400
+ // Project context not available - skip project_id injection
401
+ }
402
+ }
403
+
404
+ return provenance;
405
+ }
406
+
407
+ /**
408
+ * Coerce unknown record values to JSON-serializable DocumentMetadata values.
409
+ * Filters out non-serializable values (functions, undefined, symbols) and
410
+ * coerces compatible values to their JSON equivalents.
411
+ *
412
+ * Rationale: User-provided metadata from tool input may contain unknown types.
413
+ * Instead of blindly casting, we validate/coerce each value to ensure type safety.
414
+ */
415
+ function coerceToDocumentMetadata(record: Record<string, unknown>): DocumentMetadata {
416
+ const result: DocumentMetadata = {};
417
+
418
+ for (const [key, value] of Object.entries(record)) {
419
+ // Skip non-serializable values
420
+ if (value === undefined || typeof value === "function" || typeof value === "symbol") {
421
+ continue;
422
+ }
423
+
424
+ // Handle primitives directly
425
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
426
+ result[key] = value;
427
+ continue;
428
+ }
429
+
430
+ // Handle arrays and objects by JSON round-trip (ensures serializable)
431
+ if (typeof value === "object") {
432
+ try {
433
+ // JSON round-trip validates serializability and clones deeply
434
+ result[key] = JSON.parse(JSON.stringify(value));
435
+ } catch {
436
+ // Non-serializable object (circular refs, etc.) - skip
437
+ continue;
438
+ }
439
+ }
440
+ }
441
+
442
+ return result;
443
+ }
444
+
445
+ /**
446
+ * Merge document metadata with base provenance
447
+ *
448
+ * Rationale: Separates provenance computation (done once) from per-document
449
+ * metadata merging. Caller-provided metadata takes precedence over auto-injected.
450
+ */
451
+ function mergeWithProvenance(
452
+ documentMetadata: Record<string, unknown> | null | undefined,
453
+ baseProvenance: DocumentMetadata
454
+ ): DocumentMetadata {
455
+ // Coerce user-provided metadata to ensure JSON-serializable values
456
+ const coercedMetadata = documentMetadata ? coerceToDocumentMetadata(documentMetadata) : {};
457
+
458
+ // Base provenance (agent_pubkey, project_id) comes first, user metadata can override
459
+ return {
460
+ ...baseProvenance,
461
+ ...coercedMetadata,
462
+ };
463
+ }
464
+
465
+ /**
466
+ * Process documents and prepare them for insertion
467
+ */
468
+ async function processDocuments(
469
+ documents: z.infer<typeof ragAddDocumentsSchema>["documents"],
470
+ workingDirectory: string,
471
+ baseProvenance: DocumentMetadata
472
+ ): Promise<RAGDocument[]> {
473
+ const processedDocs: RAGDocument[] = [];
474
+
475
+ for (const doc of documents) {
476
+ try {
477
+ const { content, source } = await extractDocumentContentFromSource(
478
+ doc as DocumentInput,
479
+ workingDirectory
480
+ );
481
+
482
+ // Validate content
483
+ validateContent(content, source || "document");
484
+
485
+ // Merge document metadata with pre-computed provenance
486
+ const metadata = mergeWithProvenance(doc.metadata, baseProvenance);
487
+
488
+ processedDocs.push({
489
+ id: doc.id ?? undefined,
490
+ content,
491
+ metadata,
492
+ source: source ?? undefined,
493
+ timestamp: Date.now(),
494
+ });
495
+ } catch (error) {
496
+ // Add context to error
497
+ const identifier =
498
+ doc.id || ("uri" in doc ? doc.uri : doc.file_path) || "unknown document";
499
+ throw new Error(
500
+ `Error processing document '${identifier}': ${error instanceof Error ? error.message : "Unknown error"}`,
501
+ { cause: error }
502
+ );
503
+ }
504
+ }
505
+
506
+ return processedDocs;
507
+ }
508
+
509
+ /**
510
+ * Core implementation of adding documents to a RAG collection
511
+ */
512
+ async function executeAddDocuments(
513
+ input: z.infer<typeof ragAddDocumentsSchema>,
514
+ context: ToolExecutionContext
515
+ ): Promise<ToolResponse> {
516
+ const { collection, documents } = input;
517
+
518
+ // Pre-compute base provenance once (avoids repeated global context access per document)
519
+ const baseProvenance = computeBaseProvenance(context);
520
+
521
+ // Process documents with provenance injection
522
+ const processedDocs = await processDocuments(documents, context.workingDirectory, baseProvenance);
523
+
524
+ // Add to collection
525
+ const ragService = RAGService.getInstance();
526
+ await ragService.addDocuments(collection, processedDocs);
527
+
528
+ return {
529
+ success: true,
530
+ message: `Successfully added ${processedDocs.length} documents to collection '${collection}'`,
531
+ documents_added: processedDocs.length,
532
+ collection: collection,
533
+ };
534
+ }
535
+
536
+ /**
537
+ * Add documents to a RAG collection for semantic search
538
+ *
539
+ * Supports multiple input methods:
540
+ * - Direct text content
541
+ * - File paths (relative or absolute)
542
+ * - URIs (file://, http://, https://)
543
+ *
544
+ * Features:
545
+ * - Automatic content validation (non-empty check)
546
+ * - File size limits (100MB) with early validation
547
+ * - HTTP request timeouts (30s) to prevent hanging
548
+ * - Streaming size validation for HTTP responses
549
+ * - Extensible protocol handlers for custom schemes
550
+ * - Cross-platform file path resolution
551
+ * - Backward compatible with existing code
552
+ *
553
+ * Rationale for validations:
554
+ * - Size limits prevent memory exhaustion
555
+ * - Timeouts prevent hanging requests
556
+ * - URI validation provides early error detection
557
+ * - Content validation ensures meaningful documents
558
+ */
559
+ export function createRAGAddDocumentsTool(context: ToolExecutionContext): AISdkTool {
560
+ return tool({
561
+ description:
562
+ "Add documents to a RAG collection. Documents can be provided as text content, file paths, or URIs (file://, https://, etc.). Each document will be automatically embedded for semantic search. Enforces file size limits (100MB) and HTTP timeouts (30s).",
563
+ inputSchema: ragAddDocumentsSchema,
564
+ execute: async (input: unknown) => {
565
+ return executeToolWithErrorHandling(
566
+ "rag_add_documents",
567
+ input as z.infer<typeof ragAddDocumentsSchema>,
568
+ context,
569
+ executeAddDocuments
570
+ );
571
+ },
572
+ }) as AISdkTool;
573
+ }
@@ -0,0 +1,65 @@
1
+ import type { ToolExecutionContext } from "@/tools/types";
2
+ import { RAGService } from "@/services/rag/RAGService";
3
+ import type { AISdkTool } from "@/tools/types";
4
+ import { type ToolResponse, executeToolWithErrorHandling } from "@/tools/utils";
5
+ import { tool } from "ai";
6
+ import { z } from "zod";
7
+
8
+ const ragCreateCollectionSchema = z.object({
9
+ description: z
10
+ .string()
11
+ .trim()
12
+ .min(1, "Description is required and cannot be empty")
13
+ .describe(
14
+ "REQUIRED: A clear, concise description of why you're creating this collection (5-10 words). Helps provide human-readable context for the operation."
15
+ ),
16
+ name: z.string().describe("Name of the collection to create (alphanumeric with underscores)"),
17
+ schema: z
18
+ .record(z.string(), z.any())
19
+ .nullable()
20
+ .describe(
21
+ "Optional custom schema for the collection (default includes id, content, vector, metadata, timestamp, source)"
22
+ ),
23
+ });
24
+
25
+ /**
26
+ * Core implementation of RAG collection creation
27
+ */
28
+ async function executeCreateCollection(
29
+ input: z.infer<typeof ragCreateCollectionSchema>,
30
+ _context: ToolExecutionContext
31
+ ): Promise<ToolResponse> {
32
+ const { name, schema } = input;
33
+
34
+ const ragService = RAGService.getInstance();
35
+ const collection = await ragService.createCollection(name, schema ?? undefined);
36
+
37
+ return {
38
+ success: true,
39
+ message: `Collection '${name}' created successfully`,
40
+ collection: {
41
+ name: collection.name,
42
+ created_at: new Date(collection.created_at).toISOString(),
43
+ schema: collection.schema,
44
+ },
45
+ };
46
+ }
47
+
48
+ /**
49
+ * Create a new RAG collection for storing and retrieving vector embeddings
50
+ */
51
+ export function createRAGCreateCollectionTool(context: ToolExecutionContext): AISdkTool {
52
+ return tool({
53
+ description:
54
+ "Create a new RAG collection (vector database) for storing documents with semantic search capabilities",
55
+ inputSchema: ragCreateCollectionSchema,
56
+ execute: async (input: unknown) => {
57
+ return executeToolWithErrorHandling(
58
+ "rag_create_collection",
59
+ input as z.infer<typeof ragCreateCollectionSchema>,
60
+ context,
61
+ executeCreateCollection
62
+ );
63
+ },
64
+ }) as AISdkTool;
65
+ }
@@ -0,0 +1,68 @@
1
+ import type { ToolExecutionContext } from "@/tools/types";
2
+ import { RAGService } from "@/services/rag/RAGService";
3
+ import type { AISdkTool } from "@/tools/types";
4
+ import { type ToolResponse, executeToolWithErrorHandling } from "@/tools/utils";
5
+ import { tool } from "ai";
6
+ import { z } from "zod";
7
+
8
+ const ragDeleteCollectionSchema = z.object({
9
+ description: z
10
+ .string()
11
+ .trim()
12
+ .min(1, "Description is required and cannot be empty")
13
+ .describe(
14
+ "REQUIRED: A clear, concise description of why you're deleting this collection (5-10 words). Helps provide human-readable context for the operation."
15
+ ),
16
+ name: z.string().describe("Name of the collection to delete"),
17
+ confirm: z
18
+ .boolean()
19
+ .nullable()
20
+ .default(false)
21
+ .describe("Confirmation flag to prevent accidental deletion (must be true to proceed)"),
22
+ });
23
+
24
+ /**
25
+ * Core implementation of RAG collection deletion
26
+ */
27
+ async function executeDeleteCollection(
28
+ input: z.infer<typeof ragDeleteCollectionSchema>,
29
+ _context: ToolExecutionContext
30
+ ): Promise<ToolResponse> {
31
+ const { name, confirm = false } = input;
32
+
33
+ if (!confirm) {
34
+ return {
35
+ success: false,
36
+ error: "Deletion requires confirmation. Set confirm=true to proceed.",
37
+ warning: `This will permanently delete the collection '${name}' and all its documents.`,
38
+ };
39
+ }
40
+
41
+ const ragService = RAGService.getInstance();
42
+ await ragService.deleteCollection(name);
43
+
44
+ return {
45
+ success: true,
46
+ message: `Collection '${name}' has been permanently deleted`,
47
+ deleted_collection: name,
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Delete a RAG collection and all its documents
53
+ */
54
+ export function createRAGDeleteCollectionTool(context: ToolExecutionContext): AISdkTool {
55
+ return tool({
56
+ description:
57
+ "Delete a RAG collection and all its documents. This action is permanent and requires confirmation.",
58
+ inputSchema: ragDeleteCollectionSchema,
59
+ execute: async (input: unknown) => {
60
+ return executeToolWithErrorHandling(
61
+ "rag_delete_collection",
62
+ input as z.infer<typeof ragDeleteCollectionSchema>,
63
+ context,
64
+ executeDeleteCollection
65
+ );
66
+ },
67
+ }) as AISdkTool;
68
+ }