@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,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Registry - Central registry for all LLM providers
|
|
3
|
+
*
|
|
4
|
+
* This module provides a unified registry for managing LLM providers,
|
|
5
|
+
* supporting both standard AI SDK providers and custom agent providers.
|
|
6
|
+
* Integrates with KeyManager for multi-key rotation and fallback.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createProviderRegistry } from "ai";
|
|
10
|
+
import type { ProviderRegistryProvider } from "ai";
|
|
11
|
+
import type { ProviderV3 } from "@ai-sdk/provider";
|
|
12
|
+
import { logger } from "@/utils/logger";
|
|
13
|
+
import { keyManager } from "../key-manager";
|
|
14
|
+
import type {
|
|
15
|
+
ILLMProvider,
|
|
16
|
+
ProviderInitConfig,
|
|
17
|
+
ProviderPoolConfig,
|
|
18
|
+
ProviderMetadata,
|
|
19
|
+
ProviderRegistration,
|
|
20
|
+
ProviderRuntimeContext,
|
|
21
|
+
ProviderModelResult,
|
|
22
|
+
} from "../types";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Provider initialization result
|
|
26
|
+
*/
|
|
27
|
+
interface InitializationResult {
|
|
28
|
+
providerId: string;
|
|
29
|
+
success: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Central registry for all LLM providers
|
|
35
|
+
*
|
|
36
|
+
* The registry manages provider lifecycle:
|
|
37
|
+
* 1. Registration - Providers register themselves
|
|
38
|
+
* 2. Initialization - Providers are initialized with API keys
|
|
39
|
+
* 3. Model Creation - Providers create language models on demand
|
|
40
|
+
* 4. Key Rotation - Providers can be re-initialized with a different key on failure
|
|
41
|
+
*/
|
|
42
|
+
export class ProviderRegistry {
|
|
43
|
+
private static instance: ProviderRegistry | null = null;
|
|
44
|
+
|
|
45
|
+
private providers: Map<string, ILLMProvider> = new Map();
|
|
46
|
+
private registrations: Map<string, ProviderRegistration> = new Map();
|
|
47
|
+
private providerConfigs: Map<string, ProviderPoolConfig> = new Map();
|
|
48
|
+
private activeApiKeys: Map<string, string> = new Map();
|
|
49
|
+
private aiSdkRegistry: ProviderRegistryProvider | null = null;
|
|
50
|
+
private initialized = false;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get the singleton instance
|
|
54
|
+
*/
|
|
55
|
+
static getInstance(): ProviderRegistry {
|
|
56
|
+
if (!ProviderRegistry.instance) {
|
|
57
|
+
ProviderRegistry.instance = new ProviderRegistry();
|
|
58
|
+
}
|
|
59
|
+
return ProviderRegistry.instance;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Reset the singleton (for testing)
|
|
64
|
+
*/
|
|
65
|
+
static resetInstance(): void {
|
|
66
|
+
if (ProviderRegistry.instance) {
|
|
67
|
+
ProviderRegistry.instance.reset();
|
|
68
|
+
ProviderRegistry.instance = null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Register a provider class
|
|
74
|
+
* This should be called during module initialization
|
|
75
|
+
*/
|
|
76
|
+
register(registration: ProviderRegistration): void {
|
|
77
|
+
const { metadata } = registration;
|
|
78
|
+
|
|
79
|
+
if (this.registrations.has(metadata.id)) {
|
|
80
|
+
logger.warn(`[ProviderRegistry] Provider "${metadata.id}" already registered, skipping`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.registrations.set(metadata.id, registration);
|
|
85
|
+
logger.debug(`[ProviderRegistry] Registered provider: ${metadata.id}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register multiple providers at once
|
|
90
|
+
*/
|
|
91
|
+
registerAll(registrations: ProviderRegistration[]): void {
|
|
92
|
+
for (const reg of registrations) {
|
|
93
|
+
this.register(reg);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Initialize all registered providers with their configurations.
|
|
99
|
+
* Supports multi-key configs — keys are registered with KeyManager
|
|
100
|
+
* and a single key is selected for each provider's initial setup.
|
|
101
|
+
*/
|
|
102
|
+
async initialize(
|
|
103
|
+
configs: Record<string, ProviderPoolConfig>
|
|
104
|
+
): Promise<InitializationResult[]> {
|
|
105
|
+
const results: InitializationResult[] = [];
|
|
106
|
+
this.providers.clear();
|
|
107
|
+
this.providerConfigs.clear();
|
|
108
|
+
this.activeApiKeys.clear();
|
|
109
|
+
|
|
110
|
+
// Check if mock mode is enabled
|
|
111
|
+
if (process.env.USE_MOCK_LLM === "true") {
|
|
112
|
+
await this.initializeMockProvider();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Register all key pools with KeyManager and initialize providers
|
|
116
|
+
for (const [providerId, registration] of this.registrations) {
|
|
117
|
+
const config = configs[providerId];
|
|
118
|
+
const rawKey = config?.apiKey;
|
|
119
|
+
|
|
120
|
+
// Normalize: treat empty arrays and arrays of only empty strings as "no key"
|
|
121
|
+
const apiKey = Array.isArray(rawKey)
|
|
122
|
+
? (rawKey.filter(k => k.length > 0).length > 0 ? rawKey : undefined)
|
|
123
|
+
: (rawKey || undefined);
|
|
124
|
+
|
|
125
|
+
// Register keys with KeyManager (handles string | string[])
|
|
126
|
+
if (apiKey) {
|
|
127
|
+
keyManager.registerKeys(providerId, apiKey);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Skip providers without config (unless they don't require API key)
|
|
131
|
+
if (!apiKey && registration.metadata.capabilities.requiresApiKey) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Store the full config for potential re-initialization
|
|
136
|
+
if (config) {
|
|
137
|
+
this.providerConfigs.set(providerId, config);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Select a single key for this initialization
|
|
141
|
+
const selectedKey = apiKey ? keyManager.selectKey(providerId) : undefined;
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const provider = new registration.Provider();
|
|
145
|
+
const initConfig: ProviderInitConfig = {
|
|
146
|
+
apiKey: selectedKey,
|
|
147
|
+
baseUrl: config?.baseUrl,
|
|
148
|
+
options: config?.options,
|
|
149
|
+
};
|
|
150
|
+
await provider.initialize(initConfig);
|
|
151
|
+
this.providers.set(providerId, provider);
|
|
152
|
+
if (selectedKey) {
|
|
153
|
+
this.activeApiKeys.set(providerId, selectedKey);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
results.push({ providerId, success: true });
|
|
157
|
+
|
|
158
|
+
logger.debug(`[ProviderRegistry] Initialized provider: ${providerId}`);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
161
|
+
results.push({ providerId, success: false, error: errorMessage });
|
|
162
|
+
|
|
163
|
+
logger.error(`[ProviderRegistry] Failed to initialize provider ${providerId}`, {
|
|
164
|
+
error: errorMessage,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Build the AI SDK registry from standard providers
|
|
170
|
+
this.buildAiSdkRegistry();
|
|
171
|
+
|
|
172
|
+
this.initialized = true;
|
|
173
|
+
|
|
174
|
+
logger.debug(`[ProviderRegistry] Initialized ${this.providers.size} providers: ${Array.from(this.providers.keys()).join(", ")}`);
|
|
175
|
+
|
|
176
|
+
return results;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Re-initialize a provider with a different API key.
|
|
181
|
+
* Called when a key fails at runtime to attempt fallback.
|
|
182
|
+
*
|
|
183
|
+
* @param providerId The provider to re-initialize
|
|
184
|
+
* @param failedKey The key that failed (will be reported to KeyManager)
|
|
185
|
+
* @returns true if re-initialization succeeded with a new key
|
|
186
|
+
*/
|
|
187
|
+
async reinitializeProvider(providerId: string, failedKey: string): Promise<boolean> {
|
|
188
|
+
if (!keyManager.hasMultipleKeys(providerId)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Report the failure to track key health
|
|
193
|
+
keyManager.reportFailure(providerId, failedKey);
|
|
194
|
+
|
|
195
|
+
// Select a new key (KeyManager will avoid disabled keys)
|
|
196
|
+
const newKey = keyManager.selectKey(providerId);
|
|
197
|
+
if (!newKey || newKey === failedKey) {
|
|
198
|
+
logger.warn(`[ProviderRegistry] No alternative key available for "${providerId}"`);
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const registration = this.registrations.get(providerId);
|
|
203
|
+
const originalConfig = this.providerConfigs.get(providerId);
|
|
204
|
+
if (!registration || !originalConfig) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
// Build the new provider FIRST — never tear down before we have a replacement
|
|
210
|
+
const newProvider = new registration.Provider();
|
|
211
|
+
const initConfig: ProviderInitConfig = {
|
|
212
|
+
apiKey: newKey,
|
|
213
|
+
baseUrl: originalConfig.baseUrl,
|
|
214
|
+
options: originalConfig.options,
|
|
215
|
+
};
|
|
216
|
+
await newProvider.initialize(initConfig);
|
|
217
|
+
|
|
218
|
+
// New provider is ready — now swap it in and clean up the old one
|
|
219
|
+
const oldProvider = this.providers.get(providerId);
|
|
220
|
+
this.providers.set(providerId, newProvider);
|
|
221
|
+
this.activeApiKeys.set(providerId, newKey);
|
|
222
|
+
|
|
223
|
+
if (oldProvider) {
|
|
224
|
+
oldProvider.reset();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Rebuild the AI SDK registry to reflect the new provider instance
|
|
228
|
+
this.buildAiSdkRegistry();
|
|
229
|
+
|
|
230
|
+
const keyPreview = newKey.slice(0, 8) + "...";
|
|
231
|
+
logger.info(`[ProviderRegistry] Re-initialized "${providerId}" with key ${keyPreview}`);
|
|
232
|
+
return true;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
235
|
+
logger.error(`[ProviderRegistry] Failed to re-initialize "${providerId}"`, {
|
|
236
|
+
error: errorMessage,
|
|
237
|
+
});
|
|
238
|
+
// Old provider remains intact — no downtime
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get the currently active API key for a provider.
|
|
245
|
+
* Used by callers that need to report which key failed.
|
|
246
|
+
*/
|
|
247
|
+
getActiveApiKey(providerId: string): string | undefined {
|
|
248
|
+
return this.activeApiKeys.get(providerId);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Initialize the mock provider for testing
|
|
253
|
+
*/
|
|
254
|
+
private async initializeMockProvider(): Promise<void> {
|
|
255
|
+
try {
|
|
256
|
+
const { createMockProvider } = await import("../MockProvider");
|
|
257
|
+
const mockProvider = createMockProvider();
|
|
258
|
+
|
|
259
|
+
// Create a wrapper that satisfies ILLMProvider
|
|
260
|
+
const mockWrapper: ILLMProvider = {
|
|
261
|
+
metadata: {
|
|
262
|
+
id: "mock",
|
|
263
|
+
displayName: "Mock Provider",
|
|
264
|
+
description: "Mock provider for testing",
|
|
265
|
+
category: "standard",
|
|
266
|
+
capabilities: {
|
|
267
|
+
streaming: true,
|
|
268
|
+
toolCalling: true,
|
|
269
|
+
builtInTools: false,
|
|
270
|
+
sessionResumption: false,
|
|
271
|
+
requiresApiKey: false,
|
|
272
|
+
mcpSupport: false,
|
|
273
|
+
},
|
|
274
|
+
defaultModel: "mock-model",
|
|
275
|
+
},
|
|
276
|
+
initialize: async () => {},
|
|
277
|
+
isInitialized: () => true,
|
|
278
|
+
isAvailable: () => true,
|
|
279
|
+
getProviderInstance: () => mockProvider,
|
|
280
|
+
createModel: (modelId) => ({
|
|
281
|
+
model: mockProvider.languageModel(modelId),
|
|
282
|
+
bypassRegistry: false,
|
|
283
|
+
}),
|
|
284
|
+
reset: () => {},
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
this.providers.set("mock", mockWrapper);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
logger.error("[ProviderRegistry] Failed to load MockProvider:", error);
|
|
290
|
+
throw new Error(
|
|
291
|
+
"Mock mode is enabled but MockProvider could not be loaded. " +
|
|
292
|
+
"Make sure test dependencies are installed.",
|
|
293
|
+
{ cause: error }
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Build the AI SDK provider registry from initialized standard providers
|
|
300
|
+
*/
|
|
301
|
+
private buildAiSdkRegistry(): void {
|
|
302
|
+
const standardProviders: Record<string, ProviderV3> = {};
|
|
303
|
+
|
|
304
|
+
for (const [providerId, provider] of this.providers) {
|
|
305
|
+
// Only include standard providers in the AI SDK registry
|
|
306
|
+
if (provider.metadata.category === "standard") {
|
|
307
|
+
const instance = provider.getProviderInstance();
|
|
308
|
+
if (instance) {
|
|
309
|
+
standardProviders[providerId] = instance as ProviderV3;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (Object.keys(standardProviders).length > 0) {
|
|
315
|
+
this.aiSdkRegistry = createProviderRegistry(standardProviders);
|
|
316
|
+
} else {
|
|
317
|
+
// Create empty registry to avoid null checks
|
|
318
|
+
this.aiSdkRegistry = createProviderRegistry({});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get a provider by ID
|
|
324
|
+
*/
|
|
325
|
+
getProvider(providerId: string): ILLMProvider | undefined {
|
|
326
|
+
return this.providers.get(providerId);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Check if a provider is available
|
|
331
|
+
*/
|
|
332
|
+
hasProvider(providerId: string): boolean {
|
|
333
|
+
return this.providers.has(providerId) &&
|
|
334
|
+
(this.providers.get(providerId)?.isAvailable() ?? false);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Get the AI SDK provider registry
|
|
339
|
+
* Used for standard providers that use createProviderRegistry
|
|
340
|
+
*/
|
|
341
|
+
getAiSdkRegistry(): ProviderRegistryProvider {
|
|
342
|
+
if (!this.aiSdkRegistry) {
|
|
343
|
+
throw new Error("ProviderRegistry not initialized. Call initialize() first.");
|
|
344
|
+
}
|
|
345
|
+
return this.aiSdkRegistry;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Create a model from a provider
|
|
350
|
+
*/
|
|
351
|
+
createModel(
|
|
352
|
+
providerId: string,
|
|
353
|
+
modelId: string,
|
|
354
|
+
context?: ProviderRuntimeContext
|
|
355
|
+
): ProviderModelResult {
|
|
356
|
+
// In mock mode, always use mock provider
|
|
357
|
+
const actualProviderId = process.env.USE_MOCK_LLM === "true" ? "mock" : providerId;
|
|
358
|
+
|
|
359
|
+
const provider = this.providers.get(actualProviderId);
|
|
360
|
+
|
|
361
|
+
if (!provider) {
|
|
362
|
+
const available = Array.from(this.providers.keys());
|
|
363
|
+
throw new Error(
|
|
364
|
+
`Provider "${actualProviderId}" not available. ` +
|
|
365
|
+
`Initialized providers: ${available.length > 0 ? available.join(", ") : "none"}`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return provider.createModel(modelId, context);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get all available providers
|
|
374
|
+
*/
|
|
375
|
+
getAvailableProviders(): ProviderMetadata[] {
|
|
376
|
+
return Array.from(this.providers.values())
|
|
377
|
+
.filter(p => p.isAvailable())
|
|
378
|
+
.map(p => p.metadata);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Get all registered providers (even if not initialized)
|
|
383
|
+
*/
|
|
384
|
+
getRegisteredProviders(): ProviderMetadata[] {
|
|
385
|
+
return Array.from(this.registrations.values()).map(r => r.metadata);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Check if the registry is initialized
|
|
390
|
+
*/
|
|
391
|
+
isInitialized(): boolean {
|
|
392
|
+
return this.initialized;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Reset the registry
|
|
397
|
+
*/
|
|
398
|
+
reset(): void {
|
|
399
|
+
for (const provider of this.providers.values()) {
|
|
400
|
+
provider.reset();
|
|
401
|
+
}
|
|
402
|
+
this.providers.clear();
|
|
403
|
+
this.providerConfigs.clear();
|
|
404
|
+
this.activeApiKeys.clear();
|
|
405
|
+
this.aiSdkRegistry = null;
|
|
406
|
+
this.initialized = false;
|
|
407
|
+
keyManager.reset();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Export singleton instance
|
|
413
|
+
*/
|
|
414
|
+
export const providerRegistry = ProviderRegistry.getInstance();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Provider
|
|
3
|
+
*
|
|
4
|
+
* Direct access to Anthropic's Claude models.
|
|
5
|
+
* Supports both API keys (sk-ant-api*) and OAuth setup-tokens (sk-ant-oat*)
|
|
6
|
+
* from `claude setup-token` for Claude Code Max subscription auth.
|
|
7
|
+
*
|
|
8
|
+
* https://www.anthropic.com/
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
12
|
+
import { logger } from "@/utils/logger";
|
|
13
|
+
import type { ProviderInitConfig, ProviderMetadata } from "../types";
|
|
14
|
+
import { StandardProvider } from "../base/StandardProvider";
|
|
15
|
+
import { PROVIDER_IDS } from "../provider-ids";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Beta headers required when using OAuth setup-tokens.
|
|
19
|
+
* Without these, Anthropic rejects OAuth Bearer auth with 401.
|
|
20
|
+
*/
|
|
21
|
+
const OAUTH_BETAS = [
|
|
22
|
+
"claude-code-20250219",
|
|
23
|
+
"oauth-2025-04-20",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function isOAuthToken(key: string): boolean {
|
|
27
|
+
return key.startsWith("sk-ant-oat");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Anthropic provider implementation
|
|
32
|
+
*/
|
|
33
|
+
export class AnthropicProvider extends StandardProvider {
|
|
34
|
+
static readonly METADATA: ProviderMetadata = StandardProvider.createMetadata(
|
|
35
|
+
PROVIDER_IDS.ANTHROPIC,
|
|
36
|
+
"Anthropic",
|
|
37
|
+
"Direct access to Claude models",
|
|
38
|
+
"standard",
|
|
39
|
+
"claude-sonnet-4-20250514",
|
|
40
|
+
{
|
|
41
|
+
streaming: true,
|
|
42
|
+
toolCalling: true,
|
|
43
|
+
requiresApiKey: true,
|
|
44
|
+
},
|
|
45
|
+
"https://docs.anthropic.com/"
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
get metadata(): ProviderMetadata {
|
|
49
|
+
return AnthropicProvider.METADATA;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected createProviderInstance(config: ProviderInitConfig): unknown {
|
|
53
|
+
if (!config.apiKey) {
|
|
54
|
+
throw new Error("Anthropic requires an API key or setup-token");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (isOAuthToken(config.apiKey)) {
|
|
58
|
+
logger.info("[AnthropicProvider] Using OAuth setup-token auth (Claude Code Max subscription)");
|
|
59
|
+
return createAnthropic({
|
|
60
|
+
authToken: config.apiKey,
|
|
61
|
+
headers: {
|
|
62
|
+
"anthropic-beta": OAUTH_BETAS.join(","),
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return createAnthropic({
|
|
68
|
+
apiKey: config.apiKey,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama Provider
|
|
3
|
+
*
|
|
4
|
+
* Run open-source LLMs locally with Ollama.
|
|
5
|
+
* https://ollama.ai/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createOllama } from "ollama-ai-provider-v2";
|
|
9
|
+
import type { ProviderInitConfig, ProviderMetadata } from "../types";
|
|
10
|
+
import { StandardProvider } from "../base/StandardProvider";
|
|
11
|
+
import { PROVIDER_IDS } from "../provider-ids";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ollama provider implementation
|
|
15
|
+
*/
|
|
16
|
+
export class OllamaProvider extends StandardProvider {
|
|
17
|
+
static readonly METADATA: ProviderMetadata = StandardProvider.createMetadata(
|
|
18
|
+
PROVIDER_IDS.OLLAMA,
|
|
19
|
+
"Ollama",
|
|
20
|
+
"Run open-source LLMs locally",
|
|
21
|
+
"standard",
|
|
22
|
+
"llama3.1:8b",
|
|
23
|
+
{
|
|
24
|
+
streaming: true,
|
|
25
|
+
toolCalling: true,
|
|
26
|
+
requiresApiKey: false, // Ollama uses a base URL instead of API key
|
|
27
|
+
},
|
|
28
|
+
"https://ollama.ai/"
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
get metadata(): ProviderMetadata {
|
|
32
|
+
return OllamaProvider.METADATA;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected createProviderInstance(config: ProviderInitConfig): unknown {
|
|
36
|
+
// For Ollama, apiKey is actually the base URL
|
|
37
|
+
// The library expects the URL to include /api path
|
|
38
|
+
let baseURL: string | undefined;
|
|
39
|
+
|
|
40
|
+
if (!config.apiKey || config.apiKey === "local") {
|
|
41
|
+
// Use default (library provides http://127.0.0.1:11434/api)
|
|
42
|
+
baseURL = undefined;
|
|
43
|
+
} else {
|
|
44
|
+
// Custom URL - ensure it ends with /api
|
|
45
|
+
baseURL = config.apiKey.endsWith("/api")
|
|
46
|
+
? config.apiKey
|
|
47
|
+
: `${config.apiKey.replace(/\/$/, "")}/api`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return createOllama(baseURL ? { baseURL } : undefined);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Ollama is available if initialized (no API key required)
|
|
55
|
+
*/
|
|
56
|
+
isAvailable(): boolean {
|
|
57
|
+
return this._initialized;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Provider
|
|
3
|
+
*
|
|
4
|
+
* Direct access to OpenAI's GPT models.
|
|
5
|
+
* https://openai.com/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
9
|
+
import type { ProviderInitConfig, ProviderMetadata } from "../types";
|
|
10
|
+
import { StandardProvider } from "../base/StandardProvider";
|
|
11
|
+
import { PROVIDER_IDS } from "../provider-ids";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* OpenAI provider implementation
|
|
15
|
+
*/
|
|
16
|
+
export class OpenAIProvider extends StandardProvider {
|
|
17
|
+
static readonly METADATA: ProviderMetadata = StandardProvider.createMetadata(
|
|
18
|
+
PROVIDER_IDS.OPENAI,
|
|
19
|
+
"OpenAI",
|
|
20
|
+
"Direct access to GPT models",
|
|
21
|
+
"standard",
|
|
22
|
+
"gpt-4",
|
|
23
|
+
{
|
|
24
|
+
streaming: true,
|
|
25
|
+
toolCalling: true,
|
|
26
|
+
requiresApiKey: true,
|
|
27
|
+
},
|
|
28
|
+
"https://platform.openai.com/docs/"
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
get metadata(): ProviderMetadata {
|
|
32
|
+
return OpenAIProvider.METADATA;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected createProviderInstance(config: ProviderInitConfig): unknown {
|
|
36
|
+
if (!config.apiKey) {
|
|
37
|
+
throw new Error("OpenAI requires an API key");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return createOpenAI({
|
|
41
|
+
apiKey: config.apiKey,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter Provider
|
|
3
|
+
*
|
|
4
|
+
* OpenRouter provides access to multiple AI models through a single API.
|
|
5
|
+
* https://openrouter.ai/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
9
|
+
import type { LanguageModelUsage } from "ai";
|
|
10
|
+
import type { LanguageModelUsageWithCostUsd } from "../../types";
|
|
11
|
+
import type { ProviderInitConfig, ProviderMetadata } from "../types";
|
|
12
|
+
import { StandardProvider } from "../base/StandardProvider";
|
|
13
|
+
import { PROVIDER_IDS } from "../provider-ids";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* OpenRouter-specific metadata structure
|
|
17
|
+
*/
|
|
18
|
+
interface OpenRouterProviderMetadata {
|
|
19
|
+
id?: string;
|
|
20
|
+
usage?: {
|
|
21
|
+
cost?: number;
|
|
22
|
+
promptTokens?: number;
|
|
23
|
+
completionTokens?: number;
|
|
24
|
+
totalTokens?: number;
|
|
25
|
+
promptTokensDetails?: { cachedTokens?: number };
|
|
26
|
+
completionTokensDetails?: { reasoningTokens?: number };
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* OpenRouter provider implementation
|
|
32
|
+
*/
|
|
33
|
+
export class OpenRouterProvider extends StandardProvider {
|
|
34
|
+
static readonly METADATA: ProviderMetadata = StandardProvider.createMetadata(
|
|
35
|
+
PROVIDER_IDS.OPENROUTER,
|
|
36
|
+
"OpenRouter",
|
|
37
|
+
"Access multiple AI models through a single API",
|
|
38
|
+
"standard",
|
|
39
|
+
"openai/gpt-4",
|
|
40
|
+
{
|
|
41
|
+
streaming: true,
|
|
42
|
+
toolCalling: true,
|
|
43
|
+
requiresApiKey: true,
|
|
44
|
+
},
|
|
45
|
+
"https://openrouter.ai/docs"
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
get metadata(): ProviderMetadata {
|
|
49
|
+
return OpenRouterProvider.METADATA;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected createProviderInstance(config: ProviderInitConfig): unknown {
|
|
53
|
+
if (!config.apiKey) {
|
|
54
|
+
throw new Error("OpenRouter requires an API key");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return createOpenRouter({
|
|
58
|
+
apiKey: config.apiKey,
|
|
59
|
+
headers: {
|
|
60
|
+
"X-Title": "TENEX",
|
|
61
|
+
"HTTP-Referer": "https://tenex.chat/",
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Extract usage metadata from OpenRouter provider response
|
|
68
|
+
*/
|
|
69
|
+
static extractUsageMetadata(
|
|
70
|
+
model: string,
|
|
71
|
+
totalUsage: LanguageModelUsage | undefined,
|
|
72
|
+
providerMetadata: Record<string, unknown> | undefined
|
|
73
|
+
): LanguageModelUsageWithCostUsd {
|
|
74
|
+
const metadata = providerMetadata?.openrouter as OpenRouterProviderMetadata | undefined;
|
|
75
|
+
const usage = metadata?.usage;
|
|
76
|
+
|
|
77
|
+
const inputTokens = usage?.promptTokens ?? totalUsage?.inputTokens;
|
|
78
|
+
const outputTokens = usage?.completionTokens ?? totalUsage?.outputTokens;
|
|
79
|
+
const totalTokens = usage?.totalTokens ??
|
|
80
|
+
(inputTokens !== undefined && outputTokens !== undefined
|
|
81
|
+
? inputTokens + outputTokens
|
|
82
|
+
: undefined);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
model,
|
|
86
|
+
inputTokens,
|
|
87
|
+
outputTokens,
|
|
88
|
+
totalTokens,
|
|
89
|
+
costUsd: usage?.cost,
|
|
90
|
+
cachedInputTokens: usage?.promptTokensDetails?.cachedTokens,
|
|
91
|
+
reasoningTokens: usage?.completionTokensDetails?.reasoningTokens,
|
|
92
|
+
} as LanguageModelUsageWithCostUsd;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Extract OpenRouter generation ID for trace correlation
|
|
97
|
+
*/
|
|
98
|
+
static extractGenerationId(
|
|
99
|
+
providerMetadata: Record<string, unknown> | undefined
|
|
100
|
+
): string | undefined {
|
|
101
|
+
return (providerMetadata?.openrouter as OpenRouterProviderMetadata | undefined)?.id;
|
|
102
|
+
}
|
|
103
|
+
}
|