@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,445 @@
1
+ import type { LLMService } from "@/llm/service";
2
+ import { shortenConversationId } from "@/utils/conversation-id";
3
+ import type { ConversationStore } from "@/conversations/ConversationStore";
4
+ import type { ConversationEntry } from "@/conversations/types";
5
+ import { trace, SpanStatusCode, type Span } from "@opentelemetry/api";
6
+ import { logger } from "@/utils/logger";
7
+ import { config } from "@/services/ConfigService";
8
+ import type {
9
+ CompressionSegment,
10
+ } from "./compression-types.js";
11
+ import {
12
+ CompressionSegmentsSchema,
13
+ type CompressionSegmentInput,
14
+ } from "./compression-schema.js";
15
+ import {
16
+ estimateTokensFromEntries,
17
+ selectCandidateRangeFromEntries,
18
+ validateSegmentsForEntries,
19
+ applySegmentsToEntries,
20
+ createFallbackSegmentForEntries,
21
+ } from "./compression-utils.js";
22
+
23
+ const tracer = trace.getTracer("tenex.compression");
24
+
25
+ /**
26
+ * CompressionService - Orchestrates conversation history compression.
27
+ *
28
+ * Works at the ConversationEntry level (storage layer) before messages
29
+ * are compiled for LLM consumption.
30
+ *
31
+ * LLM REQUIREMENTS:
32
+ * - Compression requires an LLM provider with structured output (JSON mode) support
33
+ * - If summarization fails (e.g., non-JSON-capable models like some Ollama models),
34
+ * the service gracefully falls back to sliding window truncation
35
+ * - Check telemetry events (compression.summary_failed) to diagnose failures
36
+ * - Recommended: Use OpenAI, Anthropic, or other providers with native JSON support
37
+ */
38
+ export class CompressionService {
39
+ private effectiveLlmService: LLMService;
40
+
41
+ constructor(
42
+ private conversationStore: ConversationStore,
43
+ llmService: LLMService,
44
+ compressionLlmService?: LLMService
45
+ ) {
46
+ // Use dedicated compression LLM if provided, otherwise fall back to agent's LLM
47
+ this.effectiveLlmService = compressionLlmService ?? llmService;
48
+ }
49
+
50
+ /**
51
+ * Non-blocking proactive compression.
52
+ * Called after each LLM response to compress old messages.
53
+ */
54
+ async maybeCompressAsync(conversationId: string): Promise<void> {
55
+ this.performCompression(conversationId, false).catch((error) => {
56
+ logger.warn("Proactive compression failed", {
57
+ conversationId,
58
+ error: error instanceof Error ? error.message : String(error),
59
+ });
60
+ });
61
+ }
62
+
63
+ /**
64
+ * Blocking reactive compression.
65
+ * Called when messages must fit within token budget.
66
+ * If tokenBudget is undefined, uses the configured default.
67
+ */
68
+ async ensureUnderLimit(
69
+ conversationId: string,
70
+ tokenBudget?: number
71
+ ): Promise<void> {
72
+ await this.performCompression(conversationId, true, tokenBudget);
73
+ }
74
+
75
+ /**
76
+ * Get existing compression segments for a conversation.
77
+ */
78
+ async getSegments(conversationId: string): Promise<CompressionSegment[]> {
79
+ return this.conversationStore.loadCompressionLog(conversationId);
80
+ }
81
+
82
+ /**
83
+ * Apply existing compression segments to entries.
84
+ * This is called by MessageBuilder to get compressed history.
85
+ */
86
+ applyExistingCompressions(
87
+ entries: ConversationEntry[],
88
+ segments: CompressionSegment[]
89
+ ): ConversationEntry[] {
90
+ return applySegmentsToEntries(entries, segments);
91
+ }
92
+
93
+ /**
94
+ * Internal method to perform compression.
95
+ * Only creates a span when actual compression work is performed to reduce telemetry noise.
96
+ */
97
+ private async performCompression(
98
+ conversationId: string,
99
+ blocking: boolean,
100
+ tokenBudget?: number
101
+ ): Promise<void> {
102
+ // Get all entries
103
+ const entries = this.conversationStore.getAllMessages();
104
+ const existingSegments =
105
+ await this.conversationStore.loadCompressionLog(conversationId);
106
+
107
+ // Get compression config
108
+ const compressionConfig = this.getCompressionConfig();
109
+ if (!compressionConfig.enabled) {
110
+ return;
111
+ }
112
+
113
+ const effectiveBudget = tokenBudget ?? compressionConfig.tokenBudget;
114
+ // Apply existing compressions before checking token count so we don't
115
+ // trigger unnecessary LLM calls when existing segments already cover old history.
116
+ const effectiveEntries = applySegmentsToEntries(entries, existingSegments);
117
+ const currentTokens = estimateTokensFromEntries(effectiveEntries);
118
+
119
+ // Check if compression is needed - exit early without creating span
120
+ if (
121
+ !blocking &&
122
+ currentTokens < compressionConfig.tokenThreshold
123
+ ) {
124
+ // Proactive mode: only compress if over threshold
125
+ return;
126
+ }
127
+
128
+ if (blocking && currentTokens <= effectiveBudget) {
129
+ // Already under budget
130
+ return;
131
+ }
132
+
133
+ // Compression IS needed - now create the span for actual work
134
+ return tracer.startActiveSpan("compression.perform", async (span) => {
135
+ try {
136
+ span.setAttribute("conversation.id", shortenConversationId(conversationId));
137
+ span.setAttribute("blocking", blocking);
138
+ span.setAttribute("entries.total", entries.length);
139
+ span.setAttribute("segments.existing", existingSegments.length);
140
+ span.setAttribute("tokens.current", currentTokens);
141
+ span.setAttribute("tokens.budget", effectiveBudget);
142
+
143
+ // Find range to compress
144
+ const range = selectCandidateRangeFromEntries(
145
+ entries,
146
+ existingSegments[existingSegments.length - 1] || null
147
+ );
148
+
149
+ if (!range) {
150
+ if (blocking && currentTokens > effectiveBudget) {
151
+ // Must compress but can't - use fallback
152
+ await this.useFallback(
153
+ conversationId,
154
+ entries,
155
+ compressionConfig.slidingWindowSize,
156
+ span
157
+ );
158
+ }
159
+ span.setStatus({ code: SpanStatusCode.OK });
160
+ return;
161
+ }
162
+
163
+ // Attempt LLM compression
164
+ try {
165
+ const rangeEntries = entries.slice(range.startIndex, range.endIndex);
166
+ const newSegments = await this.compressEntries(rangeEntries);
167
+
168
+ // Emit telemetry for successful summary generation
169
+ span.addEvent("compression.summary_generated", {
170
+ "segments.count": newSegments.length,
171
+ "model": this.effectiveLlmService.model,
172
+ });
173
+
174
+ // Validate segments
175
+ const validation = validateSegmentsForEntries(
176
+ newSegments,
177
+ entries,
178
+ range
179
+ );
180
+
181
+ if (!validation.valid) {
182
+ logger.warn("Compression segment validation failed", {
183
+ conversationId,
184
+ error: validation.error,
185
+ });
186
+
187
+ // Emit telemetry for validation failure
188
+ span.addEvent("compression.summary_failed", {
189
+ "reason": "validation_failed",
190
+ "error": validation.error,
191
+ });
192
+
193
+ if (blocking) {
194
+ await this.useFallback(
195
+ conversationId,
196
+ entries,
197
+ compressionConfig.slidingWindowSize,
198
+ span
199
+ );
200
+ }
201
+ return;
202
+ }
203
+
204
+ // Persist segments
205
+ await this.conversationStore.appendCompressionSegments(
206
+ conversationId,
207
+ newSegments
208
+ );
209
+
210
+ // Emit telemetry for reactive compression completion
211
+ if (blocking) {
212
+ span.addEvent("compression.reactive_applied", {
213
+ "segments.added": newSegments.length,
214
+ "tokens.before": currentTokens,
215
+ "tokens.budget": effectiveBudget,
216
+ });
217
+ }
218
+
219
+ span.setAttribute("segments.added", newSegments.length);
220
+ span.setStatus({ code: SpanStatusCode.OK });
221
+ } catch (error) {
222
+ const errorMessage = error instanceof Error ? error.message : String(error);
223
+ logger.warn("LLM compression failed", {
224
+ conversationId,
225
+ error: errorMessage,
226
+ blocking,
227
+ });
228
+
229
+ // Emit telemetry for LLM failure
230
+ span.addEvent("compression.summary_failed", {
231
+ "reason": "llm_error",
232
+ "error": errorMessage,
233
+ "blocking": blocking,
234
+ });
235
+
236
+ if (blocking) {
237
+ // Graceful degradation: use fallback truncation
238
+ await this.useFallback(
239
+ conversationId,
240
+ entries,
241
+ compressionConfig.slidingWindowSize,
242
+ span
243
+ );
244
+ } else {
245
+ // Proactive mode: fail silently, don't throw
246
+ // This prevents compression failures from breaking the main flow
247
+ logger.warn("Proactive compression skipped due to LLM error", {
248
+ conversationId,
249
+ });
250
+ }
251
+ }
252
+ } catch (error) {
253
+ span.recordException(error as Error);
254
+ span.setStatus({ code: SpanStatusCode.ERROR });
255
+ throw error;
256
+ } finally {
257
+ span.end();
258
+ }
259
+ });
260
+ }
261
+
262
+ /**
263
+ * Compress a range of entries using LLM.
264
+ */
265
+ private async compressEntries(
266
+ entries: ConversationEntry[]
267
+ ): Promise<CompressionSegment[]> {
268
+ return tracer.startActiveSpan(
269
+ "compression.llm_compress",
270
+ async (span) => {
271
+ try {
272
+ span.setAttribute("entries.count", entries.length);
273
+
274
+ // Format entries for LLM, including tool payloads
275
+ const formattedEntries = entries
276
+ .map((e) => {
277
+ let formatted = `[${e.messageType}]`;
278
+
279
+ // Add text content if present
280
+ if (e.content) {
281
+ formatted += ` ${e.content}`;
282
+ }
283
+
284
+ // Add tool payload summary for tool-call/tool-result entries
285
+ if (e.toolData && e.toolData.length > 0) {
286
+ const toolSummary = e.toolData
287
+ .map((tool) => {
288
+ if ('toolName' in tool) {
289
+ // ToolCallPart
290
+ return `Tool: ${tool.toolName}`;
291
+ } else if ('toolCallId' in tool) {
292
+ // ToolResultPart - cast to any to avoid type narrowing issues
293
+ const toolResult = tool as any;
294
+ const resultPreview = typeof toolResult.result === 'string'
295
+ ? toolResult.result.substring(0, 100)
296
+ : JSON.stringify(toolResult.result).substring(0, 100);
297
+ return `Result: ${resultPreview}${resultPreview.length >= 100 ? '...' : ''}`;
298
+ }
299
+ return '';
300
+ })
301
+ .filter(Boolean)
302
+ .join(', ');
303
+
304
+ if (toolSummary) {
305
+ formatted += ` [${toolSummary}]`;
306
+ }
307
+ }
308
+
309
+ return formatted;
310
+ })
311
+ .join("\n\n");
312
+
313
+ const eventIds = entries
314
+ .filter((e) => e.eventId)
315
+ .map((e) => e.eventId!);
316
+
317
+ if (eventIds.length === 0) {
318
+ throw new Error("No eventIds found in entries to compress");
319
+ }
320
+
321
+ // Call LLM to compress
322
+ const result = await this.effectiveLlmService.generateObject(
323
+ [
324
+ {
325
+ role: "user",
326
+ content: `You are compressing conversation history. Analyze the following messages and create 1-3 compressed segments that preserve key information while being concise.
327
+
328
+ For each segment, provide:
329
+ - fromEventId: starting message event ID
330
+ - toEventId: ending message event ID
331
+ - compressed: a concise summary (2-4 sentences) of the key points
332
+
333
+ Messages to compress:
334
+ ${formattedEntries}
335
+
336
+ Event IDs in order: ${eventIds.join(", ")}
337
+
338
+ Create segments that group related topics together. Preserve important decisions, errors, and outcomes.`,
339
+ },
340
+ ],
341
+ CompressionSegmentsSchema
342
+ );
343
+
344
+ // Convert LLM output to CompressionSegment format
345
+ const segments: CompressionSegment[] = result.object.map(
346
+ (seg: CompressionSegmentInput) => ({
347
+ fromEventId: seg.fromEventId,
348
+ toEventId: seg.toEventId,
349
+ compressed: seg.compressed,
350
+ createdAt: Date.now(),
351
+ model: this.effectiveLlmService.model,
352
+ })
353
+ );
354
+
355
+ span.setAttribute("segments.count", segments.length);
356
+ span.setStatus({ code: SpanStatusCode.OK });
357
+
358
+ return segments;
359
+ } catch (error) {
360
+ span.recordException(error as Error);
361
+ span.setStatus({ code: SpanStatusCode.ERROR });
362
+ throw error;
363
+ } finally {
364
+ span.end();
365
+ }
366
+ }
367
+ );
368
+ }
369
+
370
+ /**
371
+ * Emergency fallback: create a compression segment representing truncation.
372
+ * Uses sliding window strategy when LLM compression fails.
373
+ */
374
+ private async useFallback(
375
+ conversationId: string,
376
+ entries: ConversationEntry[],
377
+ windowSize: number,
378
+ span: Span
379
+ ): Promise<void> {
380
+ span.setAttribute("fallback.used", true);
381
+ span.setAttribute("fallback.window_size", windowSize);
382
+
383
+ logger.warn("Compression fallback triggered - using sliding window truncation", {
384
+ conversationId,
385
+ entriesCount: entries.length,
386
+ windowSize,
387
+ });
388
+
389
+ // Delegate to pure utility function
390
+ const fallbackSegment = createFallbackSegmentForEntries(entries, windowSize);
391
+
392
+ if (!fallbackSegment) {
393
+ // Can't create a valid segment (too few entries or insufficient event IDs)
394
+ logger.warn("Cannot create fallback segment - insufficient data", {
395
+ conversationId,
396
+ entriesCount: entries.length,
397
+ windowSize,
398
+ });
399
+ span.setStatus({ code: SpanStatusCode.OK });
400
+ return;
401
+ }
402
+
403
+ // Persist the fallback segment
404
+ await this.conversationStore.appendCompressionSegments(
405
+ conversationId,
406
+ [fallbackSegment]
407
+ );
408
+
409
+ span.setAttribute("fallback.segment_created", true);
410
+ span.setStatus({ code: SpanStatusCode.OK });
411
+ }
412
+
413
+ /**
414
+ * Get compression configuration from config service.
415
+ * Public to allow external callers (e.g., MessageCompiler) to check config.
416
+ */
417
+ getCompressionConfig(): {
418
+ enabled: boolean;
419
+ tokenThreshold: number;
420
+ tokenBudget: number;
421
+ slidingWindowSize: number;
422
+ } {
423
+ const cfg = config.getConfig();
424
+ return {
425
+ enabled: cfg.compression?.enabled ?? true,
426
+ tokenThreshold: cfg.compression?.tokenThreshold ?? 50000,
427
+ tokenBudget: cfg.compression?.tokenBudget ?? 40000,
428
+ slidingWindowSize: cfg.compression?.slidingWindowSize ?? 50,
429
+ };
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Factory method to create CompressionService.
435
+ * @param conversationStore - The conversation store instance
436
+ * @param llmService - The agent's default LLM service (fallback)
437
+ * @param compressionLlmService - Optional dedicated LLM service for compression operations
438
+ */
439
+ export function createCompressionService(
440
+ conversationStore: ConversationStore,
441
+ llmService: LLMService,
442
+ compressionLlmService?: LLMService
443
+ ): CompressionService {
444
+ return new CompressionService(conversationStore, llmService, compressionLlmService);
445
+ }
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * Zod schema for LLM-generated compression segments.
5
+ * Used with generateObject() to get structured output from LLM.
6
+ *
7
+ * The LLM receives a range of messages and returns one or more segments
8
+ * that summarize different parts of that range.
9
+ */
10
+ export const CompressionSegmentSchema = z.object({
11
+ /** Starting event ID of the compressed range */
12
+ fromEventId: z.string().min(1, "fromEventId cannot be empty"),
13
+ /** Ending event ID of the compressed range */
14
+ toEventId: z.string().min(1, "toEventId cannot be empty"),
15
+ /** The compressed/summarized content */
16
+ compressed: z.string().min(1, "Compressed content cannot be empty"),
17
+ });
18
+
19
+ /**
20
+ * Schema for the array of segments returned by LLM.
21
+ * Typically 1-3 segments depending on the content diversity.
22
+ */
23
+ export const CompressionSegmentsSchema = z.array(CompressionSegmentSchema);
24
+
25
+ /**
26
+ * Type inference from schema for type safety.
27
+ */
28
+ export type CompressionSegmentInput = z.infer<typeof CompressionSegmentSchema>;
@@ -0,0 +1,74 @@
1
+ import type { CompiledMessage } from "@/agents/execution/MessageCompiler";
2
+
3
+ /**
4
+ * Represents a compressed segment of conversation history.
5
+ * Replaces a range of messages (fromEventId -> toEventId) with a summary.
6
+ */
7
+ export interface CompressionSegment {
8
+ /** Starting event ID of the compressed range */
9
+ fromEventId: string;
10
+ /** Ending event ID of the compressed range */
11
+ toEventId: string;
12
+ /** The compressed/summarized content */
13
+ compressed: string;
14
+ /** When this segment was created */
15
+ createdAt: number;
16
+ /** Model used for compression */
17
+ model: string;
18
+ }
19
+
20
+ /**
21
+ * Persistent log of all compression segments for a conversation.
22
+ * Stored in filesystem at compressions/{conversationId}.json
23
+ */
24
+ export interface CompressionLog {
25
+ conversationId: string;
26
+ segments: CompressionSegment[];
27
+ updatedAt: number;
28
+ }
29
+
30
+ /**
31
+ * Input to compression operations.
32
+ */
33
+ export interface CompressionInput {
34
+ conversationId: string;
35
+ messages: CompiledMessage[];
36
+ tokenBudget: number;
37
+ modelId: string;
38
+ }
39
+
40
+ /**
41
+ * Result of a compression operation.
42
+ */
43
+ export interface CompressionOutcome {
44
+ /** Messages after applying compression (or fallback) */
45
+ messages: CompiledMessage[];
46
+ /** Newly created segments (if any) */
47
+ addedSegments: CompressionSegment[];
48
+ /** True if fallback (sliding window) was used instead of LLM compression */
49
+ usedFallback: boolean;
50
+ }
51
+
52
+ /**
53
+ * Range of messages to compress (by array indices).
54
+ */
55
+ export interface CompressionRange {
56
+ startIndex: number;
57
+ endIndex: number;
58
+ }
59
+
60
+ /**
61
+ * Result of validating LLM-generated segments.
62
+ */
63
+ export interface ValidationResult {
64
+ valid: boolean;
65
+ error?: string;
66
+ }
67
+
68
+ /**
69
+ * Plan for compression operation.
70
+ */
71
+ export interface CompressionPlan {
72
+ range: CompressionRange | null;
73
+ tokenEstimate: number;
74
+ }