@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
package/package.json
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tenex-chat/backend",
|
|
3
|
+
"version": "0.9.1",
|
|
4
|
+
"description": "TENEX Command Line Interface",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"backend": "./dist/backend-wrapper.cjs"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/**/*.js",
|
|
18
|
+
"dist/**/*.cjs",
|
|
19
|
+
"!dist/**/*.map",
|
|
20
|
+
"!dist/**/__tests__",
|
|
21
|
+
"!dist/**/*.test.js",
|
|
22
|
+
"!dist/**/*.spec.js",
|
|
23
|
+
"!dist/test-utils",
|
|
24
|
+
"src/**/*.ts",
|
|
25
|
+
"!src/**/__tests__",
|
|
26
|
+
"!src/**/*.test.ts",
|
|
27
|
+
"!src/**/*.spec.ts",
|
|
28
|
+
"!src/test-utils",
|
|
29
|
+
"tsconfig.json"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"start": "bun run ./src/wrapper.ts",
|
|
33
|
+
"build": "bun scripts/build-bundled.js",
|
|
34
|
+
"prepublishOnly": "bun run build",
|
|
35
|
+
"test": "bun test",
|
|
36
|
+
"test:watch": "bun test --watch",
|
|
37
|
+
"test:coverage": "bun test --coverage",
|
|
38
|
+
"test:unit": "bun test src/**/__tests__/*.test.ts",
|
|
39
|
+
"test:integration": "bun test src/**/__tests__/*.integration.test.ts",
|
|
40
|
+
"validate:events": "bun run src/scripts/validate-events.ts",
|
|
41
|
+
"typecheck": "./scripts/typecheck.sh",
|
|
42
|
+
"typecheck:verbose": "tsc --noEmit",
|
|
43
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
44
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
45
|
+
"lint:architecture": "bun run scripts/lint-architecture.ts",
|
|
46
|
+
"clean": "rm -rf dist node_modules bun.lockb coverage",
|
|
47
|
+
"prepare": "husky"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20.0.0"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"registry": "https://registry.npmjs.org/"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@ai-sdk/anthropic": "^3.0.46",
|
|
58
|
+
"@ai-sdk/openai": "^3.0.30",
|
|
59
|
+
"@huggingface/transformers": "^3.8.1",
|
|
60
|
+
"@lancedb/lancedb": "^0.26.2",
|
|
61
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
62
|
+
"@nostr-dev-kit/ndk": "3.0.0",
|
|
63
|
+
"@openrouter/ai-sdk-provider": "^2.1.1",
|
|
64
|
+
"@opentelemetry/api": "^1.9.0",
|
|
65
|
+
"@opentelemetry/auto-instrumentations-node": "^0.70.0",
|
|
66
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.212.0",
|
|
67
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.212.0",
|
|
68
|
+
"@opentelemetry/resources": "^2.3.0",
|
|
69
|
+
"@opentelemetry/sdk-node": "^0.212.0",
|
|
70
|
+
"@opentelemetry/sdk-trace-node": "^2.3.0",
|
|
71
|
+
"@opentelemetry/semantic-conventions": "^1.38.0",
|
|
72
|
+
"ai": "^6.0.65",
|
|
73
|
+
"ai-sdk-provider-claude-code": "*",
|
|
74
|
+
"ai-sdk-provider-codex-app-server": "1.1.7",
|
|
75
|
+
"chalk": "^5.6.2",
|
|
76
|
+
"commander": "^14.0.3",
|
|
77
|
+
"cron-parser": "^5.5.0",
|
|
78
|
+
"duck-duck-scrape": "^2.2.7",
|
|
79
|
+
"inquirer": "^13.2.2",
|
|
80
|
+
"lmdb": "^3.5.1",
|
|
81
|
+
"lodash": "^4.17.23",
|
|
82
|
+
"node-cron": "^4.2.1",
|
|
83
|
+
"node-html-markdown": "^2.0.0",
|
|
84
|
+
"nostr-tools": "^2.15.0",
|
|
85
|
+
"ollama-ai-provider-v2": "^3.0.3",
|
|
86
|
+
"tseep": "^1.3.1",
|
|
87
|
+
"zod": "^4.3.6"
|
|
88
|
+
},
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"@eslint/js": "^10.0.1",
|
|
91
|
+
"esbuild": "^0.27.2",
|
|
92
|
+
"esbuild-plugin-alias": "^0.2.1",
|
|
93
|
+
"eslint": "^10.0.0",
|
|
94
|
+
"husky": "^9.1.7",
|
|
95
|
+
"typescript": "^5.9.3",
|
|
96
|
+
"typescript-eslint": "^8.53.0",
|
|
97
|
+
"vitest": "^4.0.16"
|
|
98
|
+
},
|
|
99
|
+
"type": "module",
|
|
100
|
+
"keywords": [],
|
|
101
|
+
"author": "",
|
|
102
|
+
"license": "ISC"
|
|
103
|
+
}
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import type { AgentInstance } from "@/agents/types";
|
|
2
|
+
import { createAgentInstance, loadAgentIntoRegistry } from "@/agents/agent-loader";
|
|
3
|
+
import { AgentProfilePublisher } from "@/nostr/AgentProfilePublisher";
|
|
4
|
+
import { loadEscalationAgentIntoRegistry } from "@/services/agents/EscalationService";
|
|
5
|
+
import { config } from "@/services/ConfigService";
|
|
6
|
+
import { logger } from "@/utils/logger";
|
|
7
|
+
import { NDKPrivateKeySigner, type NDKProject } from "@nostr-dev-kit/ndk";
|
|
8
|
+
import { agentStorage } from "./AgentStorage";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* AgentRegistry - In-memory runtime instances for a specific project
|
|
12
|
+
*
|
|
13
|
+
* ## Responsibility
|
|
14
|
+
* Manages runtime AgentInstance objects (with methods like sign(), createLLMService())
|
|
15
|
+
* - Scoped to ONE project - each project runtime has its own registry
|
|
16
|
+
* - Fast lookups by slug, pubkey, or eventId
|
|
17
|
+
* - Loads agents from storage and hydrates them into runtime instances
|
|
18
|
+
* - Can reload agents when storage updates
|
|
19
|
+
*
|
|
20
|
+
* ## Architecture
|
|
21
|
+
* - **AgentStorage**: Handles ALL persistence operations (separate)
|
|
22
|
+
* - **AgentRegistry** (this): Handles in-memory runtime instances only
|
|
23
|
+
* - **agent-loader**: Orchestrates loading from storage → registry (separate)
|
|
24
|
+
*
|
|
25
|
+
* ## Key Distinction: AgentInstance vs StoredAgent
|
|
26
|
+
* - **StoredAgent** (storage): Plain data object with no methods
|
|
27
|
+
* - **AgentInstance** (registry): Runtime object with sign(), createLLMService(), etc.
|
|
28
|
+
*
|
|
29
|
+
* ## Lifecycle
|
|
30
|
+
* 1. Project starts → registry created for that project
|
|
31
|
+
* 2. Agents loaded → StoredAgent → AgentInstance → added to registry
|
|
32
|
+
* 3. Project stops → registry discarded (instances are ephemeral)
|
|
33
|
+
* 4. Next run → fresh registry created, agents reloaded
|
|
34
|
+
*
|
|
35
|
+
* ## Multi-Project Isolation
|
|
36
|
+
* Each project has its own registry instance. One agent in storage can appear
|
|
37
|
+
* in multiple project registries simultaneously.
|
|
38
|
+
*
|
|
39
|
+
* ## Usage Pattern
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Load agents from project
|
|
42
|
+
* await registry.loadFromProject(ndkProject);
|
|
43
|
+
*
|
|
44
|
+
* // Get agent instance
|
|
45
|
+
* const agent = registry.getAgent('my-agent-slug');
|
|
46
|
+
*
|
|
47
|
+
* // Use agent's runtime methods
|
|
48
|
+
* await agent.sign(event);
|
|
49
|
+
* const llm = agent.createLLMService();
|
|
50
|
+
*
|
|
51
|
+
* // After storage updates, reload
|
|
52
|
+
* await agentStorage.updateDefaultConfig(pubkey, { tools: newTools });
|
|
53
|
+
* await registry.reloadAgent(pubkey); // Refresh instance
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @see AgentStorage for persistence operations
|
|
57
|
+
* @see agent-loader for loading orchestration
|
|
58
|
+
*/
|
|
59
|
+
export class AgentRegistry {
|
|
60
|
+
private agents: Map<string, AgentInstance> = new Map();
|
|
61
|
+
private agentsByPubkey: Map<string, AgentInstance> = new Map();
|
|
62
|
+
private projectDTag: string | undefined;
|
|
63
|
+
private projectPath: string; // Git repo path
|
|
64
|
+
private metadataPath: string; // TENEX metadata path
|
|
65
|
+
private ndkProject?: NDKProject;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new AgentRegistry instance.
|
|
69
|
+
* @param projectPath - The git repository path (e.g., ~/tenex/<dTag>/)
|
|
70
|
+
* @param metadataPath - The metadata path (e.g., ~/.tenex/projects/<dTag>/)
|
|
71
|
+
*/
|
|
72
|
+
constructor(projectPath: string, metadataPath: string) {
|
|
73
|
+
if (!projectPath || projectPath === "undefined") {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`AgentRegistry requires a valid projectPath. Received: ${String(projectPath)}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (!metadataPath || metadataPath === "undefined") {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`AgentRegistry requires a valid metadataPath. Received: ${String(metadataPath)}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
this.projectPath = projectPath;
|
|
84
|
+
this.metadataPath = metadataPath;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get the base path for this project (the git repository)
|
|
89
|
+
*/
|
|
90
|
+
getBasePath(): string {
|
|
91
|
+
return this.projectPath;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get the metadata path for this project (~/.tenex/projects/<dTag>/)
|
|
96
|
+
*/
|
|
97
|
+
getMetadataPath(): string {
|
|
98
|
+
return this.metadataPath;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Load agents for a project from unified storage (~/.tenex/agents/) and Nostr.
|
|
103
|
+
* Complete agent loading workflow:
|
|
104
|
+
* 1. Load agents from unified ~/.tenex/agents/ storage by event ID
|
|
105
|
+
* 2. For missing agents, fetch from Nostr and install to unified storage
|
|
106
|
+
* 3. Load newly installed agents and associate with this project
|
|
107
|
+
*/
|
|
108
|
+
async loadFromProject(ndkProject: NDKProject): Promise<void> {
|
|
109
|
+
this.ndkProject = ndkProject;
|
|
110
|
+
this.projectDTag = ndkProject.dTag;
|
|
111
|
+
|
|
112
|
+
if (!this.projectDTag) {
|
|
113
|
+
logger.error("Project missing dTag", { projectId: ndkProject.id });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Clear existing agents to ensure fresh load from project tags
|
|
118
|
+
this.agents.clear();
|
|
119
|
+
this.agentsByPubkey.clear();
|
|
120
|
+
|
|
121
|
+
// Initialize storage
|
|
122
|
+
await agentStorage.initialize();
|
|
123
|
+
|
|
124
|
+
// Get agent event IDs from project tags
|
|
125
|
+
const agentEventIds = ndkProject.tags
|
|
126
|
+
.filter((t) => t[0] === "agent" && t[1])
|
|
127
|
+
.map((t) => t[1])
|
|
128
|
+
.filter(Boolean) as string[];
|
|
129
|
+
|
|
130
|
+
logger.info(`Loading ${agentEventIds.length} agents for project ${this.projectDTag}`);
|
|
131
|
+
|
|
132
|
+
const failedAgents: string[] = [];
|
|
133
|
+
|
|
134
|
+
// Load each agent using the new loader (no redundant checks!)
|
|
135
|
+
for (const eventId of agentEventIds) {
|
|
136
|
+
try {
|
|
137
|
+
await loadAgentIntoRegistry(eventId, this);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
logger.error(`Failed to load agent ${eventId}`, { error });
|
|
140
|
+
failedAgents.push(eventId);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Check if critical agents failed
|
|
145
|
+
if (failedAgents.length > 0) {
|
|
146
|
+
// PM is the first agent in tags
|
|
147
|
+
const pmEventId = agentEventIds[0];
|
|
148
|
+
if (failedAgents.includes(pmEventId)) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`Critical agent failed to load. Agent event ID ${pmEventId} could not be fetched. This might be due to network issues or the event not being available on the configured relays.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
logger.warn(
|
|
154
|
+
`${failedAgents.length} agent(s) could not be installed but continuing with available agents`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Load locally-associated agents from storage
|
|
159
|
+
const localAgents = await agentStorage.getProjectAgents(this.projectDTag);
|
|
160
|
+
logger.info(`Found ${localAgents.length} locally-associated agents in storage for project ${this.projectDTag}`);
|
|
161
|
+
|
|
162
|
+
for (const storedAgent of localAgents) {
|
|
163
|
+
// Skip if already loaded (by eventId or slug)
|
|
164
|
+
const existingBySlug = this.agents.get(storedAgent.slug);
|
|
165
|
+
const existingByEventId = storedAgent.eventId
|
|
166
|
+
? this.getAgentByEventId(storedAgent.eventId)
|
|
167
|
+
: undefined;
|
|
168
|
+
|
|
169
|
+
if (existingBySlug || existingByEventId) {
|
|
170
|
+
logger.debug(`Agent ${storedAgent.slug} already in registry, skipping`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Load this locally-associated agent
|
|
175
|
+
try {
|
|
176
|
+
// Pass projectDTag for project-scoped config resolution
|
|
177
|
+
const agentInstance = createAgentInstance(storedAgent, this, this.projectDTag);
|
|
178
|
+
this.addAgent(agentInstance);
|
|
179
|
+
logger.info(`Loaded locally-associated agent ${storedAgent.slug} into registry`);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
logger.error(`Failed to load agent ${storedAgent.slug}`, { error });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Proactively load escalation agent if configured
|
|
186
|
+
// This ensures the escalation agent appears in "Available Agents" for all projects
|
|
187
|
+
await loadEscalationAgentIntoRegistry(this, this.projectDTag);
|
|
188
|
+
|
|
189
|
+
logger.info(`Loaded ${this.agents.size} total agents for project ${this.projectDTag}`);
|
|
190
|
+
|
|
191
|
+
// Republish kind:0 profiles for all agents now that the project has booted
|
|
192
|
+
// Fire-and-forget: don't block boot waiting for profile publishes (especially NIP-46 signing)
|
|
193
|
+
if (ndkProject) {
|
|
194
|
+
this.republishAgentProfiles(ndkProject).catch((error) => {
|
|
195
|
+
logger.warn("Background agent profile republishing failed", {
|
|
196
|
+
projectDTag: this.projectDTag,
|
|
197
|
+
error: error instanceof Error ? error.message : String(error),
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Republish kind:0 profiles for all agents in this project.
|
|
205
|
+
* Called during project boot to ensure all agent profiles are up to date.
|
|
206
|
+
*/
|
|
207
|
+
private async republishAgentProfiles(ndkProject: NDKProject): Promise<void> {
|
|
208
|
+
const projectTitle = ndkProject.tagValue("title") || "Untitled Project";
|
|
209
|
+
const whitelistedPubkeys = config.getWhitelistedPubkeys(undefined, config.getConfig());
|
|
210
|
+
const publishedCount = { success: 0, failed: 0 };
|
|
211
|
+
|
|
212
|
+
for (const agent of this.agents.values()) {
|
|
213
|
+
try {
|
|
214
|
+
const storedAgent = await agentStorage.loadAgent(agent.pubkey);
|
|
215
|
+
if (!storedAgent) {
|
|
216
|
+
logger.warn(`Could not load stored agent for profile republishing: ${agent.slug}`);
|
|
217
|
+
publishedCount.failed++;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const signer = new NDKPrivateKeySigner(storedAgent.nsec);
|
|
222
|
+
|
|
223
|
+
await AgentProfilePublisher.publishAgentProfile(
|
|
224
|
+
signer,
|
|
225
|
+
agent.name,
|
|
226
|
+
agent.role,
|
|
227
|
+
projectTitle,
|
|
228
|
+
ndkProject,
|
|
229
|
+
agent.eventId,
|
|
230
|
+
{
|
|
231
|
+
description: agent.description,
|
|
232
|
+
instructions: agent.instructions,
|
|
233
|
+
useCriteria: agent.useCriteria,
|
|
234
|
+
},
|
|
235
|
+
whitelistedPubkeys
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
publishedCount.success++;
|
|
239
|
+
logger.debug(`Republished kind:0 profile for agent ${agent.name}`);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
publishedCount.failed++;
|
|
242
|
+
logger.warn(`Failed to republish kind:0 profile for agent ${agent.name}`, { error });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
logger.info(
|
|
247
|
+
`Republished kind:0 profiles for project ${this.projectDTag}: ${publishedCount.success} succeeded, ${publishedCount.failed} failed`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Get an agent by slug
|
|
254
|
+
*/
|
|
255
|
+
getAgent(slug: string): AgentInstance | undefined {
|
|
256
|
+
return this.agents.get(slug);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get an agent by public key
|
|
261
|
+
*/
|
|
262
|
+
getAgentByPubkey(pubkey: string): AgentInstance | undefined {
|
|
263
|
+
return this.agentsByPubkey.get(pubkey);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Get all agents for the current project
|
|
268
|
+
*/
|
|
269
|
+
getAllAgents(): AgentInstance[] {
|
|
270
|
+
return Array.from(this.agents.values());
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Get all agents as a map
|
|
275
|
+
*/
|
|
276
|
+
getAllAgentsMap(): Map<string, AgentInstance> {
|
|
277
|
+
return new Map(this.agents);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Get an agent by event ID
|
|
282
|
+
*/
|
|
283
|
+
getAgentByEventId(eventId: string): AgentInstance | undefined {
|
|
284
|
+
for (const agent of this.agents.values()) {
|
|
285
|
+
if (agent.eventId === eventId) {
|
|
286
|
+
return agent;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Get the project dTag for this registry
|
|
294
|
+
*/
|
|
295
|
+
getProjectDTag(): string | undefined {
|
|
296
|
+
return this.projectDTag;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Get the NDKProject for this registry
|
|
301
|
+
*/
|
|
302
|
+
getNDKProject(): NDKProject | undefined {
|
|
303
|
+
return this.ndkProject;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Add an agent instance to the registry maps.
|
|
308
|
+
* Simple state management - no validation or loading logic.
|
|
309
|
+
*/
|
|
310
|
+
addAgent(agent: AgentInstance): void {
|
|
311
|
+
this.agents.set(agent.slug, agent);
|
|
312
|
+
this.agentsByPubkey.set(agent.pubkey, agent);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Get the Project Manager (PM) for this project
|
|
317
|
+
* PM is the first agent in the project's agent tags
|
|
318
|
+
*/
|
|
319
|
+
getProjectPM(): AgentInstance | undefined {
|
|
320
|
+
if (!this.ndkProject) return undefined;
|
|
321
|
+
|
|
322
|
+
const firstAgentEventId = this.ndkProject.tags.find((t) => t[0] === "agent" && t[1])?.[1];
|
|
323
|
+
|
|
324
|
+
if (!firstAgentEventId) return undefined;
|
|
325
|
+
|
|
326
|
+
// Find agent with this eventId
|
|
327
|
+
for (const agent of this.agents.values()) {
|
|
328
|
+
if (agent.eventId === firstAgentEventId) {
|
|
329
|
+
return agent;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Remove an agent from the current project
|
|
338
|
+
*/
|
|
339
|
+
async removeAgentFromProject(slug: string): Promise<boolean> {
|
|
340
|
+
const agent = this.agents.get(slug);
|
|
341
|
+
if (!agent || !this.projectDTag) {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Remove from storage
|
|
346
|
+
await agentStorage.removeAgentFromProject(agent.pubkey, this.projectDTag);
|
|
347
|
+
|
|
348
|
+
// Remove from memory
|
|
349
|
+
this.agents.delete(slug);
|
|
350
|
+
this.agentsByPubkey.delete(agent.pubkey);
|
|
351
|
+
|
|
352
|
+
logger.info(`Removed agent ${slug} from project ${this.projectDTag}`);
|
|
353
|
+
|
|
354
|
+
// Schedule debounced 14199 snapshot re-publish so the removed agent's p-tag is dropped
|
|
355
|
+
AgentProfilePublisher.publishProjectAgentSnapshot(this.projectDTag);
|
|
356
|
+
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Reload an agent from storage into the registry.
|
|
362
|
+
*
|
|
363
|
+
* Used after storage updates to refresh the in-memory instance.
|
|
364
|
+
* This is the second half of the storage update pattern.
|
|
365
|
+
*
|
|
366
|
+
* ## When to use
|
|
367
|
+
* Call this after any AgentStorage update method:
|
|
368
|
+
* - updateDefaultConfig()
|
|
369
|
+
* - updateProjectOverride()
|
|
370
|
+
* - Or any direct modification to stored agent data
|
|
371
|
+
*
|
|
372
|
+
* ## What it does
|
|
373
|
+
* 1. Load fresh StoredAgent from disk
|
|
374
|
+
* 2. Remove old AgentInstance from registry
|
|
375
|
+
* 3. Create new AgentInstance with fresh data
|
|
376
|
+
* 4. Add new instance to registry
|
|
377
|
+
*
|
|
378
|
+
* @param pubkey - Agent's public key (hex string)
|
|
379
|
+
* @returns true if reloaded successfully, false if agent not found in storage
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* // Update pattern
|
|
383
|
+
* await agentStorage.updateDefaultConfig(pubkey, { model: 'anthropic:claude-opus-4' });
|
|
384
|
+
* await registry.reloadAgent(pubkey); // Pick up changes
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* // Check if agent exists before using
|
|
388
|
+
* const reloaded = await registry.reloadAgent(pubkey);
|
|
389
|
+
* if (reloaded) {
|
|
390
|
+
* const agent = registry.getAgentByPubkey(pubkey);
|
|
391
|
+
* console.log('Agent reloaded:', agent.name);
|
|
392
|
+
* }
|
|
393
|
+
*/
|
|
394
|
+
async reloadAgent(pubkey: string): Promise<boolean> {
|
|
395
|
+
const storedAgent = await agentStorage.loadAgent(pubkey);
|
|
396
|
+
if (!storedAgent) {
|
|
397
|
+
logger.warn(`Agent with pubkey ${pubkey} not found in storage`);
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Remove old instance
|
|
402
|
+
const oldAgent = this.agentsByPubkey.get(pubkey);
|
|
403
|
+
if (oldAgent) {
|
|
404
|
+
this.agents.delete(oldAgent.slug);
|
|
405
|
+
this.agentsByPubkey.delete(pubkey);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Create and add new instance
|
|
409
|
+
// Pass projectDTag for project-scoped config resolution
|
|
410
|
+
const instance = createAgentInstance(storedAgent, this, this.projectDTag);
|
|
411
|
+
this.addAgent(instance);
|
|
412
|
+
|
|
413
|
+
logger.debug(`Reloaded agent ${storedAgent.name} (${storedAgent.slug})`);
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
}
|