@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,72 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { logger } from "@/utils/logger";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Simple KV store for agent-specific metadata within a conversation.
|
|
7
|
+
* Each agent in each conversation gets its own isolated metadata store.
|
|
8
|
+
*/
|
|
9
|
+
export class AgentMetadataStore {
|
|
10
|
+
private data = new Map<string, unknown>();
|
|
11
|
+
private filePath: string;
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
private conversationId: string,
|
|
15
|
+
private agentSlug: string,
|
|
16
|
+
metadataPath: string
|
|
17
|
+
) {
|
|
18
|
+
// metadataPath is ~/.tenex/projects/<dTag>/
|
|
19
|
+
const metadataDir = path.join(metadataPath, "metadata");
|
|
20
|
+
this.filePath = path.join(metadataDir, `${conversationId}-${agentSlug}.json`);
|
|
21
|
+
this.load();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get<T = unknown>(key: string): T | undefined {
|
|
25
|
+
return this.data.get(key) as T | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
set(key: string, value: unknown): void {
|
|
29
|
+
this.data.set(key, value);
|
|
30
|
+
this.save();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private load(): void {
|
|
34
|
+
try {
|
|
35
|
+
if (fs.existsSync(this.filePath)) {
|
|
36
|
+
const content = fs.readFileSync(this.filePath, "utf-8");
|
|
37
|
+
const parsed = JSON.parse(content);
|
|
38
|
+
this.data = new Map(Object.entries(parsed));
|
|
39
|
+
logger.debug("[AgentMetadataStore] Loaded metadata", {
|
|
40
|
+
conversationId: this.conversationId.substring(0, 8),
|
|
41
|
+
agentSlug: this.agentSlug,
|
|
42
|
+
keys: Array.from(this.data.keys()),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error("[AgentMetadataStore] Failed to load metadata", {
|
|
47
|
+
conversationId: this.conversationId.substring(0, 8),
|
|
48
|
+
agentSlug: this.agentSlug,
|
|
49
|
+
error,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private save(): void {
|
|
55
|
+
try {
|
|
56
|
+
fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
|
|
57
|
+
const obj = Object.fromEntries(this.data);
|
|
58
|
+
fs.writeFileSync(this.filePath, JSON.stringify(obj, null, 2));
|
|
59
|
+
logger.debug("[AgentMetadataStore] Saved metadata", {
|
|
60
|
+
conversationId: this.conversationId.substring(0, 8),
|
|
61
|
+
agentSlug: this.agentSlug,
|
|
62
|
+
keys: Array.from(this.data.keys()),
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.error("[AgentMetadataStore] Failed to save metadata", {
|
|
66
|
+
conversationId: this.conversationId.substring(0, 8),
|
|
67
|
+
agentSlug: this.agentSlug,
|
|
68
|
+
error,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getProjectContext } from "@/services/projects";
|
|
2
|
+
import { logger } from "@/utils/logger";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Result of resolving an agent slug
|
|
6
|
+
*/
|
|
7
|
+
export interface AgentResolutionResult {
|
|
8
|
+
pubkey: string | null;
|
|
9
|
+
availableSlugs: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Resolve an agent slug to a pubkey.
|
|
14
|
+
*
|
|
15
|
+
* ONLY accepts agent slugs (e.g., "architect", "claude-code").
|
|
16
|
+
* Does NOT support: pubkeys, npubs, nprofiles, hex prefixes, or agent names.
|
|
17
|
+
*
|
|
18
|
+
* @param slug - Agent slug (case-insensitive)
|
|
19
|
+
* @returns Resolution result with pubkey (or null) and list of available slugs
|
|
20
|
+
*/
|
|
21
|
+
export function resolveAgentSlug(slug: string): AgentResolutionResult {
|
|
22
|
+
const trimmedSlug = slug.trim();
|
|
23
|
+
const slugLower = trimmedSlug.toLowerCase();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const projectContext = getProjectContext();
|
|
27
|
+
const agents = projectContext.agentRegistry.getAllAgentsMap();
|
|
28
|
+
|
|
29
|
+
// First, collect all available slugs
|
|
30
|
+
const availableSlugs: string[] = Array.from(agents.keys());
|
|
31
|
+
|
|
32
|
+
// Then look for a match
|
|
33
|
+
for (const [agentSlug, agent] of agents.entries()) {
|
|
34
|
+
if (agentSlug.toLowerCase() === slugLower) {
|
|
35
|
+
return { pubkey: agent.pubkey, availableSlugs };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
logger.debug("Agent slug not found", { slug: trimmedSlug, availableSlugs });
|
|
40
|
+
return { pubkey: null, availableSlugs };
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.debug("Failed to resolve agent slug", { slug: trimmedSlug, error });
|
|
43
|
+
return { pubkey: null, availableSlugs: [] };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Use resolveAgentSlug instead for the full resolution result with available slugs.
|
|
49
|
+
* This wrapper is kept for callers that only need the pubkey without error context.
|
|
50
|
+
*
|
|
51
|
+
* Resolve an agent slug to a pubkey (simplified interface).
|
|
52
|
+
*
|
|
53
|
+
* @param slug - Agent slug (case-insensitive)
|
|
54
|
+
* @returns Pubkey hex string or null if not found
|
|
55
|
+
*/
|
|
56
|
+
export function resolveRecipientToPubkey(slug: string): string | null {
|
|
57
|
+
const result = resolveAgentSlug(slug);
|
|
58
|
+
return result.pubkey;
|
|
59
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EscalationService - Handles escalation agent resolution and auto-adding
|
|
3
|
+
*
|
|
4
|
+
* ## Responsibility
|
|
5
|
+
* Resolves escalation targets from config and ensures they're available in the
|
|
6
|
+
* current project context. Handles the auto-add flow when an escalation agent
|
|
7
|
+
* exists in global storage but isn't part of the current project.
|
|
8
|
+
*
|
|
9
|
+
* ## Architecture
|
|
10
|
+
* This service sits between the tool layer (ask.ts) and the agent infrastructure:
|
|
11
|
+
* - Uses AgentStorage for persistence
|
|
12
|
+
* - Uses AgentRegistry for runtime instances
|
|
13
|
+
* - Uses agent-loader utilities for hydration
|
|
14
|
+
* - Coordinates with ProjectContext for daemon notification
|
|
15
|
+
*
|
|
16
|
+
* ## Usage
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { resolveEscalationTarget } from "@/services/agents/EscalationService";
|
|
19
|
+
*
|
|
20
|
+
* // In a tool implementation
|
|
21
|
+
* const escalationSlug = await resolveEscalationTarget();
|
|
22
|
+
* if (escalationSlug) {
|
|
23
|
+
* // Route through escalation agent
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { AgentRegistry } from "@/agents/AgentRegistry";
|
|
29
|
+
import { agentStorage } from "@/agents/AgentStorage";
|
|
30
|
+
import { createAgentInstance } from "@/agents/agent-loader";
|
|
31
|
+
import { pubkeyFromNsec } from "@/nostr";
|
|
32
|
+
import { resolveRecipientToPubkey } from "@/services/agents/AgentResolution";
|
|
33
|
+
import { config as configService } from "@/services/ConfigService";
|
|
34
|
+
import { getProjectContext } from "@/services/projects";
|
|
35
|
+
import { logger } from "@/utils/logger";
|
|
36
|
+
|
|
37
|
+
export interface EscalationResolutionResult {
|
|
38
|
+
/** The escalation agent's slug */
|
|
39
|
+
slug: string;
|
|
40
|
+
/** Whether the agent was auto-added to the project during this resolution */
|
|
41
|
+
wasAutoAdded: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the escalation agent from config, auto-adding to project if necessary.
|
|
46
|
+
*
|
|
47
|
+
* This function handles the complete escalation target resolution:
|
|
48
|
+
* 1. Reads escalation.agent from config
|
|
49
|
+
* 2. Checks if agent is already in project (fast path)
|
|
50
|
+
* 3. If not, checks global storage and auto-adds to project
|
|
51
|
+
*
|
|
52
|
+
* @returns EscalationResolutionResult if escalation agent is available, null otherwise
|
|
53
|
+
*/
|
|
54
|
+
export async function resolveEscalationTarget(): Promise<EscalationResolutionResult | null> {
|
|
55
|
+
try {
|
|
56
|
+
const config = configService.getConfig();
|
|
57
|
+
const escalationAgentSlug = config.escalation?.agent;
|
|
58
|
+
|
|
59
|
+
if (!escalationAgentSlug) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Fast path: check if agent is already in the current project
|
|
64
|
+
const existingPubkey = resolveRecipientToPubkey(escalationAgentSlug);
|
|
65
|
+
if (existingPubkey) {
|
|
66
|
+
return { slug: escalationAgentSlug, wasAutoAdded: false };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Agent not in project - attempt auto-add
|
|
70
|
+
return await autoAddEscalationAgent(escalationAgentSlug);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
// Distinguish between expected errors (config not loaded during startup)
|
|
73
|
+
// and unexpected errors that should be investigated
|
|
74
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
75
|
+
const isConfigNotLoaded = errorMessage.includes("not loaded") || errorMessage.includes("not initialized");
|
|
76
|
+
|
|
77
|
+
if (isConfigNotLoaded) {
|
|
78
|
+
// Expected during startup - use debug level
|
|
79
|
+
logger.debug("[EscalationService] Config not loaded yet, skipping escalation resolution");
|
|
80
|
+
} else {
|
|
81
|
+
// Unexpected error - use warn level for investigation
|
|
82
|
+
logger.warn("[EscalationService] Unexpected error resolving escalation target", {
|
|
83
|
+
error,
|
|
84
|
+
errorMessage,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Auto-add an escalation agent from global storage to the current project.
|
|
93
|
+
*
|
|
94
|
+
* This is called when the escalation agent is configured but not part of
|
|
95
|
+
* the current project. It performs:
|
|
96
|
+
* 1. Lookup in global storage by slug
|
|
97
|
+
* 2. Association with current project in storage
|
|
98
|
+
* 3. Instance creation and registry registration
|
|
99
|
+
* 4. Daemon notification for routing updates
|
|
100
|
+
*
|
|
101
|
+
* @param escalationAgentSlug - The slug of the escalation agent to add
|
|
102
|
+
* @returns EscalationResolutionResult if successful, null if agent doesn't exist
|
|
103
|
+
*/
|
|
104
|
+
async function autoAddEscalationAgent(
|
|
105
|
+
escalationAgentSlug: string
|
|
106
|
+
): Promise<EscalationResolutionResult | null> {
|
|
107
|
+
// Check global storage for the agent
|
|
108
|
+
const storedAgent = await agentStorage.getAgentBySlug(escalationAgentSlug);
|
|
109
|
+
if (!storedAgent) {
|
|
110
|
+
logger.warn("[EscalationService] Escalation agent configured but not found in system", {
|
|
111
|
+
escalationAgentSlug,
|
|
112
|
+
});
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const projectCtx = getProjectContext();
|
|
117
|
+
const agentRegistry = projectCtx.agentRegistry;
|
|
118
|
+
const projectDTag = agentRegistry.getProjectDTag();
|
|
119
|
+
|
|
120
|
+
if (!projectDTag) {
|
|
121
|
+
logger.warn("[EscalationService] Cannot auto-add escalation agent: no project dTag available");
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
logger.info("[EscalationService] Auto-adding escalation agent to project", {
|
|
126
|
+
escalationAgentSlug,
|
|
127
|
+
agentName: storedAgent.name,
|
|
128
|
+
projectDTag,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Get the agent's pubkey from its nsec
|
|
132
|
+
const agentPubkey = pubkeyFromNsec(storedAgent.nsec);
|
|
133
|
+
|
|
134
|
+
// Add agent to project in storage
|
|
135
|
+
await agentStorage.addAgentToProject(agentPubkey, projectDTag);
|
|
136
|
+
|
|
137
|
+
// Reload the agent to get fresh state with the project association
|
|
138
|
+
const freshAgent = await agentStorage.loadAgent(agentPubkey);
|
|
139
|
+
if (!freshAgent) {
|
|
140
|
+
logger.error("[EscalationService] Failed to reload escalation agent after adding to project", {
|
|
141
|
+
escalationAgentSlug,
|
|
142
|
+
agentPubkey: agentPubkey.substring(0, 8),
|
|
143
|
+
});
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Create agent instance and add to registry
|
|
148
|
+
// Pass projectDTag for project-scoped config resolution
|
|
149
|
+
const agentInstance = createAgentInstance(freshAgent, agentRegistry, projectDTag);
|
|
150
|
+
agentRegistry.addAgent(agentInstance);
|
|
151
|
+
|
|
152
|
+
// Notify the Daemon about the new agent for routing
|
|
153
|
+
projectCtx.notifyAgentAdded(agentInstance);
|
|
154
|
+
|
|
155
|
+
logger.info("[EscalationService] Successfully auto-added escalation agent to project", {
|
|
156
|
+
escalationAgentSlug,
|
|
157
|
+
agentPubkey: agentPubkey.substring(0, 8),
|
|
158
|
+
projectDTag,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return { slug: escalationAgentSlug, wasAutoAdded: true };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Check if an escalation agent is configured (without auto-adding).
|
|
166
|
+
*
|
|
167
|
+
* Use this for quick checks where you don't need to trigger the auto-add flow.
|
|
168
|
+
*
|
|
169
|
+
* @returns The escalation agent slug if configured, null otherwise
|
|
170
|
+
*/
|
|
171
|
+
export function getConfiguredEscalationAgent(): string | null {
|
|
172
|
+
try {
|
|
173
|
+
const config = configService.getConfig();
|
|
174
|
+
return config.escalation?.agent || null;
|
|
175
|
+
} catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Load escalation agent into a registry proactively during project startup.
|
|
182
|
+
*
|
|
183
|
+
* This function is called during AgentRegistry.loadFromProject() to ensure
|
|
184
|
+
* the escalation agent is available in the "Available Agents" section of
|
|
185
|
+
* all project system prompts.
|
|
186
|
+
*
|
|
187
|
+
* Unlike resolveEscalationTarget() which is reactive (called when ask() is used),
|
|
188
|
+
* this function is proactive and runs during project initialization.
|
|
189
|
+
*
|
|
190
|
+
* @param agentRegistry - The agent registry to load the escalation agent into
|
|
191
|
+
* @param projectDTag - The project's dTag for storage association
|
|
192
|
+
* @returns true if escalation agent was loaded (new or existing), false otherwise
|
|
193
|
+
*/
|
|
194
|
+
export async function loadEscalationAgentIntoRegistry(
|
|
195
|
+
agentRegistry: AgentRegistry,
|
|
196
|
+
projectDTag: string | undefined
|
|
197
|
+
): Promise<boolean> {
|
|
198
|
+
// Validate projectDTag is provided and non-empty (including whitespace-only)
|
|
199
|
+
if (!projectDTag?.trim()) {
|
|
200
|
+
logger.warn("[EscalationService] Cannot load escalation agent: projectDTag is required");
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const config = configService.getConfig();
|
|
206
|
+
const escalationAgentSlug = config.escalation?.agent;
|
|
207
|
+
|
|
208
|
+
if (!escalationAgentSlug) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Fast path: check if agent is already in registry (avoid duplicate work)
|
|
213
|
+
const existingAgent = agentRegistry.getAgent(escalationAgentSlug);
|
|
214
|
+
if (existingAgent) {
|
|
215
|
+
logger.debug("[EscalationService] Escalation agent already in registry", {
|
|
216
|
+
escalationAgentSlug,
|
|
217
|
+
projectDTag,
|
|
218
|
+
});
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Check global storage for the agent
|
|
223
|
+
const storedAgent = await agentStorage.getAgentBySlug(escalationAgentSlug);
|
|
224
|
+
if (!storedAgent) {
|
|
225
|
+
logger.warn("[EscalationService] Escalation agent configured but not found in system", {
|
|
226
|
+
escalationAgentSlug,
|
|
227
|
+
});
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
logger.info("[EscalationService] Proactively loading escalation agent into registry", {
|
|
232
|
+
escalationAgentSlug,
|
|
233
|
+
agentName: storedAgent.name,
|
|
234
|
+
projectDTag,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Get the agent's pubkey from its nsec
|
|
238
|
+
const agentPubkey = pubkeyFromNsec(storedAgent.nsec);
|
|
239
|
+
|
|
240
|
+
// Add agent to project in storage (idempotent operation)
|
|
241
|
+
await agentStorage.addAgentToProject(agentPubkey, projectDTag);
|
|
242
|
+
|
|
243
|
+
// Reload the agent to get fresh state with the project association
|
|
244
|
+
const freshAgent = await agentStorage.loadAgent(agentPubkey);
|
|
245
|
+
if (!freshAgent) {
|
|
246
|
+
logger.error("[EscalationService] Failed to reload escalation agent after adding to project", {
|
|
247
|
+
escalationAgentSlug,
|
|
248
|
+
agentPubkey: agentPubkey.substring(0, 8),
|
|
249
|
+
});
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Create agent instance and add to registry
|
|
254
|
+
// Pass projectDTag for project-scoped config resolution
|
|
255
|
+
const agentInstance = createAgentInstance(freshAgent, agentRegistry, projectDTag);
|
|
256
|
+
agentRegistry.addAgent(agentInstance);
|
|
257
|
+
|
|
258
|
+
logger.info("[EscalationService] Successfully loaded escalation agent into registry", {
|
|
259
|
+
escalationAgentSlug,
|
|
260
|
+
agentPubkey: agentPubkey.substring(0, 8),
|
|
261
|
+
projectDTag,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
return true;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
// Distinguish between expected errors (config not loaded during startup)
|
|
267
|
+
// and unexpected errors that should be investigated
|
|
268
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
269
|
+
const isConfigNotLoaded = errorMessage.includes("not loaded") || errorMessage.includes("not initialized");
|
|
270
|
+
|
|
271
|
+
if (isConfigNotLoaded) {
|
|
272
|
+
logger.debug("[EscalationService] Config not loaded yet, skipping escalation agent loading");
|
|
273
|
+
} else {
|
|
274
|
+
logger.warn("[EscalationService] Unexpected error loading escalation agent into registry", {
|
|
275
|
+
error,
|
|
276
|
+
errorMessage,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { NDKAgentDefinition } from "@/events/NDKAgentDefinition";
|
|
2
|
+
import { collectEvents } from "@/nostr/collectEvents";
|
|
3
|
+
import { logger } from "@/utils/logger";
|
|
4
|
+
import type NDK from "@nostr-dev-kit/ndk";
|
|
5
|
+
import type { NDKFilter } from "@nostr-dev-kit/ndk";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for discovering NDKAgentDefinition events
|
|
9
|
+
*/
|
|
10
|
+
export interface AgentDiscoveryOptions {
|
|
11
|
+
/** Text to search for in name/description/role */
|
|
12
|
+
searchText?: string;
|
|
13
|
+
/** Minimum creation timestamp */
|
|
14
|
+
since?: number;
|
|
15
|
+
/** Maximum creation timestamp */
|
|
16
|
+
until?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Service for discovering NDKAgentDefinition events from the Nostr network
|
|
21
|
+
*/
|
|
22
|
+
export class NDKAgentDiscovery {
|
|
23
|
+
constructor(private ndk: NDK) {}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Discover NDKAgentDefinition events from the network
|
|
27
|
+
*/
|
|
28
|
+
async discoverAgents(options: AgentDiscoveryOptions = {}): Promise<NDKAgentDefinition[]> {
|
|
29
|
+
try {
|
|
30
|
+
// Build filter for kind:4199 (NDKAgentDefinition)
|
|
31
|
+
const filter: NDKFilter = {
|
|
32
|
+
kinds: NDKAgentDefinition.kinds,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (options.since) {
|
|
36
|
+
filter.since = options.since;
|
|
37
|
+
}
|
|
38
|
+
if (options.until) {
|
|
39
|
+
filter.until = options.until;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
logger.debug("Discovering NDKAgentDefinition events", { filter });
|
|
43
|
+
|
|
44
|
+
const events = await collectEvents(this.ndk, filter, {
|
|
45
|
+
subOpts: { groupable: false },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const discoveredAgents: NDKAgentDefinition[] = [];
|
|
49
|
+
for (const event of events) {
|
|
50
|
+
try {
|
|
51
|
+
discoveredAgents.push(NDKAgentDefinition.from(event));
|
|
52
|
+
} catch (err) {
|
|
53
|
+
logger.warn("Failed to parse NDKAgentDefinition", { eventId: event.id, err });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
logger.info(`Found ${discoveredAgents.length} NDKAgentDefinition events`);
|
|
58
|
+
|
|
59
|
+
// Apply local filtering if specified
|
|
60
|
+
let filtered = discoveredAgents;
|
|
61
|
+
|
|
62
|
+
if (options.searchText) {
|
|
63
|
+
filtered = this.filterByText(filtered, options.searchText);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Sort by creation time (newest first)
|
|
67
|
+
filtered.sort((a, b) => (b.created_at || 0) - (a.created_at || 0));
|
|
68
|
+
|
|
69
|
+
return filtered;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
logger.error("Failed to discover NDKAgentDefinition events", { error });
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Filter agents by text search
|
|
78
|
+
*/
|
|
79
|
+
private filterByText(agents: NDKAgentDefinition[], searchText: string): NDKAgentDefinition[] {
|
|
80
|
+
const searchLower = searchText.toLowerCase();
|
|
81
|
+
|
|
82
|
+
return agents.filter((agent) => {
|
|
83
|
+
const searchableText = [
|
|
84
|
+
agent.title || "",
|
|
85
|
+
agent.role || "",
|
|
86
|
+
agent.description || "",
|
|
87
|
+
agent.useCriteria || "",
|
|
88
|
+
]
|
|
89
|
+
.join(" ")
|
|
90
|
+
.toLowerCase();
|
|
91
|
+
|
|
92
|
+
return searchableText.includes(searchLower);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { AgentDiscoveryOptions } from "./NDKAgentDiscovery";
|
|
2
|
+
export { NDKAgentDiscovery } from "./NDKAgentDiscovery";
|
|
3
|
+
export { resolveAgentSlug, resolveRecipientToPubkey } from "./AgentResolution";
|
|
4
|
+
export type { AgentResolutionResult } from "./AgentResolution";
|
|
5
|
+
export { AgentMetadataStore } from "./AgentMetadataStore";
|
|
6
|
+
export { resolveEscalationTarget, getConfiguredEscalationAgent } from "./EscalationService";
|
|
7
|
+
export type { EscalationResolutionResult } from "./EscalationService";
|