@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,128 @@
1
+ import type { Stats } from "node:fs";
2
+ import * as fsPromises from "node:fs/promises";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { formatAnyError } from "@/lib/error-formatter";
6
+
7
+ /**
8
+ * Unified file system utilities combining patterns from CLI and shared packages
9
+ * Provides both sync and async operations with consistent error handling
10
+ *
11
+ * @module filesystem
12
+ * @description
13
+ * This module provides a comprehensive set of file system utilities with:
14
+ * - Path resolution and expansion (home directory ~)
15
+ * - Directory and file existence checks
16
+ * - JSON file read/write operations
17
+ * - Text file operations
18
+ * - Directory listing and management
19
+ * - File copying and deletion
20
+ * - Consistent error handling across all operations
21
+ */
22
+
23
+ // File operations
24
+ export async function readFile(filePath: string, encoding?: BufferEncoding): Promise<string>;
25
+ export async function readFile(filePath: string, encoding: null): Promise<Buffer>;
26
+ export async function readFile(
27
+ filePath: string,
28
+ encoding?: BufferEncoding | null
29
+ ): Promise<string | Buffer> {
30
+ return await fsPromises.readFile(filePath, encoding as BufferEncoding | null | undefined);
31
+ }
32
+
33
+ export function expandHome(filePath: string): string {
34
+ if (filePath.startsWith("~")) {
35
+ return path.join(os.homedir(), filePath.slice(1));
36
+ }
37
+ return filePath;
38
+ }
39
+
40
+ export function resolvePath(filePath: string): string {
41
+ return path.resolve(expandHome(filePath));
42
+ }
43
+
44
+ // Directory operations
45
+ export async function ensureDirectory(dirPath: string): Promise<void> {
46
+ try {
47
+ await fsPromises.access(dirPath);
48
+ } catch (err: unknown) {
49
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
50
+ await fsPromises.mkdir(dirPath, { recursive: true });
51
+ } else {
52
+ throw err;
53
+ }
54
+ }
55
+ }
56
+
57
+ export async function directoryExists(dirPath: string): Promise<boolean> {
58
+ try {
59
+ const stat = await fsPromises.stat(dirPath);
60
+ return stat.isDirectory();
61
+ } catch (err: unknown) {
62
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
63
+ return false;
64
+ }
65
+ throw err;
66
+ }
67
+ }
68
+
69
+ // Path existence check (works for both files and directories)
70
+ export async function pathExists(filePath: string): Promise<boolean> {
71
+ try {
72
+ await fsPromises.access(filePath);
73
+ return true;
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ // File operations
80
+ export async function fileExists(filePath: string): Promise<boolean> {
81
+ try {
82
+ const stat = await fsPromises.stat(filePath);
83
+ return stat.isFile();
84
+ } catch (err: unknown) {
85
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
86
+ return false;
87
+ }
88
+ throw err;
89
+ }
90
+ }
91
+
92
+ // JSON operations with error handling
93
+ export async function readJsonFile<T>(filePath: string): Promise<T | null> {
94
+ try {
95
+ const content = await fsPromises.readFile(resolvePath(filePath), "utf-8");
96
+ return JSON.parse(content) as T;
97
+ } catch (err: unknown) {
98
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
99
+ return null;
100
+ }
101
+ // Use console.error since lib/ layer should not depend on TENEX logger
102
+ console.error(`Failed to read JSON file ${filePath}: ${formatAnyError(err)}`);
103
+ throw err;
104
+ }
105
+ }
106
+
107
+ export async function writeJsonFile<T>(
108
+ filePath: string,
109
+ data: T,
110
+ options?: { spaces?: number }
111
+ ): Promise<void> {
112
+ const resolvedPath = resolvePath(filePath);
113
+ await ensureDirectory(path.dirname(resolvedPath));
114
+ const spaces = options?.spaces ?? 2;
115
+ await fsPromises.writeFile(resolvedPath, JSON.stringify(data, null, spaces));
116
+ }
117
+
118
+ // File stats
119
+ export async function getFileStats(filePath: string): Promise<Stats | null> {
120
+ try {
121
+ return await fsPromises.stat(resolvePath(filePath));
122
+ } catch (err: unknown) {
123
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
124
+ return null;
125
+ }
126
+ throw err;
127
+ }
128
+ }
@@ -0,0 +1 @@
1
+ export * from "./filesystem.js";
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Safely parse JSON with markdown code block cleanup
3
+ * @param text The text to parse, potentially containing markdown code blocks
4
+ * @param context Optional context for error logging
5
+ * @returns Parsed object or null if parsing fails
6
+ */
7
+ export function safeParseJSON<T = unknown>(text: string, context?: string): T | null {
8
+ try {
9
+ // Clean up response - remove markdown code blocks if present
10
+ let cleanText = text.trim();
11
+
12
+ // Remove ```json or ``` wrapper if present
13
+ if (cleanText.startsWith("```json")) {
14
+ cleanText = cleanText.replace(/^```json\s*/, "").replace(/```\s*$/, "");
15
+ } else if (cleanText.startsWith("```")) {
16
+ cleanText = cleanText.replace(/^```\s*/, "").replace(/```\s*$/, "");
17
+ }
18
+
19
+ return JSON.parse(cleanText);
20
+ } catch (error) {
21
+ if (context) {
22
+ // Use console.error since lib/ should not depend on TENEX logger
23
+ console.error(`[JSON Parser] Failed to parse JSON in ${context}`, {
24
+ error: error instanceof Error ? error.message : String(error),
25
+ text: text.substring(0, 200),
26
+ });
27
+ }
28
+ return null;
29
+ }
30
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Converts a string to kebab-case format
3
+ * @param str - The input string to convert
4
+ * @returns The kebab-case formatted string
5
+ * @example
6
+ * toKebabCase("HelloWorld") // "hello-world"
7
+ * toKebabCase("hello_world") // "hello-world"
8
+ * toKebabCase("Hello World") // "hello-world"
9
+ */
10
+ export function toKebabCase(str: string): string {
11
+ return str
12
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
13
+ .replace(/[\s_]+/g, "-")
14
+ .toLowerCase();
15
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Time formatting utilities
3
+ */
4
+
5
+ /**
6
+ * Format a timestamp into a human-readable "time ago" string (long form)
7
+ * Example: "2 hours ago", "45 minutes ago"
8
+ */
9
+ export function formatTimeAgo(timestamp: number): string {
10
+ const now = Date.now();
11
+ const diff = now - timestamp;
12
+ const seconds = Math.floor(diff / 1000);
13
+ const minutes = Math.floor(seconds / 60);
14
+ const hours = Math.floor(minutes / 60);
15
+ const days = Math.floor(hours / 24);
16
+ const weeks = Math.floor(days / 7);
17
+ const months = Math.floor(days / 30);
18
+
19
+ if (months > 0) {
20
+ return `${months} month${months > 1 ? "s" : ""} ago`;
21
+ }
22
+ if (weeks > 0) {
23
+ return `${weeks} week${weeks > 1 ? "s" : ""} ago`;
24
+ }
25
+ if (days > 0) {
26
+ return `${days} day${days > 1 ? "s" : ""} ago`;
27
+ }
28
+ if (hours > 0) {
29
+ return `${hours} hour${hours > 1 ? "s" : ""} ago`;
30
+ }
31
+ if (minutes > 0) {
32
+ return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
33
+ }
34
+ if (seconds > 30) {
35
+ return `${seconds} seconds ago`;
36
+ }
37
+ return "just now";
38
+ }
39
+
40
+ /**
41
+ * Format a Unix timestamp (in seconds) into a short relative time string
42
+ * Example: "2h ago", "45m ago", "3d ago"
43
+ * @param timestampSeconds - Unix timestamp in seconds
44
+ */
45
+ export function formatRelativeTimeShort(timestampSeconds: number): string {
46
+ const now = Math.floor(Date.now() / 1000);
47
+ const diff = now - timestampSeconds;
48
+
49
+ if (diff < 60) {
50
+ return "just now";
51
+ } else if (diff < 3600) {
52
+ const minutes = Math.floor(diff / 60);
53
+ return `${minutes}m ago`;
54
+ } else if (diff < 86400) {
55
+ const hours = Math.floor(diff / 3600);
56
+ return `${hours}h ago`;
57
+ } else {
58
+ const days = Math.floor(diff / 86400);
59
+ return `${days}d ago`;
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Format uptime from a start time
65
+ */
66
+ export function formatUptime(startTime: Date | null): string {
67
+ if (!startTime) return "N/A";
68
+ const now = new Date();
69
+ const diff = now.getTime() - startTime.getTime();
70
+ const hours = Math.floor(diff / 3600000);
71
+ const minutes = Math.floor((diff % 3600000) / 60000);
72
+ const seconds = Math.floor((diff % 60000) / 1000);
73
+ return `${hours}h ${minutes}m ${seconds}s`;
74
+ }
@@ -0,0 +1,277 @@
1
+ import type { AISdkTool } from "@/tools/types";
2
+ import { logger } from "@/utils/logger";
3
+ import { trace } from "@opentelemetry/api";
4
+ import type { TextStreamPart } from "ai";
5
+ import type { EventEmitter } from "tseep";
6
+ import { shouldIgnoreChunk } from "./chunk-validators";
7
+ import type { LanguageModelUsageWithCostUsd, LLMServiceEventMap } from "./types";
8
+
9
+ export interface ChunkHandlerState {
10
+ previousChunkType?: string;
11
+ cachedContentForComplete: string;
12
+ getCurrentStepUsage: () => LanguageModelUsageWithCostUsd | undefined;
13
+ getModelContextWindow: () => number | undefined;
14
+ }
15
+
16
+ /**
17
+ * Handles streaming chunks from the LLM.
18
+ * Extracted from LLMService to reduce file size.
19
+ */
20
+ export class ChunkHandler {
21
+ private state: ChunkHandlerState;
22
+ private emitter: EventEmitter<LLMServiceEventMap>;
23
+
24
+ constructor(
25
+ emitter: EventEmitter<LLMServiceEventMap>,
26
+ state: ChunkHandlerState
27
+ ) {
28
+ this.emitter = emitter;
29
+ this.state = state;
30
+ }
31
+
32
+ /**
33
+ * Main entry point for handling incoming chunks
34
+ */
35
+ handleChunk(event: { chunk: TextStreamPart<Record<string, AISdkTool>> }): void {
36
+ const chunk = event.chunk;
37
+
38
+ // Validate chunk before any processing - some LLMs send chunks that should be ignored
39
+ if (shouldIgnoreChunk(chunk)) {
40
+ return;
41
+ }
42
+
43
+ // Emit raw-chunk event for consumers (e.g., local streaming)
44
+ logger.debug("[LLMService] emitting raw-chunk", { chunkType: chunk.type });
45
+ this.emitter.emit("raw-chunk", { chunk: event.chunk });
46
+
47
+ // Emit chunk-type-change event BEFORE processing the new chunk
48
+ // This allows listeners to flush buffers before new content of a different type arrives
49
+ if (this.state.previousChunkType !== undefined && this.state.previousChunkType !== chunk.type) {
50
+ this.emitter.emit("chunk-type-change", {
51
+ from: this.state.previousChunkType,
52
+ to: chunk.type,
53
+ });
54
+ // Clear cached content after emitting chunk-type-change.
55
+ // IMPORTANT: AgentExecutor listens to chunk-type-change and publishes the content
56
+ // buffer as a kind:1 event BEFORE this clearing happens. Without that publish,
57
+ // interim text (e.g., "I'll fetch that naddr...") would be lost.
58
+ // See: src/agents/execution/AgentExecutor.ts chunk-type-change handler
59
+ this.state.cachedContentForComplete = "";
60
+ }
61
+
62
+ // Update previousChunkType AFTER emitting the change event
63
+ this.state.previousChunkType = chunk.type;
64
+
65
+ switch (chunk.type) {
66
+ case "text-delta":
67
+ this.handleTextDelta(chunk.text);
68
+ break;
69
+ case "reasoning-delta": {
70
+ // Handle reasoning-delta separately - emit reasoning event
71
+ // The AI SDK may transform our custom reasoning-delta chunks
72
+ // to use 'text' property instead of 'delta'
73
+ interface ReasoningDeltaChunk {
74
+ delta?: string;
75
+ text?: string;
76
+ }
77
+ const reasoningChunk = chunk as ReasoningDeltaChunk;
78
+ const reasoningContent = reasoningChunk.delta || reasoningChunk.text;
79
+ if (reasoningContent) {
80
+ this.handleReasoningDelta(reasoningContent);
81
+ }
82
+ break;
83
+ }
84
+ case "tool-call":
85
+ this.handleToolCall(chunk.toolCallId, chunk.toolName, chunk.input);
86
+ break;
87
+ case "tool-result":
88
+ this.handleToolResult(chunk.toolCallId, chunk.toolName, chunk.output);
89
+ break;
90
+ case "tool-error": {
91
+ this.handleToolError(chunk.toolCallId, chunk.toolName, chunk.error);
92
+ break;
93
+ }
94
+ case "tool-input-start":
95
+ // Tool input is starting to stream
96
+ trace.getActiveSpan()?.addEvent("llm.tool_input_start", {
97
+ "tool.call_id": chunk.id,
98
+ "tool.name": chunk.toolName,
99
+ });
100
+ break;
101
+ case "tool-input-delta":
102
+ // Tool input is being incrementally streamed - too verbose for traces
103
+ break;
104
+ case "reasoning-start":
105
+ trace.getActiveSpan()?.addEvent("llm.reasoning_start", {
106
+ "reasoning.id": chunk.id,
107
+ });
108
+ break;
109
+ case "reasoning-end":
110
+ trace.getActiveSpan()?.addEvent("llm.reasoning_end", {
111
+ "reasoning.id": chunk.id,
112
+ });
113
+ break;
114
+ case "error": {
115
+ // Extract detailed error information
116
+ const errorMsg =
117
+ chunk.error instanceof Error ? chunk.error.message : String(chunk.error);
118
+ const errorStack = chunk.error instanceof Error ? chunk.error.stack : undefined;
119
+
120
+ logger.error("[LLMService] ❌ Error chunk received", {
121
+ errorMessage: errorMsg,
122
+ errorStack,
123
+ errorType: chunk.error?.constructor?.name,
124
+ fullError: chunk.error,
125
+ });
126
+ this.emitter.emit("stream-error", { error: chunk.error });
127
+ break;
128
+ }
129
+ default:
130
+ // Record unknown chunk types for debugging
131
+ trace.getActiveSpan()?.addEvent("llm.unknown_chunk_type", {
132
+ "chunk.type": chunk.type,
133
+ });
134
+ }
135
+ }
136
+
137
+ private handleTextDelta(text: string): void {
138
+ this.emitter.emit("content", { delta: text });
139
+ this.state.cachedContentForComplete += text;
140
+ }
141
+
142
+ private handleReasoningDelta(text: string): void {
143
+ // Skip useless "[REDACTED]" reasoning events
144
+ if (text.trim() === "[REDACTED]") {
145
+ return;
146
+ }
147
+ this.emitter.emit("reasoning", { delta: text });
148
+ }
149
+
150
+ private handleToolCall(toolCallId: string, toolName: string, args: unknown): void {
151
+ trace.getActiveSpan()?.addEvent("llm.tool_will_execute", {
152
+ "tool.name": toolName,
153
+ "tool.call_id": toolCallId,
154
+ });
155
+ const usage = this.state.getCurrentStepUsage();
156
+ this.emitter.emit("tool-will-execute", {
157
+ toolName,
158
+ toolCallId,
159
+ args,
160
+ usage: usage
161
+ ? { ...usage, contextWindow: this.state.getModelContextWindow() }
162
+ : undefined,
163
+ });
164
+ }
165
+
166
+ private handleToolResult(toolCallId: string, toolName: string, result: unknown): void {
167
+ const hasError = isToolResultError(result);
168
+
169
+ if (hasError) {
170
+ const errorDetails = extractErrorDetails(result);
171
+ logger.error(`[LLMService] Tool '${toolName}' execution failed`, {
172
+ toolCallId,
173
+ toolName,
174
+ errorType: errorDetails?.type || "unknown",
175
+ errorMessage: errorDetails?.message || "No error details available",
176
+ });
177
+ }
178
+
179
+ trace.getActiveSpan()?.addEvent("llm.tool_did_execute", {
180
+ "tool.name": toolName,
181
+ "tool.call_id": toolCallId,
182
+ "tool.error": hasError,
183
+ });
184
+
185
+ this.emitter.emit("tool-did-execute", {
186
+ toolName,
187
+ toolCallId,
188
+ result,
189
+ error: hasError,
190
+ });
191
+ }
192
+
193
+ private handleToolError(toolCallId: string, toolName: string, error: unknown): void {
194
+ // Handle tool execution errors - emit as tool-did-execute with error flag
195
+ const errorMsg =
196
+ error instanceof Error ? error.message : String(error);
197
+ const errorStack = error instanceof Error ? (error as Error).stack : undefined;
198
+
199
+ logger.error(`[LLMService] Tool '${toolName}' threw an error`, {
200
+ toolCallId,
201
+ toolName,
202
+ error: errorMsg,
203
+ stack: errorStack,
204
+ });
205
+
206
+ // Log BOTH error event AND execution complete event for consistency
207
+ const activeSpan = trace.getActiveSpan();
208
+ activeSpan?.addEvent("llm.tool_error", {
209
+ "tool.name": toolName,
210
+ "tool.call_id": toolCallId,
211
+ "tool.error_message": errorMsg,
212
+ "tool.error_type": error?.constructor?.name || "Error",
213
+ });
214
+
215
+ // IMPORTANT: Also log tool_did_execute for error cases
216
+ // This ensures trace analysis can find tool completion regardless of success/failure
217
+ activeSpan?.addEvent("llm.tool_did_execute", {
218
+ "tool.name": toolName,
219
+ "tool.call_id": toolCallId,
220
+ "tool.error": true,
221
+ "tool.error_message": errorMsg.substring(0, 200),
222
+ });
223
+
224
+ // Emit tool-did-execute with error info so it gets persisted to conversation
225
+ // Format the error as a result object that the LLM can understand
226
+ this.emitter.emit("tool-did-execute", {
227
+ toolName,
228
+ toolCallId,
229
+ result: {
230
+ type: "error-text",
231
+ text: `Tool execution failed: ${errorMsg}`,
232
+ },
233
+ error: true,
234
+ });
235
+ }
236
+
237
+ /**
238
+ * Get the current cached content
239
+ */
240
+ getCachedContent(): string {
241
+ return this.state.cachedContentForComplete;
242
+ }
243
+
244
+ /**
245
+ * Clear the cached content
246
+ */
247
+ clearCachedContent(): void {
248
+ this.state.cachedContentForComplete = "";
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Check if a tool result indicates an error
254
+ */
255
+ function isToolResultError(result: unknown): boolean {
256
+ if (result && typeof result === "object") {
257
+ const obj = result as Record<string, unknown>;
258
+ return obj.type === "error-text" || obj.type === "error";
259
+ }
260
+ return false;
261
+ }
262
+
263
+ /**
264
+ * Extract error details from a tool result
265
+ */
266
+ function extractErrorDetails(result: unknown): { type: string; message: string } | undefined {
267
+ if (result && typeof result === "object") {
268
+ const obj = result as Record<string, unknown>;
269
+ if (obj.type === "error-text" || obj.type === "error") {
270
+ return {
271
+ type: String(obj.type),
272
+ message: String(obj.text || obj.message || "Unknown error"),
273
+ };
274
+ }
275
+ }
276
+ return undefined;
277
+ }