@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,43 @@
1
+ import { config } from "@/services/ConfigService";
2
+
3
+ /**
4
+ * Default Nostr relay URLs for TENEX
5
+ */
6
+ const DEFAULT_RELAY_URLS = ["wss://tenex.chat"];
7
+
8
+ /**
9
+ * Validate WebSocket URL format
10
+ * @param url - URL to validate
11
+ * @returns true if URL is valid WebSocket URL
12
+ */
13
+ function isValidWebSocketUrl(url: string): boolean {
14
+ try {
15
+ const parsed = new URL(url);
16
+ return parsed.protocol === "ws:" || parsed.protocol === "wss:";
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Get relay URLs for NDK connection
24
+ * Priority: config file > defaults
25
+ * @returns Array of validated WebSocket relay URLs
26
+ */
27
+ export function getRelayUrls(): string[] {
28
+ // Check config file
29
+ try {
30
+ const tenexConfig = config.getConfig();
31
+ if (tenexConfig.relays && tenexConfig.relays.length > 0) {
32
+ const urls = tenexConfig.relays.filter((url) => isValidWebSocketUrl(url));
33
+ if (urls.length > 0) {
34
+ return urls;
35
+ }
36
+ }
37
+ } catch {
38
+ // Config not loaded yet, fall through to defaults
39
+ }
40
+
41
+ // Fall back to defaults
42
+ return DEFAULT_RELAY_URLS;
43
+ }
@@ -0,0 +1,39 @@
1
+ import { propagation, context as otelContext, trace } from "@opentelemetry/api";
2
+ import { getLLMSpanId } from "../telemetry/LLMSpanRegistry.js";
3
+
4
+ /**
5
+ * Event-like object that has a tags array.
6
+ * Compatible with NDKEvent and plain objects.
7
+ */
8
+ export interface EventWithTags {
9
+ tags: string[][];
10
+ }
11
+
12
+ /**
13
+ * Inject W3C trace context into an event's tags.
14
+ * This allows the daemon to link incoming events back to their parent span.
15
+ * Also adds trace_context_llm which links to the LLM execution span for better debugging.
16
+ *
17
+ * @param event - Any object with a tags array (NDKEvent or plain object)
18
+ */
19
+ export function injectTraceContext(event: EventWithTags): void {
20
+ const carrier: Record<string, string> = {};
21
+ propagation.inject(otelContext.active(), carrier);
22
+ if (carrier.traceparent) {
23
+ event.tags.push(["trace_context", carrier.traceparent]);
24
+ }
25
+
26
+ // Add trace context that links to LLM execution span (more useful for debugging)
27
+ const activeSpan = trace.getActiveSpan();
28
+ if (activeSpan) {
29
+ const spanContext = activeSpan.spanContext();
30
+ const traceId = spanContext.traceId;
31
+
32
+ // Use LLM span ID if available (links to actual LLM execution)
33
+ // Otherwise fall back to current span ID
34
+ const llmSpanId = getLLMSpanId(traceId);
35
+ const spanIdToUse = llmSpanId || spanContext.spanId;
36
+
37
+ event.tags.push(["trace_context_llm", `00-${traceId}-${spanIdToUse}-01`]);
38
+ }
39
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Type definitions for agent Nostr events.
3
+ * Centralized types for event encoding and publishing.
4
+ */
5
+
6
+ import type { LanguageModelUsageWithCostUsd } from "@/llm/types";
7
+ import type { NDKEvent } from "@nostr-dev-kit/ndk";
8
+
9
+ // ============================================================================
10
+ // Intent Types - Express what agents want to communicate
11
+ // ============================================================================
12
+
13
+ export interface CompletionIntent {
14
+ content: string;
15
+ usage?: LanguageModelUsageWithCostUsd;
16
+ summary?: string;
17
+ // Note: llmRuntime is now tracked via EventContext.llmRuntime for all events
18
+ }
19
+
20
+ export interface ConversationIntent {
21
+ content: string;
22
+ isReasoning?: boolean;
23
+ usage?: LanguageModelUsageWithCostUsd;
24
+ }
25
+
26
+ export interface DelegationIntent {
27
+ delegations: Array<{
28
+ recipient: string;
29
+ request: string;
30
+ branch?: string;
31
+ }>;
32
+ type?: "delegation" | "delegation_followup" | "ask";
33
+ }
34
+
35
+ /**
36
+ * A single-select question where user picks one option (or provides their own answer).
37
+ */
38
+ export interface SingleSelectQuestion {
39
+ type: "question";
40
+ /** Short title for the question (displayed as header) */
41
+ title: string;
42
+ /** Full question text */
43
+ question: string;
44
+ /** Optional suggestions - if omitted, question is fully open-ended */
45
+ suggestions?: string[];
46
+ }
47
+
48
+ /**
49
+ * A multi-select question where user can pick multiple options (or provide their own answer).
50
+ */
51
+ export interface MultiSelectQuestion {
52
+ type: "multiselect";
53
+ /** Short title for the question (displayed as header) */
54
+ title: string;
55
+ /** Full question text */
56
+ question: string;
57
+ /** Optional options - if omitted, question is fully open-ended */
58
+ options?: string[];
59
+ }
60
+
61
+ /**
62
+ * Union type for all question types.
63
+ */
64
+ export type AskQuestion = SingleSelectQuestion | MultiSelectQuestion;
65
+
66
+ export interface AskIntent {
67
+ title: string;
68
+ context: string;
69
+ questions: AskQuestion[];
70
+ }
71
+
72
+ export interface ErrorIntent {
73
+ message: string;
74
+ errorType?: string;
75
+ }
76
+
77
+ export interface LessonIntent {
78
+ title: string;
79
+ lesson: string;
80
+ detailed?: string;
81
+ category?: string;
82
+ hashtags?: string[];
83
+ }
84
+
85
+ export interface ScheduledTaskInfo {
86
+ id: string;
87
+ title: string;
88
+ schedule: string; // Cron expression or ISO timestamp
89
+ /** Agent slug when resolvable, otherwise a truncated pubkey prefix */
90
+ targetAgent: string;
91
+ type: "cron" | "oneoff";
92
+ lastRun?: number; // Unix timestamp in seconds
93
+ }
94
+
95
+ export interface StatusIntent {
96
+ type: "status";
97
+ agents: Array<{ pubkey: string; slug: string }>;
98
+ models: Array<{ slug: string; agents: string[] }>;
99
+ tools: Array<{ name: string; agents: string[] }>;
100
+ worktrees?: string[]; // Array of branch names, first is default
101
+ scheduledTasks?: ScheduledTaskInfo[];
102
+ }
103
+
104
+ export interface ToolUseIntent {
105
+ toolName: string;
106
+ content: string; // e.g., "Reading $path"
107
+ args?: unknown; // Tool arguments to be serialized
108
+ referencedEventIds?: string[]; // Event IDs to reference with q-tags (e.g., delegation event IDs)
109
+ referencedAddressableEvents?: string[]; // Addressable event references with a-tags (e.g., "30023:pubkey:d-tag")
110
+ usage?: LanguageModelUsageWithCostUsd; // Cumulative usage from previous steps
111
+ }
112
+
113
+ /**
114
+ * Intent for intervention review requests.
115
+ * Used when the InterventionService detects that a user hasn't responded
116
+ * to an agent's completion and triggers a human-replica review.
117
+ *
118
+ * Names are pre-resolved by the caller (InterventionPublisher) to avoid
119
+ * layer violations - AgentEventEncoder (layer 2) cannot import PubkeyService (layer 3).
120
+ */
121
+ export interface InterventionReviewIntent {
122
+ /** Pubkey of the intervention agent (human-replica) to notify */
123
+ targetPubkey: string;
124
+ /** The conversation ID being reviewed */
125
+ conversationId: string;
126
+ /** Human-readable name of the user who hasn't responded (pre-resolved) */
127
+ userName: string;
128
+ /** Human-readable name of the agent that completed work (pre-resolved) */
129
+ agentName: string;
130
+ }
131
+
132
+ /**
133
+ * Intent for delegation marker events.
134
+ * Delegation markers track the lifecycle of delegation conversations.
135
+ * They are created when a delegation is initiated and updated when it completes/aborts.
136
+ */
137
+ export interface DelegationMarkerIntent {
138
+ /** The delegation conversation ID (the child conversation) */
139
+ delegationConversationId: string;
140
+ /** The agent pubkey that received the delegation */
141
+ recipientPubkey: string;
142
+ /** The parent conversation ID (where the delegator is working) */
143
+ parentConversationId: string;
144
+ /** Delegation status: pending, completed, or aborted */
145
+ status: "pending" | "completed" | "aborted";
146
+ /** When the delegation was initiated (Unix timestamp in seconds) */
147
+ initiatedAt?: number;
148
+ /** When the delegation completed (Unix timestamp in seconds) - only for completed/aborted */
149
+ completedAt?: number;
150
+ /** If aborted, the reason for the abort */
151
+ abortReason?: string;
152
+ }
153
+
154
+ export type AgentIntent =
155
+ | CompletionIntent
156
+ | ConversationIntent
157
+ | DelegationIntent
158
+ | AskIntent
159
+ | ErrorIntent
160
+ | LessonIntent
161
+ | StatusIntent
162
+ | ToolUseIntent
163
+ | InterventionReviewIntent
164
+ | DelegationMarkerIntent;
165
+
166
+ // ============================================================================
167
+ // Event Context - Execution context provided by RAL
168
+ // ============================================================================
169
+
170
+ export interface EventContext {
171
+ triggeringEvent: NDKEvent; // The event that triggered this execution (for reply threading)
172
+ rootEvent: { id?: string }; // The conversation root event (only ID is used for tagging)
173
+ conversationId: string; // Required for conversation lookup
174
+ executionTime?: number;
175
+ model?: string;
176
+ cost?: number; // LLM cost in USD
177
+ ralNumber: number; // RAL number for this execution - required for all conversational events
178
+ /** Incremental LLM runtime in milliseconds since last event was published */
179
+ llmRuntime?: number;
180
+ /** Total accumulated LLM runtime for this RAL (used in completion events) */
181
+ llmRuntimeTotal?: number;
182
+ /**
183
+ * Pre-resolved recipient pubkey for completion events.
184
+ * When set, the encoder uses this pubkey for the completion p-tag instead of
185
+ * triggeringEvent.pubkey. This supports delegation chain routing where completions
186
+ * must route back to the immediate delegator, not the event that happened to
187
+ * trigger the current execution (e.g., a user responding to an ask).
188
+ *
189
+ * Resolved by createEventContext() (layer 3, in services/event-context/) from the
190
+ * ConversationStore's delegation chain. This avoids layer violations - neither
191
+ * AgentPublisher nor AgentEventEncoder (layer 2) can import ConversationStore (layer 3).
192
+ */
193
+ completionRecipientPubkey?: string;
194
+ }
195
+
196
+ // ============================================================================
197
+ // Publisher Config Types
198
+ // ============================================================================
199
+
200
+ /**
201
+ * Configuration for delegation events.
202
+ */
203
+ export interface DelegateConfig {
204
+ /** The pubkey of the agent to delegate to */
205
+ recipient: string;
206
+ /** The content/instructions for the delegation */
207
+ content: string;
208
+ /** Optional branch for worktree support */
209
+ branch?: string;
210
+ /** Optional nudge event IDs to apply to the delegated agent */
211
+ nudges?: string[];
212
+ }
213
+
214
+ /**
215
+ * Configuration for ask events.
216
+ * Uses the multi-question format (title + questions).
217
+ */
218
+ export interface AskConfig {
219
+ /** The pubkey of the recipient (usually project owner/human) */
220
+ recipient: string;
221
+ /** Full context explaining why these questions are being asked */
222
+ context: string;
223
+ /** Overall title encompassing all questions */
224
+ title: string;
225
+ /** Array of questions (single-select or multi-select) */
226
+ questions: AskQuestion[];
227
+ }
@@ -0,0 +1,84 @@
1
+ import { getProjectContext } from "@/services/projects";
2
+ import type { NDKEvent } from "@nostr-dev-kit/ndk";
3
+
4
+ /**
5
+ * Check if an event is from an agent (either project agent or individual agent)
6
+ * @param event - The NDK event to check
7
+ * @returns true if the event is from an agent, false if from a user
8
+ */
9
+ export function isEventFromAgent(event: NDKEvent): boolean {
10
+ const projectCtx = getProjectContext();
11
+
12
+ // Check if it's from the project manager
13
+ if (projectCtx.projectManager?.pubkey === event.pubkey) {
14
+ return true;
15
+ }
16
+
17
+ // Check if it's from any of the registered agents
18
+ for (const agent of projectCtx.agents.values()) {
19
+ if (agent.pubkey === event.pubkey) {
20
+ return true;
21
+ }
22
+ }
23
+
24
+ return false;
25
+ }
26
+
27
+ /**
28
+ * Check if an event is from a user (not from an agent)
29
+ * @param event - The NDK event to check
30
+ * @returns true if the event is from a user, false if from an agent
31
+ */
32
+ export function isEventFromUser(event: NDKEvent): boolean {
33
+ return !isEventFromAgent(event);
34
+ }
35
+
36
+ /**
37
+ * Get the agent slug if the event is from an agent
38
+ * @param event - The NDK event to check
39
+ * @returns The agent slug if found, undefined otherwise
40
+ */
41
+ export function getAgentSlugFromEvent(event: NDKEvent): string | undefined {
42
+ if (!event.pubkey) return undefined;
43
+
44
+ const projectCtx = getProjectContext();
45
+ for (const [slug, agent] of projectCtx.agents) {
46
+ if (agent.pubkey === event.pubkey) {
47
+ return slug;
48
+ }
49
+ }
50
+
51
+ return undefined;
52
+ }
53
+
54
+ /**
55
+ * Get the agent pubkeys that are targeted by this event based on p-tags
56
+ * @param event - The NDK event to check
57
+ * @returns Array of agent pubkeys that are targeted by this event
58
+ */
59
+ export function getTargetedAgentPubkeys(event: NDKEvent): string[] {
60
+ const projectCtx = getProjectContext();
61
+ const targetedPubkeys: string[] = [];
62
+
63
+ // Get all p-tags from the event
64
+ const pTags = event.getMatchingTags("p");
65
+ if (pTags.length === 0) {
66
+ return [];
67
+ }
68
+
69
+ // Check each p-tag to see if it matches an agent
70
+ for (const pTag of pTags) {
71
+ const pubkey = pTag[1];
72
+ if (!pubkey) continue;
73
+
74
+ // Check if this pubkey belongs to an agent
75
+ for (const agent of projectCtx.agents.values()) {
76
+ if (agent.pubkey === pubkey) {
77
+ targetedPubkeys.push(pubkey);
78
+ break;
79
+ }
80
+ }
81
+ }
82
+
83
+ return targetedPubkeys;
84
+ }
@@ -0,0 +1,30 @@
1
+ import type { PromptFragment } from "./types";
2
+
3
+ export class FragmentRegistry {
4
+ private fragments = new Map<string, PromptFragment<unknown>>();
5
+
6
+ register<T>(fragment: PromptFragment<T>): void {
7
+ if (!fragment.id) {
8
+ throw new Error("Fragment must have an id");
9
+ }
10
+ this.fragments.set(fragment.id, fragment as PromptFragment<unknown>);
11
+ }
12
+
13
+ get(id: string): PromptFragment<unknown> | undefined {
14
+ return this.fragments.get(id);
15
+ }
16
+
17
+ has(id: string): boolean {
18
+ return this.fragments.has(id);
19
+ }
20
+
21
+ clear(): void {
22
+ this.fragments.clear();
23
+ }
24
+
25
+ getAllIds(): string[] {
26
+ return Array.from(this.fragments.keys());
27
+ }
28
+ }
29
+
30
+ export const fragmentRegistry = new FragmentRegistry();
@@ -0,0 +1,98 @@
1
+ import { formatAnyError } from "@/lib/error-formatter";
2
+ import { fragmentRegistry } from "./FragmentRegistry";
3
+ import type { FragmentConfig, PromptFragment } from "./types";
4
+
5
+ export class PromptBuilder {
6
+ private fragments: FragmentConfig[] = [];
7
+
8
+ add<T>(fragmentId: string, args: T, condition?: (args: T) => boolean): this {
9
+ if (!fragmentRegistry.has(fragmentId)) {
10
+ throw new Error(
11
+ `Fragment "${fragmentId}" not found in registry. Available fragments: ${fragmentRegistry.getAllIds().join(", ")}`
12
+ );
13
+ }
14
+ this.fragments.push({
15
+ fragmentId,
16
+ args,
17
+ condition: condition ? (unknownArgs) => condition(unknownArgs as T) : undefined,
18
+ });
19
+ return this;
20
+ }
21
+
22
+ addFragment<T>(fragment: PromptFragment<T>, args: T, condition?: (args: T) => boolean): this {
23
+ fragmentRegistry.register(fragment);
24
+ this.fragments.push({
25
+ fragmentId: fragment.id,
26
+ args,
27
+ condition: condition ? (unknownArgs) => condition(unknownArgs as T) : undefined,
28
+ });
29
+ return this;
30
+ }
31
+
32
+ async build(): Promise<string> {
33
+ const fragmentsWithPriority = await Promise.all(
34
+ this.fragments
35
+ .filter((config) => !config.condition || config.condition(config.args))
36
+ .map(async (config) => {
37
+ const fragment = fragmentRegistry.get(config.fragmentId);
38
+ if (!fragment) {
39
+ throw new Error(`Fragment ${config.fragmentId} not found`);
40
+ }
41
+
42
+ // Validate arguments if validator is provided
43
+ if (fragment.validateArgs && !fragment.validateArgs(config.args)) {
44
+ const receivedArgs = JSON.stringify(config.args, null, 2);
45
+ const expectedDesc =
46
+ fragment.expectedArgs || "Check fragment definition for expected arguments";
47
+ throw new Error(
48
+ `Fragment "${config.fragmentId}" received invalid arguments.\n` +
49
+ `Expected: ${expectedDesc}\n` +
50
+ `Received: ${receivedArgs}`
51
+ );
52
+ }
53
+
54
+ try {
55
+ return {
56
+ priority: fragment.priority || 50,
57
+ content: await fragment.template(config.args),
58
+ };
59
+ } catch (error) {
60
+ const errorMessage = formatAnyError(error);
61
+ const receivedArgs = JSON.stringify(config.args, null, 2);
62
+ throw new Error(
63
+ `Error executing fragment "${config.fragmentId}":\n` +
64
+ `${errorMessage}\n` +
65
+ `Arguments provided: ${receivedArgs}\n` +
66
+ `Expected: ${fragment.expectedArgs || "Check fragment definition"}`,
67
+ { cause: error }
68
+ );
69
+ }
70
+ })
71
+ );
72
+
73
+ return fragmentsWithPriority
74
+ .sort((a, b) => a.priority - b.priority)
75
+ .map((f) => f.content)
76
+ .filter((content) => content.trim().length > 0)
77
+ .join("\n\n");
78
+ }
79
+
80
+ clear(): this {
81
+ this.fragments = [];
82
+ return this;
83
+ }
84
+
85
+ getFragmentCount(): number {
86
+ return this.fragments.length;
87
+ }
88
+
89
+ /**
90
+ * Static method for building a single fragment without creating an instance
91
+ * @param fragmentId The ID of the fragment to build
92
+ * @param args The arguments to pass to the fragment
93
+ * @returns The built fragment content as a string
94
+ */
95
+ static async buildFragment<T>(fragmentId: string, args: T): Promise<string> {
96
+ return await new PromptBuilder().add(fragmentId, args).build();
97
+ }
98
+ }
@@ -0,0 +1,3 @@
1
+ export { FragmentRegistry, fragmentRegistry } from "./FragmentRegistry";
2
+ export { PromptBuilder } from "./PromptBuilder";
3
+ export type { FragmentConfig, PromptFragment } from "./types";
@@ -0,0 +1,13 @@
1
+ export interface PromptFragment<T = unknown> {
2
+ id: string;
3
+ priority?: number;
4
+ template: (args: T) => string | Promise<string>;
5
+ validateArgs?: (args: unknown) => args is T;
6
+ expectedArgs?: string; // Description of expected arguments for error messages
7
+ }
8
+
9
+ export interface FragmentConfig {
10
+ fragmentId: string;
11
+ args: unknown;
12
+ condition?: (args: unknown) => boolean;
13
+ }
@@ -0,0 +1,44 @@
1
+ import { config } from "@/services/ConfigService";
2
+ import type { PromptFragment } from "../core/types";
3
+
4
+ /**
5
+ * Global system prompt fragment.
6
+ *
7
+ * This fragment allows users to configure a system prompt that is added to ALL
8
+ * projects. It is loaded from the global config ($TENEX_BASE_DIR/config.json).
9
+ *
10
+ * Users can configure this via: `tenex setup global-system-prompt`
11
+ *
12
+ * Priority 3 places it after the core identity fragments (priorities 1 and 2),
13
+ * so it is ordered like other fragments instead of being prepended.
14
+ */
15
+
16
+ // Empty args - the fragment loads content from config
17
+ type GlobalSystemPromptArgs = Record<string, never>;
18
+
19
+ export const globalSystemPromptFragment: PromptFragment<GlobalSystemPromptArgs> = {
20
+ id: "global-system-prompt",
21
+ priority: 3,
22
+ template: () => {
23
+ try {
24
+ const tenexConfig = config.getConfig();
25
+ const globalPrompt = tenexConfig.globalSystemPrompt;
26
+
27
+ // Check if enabled and has content
28
+ if (!globalPrompt?.content || globalPrompt.content.trim().length === 0) {
29
+ return "";
30
+ }
31
+
32
+ // Check if explicitly disabled
33
+ if (globalPrompt.enabled === false) {
34
+ return "";
35
+ }
36
+
37
+ // Return the user-configured global system prompt
38
+ return globalPrompt.content.trim();
39
+ } catch {
40
+ // Config not loaded yet or error - return empty string
41
+ return "";
42
+ }
43
+ },
44
+ };
@@ -0,0 +1,69 @@
1
+ import type { AgentInstance } from "@/agents/types";
2
+ import { shortenConversationId } from "@/utils/conversation-id";
3
+ import { fragmentRegistry } from "../core/FragmentRegistry";
4
+ import type { PromptFragment } from "../core/types";
5
+
6
+ /**
7
+ * Identity fragment for agents.
8
+ */
9
+ interface AgentIdentityArgs {
10
+ agent: AgentInstance;
11
+ projectTitle: string;
12
+ projectOwnerPubkey: string;
13
+ /**
14
+ * Actual worktree path where code execution happens.
15
+ * This is displayed as "Absolute Path" in the system prompt.
16
+ */
17
+ workingDirectory?: string;
18
+ /**
19
+ * Current conversation ID (full hex).
20
+ * First 12 characters are displayed as short ID in the system prompt.
21
+ */
22
+ conversationId?: string;
23
+ }
24
+
25
+ export const agentIdentityFragment: PromptFragment<AgentIdentityArgs> = {
26
+ id: "agent-identity",
27
+ priority: 1,
28
+ template: ({ agent, projectTitle, projectOwnerPubkey, workingDirectory, conversationId }) => {
29
+ const parts: string[] = [];
30
+
31
+ // Identity
32
+ parts.push("# Your Identity\n");
33
+ parts.push(`Your name: ${agent.name} (${agent.slug})`);
34
+ if (agent.role) {
35
+ parts.push(`Your role: ${agent.role}`);
36
+ }
37
+ parts.push(`Your npub: ${agent.signer.npub}`);
38
+ parts.push(
39
+ `Your nsec: ${agent.signer.nsec} -- this is your real nsec and you CAN and SHOULD use it when you encounter a tool that needs an nsec.`
40
+ );
41
+ parts.push("");
42
+
43
+ // Instructions
44
+ if (agent.instructions) {
45
+ parts.push(`## Your Instructions\n${agent.instructions}\n`);
46
+ }
47
+
48
+ // Project context
49
+ const contextLines = [
50
+ "## Project Context",
51
+ `- Title: "${projectTitle}"`,
52
+ `- Today's Date: ${new Date().toISOString().split("T")[0]}`,
53
+ ];
54
+ if (workingDirectory) {
55
+ contextLines.push(`- Absolute Path: ${workingDirectory}`);
56
+ }
57
+ contextLines.push(`- User (Owner) pubkey: "${projectOwnerPubkey}"`);
58
+ if (conversationId) {
59
+ const shortId = shortenConversationId(conversationId);
60
+ contextLines.push(`- Current Conversation (short): ${shortId}`);
61
+ }
62
+ parts.push(contextLines.join("\n"));
63
+
64
+ return parts.join("\n");
65
+ },
66
+ };
67
+
68
+ // Register the fragment
69
+ fragmentRegistry.register(agentIdentityFragment);