@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,14 @@
1
+ /**
2
+ * Scheduling service error types
3
+ */
4
+
5
+ /**
6
+ * Error thrown when attempting to start a project that is already running.
7
+ * This is a non-fatal condition during auto-boot - the project is already available.
8
+ */
9
+ export class ProjectAlreadyRunningError extends Error {
10
+ constructor(public readonly projectId: string) {
11
+ super(`Project already running: ${projectId}`);
12
+ this.name = "ProjectAlreadyRunningError";
13
+ }
14
+ }
@@ -0,0 +1,7 @@
1
+ export { SchedulerService } from "./SchedulerService";
2
+ export type {
3
+ ScheduledTask,
4
+ ProjectBootHandler,
5
+ ProjectStateResolver,
6
+ TargetPubkeyResolver,
7
+ } from "./SchedulerService";
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Utility functions for scheduling operations.
3
+ * Shared between the scheduler service and tools.
4
+ */
5
+
6
+ /**
7
+ * Parse a relative time string (e.g., "5m", "2h", "3d") into milliseconds.
8
+ * Supported formats:
9
+ * - Xm: X minutes
10
+ * - Xh: X hours
11
+ * - Xd: X days
12
+ *
13
+ * @param delay - The delay string to parse
14
+ * @returns The delay in milliseconds, or null if the format is invalid
15
+ */
16
+ export function parseRelativeDelay(delay: string): number | null {
17
+ const match = delay.match(/^(\d+(?:\.\d+)?)\s*(m|h|d)$/i);
18
+ if (!match) {
19
+ return null;
20
+ }
21
+
22
+ const value = Number.parseFloat(match[1]);
23
+ const unit = match[2].toLowerCase();
24
+
25
+ switch (unit) {
26
+ case "m":
27
+ return value * 60 * 1000; // minutes to ms
28
+ case "h":
29
+ return value * 60 * 60 * 1000; // hours to ms
30
+ case "d":
31
+ return value * 24 * 60 * 60 * 1000; // days to ms
32
+ default:
33
+ return null;
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Format a delay string in human-readable form.
39
+ *
40
+ * @param delay - The delay string (e.g., "5m", "2h", "3d")
41
+ * @returns A human-readable string (e.g., "5 minutes", "2 hours", "3 days")
42
+ */
43
+ export function formatDelay(delay: string): string {
44
+ const match = delay.match(/^(\d+(?:\.\d+)?)\s*(m|h|d)$/i);
45
+ if (!match) return delay;
46
+
47
+ const value = Number.parseFloat(match[1]);
48
+ const unit = match[2].toLowerCase();
49
+
50
+ const unitNames: Record<string, string> = {
51
+ m: value === 1 ? "minute" : "minutes",
52
+ h: value === 1 ? "hour" : "hours",
53
+ d: value === 1 ? "day" : "days",
54
+ };
55
+
56
+ return `${value} ${unitNames[unit]}`;
57
+ }
58
+
59
+ /**
60
+ * Format an ISO timestamp in a human-readable format with UTC timezone.
61
+ * Handles invalid dates gracefully.
62
+ *
63
+ * @param isoString - The ISO date string to format
64
+ * @returns A formatted string like "Jan 30, 2024, 10:00 AM UTC" or "Invalid date" for invalid input
65
+ */
66
+ export function formatExecuteAt(isoString: string): string {
67
+ const date = new Date(isoString);
68
+ if (Number.isNaN(date.getTime())) {
69
+ return "Invalid date";
70
+ }
71
+
72
+ return `${date.toLocaleString("en-US", {
73
+ dateStyle: "medium",
74
+ timeStyle: "short",
75
+ timeZone: "UTC",
76
+ })} UTC`;
77
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * SearchProviderRegistry - Registry for search providers.
3
+ *
4
+ * Holds all registered search providers and provides lookup by name.
5
+ * Providers are registered during application bootstrap.
6
+ */
7
+
8
+ import type { SearchProvider } from "./types";
9
+
10
+ export class SearchProviderRegistry {
11
+ private static instance: SearchProviderRegistry | null = null;
12
+ private providers = new Map<string, SearchProvider>();
13
+
14
+ private constructor() {}
15
+
16
+ public static getInstance(): SearchProviderRegistry {
17
+ if (!SearchProviderRegistry.instance) {
18
+ SearchProviderRegistry.instance = new SearchProviderRegistry();
19
+ }
20
+ return SearchProviderRegistry.instance;
21
+ }
22
+
23
+ /**
24
+ * Register a search provider.
25
+ * @param provider - The search provider to register
26
+ */
27
+ public register(provider: SearchProvider): void {
28
+ this.providers.set(provider.name, provider);
29
+ }
30
+
31
+ /**
32
+ * Get a provider by name.
33
+ */
34
+ public get(name: string): SearchProvider | undefined {
35
+ return this.providers.get(name);
36
+ }
37
+
38
+ /**
39
+ * Get all registered providers.
40
+ */
41
+ public getAll(): SearchProvider[] {
42
+ return Array.from(this.providers.values());
43
+ }
44
+
45
+ /**
46
+ * Get provider names.
47
+ */
48
+ public getNames(): string[] {
49
+ return Array.from(this.providers.keys());
50
+ }
51
+
52
+ /**
53
+ * Check if a provider is registered.
54
+ */
55
+ public has(name: string): boolean {
56
+ return this.providers.has(name);
57
+ }
58
+
59
+ /**
60
+ * Get providers filtered by collection names.
61
+ * If no names provided, returns all providers.
62
+ */
63
+ public getByNames(names?: string[]): SearchProvider[] {
64
+ if (!names || names.length === 0) {
65
+ return this.getAll();
66
+ }
67
+ return names
68
+ .map((name) => this.providers.get(name))
69
+ .filter((p): p is SearchProvider => p !== undefined);
70
+ }
71
+
72
+ /**
73
+ * Reset singleton (for testing).
74
+ */
75
+ public static resetInstance(): void {
76
+ SearchProviderRegistry.instance = null;
77
+ }
78
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * UnifiedSearchService - Orchestrates search across all RAG collections.
3
+ *
4
+ * Queries all registered search providers in parallel, merges results
5
+ * by relevance score, and optionally applies LLM extraction when a
6
+ * prompt is provided.
7
+ *
8
+ * Key behaviors:
9
+ * - Parallel queries across all providers
10
+ * - Graceful degradation: one collection failure doesn't block others
11
+ * - Project-scoped isolation via projectId
12
+ * - Optional LLM extraction with configurable prompt
13
+ */
14
+
15
+ import { logger } from "@/utils/logger";
16
+ import { config as configService } from "@/services/ConfigService";
17
+ import { SearchProviderRegistry } from "./SearchProviderRegistry";
18
+ import type { SearchOptions, SearchResult, UnifiedSearchOutput } from "./types";
19
+
20
+ /** Default search parameters */
21
+ const DEFAULT_LIMIT = 10;
22
+ const DEFAULT_MIN_SCORE = 0.3;
23
+
24
+ export class UnifiedSearchService {
25
+ private static instance: UnifiedSearchService | null = null;
26
+ private registry: SearchProviderRegistry;
27
+
28
+ private constructor() {
29
+ this.registry = SearchProviderRegistry.getInstance();
30
+ }
31
+
32
+ public static getInstance(): UnifiedSearchService {
33
+ if (!UnifiedSearchService.instance) {
34
+ UnifiedSearchService.instance = new UnifiedSearchService();
35
+ }
36
+ return UnifiedSearchService.instance;
37
+ }
38
+
39
+ /**
40
+ * Perform a unified search across all (or selected) collections.
41
+ */
42
+ public async search(options: SearchOptions): Promise<UnifiedSearchOutput> {
43
+ const {
44
+ query,
45
+ projectId,
46
+ limit = DEFAULT_LIMIT,
47
+ minScore = DEFAULT_MIN_SCORE,
48
+ prompt,
49
+ collections,
50
+ } = options;
51
+
52
+ logger.info("🔍 [UnifiedSearch] Starting search", {
53
+ query,
54
+ projectId,
55
+ limit,
56
+ minScore,
57
+ prompt: prompt ? `${prompt.substring(0, 50)}...` : undefined,
58
+ collections: collections || "all",
59
+ });
60
+
61
+ // Get providers to search
62
+ const providers = this.registry.getByNames(collections);
63
+ if (providers.length === 0) {
64
+ logger.warn("[UnifiedSearch] No search providers available");
65
+ return {
66
+ success: true,
67
+ results: [],
68
+ totalResults: 0,
69
+ query,
70
+ collectionsSearched: [],
71
+ warnings: ["No search collections are available. RAG may not be initialized."],
72
+ };
73
+ }
74
+
75
+ // Query all providers in parallel with graceful degradation
76
+ const searchPromises = providers.map(async (provider) => {
77
+ try {
78
+ const results = await provider.search(query, projectId, limit, minScore);
79
+ return { name: provider.name, results, error: null };
80
+ } catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ logger.warn(`[UnifiedSearch] Provider '${provider.name}' failed`, {
83
+ error: message,
84
+ });
85
+ return { name: provider.name, results: [] as SearchResult[], error: message };
86
+ }
87
+ });
88
+
89
+ const providerResults = await Promise.all(searchPromises);
90
+
91
+ // Collect results and track errors
92
+ const allResults: SearchResult[] = [];
93
+ const collectionsSearched: string[] = [];
94
+ const collectionsErrored: string[] = [];
95
+ const warnings: string[] = [];
96
+
97
+ for (const { name, results, error } of providerResults) {
98
+ if (error) {
99
+ collectionsErrored.push(name);
100
+ warnings.push(`Collection '${name}' search failed: ${error}`);
101
+ } else {
102
+ collectionsSearched.push(name);
103
+ allResults.push(...results);
104
+ }
105
+ }
106
+
107
+ // Sort all results by relevance score (highest first)
108
+ allResults.sort((a, b) => b.relevanceScore - a.relevanceScore);
109
+
110
+ // Apply overall limit
111
+ const limitedResults = allResults.slice(0, limit);
112
+
113
+ // Optional LLM extraction when prompt is provided
114
+ let extraction: string | undefined;
115
+ if (prompt && limitedResults.length > 0) {
116
+ extraction = await this.extractWithLLM(query, prompt, limitedResults);
117
+ }
118
+
119
+ logger.info("✅ [UnifiedSearch] Search complete", {
120
+ query,
121
+ totalResults: limitedResults.length,
122
+ collectionsSearched,
123
+ collectionsErrored: collectionsErrored.length > 0 ? collectionsErrored : undefined,
124
+ hasExtraction: !!extraction,
125
+ });
126
+
127
+ return {
128
+ success: true,
129
+ results: limitedResults,
130
+ totalResults: limitedResults.length,
131
+ query,
132
+ collectionsSearched,
133
+ ...(collectionsErrored.length > 0 && { collectionsErrored }),
134
+ ...(warnings.length > 0 && { warnings }),
135
+ ...(extraction && { extraction }),
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Use a fast/cheap LLM to extract focused information from search results.
141
+ *
142
+ * Uses the 'summarization' config if available, falls back to 'search',
143
+ * then falls back to the default LLM config.
144
+ */
145
+ private async extractWithLLM(
146
+ query: string,
147
+ prompt: string,
148
+ results: SearchResult[]
149
+ ): Promise<string | undefined> {
150
+ try {
151
+ // Try to find a fast/cheap model config
152
+ const configName = this.getExtractionModelConfig();
153
+ if (!configName) {
154
+ logger.debug("[UnifiedSearch] No LLM config available for extraction");
155
+ return undefined;
156
+ }
157
+
158
+ const llmService = configService.createLLMService(configName);
159
+
160
+ // Build context from search results
161
+ const resultContext = results
162
+ .map((r, i) => {
163
+ const parts = [`[${i + 1}] (${r.source}) ${r.title}`];
164
+ if (r.summary) parts.push(` ${r.summary}`);
165
+ if (r.tags?.length) parts.push(` Tags: ${r.tags.join(", ")}`);
166
+ return parts.join("\n");
167
+ })
168
+ .join("\n\n");
169
+
170
+ const systemPrompt =
171
+ "You are a search result extraction assistant. " +
172
+ "Given search results and a specific prompt, extract and synthesize " +
173
+ "the most relevant information. Be concise and focused. " +
174
+ "Reference results by their number when citing information.";
175
+
176
+ const userPrompt =
177
+ `Search query: "${query}"\n\n` +
178
+ `Extraction prompt: ${prompt}\n\n` +
179
+ `Search results:\n${resultContext}\n\n` +
180
+ "Based on these search results, provide a focused extraction addressing the prompt.";
181
+
182
+ const result = await llmService.generateText([
183
+ { role: "system", content: systemPrompt },
184
+ { role: "user", content: userPrompt },
185
+ ]);
186
+
187
+ return result.text;
188
+ } catch (error) {
189
+ const message = error instanceof Error ? error.message : String(error);
190
+ logger.warn("[UnifiedSearch] LLM extraction failed", { error: message });
191
+ return undefined;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Get the best available LLM config name for extraction.
197
+ * Priority: search config (typically fast/cheap) > undefined (createLLMService uses default)
198
+ */
199
+ private getExtractionModelConfig(): string | undefined {
200
+ try {
201
+ // Try search config first (typically configured as a fast/cheap model)
202
+ const search = configService.getSearchModelName();
203
+ if (search) return search;
204
+ } catch {
205
+ // Not available
206
+ }
207
+
208
+ // Return undefined - createLLMService will use default config with fallback
209
+ return undefined;
210
+ }
211
+
212
+ /**
213
+ * Reset singleton (for testing).
214
+ */
215
+ public static resetInstance(): void {
216
+ UnifiedSearchService.instance = null;
217
+ }
218
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Unified Search Module
3
+ *
4
+ * Provides cross-collection semantic search across reports,
5
+ * conversations, and lessons within project boundaries.
6
+ */
7
+
8
+ export { buildProjectFilter } from "./projectFilter";
9
+ export { SearchProviderRegistry } from "./SearchProviderRegistry";
10
+ export { UnifiedSearchService } from "./UnifiedSearchService";
11
+ export type {
12
+ SearchOptions,
13
+ SearchProvider,
14
+ SearchResult,
15
+ UnifiedSearchOutput,
16
+ } from "./types";
17
+
18
+ // Providers
19
+ export { ReportSearchProvider } from "./providers/ReportSearchProvider";
20
+ export { ConversationSearchProvider } from "./providers/ConversationSearchProvider";
21
+ export { LessonSearchProvider } from "./providers/LessonSearchProvider";
22
+
23
+ import { SearchProviderRegistry } from "./SearchProviderRegistry";
24
+ import { ReportSearchProvider } from "./providers/ReportSearchProvider";
25
+ import { ConversationSearchProvider } from "./providers/ConversationSearchProvider";
26
+ import { LessonSearchProvider } from "./providers/LessonSearchProvider";
27
+
28
+ /**
29
+ * Bootstrap all search providers.
30
+ * Call this during application initialization after RAG services are available.
31
+ * Idempotent - safe to call multiple times.
32
+ */
33
+ export function bootstrapSearchProviders(): void {
34
+ const registry = SearchProviderRegistry.getInstance();
35
+
36
+ if (!registry.has("reports")) {
37
+ registry.register(new ReportSearchProvider());
38
+ }
39
+
40
+ if (!registry.has("conversations")) {
41
+ registry.register(new ConversationSearchProvider());
42
+ }
43
+
44
+ if (!registry.has("lessons")) {
45
+ registry.register(new LessonSearchProvider());
46
+ }
47
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Centralized SQL project filter for RAG queries.
3
+ *
4
+ * Shared utility for the `metadata LIKE '%"projectId":"..."'` SQL prefilter pattern
5
+ * used across all project-scoped RAG collections (reports, conversations, lessons).
6
+ *
7
+ * Applied DURING vector search (prefilter) to ensure proper project isolation.
8
+ */
9
+
10
+ /**
11
+ * Build a SQL prefilter string for project isolation in LanceDB queries.
12
+ *
13
+ * @param projectId - The project ID to filter by. Pass 'ALL' or undefined to skip filtering.
14
+ * @returns SQL filter string or undefined if no filtering needed.
15
+ */
16
+ export function buildProjectFilter(projectId?: string): string | undefined {
17
+ if (!projectId || projectId.toLowerCase() === "all") {
18
+ return undefined;
19
+ }
20
+ const escapedProjectId = projectId.replace(/'/g, "''");
21
+ return `metadata LIKE '%"projectId":"${escapedProjectId}"%'`;
22
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * ConversationSearchProvider - Search provider for conversations.
3
+ *
4
+ * Queries the `conversation_embeddings` RAG collection via ConversationEmbeddingService.
5
+ */
6
+
7
+ import { logger } from "@/utils/logger";
8
+ import { getConversationEmbeddingService } from "@/conversations/search/embeddings";
9
+ import type { SearchProvider, SearchResult } from "../types";
10
+
11
+ export class ConversationSearchProvider implements SearchProvider {
12
+ readonly name = "conversations";
13
+ readonly description = "Past conversation threads and discussions";
14
+
15
+ async search(
16
+ query: string,
17
+ projectId: string,
18
+ limit: number,
19
+ minScore: number
20
+ ): Promise<SearchResult[]> {
21
+ const conversationEmbeddingService = getConversationEmbeddingService();
22
+
23
+ const results = await conversationEmbeddingService.semanticSearch(query, {
24
+ limit,
25
+ minScore,
26
+ projectId,
27
+ });
28
+
29
+ logger.debug("[ConversationSearchProvider] Search complete", {
30
+ query,
31
+ projectId,
32
+ found: results.length,
33
+ });
34
+
35
+ return results.map((result) => ({
36
+ source: this.name,
37
+ id: result.conversationId,
38
+ projectId: result.projectId || projectId,
39
+ relevanceScore: result.relevanceScore,
40
+ title: result.title || "",
41
+ summary: result.summary || "",
42
+ createdAt: result.createdAt,
43
+ updatedAt: result.lastActivity,
44
+ retrievalTool: "conversation_get" as const,
45
+ retrievalArg: result.conversationId,
46
+ }));
47
+ }
48
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * LessonSearchProvider - Search provider for lessons.
3
+ *
4
+ * Queries the `lessons` RAG collection directly via RAGService
5
+ * since lessons don't have a dedicated embedding service like
6
+ * reports and conversations do.
7
+ */
8
+
9
+ import { logger } from "@/utils/logger";
10
+ import { RAGService, type RAGQueryResult } from "@/services/rag/RAGService";
11
+ import { buildProjectFilter } from "../projectFilter";
12
+ import type { SearchProvider, SearchResult } from "../types";
13
+
14
+ /** Collection name for lessons (matches what learn.ts uses) */
15
+ const LESSONS_COLLECTION = "lessons";
16
+
17
+ export class LessonSearchProvider implements SearchProvider {
18
+ readonly name = "lessons";
19
+ readonly description = "Agent lessons and insights";
20
+
21
+ async search(
22
+ query: string,
23
+ projectId: string,
24
+ limit: number,
25
+ minScore: number
26
+ ): Promise<SearchResult[]> {
27
+ const ragService = RAGService.getInstance();
28
+
29
+ // Check if the lessons collection exists
30
+ const collections = await ragService.listCollections();
31
+ if (!collections.includes(LESSONS_COLLECTION)) {
32
+ logger.debug("[LessonSearchProvider] Lessons collection does not exist");
33
+ return [];
34
+ }
35
+
36
+ const filter = buildProjectFilter(projectId);
37
+
38
+ const results = await ragService.queryWithFilter(
39
+ LESSONS_COLLECTION,
40
+ query,
41
+ limit * 2, // Request more to account for minScore filtering
42
+ filter
43
+ );
44
+
45
+ logger.debug("[LessonSearchProvider] Search complete", {
46
+ query,
47
+ projectId,
48
+ rawResults: results.length,
49
+ });
50
+
51
+ return results
52
+ .filter((result: RAGQueryResult) => result.score >= minScore)
53
+ .slice(0, limit)
54
+ .map((result: RAGQueryResult) => this.transformResult(result, projectId));
55
+ }
56
+
57
+ private transformResult(result: RAGQueryResult, fallbackProjectId: string): SearchResult {
58
+ const metadata = result.document.metadata || {};
59
+
60
+ return {
61
+ source: this.name,
62
+ id: result.document.id || "",
63
+ projectId: String(metadata.projectId || fallbackProjectId),
64
+ relevanceScore: result.score,
65
+ title: String(metadata.title || ""),
66
+ summary: result.document.content?.substring(0, 200) || "",
67
+ createdAt: metadata.timestamp ? Number(metadata.timestamp) : undefined,
68
+ author: String(metadata.agentPubkey || ""),
69
+ authorName: String(metadata.agentName || ""),
70
+ tags: Array.isArray(metadata.hashtags) ? (metadata.hashtags as string[]) : undefined,
71
+ retrievalTool: "lesson_get" as const,
72
+ retrievalArg: result.document.id || "",
73
+ };
74
+ }
75
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * ReportSearchProvider - Search provider for project reports.
3
+ *
4
+ * Queries the `project_reports` RAG collection via ReportEmbeddingService.
5
+ */
6
+
7
+ import { logger } from "@/utils/logger";
8
+ import { getReportEmbeddingService } from "@/services/reports/ReportEmbeddingService";
9
+ import type { SearchProvider, SearchResult } from "../types";
10
+
11
+ export class ReportSearchProvider implements SearchProvider {
12
+ readonly name = "reports";
13
+ readonly description = "Project reports and documentation";
14
+
15
+ async search(
16
+ query: string,
17
+ projectId: string,
18
+ limit: number,
19
+ minScore: number
20
+ ): Promise<SearchResult[]> {
21
+ const reportEmbeddingService = getReportEmbeddingService();
22
+
23
+ const results = await reportEmbeddingService.semanticSearch(query, {
24
+ limit,
25
+ minScore,
26
+ projectId,
27
+ });
28
+
29
+ logger.debug("[ReportSearchProvider] Search complete", {
30
+ query,
31
+ projectId,
32
+ found: results.length,
33
+ });
34
+
35
+ return results.map((result) => ({
36
+ source: this.name,
37
+ id: result.slug,
38
+ projectId: result.projectId,
39
+ relevanceScore: result.relevanceScore,
40
+ title: result.title,
41
+ summary: result.summary || "",
42
+ createdAt: result.publishedAt,
43
+ author: result.author,
44
+ tags: result.hashtags,
45
+ retrievalTool: "report_read" as const,
46
+ retrievalArg: result.slug,
47
+ }));
48
+ }
49
+ }