@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,114 @@
|
|
|
1
|
+
import { logger } from "@/utils/logger";
|
|
2
|
+
import type { Heuristic, HeuristicTiming, PostCompletionContext, PreToolContext } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Singleton registry for managing supervision heuristics
|
|
6
|
+
* Allows registration and retrieval of heuristics by timing and tool filter
|
|
7
|
+
*/
|
|
8
|
+
export class HeuristicRegistry {
|
|
9
|
+
private static instance: HeuristicRegistry | null = null;
|
|
10
|
+
|
|
11
|
+
private heuristics: Map<string, Heuristic<unknown>> = new Map();
|
|
12
|
+
|
|
13
|
+
private constructor() {
|
|
14
|
+
// Private constructor for singleton pattern
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the singleton instance of the registry
|
|
19
|
+
*/
|
|
20
|
+
static getInstance(): HeuristicRegistry {
|
|
21
|
+
if (!HeuristicRegistry.instance) {
|
|
22
|
+
HeuristicRegistry.instance = new HeuristicRegistry();
|
|
23
|
+
}
|
|
24
|
+
return HeuristicRegistry.instance;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Register a heuristic with the registry
|
|
29
|
+
* @param heuristic - The heuristic to register
|
|
30
|
+
*/
|
|
31
|
+
register<T>(heuristic: Heuristic<T>): void {
|
|
32
|
+
if (this.heuristics.has(heuristic.id)) {
|
|
33
|
+
logger.warn(
|
|
34
|
+
`[HeuristicRegistry] Heuristic with id "${heuristic.id}" already registered, overwriting`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
this.heuristics.set(heuristic.id, heuristic as Heuristic<unknown>);
|
|
38
|
+
logger.debug(`[HeuristicRegistry] Registered heuristic: ${heuristic.id} (${heuristic.timing})`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get all heuristics for a specific timing
|
|
43
|
+
* @param timing - The timing to filter by
|
|
44
|
+
* @returns Array of heuristics matching the timing
|
|
45
|
+
*/
|
|
46
|
+
getByTiming(timing: HeuristicTiming): Heuristic<unknown>[] {
|
|
47
|
+
const result: Heuristic<unknown>[] = [];
|
|
48
|
+
for (const heuristic of this.heuristics.values()) {
|
|
49
|
+
if (heuristic.timing === timing) {
|
|
50
|
+
result.push(heuristic);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get pre-tool-execution heuristics filtered by tool name
|
|
58
|
+
* Returns heuristics that either have no tool filter or include the given tool
|
|
59
|
+
* @param toolName - The tool name to filter by
|
|
60
|
+
* @returns Array of applicable pre-tool heuristics
|
|
61
|
+
*/
|
|
62
|
+
getPreToolHeuristics(toolName: string): Heuristic<PreToolContext>[] {
|
|
63
|
+
const result: Heuristic<PreToolContext>[] = [];
|
|
64
|
+
for (const heuristic of this.heuristics.values()) {
|
|
65
|
+
if (heuristic.timing !== "pre-tool-execution") {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// Include if no tool filter or tool is in the filter list
|
|
69
|
+
if (!heuristic.toolFilter || heuristic.toolFilter.includes(toolName)) {
|
|
70
|
+
result.push(heuristic as Heuristic<PreToolContext>);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get all post-completion heuristics
|
|
78
|
+
* @returns Array of post-completion heuristics
|
|
79
|
+
*/
|
|
80
|
+
getPostCompletionHeuristics(): Heuristic<PostCompletionContext>[] {
|
|
81
|
+
return this.getByTiming("post-completion") as Heuristic<PostCompletionContext>[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get a specific heuristic by ID
|
|
86
|
+
* @param id - The heuristic ID
|
|
87
|
+
* @returns The heuristic or undefined if not found
|
|
88
|
+
*/
|
|
89
|
+
get(id: string): Heuristic<unknown> | undefined {
|
|
90
|
+
return this.heuristics.get(id);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Clear all registered heuristics (mainly for testing)
|
|
95
|
+
*/
|
|
96
|
+
clear(): void {
|
|
97
|
+
this.heuristics.clear();
|
|
98
|
+
logger.debug("[HeuristicRegistry] Cleared all heuristics");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get all registered heuristic IDs (for debugging)
|
|
103
|
+
*/
|
|
104
|
+
getAllIds(): string[] {
|
|
105
|
+
return Array.from(this.heuristics.keys());
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get the count of registered heuristics
|
|
110
|
+
*/
|
|
111
|
+
get size(): number {
|
|
112
|
+
return this.heuristics.size;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CorrectionAction,
|
|
3
|
+
Heuristic,
|
|
4
|
+
HeuristicDetection,
|
|
5
|
+
PostCompletionContext,
|
|
6
|
+
VerificationResult,
|
|
7
|
+
} from "../types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Heuristic that prevents agents from completing when they have pending or in_progress todos.
|
|
11
|
+
*
|
|
12
|
+
* This ensures agents don't abandon work they've planned. If an agent creates a todo list
|
|
13
|
+
* but tries to finish without completing (or explicitly skipping) all items, this heuristic
|
|
14
|
+
* will block the completion and prompt the agent to address their remaining todos.
|
|
15
|
+
*
|
|
16
|
+
* Uses skipVerification=true because this is an objective check - either todos are incomplete
|
|
17
|
+
* or they aren't. No LLM judgment needed.
|
|
18
|
+
*/
|
|
19
|
+
export class PendingTodosHeuristic implements Heuristic<PostCompletionContext> {
|
|
20
|
+
id = "pending-todos";
|
|
21
|
+
name = "Agent Completing With Pending Todos";
|
|
22
|
+
timing = "post-completion" as const;
|
|
23
|
+
skipVerification = true; // Objective check - todos are data, not judgment
|
|
24
|
+
|
|
25
|
+
async detect(context: PostCompletionContext): Promise<HeuristicDetection> {
|
|
26
|
+
// Skip if agent has no todos at all
|
|
27
|
+
if (context.todos.length === 0) {
|
|
28
|
+
return { triggered: false };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Skip if agent has pending delegations - they're legitimately waiting for delegated work
|
|
32
|
+
// to complete. Nagging about incomplete todos while waiting on delegations is confusing.
|
|
33
|
+
if (context.pendingDelegationCount > 0) {
|
|
34
|
+
return {
|
|
35
|
+
triggered: false,
|
|
36
|
+
reason: `Agent has ${context.pendingDelegationCount} pending delegation(s) - skipping todo check`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Find todos that are incomplete (pending or in_progress)
|
|
41
|
+
const incompleteTodos = context.todos.filter(
|
|
42
|
+
(t) => t.status === "pending" || t.status === "in_progress"
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// No incomplete todos = agent is done
|
|
46
|
+
if (incompleteTodos.length === 0) {
|
|
47
|
+
return { triggered: false };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
triggered: true,
|
|
52
|
+
reason: `Agent has ${incompleteTodos.length} incomplete todo(s) (pending or in_progress)`,
|
|
53
|
+
evidence: {
|
|
54
|
+
incompleteTodos: incompleteTodos.map((t) => ({
|
|
55
|
+
id: t.id,
|
|
56
|
+
title: t.title,
|
|
57
|
+
status: t.status,
|
|
58
|
+
})),
|
|
59
|
+
totalTodos: context.todos.length,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
buildVerificationPrompt(_context: PostCompletionContext, _detection: HeuristicDetection): string {
|
|
65
|
+
// Not used since skipVerification is true
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
buildCorrectionMessage(context: PostCompletionContext, _verification: VerificationResult): string {
|
|
70
|
+
const incompleteTodos = context.todos.filter(
|
|
71
|
+
(t) => t.status === "pending" || t.status === "in_progress"
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const todoList = incompleteTodos
|
|
75
|
+
.map((t) => `- [${t.status}] **${t.title}**${t.description ? `: ${t.description}` : ""}`)
|
|
76
|
+
.join("\n");
|
|
77
|
+
|
|
78
|
+
return `You have incomplete items in your todo list:
|
|
79
|
+
|
|
80
|
+
${todoList}
|
|
81
|
+
|
|
82
|
+
Would you like to address these before finishing your turn? If you're intentionally leaving them incomplete (waiting on delegation, user request, or other valid reasons), please confirm your intent.
|
|
83
|
+
|
|
84
|
+
You can use \`todo_write\` to update item statuses if needed.`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
getCorrectionAction(_verification: VerificationResult): CorrectionAction {
|
|
88
|
+
return {
|
|
89
|
+
type: "suppress-publish",
|
|
90
|
+
reEngage: true, // Re-engage agent to address todos
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { isDelegateToolName } from "@/agents/tool-names";
|
|
2
|
+
import type { CorrectionAction, Heuristic, HeuristicDetection, PostCompletionContext, VerificationResult } from "../types";
|
|
3
|
+
|
|
4
|
+
export class SilentAgentHeuristic implements Heuristic<PostCompletionContext> {
|
|
5
|
+
id = "silent-agent";
|
|
6
|
+
name = "Silent Agent Detection";
|
|
7
|
+
timing = "post-completion" as const;
|
|
8
|
+
|
|
9
|
+
async detect(context: PostCompletionContext): Promise<HeuristicDetection> {
|
|
10
|
+
const content = context.messageContent?.trim() || "";
|
|
11
|
+
const hasMeaningfulContent = content.length > 0;
|
|
12
|
+
const hasToolCalls = context.toolCallsMade.length > 0;
|
|
13
|
+
|
|
14
|
+
// Silent = no content AND no tool calls that would produce output
|
|
15
|
+
// Exception: delegate calls are ok since agent is waiting for delegation
|
|
16
|
+
const delegateCalls = context.toolCallsMade.filter((toolName) => isDelegateToolName(toolName));
|
|
17
|
+
const hasOnlyDelegateCalls = hasToolCalls && delegateCalls.length === context.toolCallsMade.length;
|
|
18
|
+
|
|
19
|
+
const isSilent = !hasMeaningfulContent && !hasOnlyDelegateCalls;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
triggered: isSilent,
|
|
23
|
+
reason: isSilent ? "Agent completed without generating any output or meaningful tool calls" : undefined,
|
|
24
|
+
evidence: {
|
|
25
|
+
messageContent: content.substring(0, 100),
|
|
26
|
+
toolCallsMade: context.toolCallsMade,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
buildVerificationPrompt(context: PostCompletionContext, detection: HeuristicDetection): string {
|
|
32
|
+
const evidence = detection.evidence as { messageContent?: string } | undefined;
|
|
33
|
+
return `The agent "${context.agentSlug}" completed its turn without producing any visible output.
|
|
34
|
+
This may indicate the agent failed to respond appropriately.
|
|
35
|
+
|
|
36
|
+
Evidence:
|
|
37
|
+
- Message content: "${evidence?.messageContent || "(empty)"}"
|
|
38
|
+
- Tool calls: ${JSON.stringify(context.toolCallsMade)}
|
|
39
|
+
|
|
40
|
+
Is this acceptable behavior or should the agent be prompted to respond?`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
buildCorrectionMessage(_context: PostCompletionContext, verification: VerificationResult): string {
|
|
44
|
+
return verification.correctionMessage ||
|
|
45
|
+
"You completed your turn without providing any response. Please provide a meaningful response to the user's request.";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getCorrectionAction(_verification: VerificationResult): CorrectionAction {
|
|
49
|
+
return {
|
|
50
|
+
type: "suppress-publish",
|
|
51
|
+
reEngage: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { HeuristicRegistry } from "./HeuristicRegistry";
|
|
2
|
+
export { SilentAgentHeuristic } from "./SilentAgentHeuristic";
|
|
3
|
+
export { DelegationClaimHeuristic } from "./DelegationClaimHeuristic";
|
|
4
|
+
export { ConsecutiveToolsWithoutTodoHeuristic } from "./ConsecutiveToolsWithoutTodoHeuristic";
|
|
5
|
+
export { PendingTodosHeuristic } from "./PendingTodosHeuristic";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
export * from "./types";
|
|
3
|
+
|
|
4
|
+
// Heuristics
|
|
5
|
+
export { HeuristicRegistry } from "./heuristics";
|
|
6
|
+
export {
|
|
7
|
+
SilentAgentHeuristic,
|
|
8
|
+
DelegationClaimHeuristic,
|
|
9
|
+
PendingTodosHeuristic,
|
|
10
|
+
} from "./heuristics";
|
|
11
|
+
|
|
12
|
+
// Services
|
|
13
|
+
export { SupervisorLLMService, supervisorLLMService } from "./SupervisorLLMService";
|
|
14
|
+
export {
|
|
15
|
+
SupervisorOrchestrator,
|
|
16
|
+
supervisorOrchestrator,
|
|
17
|
+
type SupervisionCheckResult,
|
|
18
|
+
} from "./SupervisorOrchestrator";
|
|
19
|
+
|
|
20
|
+
// Registration
|
|
21
|
+
export { registerDefaultHeuristics, updateKnownAgentSlugs } from "./registerHeuristics";
|
|
22
|
+
|
|
23
|
+
// Health Check
|
|
24
|
+
export {
|
|
25
|
+
checkSupervisionHealth,
|
|
26
|
+
assertSupervisionHealth,
|
|
27
|
+
type SupervisionHealthCheckResult,
|
|
28
|
+
} from "./supervisionHealthCheck";
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register all default heuristics with the HeuristicRegistry
|
|
3
|
+
* This should be called during application startup
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from "@/utils/logger";
|
|
6
|
+
import {
|
|
7
|
+
HeuristicRegistry,
|
|
8
|
+
SilentAgentHeuristic,
|
|
9
|
+
DelegationClaimHeuristic,
|
|
10
|
+
ConsecutiveToolsWithoutTodoHeuristic,
|
|
11
|
+
PendingTodosHeuristic,
|
|
12
|
+
} from "./heuristics";
|
|
13
|
+
import { trace, SpanStatusCode } from "@opentelemetry/api";
|
|
14
|
+
|
|
15
|
+
const tracer = trace.getTracer("tenex.supervision");
|
|
16
|
+
|
|
17
|
+
let registered = false;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Register all default supervision heuristics
|
|
21
|
+
* Safe to call multiple times - will only register once
|
|
22
|
+
*
|
|
23
|
+
* IMPORTANT: This must be called during startup to enable supervision.
|
|
24
|
+
* Without registered heuristics, the supervision system will throw an error
|
|
25
|
+
* (fail-closed behavior to prevent silent supervision bypass).
|
|
26
|
+
*/
|
|
27
|
+
export function registerDefaultHeuristics(): void {
|
|
28
|
+
if (registered) {
|
|
29
|
+
// Routine re-registration check - use DEBUG to avoid log spam
|
|
30
|
+
logger.debug("[Supervision] Heuristics already registered, skipping re-registration", {
|
|
31
|
+
count: HeuristicRegistry.getInstance().size,
|
|
32
|
+
ids: HeuristicRegistry.getInstance().getAllIds(),
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const span = tracer.startSpan("supervision.register_default_heuristics");
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const registry = HeuristicRegistry.getInstance();
|
|
41
|
+
const sizeBefore = registry.size;
|
|
42
|
+
|
|
43
|
+
span.setAttribute("registry.size_before", sizeBefore);
|
|
44
|
+
|
|
45
|
+
// Register post-completion heuristics
|
|
46
|
+
registry.register(new SilentAgentHeuristic());
|
|
47
|
+
registry.register(new DelegationClaimHeuristic());
|
|
48
|
+
registry.register(new ConsecutiveToolsWithoutTodoHeuristic());
|
|
49
|
+
registry.register(new PendingTodosHeuristic());
|
|
50
|
+
|
|
51
|
+
registered = true;
|
|
52
|
+
const sizeAfter = registry.size;
|
|
53
|
+
const registeredIds = registry.getAllIds();
|
|
54
|
+
|
|
55
|
+
span.setAttributes({
|
|
56
|
+
"registry.size_after": sizeAfter,
|
|
57
|
+
"registry.heuristics_added": sizeAfter - sizeBefore,
|
|
58
|
+
"registry.ids": registeredIds.join(","),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
span.addEvent("supervision.heuristics_registered", {
|
|
62
|
+
"count": sizeAfter,
|
|
63
|
+
"ids": registeredIds.join(","),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
67
|
+
|
|
68
|
+
// Use INFO level to ensure this is always visible in logs
|
|
69
|
+
logger.info("[Supervision] Successfully registered default heuristics", {
|
|
70
|
+
count: sizeAfter,
|
|
71
|
+
ids: registeredIds,
|
|
72
|
+
sizeBefore,
|
|
73
|
+
sizeAfter,
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Normalize error before recording
|
|
77
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
78
|
+
span.recordException(normalizedError);
|
|
79
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: "Failed to register heuristics" });
|
|
80
|
+
logger.error("[Supervision] FATAL: Failed to register default heuristics", normalizedError);
|
|
81
|
+
throw error;
|
|
82
|
+
} finally {
|
|
83
|
+
span.end();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Configure the DelegationClaimHeuristic with known agent slugs
|
|
89
|
+
* Should be called when agents are loaded/changed
|
|
90
|
+
*/
|
|
91
|
+
export function updateKnownAgentSlugs(slugs: string[]): void {
|
|
92
|
+
const registry = HeuristicRegistry.getInstance();
|
|
93
|
+
const heuristic = registry.get("delegation-claim") as DelegationClaimHeuristic | undefined;
|
|
94
|
+
if (heuristic) {
|
|
95
|
+
heuristic.setKnownAgentSlugs(slugs);
|
|
96
|
+
logger.debug("[Supervision] Updated known agent slugs", { count: slugs.length });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Reset registration state for testing purposes.
|
|
102
|
+
* This allows tests to verify fail-closed behavior by clearing heuristics
|
|
103
|
+
* and ensuring registerDefaultHeuristics() will run fresh.
|
|
104
|
+
*
|
|
105
|
+
* WARNING: Only use in tests. Never call in production code.
|
|
106
|
+
*/
|
|
107
|
+
export function resetRegistrationForTesting(): void {
|
|
108
|
+
registered = false;
|
|
109
|
+
HeuristicRegistry.getInstance().clear();
|
|
110
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized supervision health check utility.
|
|
3
|
+
* Ensures consistent fail-closed validation across all supervision entry points.
|
|
4
|
+
*
|
|
5
|
+
* The supervision system uses a fail-closed approach: if heuristics aren't properly
|
|
6
|
+
* registered, the system should refuse to proceed rather than silently bypassing supervision.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { HeuristicRegistry } from "./heuristics/HeuristicRegistry";
|
|
10
|
+
import { registerDefaultHeuristics } from "./registerHeuristics";
|
|
11
|
+
import { logger } from "@/utils/logger";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Result of a supervision health check.
|
|
15
|
+
*/
|
|
16
|
+
export interface SupervisionHealthCheckResult {
|
|
17
|
+
/** Whether the health check passed */
|
|
18
|
+
healthy: boolean;
|
|
19
|
+
/** Total number of registered heuristics */
|
|
20
|
+
registrySize: number;
|
|
21
|
+
/** Number of post-completion heuristics */
|
|
22
|
+
postCompletionCount: number;
|
|
23
|
+
/** IDs of all registered heuristics */
|
|
24
|
+
heuristicIds: string[];
|
|
25
|
+
/** Error message if unhealthy */
|
|
26
|
+
errorMessage?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Perform a comprehensive supervision health check.
|
|
31
|
+
*
|
|
32
|
+
* This validates the CURRENT state of the registry:
|
|
33
|
+
* 1. Registry is not empty (CRITICAL - fail-closed)
|
|
34
|
+
* 2. Post-completion heuristics exist (CRITICAL - fail-closed)
|
|
35
|
+
*
|
|
36
|
+
* NOTE: This function does NOT register heuristics - callers should ensure
|
|
37
|
+
* registerDefaultHeuristics() has been called before checking health.
|
|
38
|
+
* This separation allows proper testing of fail-closed behavior.
|
|
39
|
+
*
|
|
40
|
+
* FAIL-CLOSED SEMANTICS:
|
|
41
|
+
* - Returns healthy=false if ANY critical condition is not met
|
|
42
|
+
* - Caller is responsible for acting on the result (throwing, logging, etc.)
|
|
43
|
+
*
|
|
44
|
+
* @returns Health check result with diagnostic information
|
|
45
|
+
*/
|
|
46
|
+
export function checkSupervisionHealth(): SupervisionHealthCheckResult {
|
|
47
|
+
const registry = HeuristicRegistry.getInstance();
|
|
48
|
+
const registrySize = registry.size;
|
|
49
|
+
const heuristicIds = registry.getAllIds();
|
|
50
|
+
const postCompletionCount = registry.getPostCompletionHeuristics().length;
|
|
51
|
+
|
|
52
|
+
// FAIL-CLOSED: Both conditions must be met
|
|
53
|
+
if (registrySize === 0) {
|
|
54
|
+
const errorMessage =
|
|
55
|
+
`FATAL: Supervision system has no heuristics registered! ` +
|
|
56
|
+
`This indicates a critical configuration error. ` +
|
|
57
|
+
`The system cannot proceed without supervision.`;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
healthy: false,
|
|
61
|
+
registrySize,
|
|
62
|
+
postCompletionCount,
|
|
63
|
+
heuristicIds,
|
|
64
|
+
errorMessage,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (postCompletionCount === 0) {
|
|
69
|
+
const errorMessage =
|
|
70
|
+
`FATAL: No post-completion heuristics registered! ` +
|
|
71
|
+
`Registry has ${registrySize} total heuristics: [${heuristicIds.join(", ")}], ` +
|
|
72
|
+
`but none are post-completion type. ` +
|
|
73
|
+
`Supervision system is misconfigured - refusing to proceed without post-completion checks.`;
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
healthy: false,
|
|
77
|
+
registrySize,
|
|
78
|
+
postCompletionCount,
|
|
79
|
+
heuristicIds,
|
|
80
|
+
errorMessage,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
healthy: true,
|
|
86
|
+
registrySize,
|
|
87
|
+
postCompletionCount,
|
|
88
|
+
heuristicIds,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Assert supervision health, throwing if unhealthy.
|
|
94
|
+
*
|
|
95
|
+
* This function:
|
|
96
|
+
* 1. Ensures heuristics are registered (calls registerDefaultHeuristics)
|
|
97
|
+
* 2. Performs health check
|
|
98
|
+
* 3. Throws if unhealthy
|
|
99
|
+
*
|
|
100
|
+
* Use this at startup or before executing completions to ensure
|
|
101
|
+
* fail-closed behavior is enforced consistently.
|
|
102
|
+
*
|
|
103
|
+
* @param context - Context string for error messages (e.g., "AgentExecutor", "ProjectRuntime")
|
|
104
|
+
* @throws Error if supervision health check fails
|
|
105
|
+
*/
|
|
106
|
+
export function assertSupervisionHealth(context: string): void {
|
|
107
|
+
// Ensure heuristics are registered before checking health
|
|
108
|
+
registerDefaultHeuristics();
|
|
109
|
+
|
|
110
|
+
const result = checkSupervisionHealth();
|
|
111
|
+
|
|
112
|
+
if (!result.healthy) {
|
|
113
|
+
const fullMessage = `[${context}] ${result.errorMessage}`;
|
|
114
|
+
logger.error(fullMessage);
|
|
115
|
+
throw new Error(fullMessage);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
logger.debug(`[${context}] Supervision health check passed`, {
|
|
119
|
+
registrySize: result.registrySize,
|
|
120
|
+
postCompletionCount: result.postCompletionCount,
|
|
121
|
+
heuristicIds: result.heuristicIds,
|
|
122
|
+
});
|
|
123
|
+
}
|