@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,484 @@
1
+ /**
2
+ * ConversationEmbeddingService - Semantic search for conversations
3
+ *
4
+ * This service manages embeddings for conversation summaries to enable
5
+ * natural language semantic search across conversations.
6
+ *
7
+ * Key features:
8
+ * - Embeds conversation summaries (not individual messages - too expensive)
9
+ * - Uses existing RAG infrastructure (LanceDB, embedding providers)
10
+ * - Supports hybrid search (semantic + keyword fallback)
11
+ * - Graceful degradation when embeddings unavailable
12
+ * - Project isolation: filters are applied DURING vector search (prefilter)
13
+ * - Upsert semantics: re-indexing updates existing documents
14
+ */
15
+
16
+ import { logger } from "@/utils/logger";
17
+ import { RAGService, type RAGDocument, type RAGQueryResult } from "@/services/rag/RAGService";
18
+ import { ConversationStore } from "@/conversations/ConversationStore";
19
+ import { conversationRegistry } from "@/conversations/ConversationRegistry";
20
+
21
+ /** Collection name for conversation embeddings */
22
+ const CONVERSATION_COLLECTION = "conversation_embeddings";
23
+
24
+ /**
25
+ * Document structure for conversation embeddings
26
+ */
27
+ export interface ConversationEmbeddingDocument {
28
+ conversationId: string;
29
+ projectId: string;
30
+ title: string;
31
+ summary?: string;
32
+ embeddingContent: string; // Combined text used for embedding
33
+ messageCount: number;
34
+ createdAt?: number;
35
+ lastActivity?: number;
36
+ }
37
+
38
+ /**
39
+ * Result from semantic search
40
+ */
41
+ export interface SemanticSearchResult {
42
+ conversationId: string;
43
+ projectId?: string;
44
+ title?: string;
45
+ summary?: string;
46
+ messageCount: number;
47
+ createdAt?: number;
48
+ lastActivity?: number;
49
+ relevanceScore: number;
50
+ }
51
+
52
+ /**
53
+ * Discriminated union result from buildDocument.
54
+ * Distinguishes between "no indexable content" and transient errors
55
+ * so the caller can decide whether to permanently mark as indexed
56
+ * or leave for retry.
57
+ */
58
+ export type BuildDocumentResult =
59
+ | { kind: "ok"; document: RAGDocument }
60
+ | { kind: "noContent" }
61
+ | { kind: "error"; reason: string };
62
+
63
+ /**
64
+ * Options for semantic search
65
+ */
66
+ export interface SemanticSearchOptions {
67
+ limit?: number;
68
+ minScore?: number;
69
+ projectId?: string; // Filter by project, 'ALL' for all projects
70
+ }
71
+
72
+ /**
73
+ * Service for managing conversation embeddings and semantic search
74
+ */
75
+ export class ConversationEmbeddingService {
76
+ private static instance: ConversationEmbeddingService | null = null;
77
+ private ragService: RAGService;
78
+ private initialized = false;
79
+ private initializationPromise: Promise<void> | null = null;
80
+
81
+ private constructor() {
82
+ this.ragService = RAGService.getInstance();
83
+ }
84
+
85
+ /**
86
+ * Get singleton instance
87
+ */
88
+ public static getInstance(): ConversationEmbeddingService {
89
+ if (!ConversationEmbeddingService.instance) {
90
+ ConversationEmbeddingService.instance = new ConversationEmbeddingService();
91
+ }
92
+ return ConversationEmbeddingService.instance;
93
+ }
94
+
95
+ /**
96
+ * Initialize the service (creates collection if needed)
97
+ * FIX #4: Clear initializationPromise on failure to allow retries
98
+ */
99
+ public async initialize(): Promise<void> {
100
+ if (this.initialized) return;
101
+ if (this.initializationPromise) return this.initializationPromise;
102
+
103
+ this.initializationPromise = this.doInitialize();
104
+ try {
105
+ await this.initializationPromise;
106
+ } catch (error) {
107
+ // Clear promise on failure so subsequent calls can retry
108
+ this.initializationPromise = null;
109
+ throw error;
110
+ }
111
+ }
112
+
113
+ private async doInitialize(): Promise<void> {
114
+ try {
115
+ logger.debug("Initializing ConversationEmbeddingService");
116
+
117
+ // Check if collection exists
118
+ const collections = await this.ragService.listCollections();
119
+ if (!collections.includes(CONVERSATION_COLLECTION)) {
120
+ // Create the collection
121
+ await this.ragService.createCollection(CONVERSATION_COLLECTION);
122
+ logger.info(`Created conversation embeddings collection: ${CONVERSATION_COLLECTION}`);
123
+ }
124
+
125
+ this.initialized = true;
126
+ logger.info("ConversationEmbeddingService initialized successfully");
127
+ } catch (error) {
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ logger.error("Failed to initialize ConversationEmbeddingService", { error: message });
130
+ throw new Error(`ConversationEmbeddingService initialization failed: ${message}`, { cause: error });
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Ensure service is initialized before operations
136
+ */
137
+ private async ensureInitialized(): Promise<void> {
138
+ if (!this.initialized) {
139
+ await this.initialize();
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Build embedding content from conversation metadata
145
+ * Combines title and summary for richer semantic matching
146
+ */
147
+ private buildEmbeddingContent(
148
+ title?: string,
149
+ summary?: string,
150
+ lastUserMessage?: string
151
+ ): string {
152
+ const parts: string[] = [];
153
+
154
+ if (title) {
155
+ parts.push(`Title: ${title}`);
156
+ }
157
+
158
+ if (summary) {
159
+ parts.push(`Summary: ${summary}`);
160
+ }
161
+
162
+ // Include last user message for additional context
163
+ if (lastUserMessage) {
164
+ // Truncate if too long
165
+ const truncated = lastUserMessage.length > 500
166
+ ? lastUserMessage.substring(0, 500) + "..."
167
+ : lastUserMessage;
168
+ parts.push(`Last message: ${truncated}`);
169
+ }
170
+
171
+ return parts.join("\n\n");
172
+ }
173
+
174
+ /**
175
+ * Build a RAGDocument for a conversation without writing it to the database.
176
+ *
177
+ * Returns a discriminated union:
178
+ * - `{ kind: 'ok', document }` when a document was successfully built
179
+ * - `{ kind: 'noContent' }` when the conversation has no indexable content
180
+ * - `{ kind: 'error', reason }` on transient failures (registry miss, etc.)
181
+ *
182
+ * Used by ConversationIndexingJob to collect documents for batch writing.
183
+ */
184
+ public buildDocument(
185
+ conversationId: string,
186
+ projectId: string,
187
+ store?: ConversationStore
188
+ ): BuildDocumentResult {
189
+ try {
190
+ // Load store if not provided
191
+ if (!store) {
192
+ store = conversationRegistry.get(conversationId);
193
+ if (!store) {
194
+ // Not in registry means zero messages loaded — genuinely no content to embed
195
+ logger.debug(`Conversation ${conversationId.substring(0, 8)} not in registry, no content`);
196
+ return { kind: "noContent" };
197
+ }
198
+ }
199
+
200
+ const messages = store.getAllMessages();
201
+ const metadata = store.metadata;
202
+ const title = metadata.title ?? store.title;
203
+ const summary = metadata.summary;
204
+ const lastUserMessage = metadata.last_user_message;
205
+
206
+ // Build embedding content
207
+ const embeddingContent = this.buildEmbeddingContent(title, summary, lastUserMessage);
208
+
209
+ // Skip if no content to embed
210
+ if (!embeddingContent.trim()) {
211
+ logger.debug(`No content to embed for conversation ${conversationId.substring(0, 8)}`);
212
+ return { kind: "noContent" };
213
+ }
214
+
215
+ const firstMessage = messages[0];
216
+ const lastMessage = messages[messages.length - 1];
217
+
218
+ const documentId = `conv_${projectId}_${conversationId}`;
219
+
220
+ return {
221
+ kind: "ok",
222
+ document: {
223
+ id: documentId,
224
+ content: embeddingContent,
225
+ metadata: {
226
+ conversationId,
227
+ projectId,
228
+ title: title || "",
229
+ summary: summary || "",
230
+ messageCount: messages.length,
231
+ createdAt: firstMessage?.timestamp,
232
+ lastActivity: lastMessage?.timestamp,
233
+ },
234
+ timestamp: lastMessage?.timestamp || Date.now(),
235
+ source: "conversation",
236
+ },
237
+ };
238
+ } catch (error) {
239
+ const message = error instanceof Error ? error.message : String(error);
240
+ logger.error("Failed to build document for conversation", {
241
+ conversationId: conversationId.substring(0, 8),
242
+ error: message,
243
+ });
244
+ return { kind: "error", reason: message };
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Index a single conversation
250
+ * FIX #3: Returns boolean indicating success for accurate counting
251
+ *
252
+ * Note on project validation (FIX #5): Since we iterate conversations using
253
+ * `listConversationIdsFromDiskForProject(projectId)`, the conversation is already
254
+ * guaranteed to exist in that project's directory. The projectId is embedded
255
+ * in the document ID (`conv_${projectId}_${conversationId}`) for query filtering.
256
+ */
257
+ public async indexConversation(
258
+ conversationId: string,
259
+ projectId: string,
260
+ store?: ConversationStore
261
+ ): Promise<boolean> {
262
+ await this.ensureInitialized();
263
+
264
+ try {
265
+ const result = this.buildDocument(conversationId, projectId, store);
266
+
267
+ if (result.kind !== "ok") {
268
+ return false;
269
+ }
270
+
271
+ const document = result.document;
272
+ // buildDocument always sets document.id — use it as the single source of truth
273
+ const documentId = document.id ?? `conv_${projectId}_${conversationId}`;
274
+
275
+ // Delete existing document before inserting (upsert semantics)
276
+ // This prevents duplicate entries when re-indexing
277
+ try {
278
+ await this.ragService.deleteDocumentById(CONVERSATION_COLLECTION, documentId);
279
+ logger.debug(`Deleted existing embedding for ${conversationId.substring(0, 8)}`);
280
+ } catch {
281
+ // Document might not exist - that's fine
282
+ }
283
+
284
+ // Add to collection
285
+ await this.ragService.addDocuments(CONVERSATION_COLLECTION, [document]);
286
+
287
+ logger.debug(`Indexed conversation ${conversationId.substring(0, 8)} for project ${projectId}`);
288
+ return true;
289
+ } catch (error) {
290
+ const message = error instanceof Error ? error.message : String(error);
291
+ logger.error("Failed to index conversation", {
292
+ conversationId: conversationId.substring(0, 8),
293
+ error: message,
294
+ });
295
+ // Don't throw - indexing failures shouldn't break the application
296
+ return false;
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Get the collection name for conversation embeddings.
302
+ * Exposed for use by ConversationIndexingJob for batch operations.
303
+ */
304
+ public getCollectionName(): string {
305
+ return CONVERSATION_COLLECTION;
306
+ }
307
+
308
+ /**
309
+ * Index all conversations for a project
310
+ * FIX #3: Only count successful indexings
311
+ */
312
+ public async indexProjectConversations(projectId: string): Promise<number> {
313
+ await this.ensureInitialized();
314
+
315
+ let indexed = 0;
316
+ const conversationIds = conversationRegistry.listConversationIdsFromDiskForProject(projectId);
317
+
318
+ logger.info(`Indexing ${conversationIds.length} conversations for project ${projectId}`);
319
+
320
+ for (const conversationId of conversationIds) {
321
+ const success = await this.indexConversation(conversationId, projectId);
322
+ if (success) {
323
+ indexed++;
324
+ }
325
+ }
326
+
327
+ logger.info(`Indexed ${indexed}/${conversationIds.length} conversations for project ${projectId}`);
328
+ return indexed;
329
+ }
330
+
331
+ /**
332
+ * Index all conversations across all projects
333
+ */
334
+ public async indexAllConversations(): Promise<number> {
335
+ await this.ensureInitialized();
336
+
337
+ let totalIndexed = 0;
338
+ const projectIds = conversationRegistry.listProjectIdsFromDisk();
339
+
340
+ logger.info(`Indexing conversations across ${projectIds.length} projects`);
341
+
342
+ for (const projectId of projectIds) {
343
+ const indexed = await this.indexProjectConversations(projectId);
344
+ totalIndexed += indexed;
345
+ }
346
+
347
+ logger.info(`Total indexed: ${totalIndexed} conversations`);
348
+ return totalIndexed;
349
+ }
350
+
351
+ /**
352
+ * Build SQL filter for project isolation
353
+ * FIX #1: This filter is applied DURING vector search (prefilter), not after
354
+ */
355
+ private buildProjectFilter(projectId?: string): string | undefined {
356
+ if (!projectId || projectId.toLowerCase() === "all") {
357
+ return undefined;
358
+ }
359
+ // Filter on the metadata JSON string - LanceDB stores metadata as JSON string
360
+ // We need to match the projectId within the serialized JSON
361
+ const escapedProjectId = projectId.replace(/'/g, "''");
362
+ return `metadata LIKE '%"projectId":"${escapedProjectId}"%'`;
363
+ }
364
+
365
+ /**
366
+ * Perform semantic search on conversations
367
+ * FIX #1: Project filter is now applied DURING vector search (prefilter),
368
+ * ensuring proper project isolation without leakage from other projects
369
+ */
370
+ public async semanticSearch(
371
+ query: string,
372
+ options: SemanticSearchOptions = {}
373
+ ): Promise<SemanticSearchResult[]> {
374
+ await this.ensureInitialized();
375
+
376
+ const { limit = 20, minScore = 0.3, projectId } = options;
377
+
378
+ try {
379
+ logger.info("🔍 Semantic search", { query, limit, minScore, projectId });
380
+
381
+ // FIX #1: Build SQL filter for project isolation - applied DURING vector search
382
+ const filter = this.buildProjectFilter(projectId);
383
+
384
+ // Perform RAG query with prefilter for project isolation
385
+ // Request more results to account for minScore filtering
386
+ const results = await this.ragService.queryWithFilter(
387
+ CONVERSATION_COLLECTION,
388
+ query,
389
+ limit * 2, // Request more to filter by minScore
390
+ filter
391
+ );
392
+
393
+ // Transform and filter by minScore only (project filtering already done)
394
+ const searchResults: SemanticSearchResult[] = results
395
+ .filter((result: RAGQueryResult) => result.score >= minScore)
396
+ .slice(0, limit)
397
+ .map((result: RAGQueryResult) => this.transformResult(result));
398
+
399
+ logger.info("✅ Semantic search complete", {
400
+ query,
401
+ found: searchResults.length,
402
+ limit,
403
+ projectFilter: filter || "none",
404
+ });
405
+
406
+ return searchResults;
407
+ } catch (error) {
408
+ const message = error instanceof Error ? error.message : String(error);
409
+ logger.error("Semantic search failed", { query, error: message });
410
+
411
+ // Return empty results on error - let caller fall back to keyword search
412
+ return [];
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Transform RAG result to SearchResult
418
+ */
419
+ private transformResult(result: RAGQueryResult): SemanticSearchResult {
420
+ const metadata = result.document.metadata || {};
421
+
422
+ return {
423
+ conversationId: String(metadata.conversationId || result.document.id || ""),
424
+ projectId: String(metadata.projectId || ""),
425
+ title: String(metadata.title || ""),
426
+ summary: String(metadata.summary || ""),
427
+ messageCount: Number(metadata.messageCount || 0),
428
+ createdAt: metadata.createdAt ? Number(metadata.createdAt) : undefined,
429
+ lastActivity: metadata.lastActivity ? Number(metadata.lastActivity) : undefined,
430
+ relevanceScore: result.score,
431
+ };
432
+ }
433
+
434
+ /**
435
+ * Check if the service has any indexed conversations
436
+ */
437
+ public async hasIndexedConversations(): Promise<boolean> {
438
+ try {
439
+ await this.ensureInitialized();
440
+ const collections = await this.ragService.listCollections();
441
+ return collections.includes(CONVERSATION_COLLECTION);
442
+ } catch {
443
+ return false;
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Get embedding provider info
449
+ */
450
+ public async getEmbeddingInfo(): Promise<string> {
451
+ await this.ensureInitialized();
452
+ return this.ragService.getEmbeddingProviderInfo();
453
+ }
454
+
455
+ /**
456
+ * Clear all conversation embeddings
457
+ */
458
+ public async clearIndex(): Promise<void> {
459
+ try {
460
+ await this.ragService.deleteCollection(CONVERSATION_COLLECTION);
461
+ logger.info("Cleared conversation embeddings index");
462
+ } catch (error) {
463
+ logger.debug("No index to clear or error clearing", { error });
464
+ }
465
+
466
+ // Reset initialization state
467
+ this.initialized = false;
468
+ this.initializationPromise = null;
469
+ }
470
+
471
+ /**
472
+ * Reset singleton instance (for testing)
473
+ */
474
+ public static resetInstance(): void {
475
+ if (ConversationEmbeddingService.instance) {
476
+ ConversationEmbeddingService.instance = null;
477
+ }
478
+ }
479
+ }
480
+
481
+ // Export lazy getter to avoid eagerly initializing at module load time
482
+ export function getConversationEmbeddingService(): ConversationEmbeddingService {
483
+ return ConversationEmbeddingService.getInstance();
484
+ }