@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,165 @@
|
|
|
1
|
+
import type { NDKEvent } from "@nostr-dev-kit/ndk";
|
|
2
|
+
import { NDKArticle } from "@nostr-dev-kit/ndk";
|
|
3
|
+
import { trace } from "@opentelemetry/api";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import type { AgentExecutor } from "../agents/execution/AgentExecutor";
|
|
6
|
+
import { createExecutionContext } from "../agents/execution/ExecutionContextFactory";
|
|
7
|
+
import { ConversationStore } from "../conversations/ConversationStore";
|
|
8
|
+
import type { ConversationMetadata } from "../conversations/types";
|
|
9
|
+
import { AgentEventDecoder } from "../nostr/AgentEventDecoder";
|
|
10
|
+
import { getNDK } from "../nostr/ndkClient";
|
|
11
|
+
import { TagExtractor } from "../nostr/TagExtractor";
|
|
12
|
+
import { getProjectContext } from "@/services/projects";
|
|
13
|
+
import { formatAnyError } from "@/lib/error-formatter";
|
|
14
|
+
import { logger } from "../utils/logger";
|
|
15
|
+
import { AgentRouter } from "@/services/dispatch/AgentRouter";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Fetch a kind 30023 (NDKArticle) from an a-tag reference.
|
|
19
|
+
* @param aTagValue - The a-tag value in format "30023:pubkey:d-tag"
|
|
20
|
+
* @returns The article metadata or null if not found
|
|
21
|
+
*/
|
|
22
|
+
async function fetchReferencedArticle(
|
|
23
|
+
aTagValue: string
|
|
24
|
+
): Promise<ConversationMetadata["referencedArticle"] | null> {
|
|
25
|
+
try {
|
|
26
|
+
const parts = aTagValue.split(":");
|
|
27
|
+
if (parts.length < 3 || parts[0] !== "30023") {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const [, pubkey, ...dTagParts] = parts;
|
|
32
|
+
const dTag = dTagParts.join(":"); // Handle d-tags that contain colons
|
|
33
|
+
|
|
34
|
+
const ndk = getNDK();
|
|
35
|
+
const filter = {
|
|
36
|
+
kinds: [30023],
|
|
37
|
+
authors: [pubkey],
|
|
38
|
+
"#d": [dTag],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const events = await ndk.fetchEvents(filter);
|
|
42
|
+
if (events.size === 0) {
|
|
43
|
+
logger.debug(chalk.yellow(`Referenced article not found: ${aTagValue}`));
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const event = Array.from(events)[0];
|
|
48
|
+
const article = NDKArticle.from(event);
|
|
49
|
+
|
|
50
|
+
logger.info(chalk.cyan(`📄 Fetched referenced article: "${article.title || dTag}"`));
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
title: article.title || dTag,
|
|
54
|
+
content: article.content || "",
|
|
55
|
+
dTag,
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
logger.debug(chalk.yellow(`Failed to fetch referenced article: ${formatAnyError(error)}`));
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Extract and fetch the first kind 30023 article reference from an event's a-tags.
|
|
65
|
+
* @param event - The event to extract article references from
|
|
66
|
+
* @returns The article metadata or null if none found
|
|
67
|
+
*/
|
|
68
|
+
async function extractReferencedArticle(
|
|
69
|
+
event: NDKEvent
|
|
70
|
+
): Promise<ConversationMetadata["referencedArticle"] | null> {
|
|
71
|
+
const aTags = TagExtractor.getATags(event);
|
|
72
|
+
|
|
73
|
+
// Find the first a-tag referencing a kind 30023 (article)
|
|
74
|
+
const articleATag = aTags.find((tag) => tag.startsWith("30023:"));
|
|
75
|
+
if (!articleATag) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return fetchReferencedArticle(articleATag);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface EventHandlerContext {
|
|
83
|
+
agentExecutor: AgentExecutor;
|
|
84
|
+
/**
|
|
85
|
+
* Project directory (normal git repository root).
|
|
86
|
+
* Worktrees are in .worktrees/ subdirectory.
|
|
87
|
+
*/
|
|
88
|
+
projectBasePath: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const handleNewConversation = async (
|
|
92
|
+
event: NDKEvent,
|
|
93
|
+
context: EventHandlerContext
|
|
94
|
+
): Promise<void> => {
|
|
95
|
+
try {
|
|
96
|
+
// Create conversation
|
|
97
|
+
const conversation = await ConversationStore.create(event);
|
|
98
|
+
|
|
99
|
+
// Check for referenced kind 30023 articles and populate metadata
|
|
100
|
+
const referencedArticle = await extractReferencedArticle(event);
|
|
101
|
+
if (referencedArticle) {
|
|
102
|
+
conversation.updateMetadata({ referencedArticle });
|
|
103
|
+
await conversation.save();
|
|
104
|
+
|
|
105
|
+
const activeSpan = trace.getActiveSpan();
|
|
106
|
+
if (activeSpan) {
|
|
107
|
+
activeSpan.addEvent("referenced_article_loaded", {
|
|
108
|
+
"article.title": referencedArticle.title,
|
|
109
|
+
"article.dTag": referencedArticle.dTag,
|
|
110
|
+
"article.content_length": referencedArticle.content.length,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Get project context
|
|
116
|
+
const projectCtx = getProjectContext();
|
|
117
|
+
|
|
118
|
+
// Use AgentRouter to resolve target agents (includes project validation for global agents)
|
|
119
|
+
const targetAgents = AgentRouter.resolveTargetAgents(event, projectCtx);
|
|
120
|
+
|
|
121
|
+
// Add telemetry for routing decision
|
|
122
|
+
const activeSpan = trace.getActiveSpan();
|
|
123
|
+
if (activeSpan) {
|
|
124
|
+
const mentionedPubkeys = AgentEventDecoder.getMentionedPubkeys(event);
|
|
125
|
+
activeSpan.addEvent("agent_routing", {
|
|
126
|
+
"routing.mentioned_pubkeys_count": mentionedPubkeys.length,
|
|
127
|
+
"routing.resolved_agent_count": targetAgents.length,
|
|
128
|
+
"routing.agent_names": targetAgents.map((a) => a.name).join(", "),
|
|
129
|
+
"routing.agent_roles": targetAgents.map((a) => a.role).join(", "),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// If no valid agents found (filtered by project context), return
|
|
134
|
+
if (targetAgents.length === 0) {
|
|
135
|
+
logger.info(
|
|
136
|
+
chalk.gray(
|
|
137
|
+
"New conversation - no valid agents to route to (may have been filtered by project context)"
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
if (activeSpan) {
|
|
141
|
+
activeSpan.addEvent("agent_routing_failed", { reason: "no_agents_resolved" });
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Use first agent for new conversation
|
|
147
|
+
const targetAgent = targetAgents[0];
|
|
148
|
+
|
|
149
|
+
// Create execution context (new conversations don't have branch tags)
|
|
150
|
+
const executionContext = await createExecutionContext({
|
|
151
|
+
agent: targetAgent,
|
|
152
|
+
conversationId: conversation.id,
|
|
153
|
+
projectBasePath: context.projectBasePath,
|
|
154
|
+
triggeringEvent: event,
|
|
155
|
+
mcpManager: projectCtx.mcpManager,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Execute with the appropriate agent
|
|
159
|
+
await context.agentExecutor.execute(executionContext);
|
|
160
|
+
|
|
161
|
+
logger.info(chalk.green("✅ Conversation routed successfully"));
|
|
162
|
+
} catch (error) {
|
|
163
|
+
logger.info(chalk.red(`❌ Failed to route conversation: ${formatAnyError(error)}`));
|
|
164
|
+
}
|
|
165
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { NDKEvent, NDKProject } from "@nostr-dev-kit/ndk";
|
|
2
|
+
import { NDKMCPTool } from "../events/NDKMCPTool";
|
|
3
|
+
import { getNDK } from "../nostr";
|
|
4
|
+
import { TagExtractor } from "../nostr/TagExtractor";
|
|
5
|
+
import { getProjectContext } from "@/services/projects";
|
|
6
|
+
import {
|
|
7
|
+
getInstalledMCPEventIds,
|
|
8
|
+
installMCPServerFromEvent,
|
|
9
|
+
removeMCPServerByEventId,
|
|
10
|
+
} from "../services/mcp/mcpInstaller";
|
|
11
|
+
import { installAgentFromNostr } from "../agents/agent-installer";
|
|
12
|
+
import { logger } from "../utils/logger";
|
|
13
|
+
import { trace } from "@opentelemetry/api";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Handles project update events by syncing agent and MCP tool definitions.
|
|
17
|
+
* When a project event is received, this function:
|
|
18
|
+
* 1. Checks if the event is for the currently loaded project
|
|
19
|
+
* 2. Identifies new agents and MCP tools that have been added to the project
|
|
20
|
+
* 3. Fetches definitions from Nostr for new agents and MCP tools
|
|
21
|
+
* 4. Saves definitions to disk and registers them
|
|
22
|
+
* 5. Updates the ProjectContext with the new configuration
|
|
23
|
+
*/
|
|
24
|
+
export async function handleProjectEvent(event: NDKEvent): Promise<void> {
|
|
25
|
+
const title = TagExtractor.getTagValue(event, "title") || "Untitled";
|
|
26
|
+
|
|
27
|
+
// Extract agent event IDs from the project
|
|
28
|
+
const agentEventIds = TagExtractor.getTagValues(event, "agent")
|
|
29
|
+
.filter((id): id is string => typeof id === "string");
|
|
30
|
+
|
|
31
|
+
// Extract MCP tool event IDs from the project
|
|
32
|
+
const mcpEventIds = TagExtractor.getTagValues(event, "mcp")
|
|
33
|
+
.filter((id): id is string => typeof id === "string");
|
|
34
|
+
|
|
35
|
+
trace.getActiveSpan()?.addEvent("project.update_received", {
|
|
36
|
+
"project.title": title,
|
|
37
|
+
"project.agent_count": agentEventIds.length,
|
|
38
|
+
"project.mcp_count": mcpEventIds.length,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const currentContext = getProjectContext();
|
|
43
|
+
const metadataPath = currentContext.agentRegistry.getMetadataPath();
|
|
44
|
+
|
|
45
|
+
// Check if this is the same project that's currently loaded
|
|
46
|
+
const currentProjectDTag = currentContext.project.dTag;
|
|
47
|
+
const eventDTag = TagExtractor.getDTag(event);
|
|
48
|
+
|
|
49
|
+
if (currentProjectDTag !== eventDTag) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const ndkProject = event as NDKProject;
|
|
54
|
+
|
|
55
|
+
// Track which agents need to be added or updated
|
|
56
|
+
const currentAgentEventIds = new Set<string>();
|
|
57
|
+
for (const agent of currentContext.agents.values()) {
|
|
58
|
+
if (agent.eventId) {
|
|
59
|
+
currentAgentEventIds.add(agent.eventId);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Find new agents that need to be fetched
|
|
64
|
+
const newAgentEventIds = agentEventIds.filter(
|
|
65
|
+
(id) => !!id && !currentAgentEventIds.has(id)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Find agents that need to be removed (exist locally but not in the project)
|
|
69
|
+
const newAgentEventIdsSet = new Set(agentEventIds);
|
|
70
|
+
const agentsToRemove = Array.from(currentAgentEventIds).filter(
|
|
71
|
+
(id) => !newAgentEventIdsSet.has(id)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Handle agent removals first
|
|
75
|
+
if (agentsToRemove.length > 0) {
|
|
76
|
+
const agentRegistry = currentContext.agentRegistry;
|
|
77
|
+
|
|
78
|
+
for (const eventId of agentsToRemove) {
|
|
79
|
+
// Find agent by eventId
|
|
80
|
+
const agent = Array.from(currentContext.agents.values()).find(
|
|
81
|
+
(a) => a.eventId === eventId
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (agent) {
|
|
85
|
+
try {
|
|
86
|
+
await agentRegistry.removeAgentFromProject(agent.slug);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
logger.error(`Error removing agent ${agent.slug}`, { error });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Process agent and MCP tool changes
|
|
95
|
+
const ndk = getNDK();
|
|
96
|
+
|
|
97
|
+
// Fetch and install new agent definitions using shared function
|
|
98
|
+
if (newAgentEventIds.length > 0) {
|
|
99
|
+
for (const eventId of newAgentEventIds) {
|
|
100
|
+
try {
|
|
101
|
+
await installAgentFromNostr(eventId, undefined, ndk);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
logger.error("Failed to install agent from event", { eventId, error });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Reload the agent registry to pick up new agents
|
|
107
|
+
await currentContext.agentRegistry.loadFromProject(ndkProject);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Process MCP tool changes
|
|
111
|
+
|
|
112
|
+
// Get currently installed MCP event IDs (only those with event IDs)
|
|
113
|
+
const installedMCPEventIds = await getInstalledMCPEventIds(metadataPath);
|
|
114
|
+
|
|
115
|
+
// Find new MCP tools that need to be fetched
|
|
116
|
+
const newMCPEventIds = mcpEventIds.filter((id) => !!id && !installedMCPEventIds.has(id));
|
|
117
|
+
|
|
118
|
+
// Find MCP tools that need to be removed (exist locally but not in the project)
|
|
119
|
+
const newMCPEventIdsSet = new Set(mcpEventIds);
|
|
120
|
+
const mcpToolsToRemove = Array.from(installedMCPEventIds).filter(
|
|
121
|
+
(id) => !newMCPEventIdsSet.has(id)
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Handle MCP tool removals first
|
|
125
|
+
for (const eventId of mcpToolsToRemove) {
|
|
126
|
+
try {
|
|
127
|
+
await removeMCPServerByEventId(metadataPath, eventId);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
logger.error("Failed to remove MCP tool", { error, eventId });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Fetch and install new MCP tools
|
|
134
|
+
for (const eventId of newMCPEventIds) {
|
|
135
|
+
try {
|
|
136
|
+
const mcpEvent = await ndk.fetchEvent(eventId);
|
|
137
|
+
if (mcpEvent) {
|
|
138
|
+
const mcpTool = NDKMCPTool.from(mcpEvent);
|
|
139
|
+
await installMCPServerFromEvent(metadataPath, mcpTool);
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
logger.error("Failed to fetch or install MCP tool", { error, eventId });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Reload MCP service if there were any MCP tool changes
|
|
147
|
+
const hasMCPChanges = newMCPEventIds.length > 0 || mcpToolsToRemove.length > 0;
|
|
148
|
+
if (hasMCPChanges && currentContext.mcpManager) {
|
|
149
|
+
await currentContext.mcpManager.reload(metadataPath);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Update the existing project context atomically
|
|
153
|
+
// This will reload agents from the project
|
|
154
|
+
await currentContext.updateProjectData(ndkProject);
|
|
155
|
+
|
|
156
|
+
trace.getActiveSpan()?.addEvent("project.updated", {
|
|
157
|
+
"project.total_agents": currentContext.agents.size,
|
|
158
|
+
"project.agents_added": newAgentEventIds.length,
|
|
159
|
+
"project.agents_removed": agentsToRemove.length,
|
|
160
|
+
"project.mcp_added": newMCPEventIds.length,
|
|
161
|
+
"project.mcp_removed": mcpToolsToRemove.length,
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
logger.error("Failed to update project from event", { error });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentExecutor } from "@/agents/execution/AgentExecutor";
|
|
2
|
+
import { AgentDispatchService } from "@/services/dispatch/AgentDispatchService";
|
|
3
|
+
import type { NDKEvent } from "@nostr-dev-kit/ndk";
|
|
4
|
+
|
|
5
|
+
interface EventHandlerContext {
|
|
6
|
+
agentExecutor: AgentExecutor;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Main entry point for handling chat messages.
|
|
11
|
+
*/
|
|
12
|
+
export const handleChatMessage = async (
|
|
13
|
+
event: NDKEvent,
|
|
14
|
+
context: EventHandlerContext
|
|
15
|
+
): Promise<void> => {
|
|
16
|
+
const dispatcher = AgentDispatchService.getInstance();
|
|
17
|
+
await dispatcher.dispatch(event, context);
|
|
18
|
+
};
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import type NDK from "@nostr-dev-kit/ndk";
|
|
2
|
+
import { NDKEvent, type NDKRawEvent } from "@nostr-dev-kit/ndk";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tuple type for e-tags: ["e", eventId, relayUrl, marker]
|
|
6
|
+
*/
|
|
7
|
+
export type ETag = [marker: "e", eventId: string, relayUrl: string, tagMarker: string];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Parsed e-tag reference with typed fields
|
|
11
|
+
*/
|
|
12
|
+
export interface ETagReference {
|
|
13
|
+
eventId: string;
|
|
14
|
+
relayUrl?: string;
|
|
15
|
+
marker?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class NDKAgentDefinition extends NDKEvent {
|
|
19
|
+
static kind = 4199;
|
|
20
|
+
static kinds = [4199];
|
|
21
|
+
|
|
22
|
+
constructor(ndk?: NDK, event?: NDKEvent | NDKRawEvent) {
|
|
23
|
+
super(ndk, event);
|
|
24
|
+
this.kind ??= 4199;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static from(event: NDKEvent): NDKAgentDefinition {
|
|
28
|
+
return new NDKAgentDefinition(event.ndk, event);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The canonical title/name of the agent.
|
|
33
|
+
* Maps to the "title" tag.
|
|
34
|
+
*/
|
|
35
|
+
get title(): string | undefined {
|
|
36
|
+
return this.tagValue("title");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
set title(value: string | undefined) {
|
|
40
|
+
this.setOptionalTag("title", value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Alias for `title`. Prefer using `title` directly.
|
|
45
|
+
* @deprecated Use `title` instead. Will be removed in a future version.
|
|
46
|
+
*/
|
|
47
|
+
get name(): string | undefined {
|
|
48
|
+
return this.title;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @deprecated Use `title` instead. Will be removed in a future version.
|
|
53
|
+
*/
|
|
54
|
+
set name(value: string | undefined) {
|
|
55
|
+
this.title = value;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get description(): string | undefined {
|
|
59
|
+
return this.tagValue("description");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A one-liner description of the agent's purpose or functionality.
|
|
64
|
+
*/
|
|
65
|
+
set description(value: string | undefined) {
|
|
66
|
+
this.setOptionalTag("description", value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Extended markdown description from the event content field.
|
|
71
|
+
* MAY contain markdown-formatted extended description of the agent.
|
|
72
|
+
*/
|
|
73
|
+
get markdownDescription(): string | undefined {
|
|
74
|
+
return this.content || undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Set the extended markdown description in the event content field.
|
|
79
|
+
*/
|
|
80
|
+
set markdownDescription(value: string | undefined) {
|
|
81
|
+
this.content = value ?? "";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get role(): string | undefined {
|
|
85
|
+
return this.tagValue("role");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The expertise and personality for this agent.
|
|
90
|
+
* This shapes how the agent interacts with users and other agents.
|
|
91
|
+
*/
|
|
92
|
+
set role(value: string | undefined) {
|
|
93
|
+
this.setOptionalTag("role", value);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get instructions(): string | undefined {
|
|
97
|
+
return this.tagValue("instructions");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Detailed instructions or guidelines for the agent's operation.
|
|
102
|
+
*/
|
|
103
|
+
set instructions(value: string | undefined) {
|
|
104
|
+
this.setOptionalTag("instructions", value);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get version(): number {
|
|
108
|
+
const val = this.tagValue("ver");
|
|
109
|
+
if (val === undefined) return 1; // Default version if not specified
|
|
110
|
+
const parsed = Number.parseInt(val, 10);
|
|
111
|
+
return Number.isNaN(parsed) ? 1 : parsed; // Fallback to 1 if parsing fails
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
set version(value: number) {
|
|
115
|
+
this.removeTag("ver");
|
|
116
|
+
this.tags.push(["ver", value.toString()]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get useCriteria(): string | undefined {
|
|
120
|
+
return this.tagValue("use-criteria");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Criteria for when this agent should be selected or used.
|
|
125
|
+
* This helps with agent routing and selection.
|
|
126
|
+
*/
|
|
127
|
+
set useCriteria(value: string | undefined) {
|
|
128
|
+
this.setOptionalTag("use-criteria", value);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
get category(): string | undefined {
|
|
132
|
+
return this.tagValue("category");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Category for the agent (e.g., 'developer', 'analyst', 'assistant').
|
|
137
|
+
*/
|
|
138
|
+
set category(value: string | undefined) {
|
|
139
|
+
this.setOptionalTag("category", value);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get slug(): string | undefined {
|
|
143
|
+
return this.tagValue("d");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The slug identifier for this agent definition.
|
|
148
|
+
* This is used to find different versions from the same author of the same agent
|
|
149
|
+
* (e.g., version 1, 2, 3 of a 'human-replica' agent would all share ["d", "human-replica"]).
|
|
150
|
+
*
|
|
151
|
+
* Note: Unlike other setters, this uses `value !== undefined` instead of truthy check
|
|
152
|
+
* because empty string is a valid d-tag value per Nostr conventions. Only `undefined`
|
|
153
|
+
* should clear the tag. This is intentionally different from setOptionalTag behavior.
|
|
154
|
+
*/
|
|
155
|
+
set slug(value: string | undefined) {
|
|
156
|
+
this.removeTag("d");
|
|
157
|
+
if (value !== undefined) this.tags.push(["d", value]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get script e-tags from the agent definition.
|
|
162
|
+
* Script e-tags reference kind 1063 (NIP-94 file metadata) events
|
|
163
|
+
* that contain files bundled with the agent.
|
|
164
|
+
*
|
|
165
|
+
* @returns Array of parsed e-tag references
|
|
166
|
+
* @deprecated Use getFileETags() instead, which returns all e-tags (not just "script" marker)
|
|
167
|
+
*/
|
|
168
|
+
getScriptETags(): ETagReference[] {
|
|
169
|
+
return this.parseETags("script");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get all e-tags from the agent definition.
|
|
174
|
+
* E-tags may reference kind 1063 (NIP-94 file metadata) events
|
|
175
|
+
* that contain files bundled with the agent, or other related events.
|
|
176
|
+
*
|
|
177
|
+
* Unlike getScriptETags(), this method returns ALL e-tags, not just
|
|
178
|
+
* those with a specific marker, allowing for general event references.
|
|
179
|
+
*
|
|
180
|
+
* @returns Array of parsed e-tag references
|
|
181
|
+
*/
|
|
182
|
+
getETags(): ETagReference[] {
|
|
183
|
+
return this.parseETags();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get e-tags with the "file" marker.
|
|
188
|
+
* These reference kind 1063 (NIP-94 file metadata) events that contain
|
|
189
|
+
* files bundled with this agent definition.
|
|
190
|
+
*
|
|
191
|
+
* @returns Array of parsed e-tag references
|
|
192
|
+
*/
|
|
193
|
+
getFileETags(): ETagReference[] {
|
|
194
|
+
return this.parseETags("file");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get e-tags with the "fork" marker.
|
|
199
|
+
* These reference the source kind 4199 agent definition event that
|
|
200
|
+
* this agent was forked from.
|
|
201
|
+
*
|
|
202
|
+
* @returns Array of parsed e-tag references
|
|
203
|
+
*/
|
|
204
|
+
getForkETags(): ETagReference[] {
|
|
205
|
+
return this.parseETags("fork");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get the source agent definition this was forked from (if any).
|
|
210
|
+
* Returns the first fork e-tag, or undefined if this is not a fork.
|
|
211
|
+
*
|
|
212
|
+
* @returns Object with eventId and optional relayUrl, or undefined
|
|
213
|
+
*/
|
|
214
|
+
getForkSource(): { eventId: string; relayUrl?: string } | undefined {
|
|
215
|
+
const forks = this.getForkETags();
|
|
216
|
+
return forks.length > 0 ? forks[0] : undefined;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Add a file reference e-tag with the "file" marker.
|
|
221
|
+
* References a kind 1063 (NIP-94 file metadata) event.
|
|
222
|
+
*
|
|
223
|
+
* @param eventId - The event ID of the kind 1063 file metadata event
|
|
224
|
+
* @param relayUrl - Optional relay hint URL
|
|
225
|
+
*/
|
|
226
|
+
addFileReference(eventId: string, relayUrl?: string): void {
|
|
227
|
+
this.tags.push(this.buildETag(eventId, relayUrl, "file"));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Set the fork source for this agent definition.
|
|
232
|
+
* Removes any existing fork e-tags and adds a new one.
|
|
233
|
+
*
|
|
234
|
+
* @param eventId - The event ID of the source kind 4199 agent definition
|
|
235
|
+
* @param relayUrl - Optional relay hint URL
|
|
236
|
+
*/
|
|
237
|
+
setForkSource(eventId: string, relayUrl?: string): void {
|
|
238
|
+
// Remove existing fork tags
|
|
239
|
+
this.tags = this.tags.filter((tag) => !(tag[0] === "e" && tag[3] === "fork"));
|
|
240
|
+
|
|
241
|
+
// Add new fork tag
|
|
242
|
+
this.tags.push(this.buildETag(eventId, relayUrl, "fork"));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Build an e-tag tuple with the standard format: ["e", eventId, relayUrl, marker]
|
|
247
|
+
*
|
|
248
|
+
* @param eventId - The event ID to reference
|
|
249
|
+
* @param relayUrl - Optional relay hint URL (defaults to empty string if not provided)
|
|
250
|
+
* @param marker - The marker for the e-tag (e.g., "file", "fork", "script")
|
|
251
|
+
* @returns The constructed e-tag tuple
|
|
252
|
+
*/
|
|
253
|
+
private buildETag(eventId: string, relayUrl: string | undefined, marker: string): ETag {
|
|
254
|
+
return ["e", eventId, relayUrl ?? "", marker];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Parse e-tags from the event, optionally filtering by marker.
|
|
259
|
+
* Consolidates the common filter/map logic for e-tag extraction.
|
|
260
|
+
*
|
|
261
|
+
* @param marker - Optional marker to filter by (e.g., "file", "fork", "script").
|
|
262
|
+
* If not provided, returns all e-tags.
|
|
263
|
+
* @returns Array of parsed e-tag references with eventId, relayUrl, and marker
|
|
264
|
+
*/
|
|
265
|
+
private parseETags(marker?: string): ETagReference[] {
|
|
266
|
+
return this.tags
|
|
267
|
+
.filter((tag) => tag[0] === "e" && !!tag[1] && (marker === undefined || tag[3] === marker))
|
|
268
|
+
.map((tag) => ({
|
|
269
|
+
eventId: tag[1],
|
|
270
|
+
relayUrl: tag[2] || undefined,
|
|
271
|
+
marker: tag[3] || undefined,
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Set an optional tag value with consistent semantics.
|
|
277
|
+
* Removes any existing tag with the same name, then adds it back only if value is truthy.
|
|
278
|
+
* This means empty strings, undefined, and null all clear the tag.
|
|
279
|
+
*
|
|
280
|
+
* Note: For tags where empty string is a valid value (like the "d" tag for slug),
|
|
281
|
+
* use direct tag manipulation with `value !== undefined` check instead of this helper.
|
|
282
|
+
*
|
|
283
|
+
* @param tagName - The tag name to set
|
|
284
|
+
* @param value - The value to set, or falsy value to clear the tag
|
|
285
|
+
*/
|
|
286
|
+
private setOptionalTag(tagName: string, value: string | undefined): void {
|
|
287
|
+
this.removeTag(tagName);
|
|
288
|
+
if (value) {
|
|
289
|
+
this.tags.push([tagName, value]);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|