@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.
- package/README.md +194 -0
- package/dist/backend-wrapper.cjs +3 -0
- package/dist/src/index.js +331928 -0
- package/package.json +103 -0
- package/src/agents/AgentRegistry.ts +418 -0
- package/src/agents/AgentStorage.ts +1133 -0
- package/src/agents/ConfigResolver.ts +229 -0
- package/src/agents/agent-installer.ts +236 -0
- package/src/agents/agent-loader.ts +241 -0
- package/src/agents/constants.ts +82 -0
- package/src/agents/errors.ts +48 -0
- package/src/agents/execution/AgentExecutor.ts +561 -0
- package/src/agents/execution/ExecutionContextFactory.ts +112 -0
- package/src/agents/execution/MessageCompiler.ts +597 -0
- package/src/agents/execution/MessageSyncer.ts +100 -0
- package/src/agents/execution/PostCompletionChecker.ts +278 -0
- package/src/agents/execution/ProgressMonitor.ts +50 -0
- package/src/agents/execution/RALResolver.ts +177 -0
- package/src/agents/execution/SessionManager.ts +181 -0
- package/src/agents/execution/StreamCallbacks.ts +312 -0
- package/src/agents/execution/StreamExecutionHandler.ts +579 -0
- package/src/agents/execution/StreamSetup.ts +313 -0
- package/src/agents/execution/ToolEventHandlers.ts +239 -0
- package/src/agents/execution/ToolExecutionTracker.ts +498 -0
- package/src/agents/execution/ToolResultUtils.ts +97 -0
- package/src/agents/execution/ToolSupervisionWrapper.ts +174 -0
- package/src/agents/execution/constants.ts +16 -0
- package/src/agents/execution/index.ts +3 -0
- package/src/agents/execution/types.ts +96 -0
- package/src/agents/execution/utils.ts +26 -0
- package/src/agents/index.ts +4 -0
- package/src/agents/script-installer.ts +266 -0
- package/src/agents/supervision/SupervisorLLMService.ts +253 -0
- package/src/agents/supervision/SupervisorOrchestrator.ts +471 -0
- package/src/agents/supervision/heuristics/ConsecutiveToolsWithoutTodoHeuristic.ts +73 -0
- package/src/agents/supervision/heuristics/DelegationClaimHeuristic.ts +80 -0
- package/src/agents/supervision/heuristics/HeuristicRegistry.ts +114 -0
- package/src/agents/supervision/heuristics/PendingTodosHeuristic.ts +93 -0
- package/src/agents/supervision/heuristics/SilentAgentHeuristic.ts +54 -0
- package/src/agents/supervision/heuristics/index.ts +5 -0
- package/src/agents/supervision/index.ts +28 -0
- package/src/agents/supervision/registerHeuristics.ts +110 -0
- package/src/agents/supervision/supervisionHealthCheck.ts +123 -0
- package/src/agents/supervision/types.ts +171 -0
- package/src/agents/tool-names.ts +46 -0
- package/src/agents/tool-normalization.ts +184 -0
- package/src/agents/types/index.ts +2 -0
- package/src/agents/types/runtime.ts +74 -0
- package/src/agents/types/storage.ts +145 -0
- package/src/commands/agent/import/index.ts +6 -0
- package/src/commands/agent/import/openclaw-distiller.ts +57 -0
- package/src/commands/agent/import/openclaw-reader.ts +141 -0
- package/src/commands/agent/import/openclaw.ts +154 -0
- package/src/commands/agent/index.ts +6 -0
- package/src/commands/agent.ts +215 -0
- package/src/commands/daemon.ts +198 -0
- package/src/commands/doctor.ts +134 -0
- package/src/commands/setup/embed.ts +228 -0
- package/src/commands/setup/global-system-prompt.ts +223 -0
- package/src/commands/setup/image.ts +179 -0
- package/src/commands/setup/index.ts +16 -0
- package/src/commands/setup/interactive.ts +95 -0
- package/src/commands/setup/llm.ts +38 -0
- package/src/commands/setup/onboarding.ts +294 -0
- package/src/commands/setup/providers.ts +27 -0
- package/src/constants.ts +34 -0
- package/src/conversations/ConversationDiskReader.ts +148 -0
- package/src/conversations/ConversationRegistry.ts +728 -0
- package/src/conversations/ConversationStore.ts +868 -0
- package/src/conversations/MessageBuilder.ts +866 -0
- package/src/conversations/executionTime.ts +62 -0
- package/src/conversations/formatters/DelegationXmlFormatter.ts +64 -0
- package/src/conversations/formatters/ThreadedConversationFormatter.ts +303 -0
- package/src/conversations/formatters/index.ts +9 -0
- package/src/conversations/formatters/utils/MessageFormatter.ts +46 -0
- package/src/conversations/formatters/utils/TimestampFormatter.ts +56 -0
- package/src/conversations/formatters/utils/TreeBuilder.ts +131 -0
- package/src/conversations/formatters/utils/TreeRenderer.ts +49 -0
- package/src/conversations/index.ts +2 -0
- package/src/conversations/persistence/ToolMessageStorage.ts +143 -0
- package/src/conversations/search/ConversationIndexManager.ts +393 -0
- package/src/conversations/search/QueryParser.ts +114 -0
- package/src/conversations/search/SearchEngine.ts +175 -0
- package/src/conversations/search/SnippetExtractor.ts +345 -0
- package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +484 -0
- package/src/conversations/search/embeddings/ConversationIndexingJob.ts +320 -0
- package/src/conversations/search/embeddings/IndexingStateManager.ts +338 -0
- package/src/conversations/search/embeddings/index.ts +18 -0
- package/src/conversations/search/index.ts +49 -0
- package/src/conversations/search/types.ts +124 -0
- package/src/conversations/services/CategoryManager.ts +160 -0
- package/src/conversations/services/ConversationResolver.ts +296 -0
- package/src/conversations/services/ConversationSummarizer.ts +234 -0
- package/src/conversations/services/MetadataDebounceManager.ts +188 -0
- package/src/conversations/services/index.ts +2 -0
- package/src/conversations/types.ts +148 -0
- package/src/conversations/utils/content-utils.ts +69 -0
- package/src/conversations/utils/image-placeholder.ts +281 -0
- package/src/conversations/utils/image-url-utils.ts +171 -0
- package/src/conversations/utils/multimodal-content.ts +90 -0
- package/src/conversations/utils/tool-result-truncator.ts +159 -0
- package/src/daemon/Daemon.ts +1883 -0
- package/src/daemon/ProjectRuntime.ts +657 -0
- package/src/daemon/RestartState.ts +152 -0
- package/src/daemon/RuntimeLifecycle.ts +268 -0
- package/src/daemon/SubscriptionManager.ts +305 -0
- package/src/daemon/UnixSocketTransport.ts +318 -0
- package/src/daemon/filters/SubscriptionFilterBuilder.ts +119 -0
- package/src/daemon/index.ts +9 -0
- package/src/daemon/routing/DaemonRouter.ts +491 -0
- package/src/daemon/types.ts +150 -0
- package/src/daemon/utils/routing-log.ts +76 -0
- package/src/daemon/utils/telemetry.ts +173 -0
- package/src/event-handler/agentDeletion.ts +383 -0
- package/src/event-handler/index.ts +749 -0
- package/src/event-handler/newConversation.ts +165 -0
- package/src/event-handler/project.ts +166 -0
- package/src/event-handler/reply.ts +18 -0
- package/src/events/NDKAgentDefinition.ts +292 -0
- package/src/events/NDKAgentLesson.ts +106 -0
- package/src/events/NDKEventMetadata.ts +34 -0
- package/src/events/NDKMCPTool.ts +60 -0
- package/src/events/NDKProjectStatus.ts +384 -0
- package/src/events/index.ts +4 -0
- package/src/index.ts +126 -0
- package/src/lib/agent-home.ts +334 -0
- package/src/lib/error-formatter.ts +200 -0
- package/src/lib/fs/filesystem.ts +128 -0
- package/src/lib/fs/index.ts +1 -0
- package/src/lib/json-parser.ts +30 -0
- package/src/lib/string.ts +15 -0
- package/src/lib/time.ts +74 -0
- package/src/llm/ChunkHandler.ts +277 -0
- package/src/llm/FinishHandler.ts +250 -0
- package/src/llm/LLMConfigEditor.ts +154 -0
- package/src/llm/LLMServiceFactory.ts +230 -0
- package/src/llm/MessageProcessor.ts +90 -0
- package/src/llm/RecordingState.ts +37 -0
- package/src/llm/StreamPublisher.ts +40 -0
- package/src/llm/TracingUtils.ts +77 -0
- package/src/llm/chunk-validators.ts +57 -0
- package/src/llm/constants.ts +6 -0
- package/src/llm/index.ts +12 -0
- package/src/llm/meta/MetaModelResolver.ts +352 -0
- package/src/llm/meta/index.ts +11 -0
- package/src/llm/middleware/flight-recorder.ts +188 -0
- package/src/llm/providers/MockProvider.ts +332 -0
- package/src/llm/providers/agent/ClaudeCodeProvider.ts +343 -0
- package/src/llm/providers/agent/ClaudeCodeToolsAdapter.ts +203 -0
- package/src/llm/providers/agent/CodexAppServerProvider.ts +214 -0
- package/src/llm/providers/agent/CodexAppServerToolsAdapter.ts +91 -0
- package/src/llm/providers/agent/index.ts +10 -0
- package/src/llm/providers/base/AgentProvider.ts +107 -0
- package/src/llm/providers/base/BaseProvider.ts +114 -0
- package/src/llm/providers/base/StandardProvider.ts +38 -0
- package/src/llm/providers/base/index.ts +9 -0
- package/src/llm/providers/index.ts +106 -0
- package/src/llm/providers/key-manager.ts +238 -0
- package/src/llm/providers/ollama-models.ts +105 -0
- package/src/llm/providers/openrouter-models.ts +102 -0
- package/src/llm/providers/provider-ids.ts +18 -0
- package/src/llm/providers/registry/ProviderRegistry.ts +414 -0
- package/src/llm/providers/registry/index.ts +7 -0
- package/src/llm/providers/standard/AnthropicProvider.ts +71 -0
- package/src/llm/providers/standard/OllamaProvider.ts +59 -0
- package/src/llm/providers/standard/OpenAIProvider.ts +44 -0
- package/src/llm/providers/standard/OpenRouterProvider.ts +103 -0
- package/src/llm/providers/standard/index.ts +10 -0
- package/src/llm/providers/types.ts +194 -0
- package/src/llm/providers/usage-metadata.ts +78 -0
- package/src/llm/service.ts +713 -0
- package/src/llm/types.ts +167 -0
- package/src/llm/utils/ConfigurationManager.ts +650 -0
- package/src/llm/utils/ConfigurationTester.ts +229 -0
- package/src/llm/utils/ModelSelector.ts +212 -0
- package/src/llm/utils/ProviderConfigUI.ts +177 -0
- package/src/llm/utils/claudeCodePromptCompiler.ts +141 -0
- package/src/llm/utils/codex-models.ts +53 -0
- package/src/llm/utils/context-window-cache.ts +30 -0
- package/src/llm/utils/models-dev-cache.ts +267 -0
- package/src/llm/utils/provider-setup.ts +50 -0
- package/src/llm/utils/tool-errors.ts +78 -0
- package/src/llm/utils/usage.ts +74 -0
- package/src/logging/EventRoutingLogger.ts +205 -0
- package/src/nostr/AgentEventDecoder.ts +357 -0
- package/src/nostr/AgentEventEncoder.ts +677 -0
- package/src/nostr/AgentProfilePublisher.ts +657 -0
- package/src/nostr/AgentPublisher.ts +437 -0
- package/src/nostr/BlossomService.ts +226 -0
- package/src/nostr/InterventionPublisher.ts +132 -0
- package/src/nostr/TagExtractor.ts +228 -0
- package/src/nostr/collectEvents.ts +83 -0
- package/src/nostr/constants.ts +38 -0
- package/src/nostr/encryption.ts +26 -0
- package/src/nostr/index.ts +31 -0
- package/src/nostr/keys.ts +17 -0
- package/src/nostr/kinds.ts +37 -0
- package/src/nostr/ndkClient.ts +72 -0
- package/src/nostr/relays.ts +43 -0
- package/src/nostr/trace-context.ts +39 -0
- package/src/nostr/types.ts +227 -0
- package/src/nostr/utils.ts +84 -0
- package/src/prompts/core/FragmentRegistry.ts +30 -0
- package/src/prompts/core/PromptBuilder.ts +98 -0
- package/src/prompts/core/index.ts +3 -0
- package/src/prompts/core/types.ts +13 -0
- package/src/prompts/fragments/00-global-system-prompt.ts +44 -0
- package/src/prompts/fragments/01-agent-identity.ts +69 -0
- package/src/prompts/fragments/02-agent-home-directory.ts +114 -0
- package/src/prompts/fragments/03-system-reminders-explanation.ts +14 -0
- package/src/prompts/fragments/04-relay-configuration.ts +38 -0
- package/src/prompts/fragments/05-delegation-chain.ts +45 -0
- package/src/prompts/fragments/06-agent-todos.ts +74 -0
- package/src/prompts/fragments/06-todo-usage-guidance.ts +34 -0
- package/src/prompts/fragments/07-meta-project-context.ts +234 -0
- package/src/prompts/fragments/08-active-conversations.ts +382 -0
- package/src/prompts/fragments/09-recent-conversations.ts +153 -0
- package/src/prompts/fragments/10-referenced-article.ts +21 -0
- package/src/prompts/fragments/11-nudges.ts +134 -0
- package/src/prompts/fragments/12-skills.ts +127 -0
- package/src/prompts/fragments/13-available-nudges.ts +122 -0
- package/src/prompts/fragments/15-available-agents.ts +53 -0
- package/src/prompts/fragments/16-stay-in-your-lane.ts +41 -0
- package/src/prompts/fragments/17-todo-before-delegation.ts +39 -0
- package/src/prompts/fragments/20-voice-mode.ts +62 -0
- package/src/prompts/fragments/22-scheduled-tasks.ts +175 -0
- package/src/prompts/fragments/24-retrieved-lessons.ts +26 -0
- package/src/prompts/fragments/25-rag-instructions.ts +333 -0
- package/src/prompts/fragments/26-mcp-resources.ts +237 -0
- package/src/prompts/fragments/27-memorized-reports.ts +77 -0
- package/src/prompts/fragments/28-agent-directed-monitoring.ts +32 -0
- package/src/prompts/fragments/29-rag-collections.ts +50 -0
- package/src/prompts/fragments/30-worktree-context.ts +98 -0
- package/src/prompts/fragments/31-agents-md-guidance.ts +96 -0
- package/src/prompts/fragments/32-process-metrics.ts +72 -0
- package/src/prompts/fragments/debug-mode.ts +48 -0
- package/src/prompts/fragments/delegation-completion.ts +44 -0
- package/src/prompts/fragments/index.ts +91 -0
- package/src/prompts/index.ts +21 -0
- package/src/prompts/utils/systemPromptBuilder.ts +777 -0
- package/src/scripts/migrate-prefix-index.ts +157 -0
- package/src/services/AgentDefinitionMonitor.ts +701 -0
- package/src/services/ConfigService.ts +723 -0
- package/src/services/CooldownRegistry.ts +199 -0
- package/src/services/LLMOperationsRegistry.ts +424 -0
- package/src/services/OwnerAgentListService.ts +354 -0
- package/src/services/PubkeyService.ts +308 -0
- package/src/services/agents/AgentMetadataStore.ts +72 -0
- package/src/services/agents/AgentResolution.ts +59 -0
- package/src/services/agents/EscalationService.ts +281 -0
- package/src/services/agents/NDKAgentDiscovery.ts +95 -0
- package/src/services/agents/index.ts +7 -0
- package/src/services/agents-md/AgentsMdService.ts +184 -0
- package/src/services/agents-md/SystemReminderInjector.ts +238 -0
- package/src/services/agents-md/index.ts +11 -0
- package/src/services/apns/APNsClient.ts +203 -0
- package/src/services/apns/APNsService.ts +358 -0
- package/src/services/apns/index.ts +11 -0
- package/src/services/apns/types.ts +80 -0
- package/src/services/compression/CompressionService.ts +445 -0
- package/src/services/compression/compression-schema.ts +28 -0
- package/src/services/compression/compression-types.ts +74 -0
- package/src/services/compression/compression-utils.ts +587 -0
- package/src/services/config/types.ts +394 -0
- package/src/services/dispatch/AgentDispatchService.ts +937 -0
- package/src/services/dispatch/AgentRouter.ts +181 -0
- package/src/services/dispatch/DelegationCompletionHandler.ts +232 -0
- package/src/services/embedding/EmbeddingProvider.ts +188 -0
- package/src/services/embedding/index.ts +5 -0
- package/src/services/event-context/EventContextService.ts +108 -0
- package/src/services/event-context/index.ts +2 -0
- package/src/services/heuristics/ContextBuilder.ts +106 -0
- package/src/services/heuristics/HeuristicEngine.ts +200 -0
- package/src/services/heuristics/formatters.ts +58 -0
- package/src/services/heuristics/index.ts +12 -0
- package/src/services/heuristics/rules/index.ts +25 -0
- package/src/services/heuristics/rules/todoBeforeDelegation.ts +69 -0
- package/src/services/heuristics/rules/todoReminderOnToolUse.ts +63 -0
- package/src/services/heuristics/types.ts +144 -0
- package/src/services/image/ImageGenerationService.ts +389 -0
- package/src/services/image/index.ts +12 -0
- package/src/services/intervention/InterventionService.ts +1352 -0
- package/src/services/intervention/index.ts +7 -0
- package/src/services/mcp/MCPManager.ts +683 -0
- package/src/services/mcp/McpNotificationDelivery.ts +139 -0
- package/src/services/mcp/McpSubscriptionService.ts +653 -0
- package/src/services/mcp/mcpInstaller.ts +130 -0
- package/src/services/nip46/Nip46SigningLog.ts +81 -0
- package/src/services/nip46/Nip46SigningService.ts +467 -0
- package/src/services/nip46/index.ts +4 -0
- package/src/services/nudge/NudgeService.ts +224 -0
- package/src/services/nudge/NudgeWhitelistService.ts +382 -0
- package/src/services/nudge/index.ts +5 -0
- package/src/services/nudge/types.ts +83 -0
- package/src/services/projects/ProjectContext.ts +672 -0
- package/src/services/projects/ProjectContextStore.ts +102 -0
- package/src/services/projects/index.ts +6 -0
- package/src/services/prompt-compiler/index.ts +15 -0
- package/src/services/prompt-compiler/prompt-compiler-service.ts +1143 -0
- package/src/services/pubkey-gate/PubkeyGateService.ts +93 -0
- package/src/services/pubkey-gate/index.ts +1 -0
- package/src/services/rag/EmbeddingProviderFactory.ts +292 -0
- package/src/services/rag/LanceDBMaintenanceService.ts +211 -0
- package/src/services/rag/RAGDatabaseService.ts +173 -0
- package/src/services/rag/RAGOperations.ts +682 -0
- package/src/services/rag/RAGService.ts +240 -0
- package/src/services/rag/RagSubscriptionService.ts +618 -0
- package/src/services/rag/rag-utils.ts +174 -0
- package/src/services/ral/PendingDelegationsRegistry.ts +168 -0
- package/src/services/ral/RALRegistry.ts +2782 -0
- package/src/services/ral/index.ts +4 -0
- package/src/services/ral/types.ts +292 -0
- package/src/services/reports/LocalReportStore.ts +380 -0
- package/src/services/reports/ReportEmbeddingService.ts +430 -0
- package/src/services/reports/ReportService.ts +440 -0
- package/src/services/reports/articleUtils.ts +52 -0
- package/src/services/reports/index.ts +7 -0
- package/src/services/scheduling/SchedulerService.ts +1057 -0
- package/src/services/scheduling/errors.ts +14 -0
- package/src/services/scheduling/index.ts +7 -0
- package/src/services/scheduling/utils.ts +77 -0
- package/src/services/search/SearchProviderRegistry.ts +78 -0
- package/src/services/search/UnifiedSearchService.ts +218 -0
- package/src/services/search/index.ts +47 -0
- package/src/services/search/projectFilter.ts +22 -0
- package/src/services/search/providers/ConversationSearchProvider.ts +48 -0
- package/src/services/search/providers/LessonSearchProvider.ts +75 -0
- package/src/services/search/providers/ReportSearchProvider.ts +49 -0
- package/src/services/search/types.ts +144 -0
- package/src/services/skill/SkillService.ts +482 -0
- package/src/services/skill/index.ts +2 -0
- package/src/services/skill/types.ts +70 -0
- package/src/services/status/OperationsStatusService.ts +276 -0
- package/src/services/status/ProjectStatusService.ts +522 -0
- package/src/services/status/index.ts +11 -0
- package/src/services/storage/PrefixKVStore.ts +242 -0
- package/src/services/storage/index.ts +1 -0
- package/src/services/system-reminder/SystemReminderUtils.ts +96 -0
- package/src/services/system-reminder/index.ts +7 -0
- package/src/services/trust-pubkeys/TrustPubkeyService.ts +325 -0
- package/src/services/trust-pubkeys/index.ts +2 -0
- package/src/telemetry/ConversationSpanManager.ts +111 -0
- package/src/telemetry/EventLoopMonitor.ts +206 -0
- package/src/telemetry/LLMSpanRegistry.ts +20 -0
- package/src/telemetry/NostrSpanProcessor.ts +89 -0
- package/src/telemetry/ToolCallSpanProcessor.ts +66 -0
- package/src/telemetry/diagnostics.ts +27 -0
- package/src/telemetry/setup.ts +120 -0
- package/src/tools/implementations/agents_discover.ts +121 -0
- package/src/tools/implementations/agents_hire.ts +127 -0
- package/src/tools/implementations/agents_list.ts +96 -0
- package/src/tools/implementations/agents_publish.ts +611 -0
- package/src/tools/implementations/agents_read.ts +173 -0
- package/src/tools/implementations/agents_write.ts +200 -0
- package/src/tools/implementations/ask.ts +411 -0
- package/src/tools/implementations/change_model.ts +141 -0
- package/src/tools/implementations/conversation_get.ts +661 -0
- package/src/tools/implementations/conversation_list.ts +377 -0
- package/src/tools/implementations/conversation_search.ts +370 -0
- package/src/tools/implementations/delegate.ts +327 -0
- package/src/tools/implementations/delegate_crossproject.ts +209 -0
- package/src/tools/implementations/delegate_followup.ts +300 -0
- package/src/tools/implementations/fs_edit.ts +162 -0
- package/src/tools/implementations/fs_glob.ts +182 -0
- package/src/tools/implementations/fs_grep.ts +513 -0
- package/src/tools/implementations/fs_read.ts +332 -0
- package/src/tools/implementations/fs_write.ts +113 -0
- package/src/tools/implementations/generate_image.ts +259 -0
- package/src/tools/implementations/home_fs.ts +515 -0
- package/src/tools/implementations/kill.ts +651 -0
- package/src/tools/implementations/learn.ts +166 -0
- package/src/tools/implementations/lesson-formatter.ts +38 -0
- package/src/tools/implementations/lesson_delete.ts +164 -0
- package/src/tools/implementations/lesson_get.ts +105 -0
- package/src/tools/implementations/lessons_list.ts +153 -0
- package/src/tools/implementations/mcp_resource_read.ts +161 -0
- package/src/tools/implementations/mcp_subscribe.ts +158 -0
- package/src/tools/implementations/mcp_subscription_stop.ts +85 -0
- package/src/tools/implementations/nostr_fetch.ts +149 -0
- package/src/tools/implementations/nostr_publish_as_user.ts +353 -0
- package/src/tools/implementations/project_list.ts +146 -0
- package/src/tools/implementations/rag_add_documents.ts +573 -0
- package/src/tools/implementations/rag_create_collection.ts +65 -0
- package/src/tools/implementations/rag_delete_collection.ts +68 -0
- package/src/tools/implementations/rag_list_collections.ts +77 -0
- package/src/tools/implementations/rag_query.ts +107 -0
- package/src/tools/implementations/rag_subscription_create.ts +105 -0
- package/src/tools/implementations/rag_subscription_delete.ts +80 -0
- package/src/tools/implementations/rag_subscription_get.ts +123 -0
- package/src/tools/implementations/rag_subscription_list.ts +128 -0
- package/src/tools/implementations/report_delete.ts +79 -0
- package/src/tools/implementations/report_read.ts +160 -0
- package/src/tools/implementations/report_write.ts +278 -0
- package/src/tools/implementations/reports_list.ts +77 -0
- package/src/tools/implementations/schedule_task.ts +104 -0
- package/src/tools/implementations/schedule_task_cancel.ts +62 -0
- package/src/tools/implementations/schedule_task_once.ts +128 -0
- package/src/tools/implementations/schedule_tasks_list.ts +79 -0
- package/src/tools/implementations/search.ts +160 -0
- package/src/tools/implementations/shell.ts +553 -0
- package/src/tools/implementations/todo.ts +260 -0
- package/src/tools/implementations/upload_blob.ts +381 -0
- package/src/tools/implementations/web_fetch.ts +153 -0
- package/src/tools/implementations/web_search.ts +250 -0
- package/src/tools/registry.ts +670 -0
- package/src/tools/types.ts +177 -0
- package/src/tools/utils.ts +256 -0
- package/src/types/event-ids.ts +320 -0
- package/src/types/index.ts +46 -0
- package/src/utils/agentFetcher.ts +107 -0
- package/src/utils/cli-error.ts +29 -0
- package/src/utils/conversation-id.ts +27 -0
- package/src/utils/conversation-utils.ts +1 -0
- package/src/utils/delegation-chain.ts +357 -0
- package/src/utils/error-handler.ts +42 -0
- package/src/utils/git/gitignore.ts +69 -0
- package/src/utils/git/index.ts +2 -0
- package/src/utils/git/initializeGitRepo.ts +204 -0
- package/src/utils/git/worktree.ts +260 -0
- package/src/utils/lessonFormatter.ts +70 -0
- package/src/utils/lessonTrust.ts +24 -0
- package/src/utils/lockfile.ts +123 -0
- package/src/utils/logger.ts +149 -0
- package/src/utils/nostr-entity-parser.ts +365 -0
- package/src/utils/process.ts +49 -0
- package/src/wrapper.ts +262 -0
- 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
|
+
}
|