@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,471 @@
1
+ import { logger } from "@/utils/logger";
2
+ import { HeuristicRegistry } from "./heuristics/HeuristicRegistry";
3
+ import { supervisorLLMService } from "./SupervisorLLMService";
4
+ import { checkSupervisionHealth } from "./supervisionHealthCheck";
5
+ import type {
6
+ CorrectionAction,
7
+ HeuristicDetection,
8
+ PostCompletionContext,
9
+ PreToolContext,
10
+ SupervisionContext,
11
+ SupervisionState,
12
+ VerificationResult,
13
+ } from "./types";
14
+ import { MAX_SUPERVISION_RETRIES } from "./types";
15
+ import { trace, SpanStatusCode } from "@opentelemetry/api";
16
+
17
+ const tracer = trace.getTracer("tenex.supervision");
18
+
19
+ /**
20
+ * Determines if a correction message should be built for the given action.
21
+ * - inject-message type always needs a message
22
+ * - block-tool type always needs a message
23
+ * - suppress-publish type needs a message only when reEngage is true (to guide the agent on what to fix)
24
+ * Uses strict undefined check to preserve intentional empty strings.
25
+ */
26
+ function shouldBuildCorrectionMessage(action: CorrectionAction): boolean {
27
+ if (action.message !== undefined) return false;
28
+ if (action.type === "inject-message" || action.type === "block-tool") return true;
29
+ return action.type === "suppress-publish" && action.reEngage === true;
30
+ }
31
+
32
+ /**
33
+ * Result of a supervision check
34
+ */
35
+ export interface SupervisionCheckResult {
36
+ /** Whether any heuristic was triggered and verified as a violation */
37
+ hasViolation: boolean;
38
+ /** The correction action to take if there's a violation */
39
+ correctionAction?: CorrectionAction;
40
+ /** The heuristic that triggered the violation */
41
+ heuristicId?: string;
42
+ /** The detection that was triggered */
43
+ detection?: HeuristicDetection;
44
+ /** The verification result from the LLM */
45
+ verification?: VerificationResult;
46
+ }
47
+
48
+ /**
49
+ * Main orchestrator for agent supervision
50
+ * Coordinates heuristic checks and LLM verification
51
+ */
52
+ export class SupervisorOrchestrator {
53
+ private supervisionStates: Map<string, SupervisionState> = new Map();
54
+ private registry: HeuristicRegistry;
55
+
56
+ constructor() {
57
+ this.registry = HeuristicRegistry.getInstance();
58
+ }
59
+
60
+ /**
61
+ * Get the current supervision state for an execution
62
+ * Creates a new state if one doesn't exist
63
+ * @param executionId - Unique identifier for the execution
64
+ */
65
+ getSupervisionState(executionId: string): SupervisionState {
66
+ let state = this.supervisionStates.get(executionId);
67
+ if (!state) {
68
+ state = {
69
+ retryCount: 0,
70
+ maxRetries: MAX_SUPERVISION_RETRIES,
71
+ enforcedHeuristics: new Set(),
72
+ };
73
+ this.supervisionStates.set(executionId, state);
74
+ }
75
+ return state;
76
+ }
77
+
78
+ /**
79
+ * Check if a heuristic has been enforced in this execution
80
+ * @param executionId - Unique identifier for the execution
81
+ * @param heuristicId - The heuristic ID to check
82
+ */
83
+ isHeuristicEnforced(executionId: string, heuristicId: string): boolean {
84
+ const state = this.getSupervisionState(executionId);
85
+ return state.enforcedHeuristics.has(heuristicId);
86
+ }
87
+
88
+ /**
89
+ * Mark a heuristic as enforced for this execution
90
+ * @param executionId - Unique identifier for the execution
91
+ * @param heuristicId - The heuristic ID to mark as enforced
92
+ */
93
+ markHeuristicEnforced(executionId: string, heuristicId: string): void {
94
+ const state = this.getSupervisionState(executionId);
95
+ state.enforcedHeuristics.add(heuristicId);
96
+ logger.debug(`[SupervisorOrchestrator] Marked heuristic "${heuristicId}" as enforced for ${executionId}`);
97
+ }
98
+
99
+ /**
100
+ * Increment the retry count for an execution
101
+ * @param executionId - Unique identifier for the execution
102
+ */
103
+ incrementRetryCount(executionId: string): void {
104
+ const state = this.getSupervisionState(executionId);
105
+ state.retryCount++;
106
+ logger.debug(`[SupervisorOrchestrator] Retry count for ${executionId}: ${state.retryCount}`);
107
+ }
108
+
109
+ /**
110
+ * Check if an execution has exceeded the maximum retries
111
+ * @param executionId - Unique identifier for the execution
112
+ */
113
+ hasExceededMaxRetries(executionId: string): boolean {
114
+ const state = this.getSupervisionState(executionId);
115
+ return state.retryCount >= state.maxRetries;
116
+ }
117
+
118
+ /**
119
+ * Clear the supervision state for an execution
120
+ * @param executionId - Unique identifier for the execution
121
+ */
122
+ clearState(executionId: string): void {
123
+ this.supervisionStates.delete(executionId);
124
+ logger.debug(`[SupervisorOrchestrator] Cleared supervision state for ${executionId}`);
125
+ }
126
+
127
+ /**
128
+ * Build the supervision context for LLM verification
129
+ */
130
+ private buildSupervisionContext(
131
+ context: PostCompletionContext | PreToolContext,
132
+ heuristicId: string,
133
+ detection: HeuristicDetection
134
+ ): SupervisionContext {
135
+ return {
136
+ agentSlug: context.agentSlug,
137
+ agentPubkey: context.agentPubkey,
138
+ systemPrompt: context.systemPrompt,
139
+ conversationHistory: context.conversationHistory,
140
+ availableTools: context.availableTools,
141
+ triggeringHeuristic: heuristicId,
142
+ detection,
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Check all post-completion heuristics
148
+ * @param context - The post-completion context
149
+ * @param executionId - Unique identifier for the execution (used to skip already-enforced heuristics)
150
+ * @returns Result of the supervision check
151
+ */
152
+ async checkPostCompletion(context: PostCompletionContext, executionId?: string): Promise<SupervisionCheckResult> {
153
+ const span = tracer.startSpan("supervision.check_post_completion", {
154
+ attributes: {
155
+ "agent.slug": context.agentSlug,
156
+ "agent.pubkey": context.agentPubkey,
157
+ "execution.id": executionId || "none",
158
+ },
159
+ });
160
+
161
+ // Track if any error occurred during heuristic execution
162
+ let hadError = false;
163
+
164
+ try {
165
+ // Use centralized health check for consistent fail-closed validation
166
+ // NOTE: We do NOT call registerDefaultHeuristics() here. Registration must happen
167
+ // at startup (in AgentExecutor or ProjectRuntime). If heuristics aren't registered,
168
+ // we fail-closed by checking the current state and throwing.
169
+ const healthResult = checkSupervisionHealth();
170
+
171
+ span.setAttributes({
172
+ "heuristics.registry_size": healthResult.registrySize,
173
+ "heuristics.post_completion_count": healthResult.postCompletionCount,
174
+ "heuristics.ids": healthResult.heuristicIds.join(","),
175
+ });
176
+
177
+ // FAIL-CLOSED: Health check validates both registry size AND post-completion count
178
+ if (!healthResult.healthy) {
179
+ const errorMessage = `[SupervisorOrchestrator] ${healthResult.errorMessage}`;
180
+
181
+ logger.error(errorMessage);
182
+ span.recordException(new Error(errorMessage));
183
+ span.setStatus({ code: SpanStatusCode.ERROR, message: "Supervision health check failed" });
184
+ span.addEvent("supervision.health_check_failed", {
185
+ "registry.size": healthResult.registrySize,
186
+ "registry.ids": healthResult.heuristicIds.join(","),
187
+ "post_completion.count": healthResult.postCompletionCount,
188
+ });
189
+
190
+ throw new Error(
191
+ "Supervision system misconfigured: no post-completion heuristics registered. " +
192
+ "Call registerDefaultHeuristics() during startup."
193
+ );
194
+ }
195
+
196
+ const heuristics = this.registry.getPostCompletionHeuristics();
197
+
198
+ // Routine execution - use DEBUG level to avoid log spam
199
+ logger.debug(
200
+ `[SupervisorOrchestrator] Running ${heuristics.length} post-completion heuristics for ${context.agentSlug}`,
201
+ {
202
+ heuristicIds: heuristics.map(h => h.id),
203
+ registrySize: healthResult.registrySize,
204
+ executionId,
205
+ }
206
+ );
207
+
208
+ span.addEvent("supervision.heuristics_check_started", {
209
+ "heuristics.count": heuristics.length,
210
+ });
211
+
212
+ for (const heuristic of heuristics) {
213
+ // Skip heuristics already enforced in this execution
214
+ if (executionId && this.isHeuristicEnforced(executionId, heuristic.id)) {
215
+ logger.debug(`[SupervisorOrchestrator] Skipping heuristic "${heuristic.id}" - already enforced`);
216
+ continue;
217
+ }
218
+
219
+ try {
220
+ // Run detection
221
+ const detection = await heuristic.detect(context);
222
+
223
+ span.addEvent("supervision.heuristic_checked", {
224
+ "heuristic.id": heuristic.id,
225
+ "heuristic.triggered": detection.triggered,
226
+ });
227
+
228
+ if (!detection.triggered) {
229
+ continue;
230
+ }
231
+
232
+ // Triggered heuristics are significant - keep at INFO level
233
+ logger.info(
234
+ `[SupervisorOrchestrator] Heuristic "${heuristic.id}" triggered for ${context.agentSlug}`,
235
+ { reason: detection.reason }
236
+ );
237
+
238
+ // For heuristics that skip verification, treat detection as confirmed
239
+ if (heuristic.skipVerification) {
240
+ logger.debug(
241
+ `[SupervisorOrchestrator] Heuristic "${heuristic.id}" skips verification, applying correction directly`
242
+ );
243
+
244
+ const syntheticVerification: VerificationResult = {
245
+ verdict: "violation",
246
+ explanation: "Heuristic configured to skip LLM verification",
247
+ };
248
+
249
+ const correctionAction = heuristic.getCorrectionAction(syntheticVerification);
250
+
251
+ if (shouldBuildCorrectionMessage(correctionAction)) {
252
+ correctionAction.message = heuristic.buildCorrectionMessage(
253
+ context,
254
+ syntheticVerification
255
+ );
256
+ }
257
+
258
+ span.addEvent("supervision.violation_detected", {
259
+ "heuristic.id": heuristic.id,
260
+ "action.type": correctionAction.type,
261
+ "skipped_verification": true,
262
+ });
263
+ span.setStatus({ code: SpanStatusCode.OK });
264
+
265
+ return {
266
+ hasViolation: true,
267
+ correctionAction,
268
+ heuristicId: heuristic.id,
269
+ detection,
270
+ verification: syntheticVerification,
271
+ };
272
+ }
273
+
274
+ // Build verification prompt and context
275
+ const verificationPrompt = heuristic.buildVerificationPrompt(context, detection);
276
+ const supervisionContext = this.buildSupervisionContext(
277
+ context,
278
+ heuristic.id,
279
+ detection
280
+ );
281
+
282
+ // Verify with LLM
283
+ const verification = await supervisorLLMService.verify(
284
+ supervisionContext,
285
+ verificationPrompt
286
+ );
287
+
288
+ if (verification.verdict === "violation") {
289
+ // Violations are significant - keep at WARN level
290
+ logger.warn(
291
+ `[SupervisorOrchestrator] Violation confirmed for heuristic "${heuristic.id}"`,
292
+ { explanation: verification.explanation }
293
+ );
294
+
295
+ // Get correction action
296
+ const correctionAction = heuristic.getCorrectionAction(verification);
297
+
298
+ // Build correction message if action type supports it
299
+ if (shouldBuildCorrectionMessage(correctionAction)) {
300
+ correctionAction.message = heuristic.buildCorrectionMessage(
301
+ context,
302
+ verification
303
+ );
304
+ }
305
+
306
+ span.addEvent("supervision.violation_detected", {
307
+ "heuristic.id": heuristic.id,
308
+ "action.type": correctionAction.type,
309
+ "skipped_verification": false,
310
+ });
311
+ span.setStatus({ code: SpanStatusCode.OK });
312
+
313
+ return {
314
+ hasViolation: true,
315
+ correctionAction,
316
+ heuristicId: heuristic.id,
317
+ detection,
318
+ verification,
319
+ };
320
+ }
321
+
322
+ // False positives are routine - use DEBUG level
323
+ logger.debug(
324
+ `[SupervisorOrchestrator] Heuristic "${heuristic.id}" detection was false positive`,
325
+ { explanation: verification.explanation }
326
+ );
327
+ } catch (error) {
328
+ // Normalize error before recording
329
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
330
+ hadError = true;
331
+
332
+ logger.error(
333
+ `[SupervisorOrchestrator] Error running heuristic "${heuristic.id}"`,
334
+ normalizedError
335
+ );
336
+ span.recordException(normalizedError);
337
+ // Continue to next heuristic on error
338
+ }
339
+ }
340
+
341
+ span.addEvent("supervision.check_completed", {
342
+ "violations_found": false,
343
+ "had_errors": hadError,
344
+ });
345
+
346
+ // Set span status based on whether errors occurred during heuristic execution
347
+ if (hadError) {
348
+ span.setStatus({ code: SpanStatusCode.ERROR, message: "Errors occurred during heuristic execution" });
349
+ } else {
350
+ span.setStatus({ code: SpanStatusCode.OK });
351
+ }
352
+
353
+ // Routine successful completion - use DEBUG level
354
+ logger.debug("[SupervisorOrchestrator] All heuristics passed - no violations detected", {
355
+ agent: context.agentSlug,
356
+ heuristicsChecked: heuristics.length,
357
+ });
358
+
359
+ return { hasViolation: false };
360
+ } catch (error) {
361
+ // Normalize error before recording
362
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
363
+ span.recordException(normalizedError);
364
+ span.setStatus({ code: SpanStatusCode.ERROR });
365
+ throw error;
366
+ } finally {
367
+ span.end();
368
+ }
369
+ }
370
+
371
+ /**
372
+ * Check pre-tool execution heuristics for a specific tool
373
+ * @param context - The pre-tool context
374
+ * @param executionId - Unique identifier for the execution (used to skip already-enforced heuristics)
375
+ * @returns Result of the supervision check
376
+ */
377
+ async checkPreTool(context: PreToolContext, executionId?: string): Promise<SupervisionCheckResult> {
378
+ const heuristics = this.registry.getPreToolHeuristics(context.toolName);
379
+
380
+ if (heuristics.length === 0) {
381
+ logger.debug(
382
+ `[SupervisorOrchestrator] No pre-tool heuristics for tool "${context.toolName}"`
383
+ );
384
+ return { hasViolation: false };
385
+ }
386
+
387
+ logger.debug(
388
+ `[SupervisorOrchestrator] Running ${heuristics.length} pre-tool heuristics for "${context.toolName}"`
389
+ );
390
+
391
+ for (const heuristic of heuristics) {
392
+ // Skip heuristics already enforced in this execution
393
+ if (executionId && this.isHeuristicEnforced(executionId, heuristic.id)) {
394
+ logger.debug(`[SupervisorOrchestrator] Skipping pre-tool heuristic "${heuristic.id}" - already enforced`);
395
+ continue;
396
+ }
397
+
398
+ try {
399
+ // Run detection
400
+ const detection = await heuristic.detect(context);
401
+
402
+ if (!detection.triggered) {
403
+ continue;
404
+ }
405
+
406
+ logger.info(
407
+ `[SupervisorOrchestrator] Pre-tool heuristic "${heuristic.id}" triggered for "${context.toolName}"`,
408
+ { reason: detection.reason }
409
+ );
410
+
411
+ // Build verification prompt and context
412
+ const verificationPrompt = heuristic.buildVerificationPrompt(context, detection);
413
+ const supervisionContext = this.buildSupervisionContext(
414
+ context,
415
+ heuristic.id,
416
+ detection
417
+ );
418
+
419
+ // Verify with LLM
420
+ const verification = await supervisorLLMService.verify(
421
+ supervisionContext,
422
+ verificationPrompt
423
+ );
424
+
425
+ if (verification.verdict === "violation") {
426
+ logger.warn(
427
+ `[SupervisorOrchestrator] Pre-tool violation confirmed for "${heuristic.id}"`,
428
+ { explanation: verification.explanation, tool: context.toolName }
429
+ );
430
+
431
+ // Get correction action
432
+ const correctionAction = heuristic.getCorrectionAction(verification);
433
+
434
+ // Build correction message if action type supports it
435
+ if (shouldBuildCorrectionMessage(correctionAction)) {
436
+ correctionAction.message = heuristic.buildCorrectionMessage(
437
+ context,
438
+ verification
439
+ );
440
+ }
441
+
442
+ return {
443
+ hasViolation: true,
444
+ correctionAction,
445
+ heuristicId: heuristic.id,
446
+ detection,
447
+ verification,
448
+ };
449
+ }
450
+
451
+ logger.debug(
452
+ `[SupervisorOrchestrator] Pre-tool heuristic "${heuristic.id}" was false positive`,
453
+ { explanation: verification.explanation }
454
+ );
455
+ } catch (error) {
456
+ logger.error(
457
+ `[SupervisorOrchestrator] Error running pre-tool heuristic "${heuristic.id}"`,
458
+ error
459
+ );
460
+ // Continue to next heuristic on error
461
+ }
462
+ }
463
+
464
+ return { hasViolation: false };
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Singleton instance of the supervisor orchestrator
470
+ */
471
+ export const supervisorOrchestrator = new SupervisorOrchestrator();
@@ -0,0 +1,73 @@
1
+ import type {
2
+ CorrectionAction,
3
+ Heuristic,
4
+ HeuristicDetection,
5
+ PostCompletionContext,
6
+ VerificationResult,
7
+ } from "../types";
8
+
9
+ /**
10
+ * Default threshold for consecutive tool calls before nudging
11
+ */
12
+ const DEFAULT_THRESHOLD = 5;
13
+
14
+ /**
15
+ * Heuristic that nudges agents to use todo tracking after many consecutive tool calls
16
+ * without a todo list. This is a low-stakes, one-time nudge that skips LLM verification.
17
+ */
18
+ export class ConsecutiveToolsWithoutTodoHeuristic implements Heuristic<PostCompletionContext> {
19
+ id = "consecutive-tools-without-todo";
20
+ name = "Consecutive Tool Uses Without Todo List";
21
+ timing = "post-completion" as const;
22
+ skipVerification = true; // Low-stakes nudge, no LLM verification needed
23
+
24
+ private threshold: number;
25
+
26
+ constructor(threshold: number = DEFAULT_THRESHOLD) {
27
+ this.threshold = threshold;
28
+ }
29
+
30
+ async detect(context: PostCompletionContext): Promise<HeuristicDetection> {
31
+ // Skip if agent already has todos
32
+ if (context.todos.length > 0) {
33
+ return { triggered: false };
34
+ }
35
+
36
+ // Skip if already nudged in this conversation
37
+ if (context.hasBeenNudgedAboutTodos) {
38
+ return { triggered: false };
39
+ }
40
+
41
+ // Check tool call count
42
+ if (context.toolCallsMade.length < this.threshold) {
43
+ return { triggered: false };
44
+ }
45
+
46
+ return {
47
+ triggered: true,
48
+ reason: `Agent made ${context.toolCallsMade.length} tool calls without tracking work in a todo list`,
49
+ evidence: {
50
+ toolCount: context.toolCallsMade.length,
51
+ threshold: this.threshold,
52
+ },
53
+ };
54
+ }
55
+
56
+ buildVerificationPrompt(_context: PostCompletionContext, _detection: HeuristicDetection): string {
57
+ // Not used since skipVerification is true
58
+ return "";
59
+ }
60
+
61
+ buildCorrectionMessage(_context: PostCompletionContext, _verification: VerificationResult): string {
62
+ return `**Task Tracking Suggestion:** You've made several tool calls without tracking your work. Consider using \`todo_write()\` to break down complex tasks into trackable steps - it helps show progress and ensures nothing is missed.
63
+
64
+ This is a one-time suggestion.`;
65
+ }
66
+
67
+ getCorrectionAction(_verification: VerificationResult): CorrectionAction {
68
+ return {
69
+ type: "inject-message",
70
+ reEngage: false, // Don't re-engage, just note for future
71
+ };
72
+ }
73
+ }
@@ -0,0 +1,80 @@
1
+ import { isDelegateToolName } from "@/agents/tool-names";
2
+ import type { CorrectionAction, Heuristic, HeuristicDetection, PostCompletionContext, VerificationResult } from "../types";
3
+
4
+ export class DelegationClaimHeuristic implements Heuristic<PostCompletionContext> {
5
+ id = "delegation-claim";
6
+ name = "Delegation Claim Without Tool Call";
7
+ timing = "post-completion" as const;
8
+
9
+ // List of known agent slugs should be passed in or fetched
10
+ private knownAgentSlugs: string[] = [];
11
+
12
+ setKnownAgentSlugs(slugs: string[]): void {
13
+ this.knownAgentSlugs = slugs;
14
+ }
15
+
16
+ async detect(context: PostCompletionContext): Promise<HeuristicDetection> {
17
+ const content = context.messageContent.toLowerCase();
18
+
19
+ // Check for delegation-related keywords
20
+ const hasDelegationIntent =
21
+ content.includes("delegate") ||
22
+ content.includes("delegating") ||
23
+ content.includes("i'll delegate") ||
24
+ content.includes("i will delegate") ||
25
+ content.includes("let me delegate");
26
+
27
+ if (!hasDelegationIntent) {
28
+ return { triggered: false };
29
+ }
30
+
31
+ // Check if delegate tool was actually called
32
+ const delegateToolCalled = context.toolCallsMade.some((toolName) => isDelegateToolName(toolName));
33
+
34
+ if (delegateToolCalled) {
35
+ return { triggered: false };
36
+ }
37
+
38
+ // Check if any known agent slugs are mentioned
39
+ const mentionedSlugs = this.knownAgentSlugs.filter(slug =>
40
+ content.includes(slug.toLowerCase())
41
+ );
42
+
43
+ const triggered = hasDelegationIntent && !delegateToolCalled && mentionedSlugs.length > 0;
44
+
45
+ return {
46
+ triggered,
47
+ reason: triggered
48
+ ? `Agent claimed to delegate to ${mentionedSlugs.join(", ")} but did not call delegate tool`
49
+ : undefined,
50
+ evidence: {
51
+ mentionedSlugs,
52
+ delegationPhraseFound: hasDelegationIntent,
53
+ toolCallsMade: context.toolCallsMade,
54
+ },
55
+ };
56
+ }
57
+
58
+ buildVerificationPrompt(context: PostCompletionContext, detection: HeuristicDetection): string {
59
+ const evidence = detection.evidence as { mentionedSlugs?: string[] } | undefined;
60
+ return `The agent "${context.agentSlug}" mentioned delegating to agents ${JSON.stringify(evidence?.mentionedSlugs)} but did not call the delegate tool.
61
+
62
+ Message content excerpt: "${context.messageContent.substring(0, 500)}"
63
+
64
+ Tools called: ${JSON.stringify(context.toolCallsMade)}
65
+
66
+ Did the agent intend to delegate but forget to use the tool, or was this just a discussion about delegation?`;
67
+ }
68
+
69
+ buildCorrectionMessage(_context: PostCompletionContext, verification: VerificationResult): string {
70
+ return verification.correctionMessage ||
71
+ "You mentioned delegating to an agent but did not call the delegate tool. If you intended to delegate, please use the delegate tool. If you were just discussing delegation, please clarify your intentions.";
72
+ }
73
+
74
+ getCorrectionAction(_verification: VerificationResult): CorrectionAction {
75
+ return {
76
+ type: "suppress-publish",
77
+ reEngage: true,
78
+ };
79
+ }
80
+ }