@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,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the reactive heuristic reminder system
|
|
3
|
+
*
|
|
4
|
+
* This module defines the core types for heuristics that provide
|
|
5
|
+
* real-time guidance to agents based on their actions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Context provided to heuristics for evaluation.
|
|
11
|
+
* All data is precomputed for O(1) access - NO expensive scans allowed.
|
|
12
|
+
* BLOCKER 3 FIX: Includes timestamp for deterministic violation IDs.
|
|
13
|
+
*/
|
|
14
|
+
export interface HeuristicContext {
|
|
15
|
+
/** Agent's public key */
|
|
16
|
+
agentPubkey: string;
|
|
17
|
+
|
|
18
|
+
/** Conversation ID */
|
|
19
|
+
conversationId: string;
|
|
20
|
+
|
|
21
|
+
/** Current RAL number */
|
|
22
|
+
ralNumber: number;
|
|
23
|
+
|
|
24
|
+
/** Timestamp when evaluation started (for deterministic IDs) */
|
|
25
|
+
evaluationTimestamp: number;
|
|
26
|
+
|
|
27
|
+
/** Tool that just executed */
|
|
28
|
+
tool: {
|
|
29
|
+
name: string;
|
|
30
|
+
callId: string;
|
|
31
|
+
args: unknown;
|
|
32
|
+
result: unknown;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Precomputed conversation state (O(1) lookups) */
|
|
36
|
+
state: {
|
|
37
|
+
/** Has TodoWrite been called in this RAL? */
|
|
38
|
+
hasTodoWrite: boolean;
|
|
39
|
+
|
|
40
|
+
/** Has delegation tool been called in this RAL? */
|
|
41
|
+
hasDelegation: boolean;
|
|
42
|
+
|
|
43
|
+
/** Count of pending delegations for this RAL */
|
|
44
|
+
pendingDelegationCount: number;
|
|
45
|
+
|
|
46
|
+
/** Current git branch (if available) */
|
|
47
|
+
currentBranch?: string;
|
|
48
|
+
|
|
49
|
+
/** Is this a worktree branch? */
|
|
50
|
+
isWorktreeBranch: boolean;
|
|
51
|
+
|
|
52
|
+
/** Has verification been performed? (e.g., tests, builds) */
|
|
53
|
+
hasVerification: boolean;
|
|
54
|
+
|
|
55
|
+
/** Has git-agent been used for commits? */
|
|
56
|
+
hasGitAgentCommit: boolean;
|
|
57
|
+
|
|
58
|
+
/** Total message count in conversation */
|
|
59
|
+
messageCount: number;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** Recent tool history (limited, bounded list) */
|
|
63
|
+
recentTools: Array<{
|
|
64
|
+
name: string;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A violation represents a heuristic rule that was broken.
|
|
71
|
+
* These are stored in RAL state and injected as warnings.
|
|
72
|
+
*/
|
|
73
|
+
export interface HeuristicViolation {
|
|
74
|
+
/** Unique ID for this violation type */
|
|
75
|
+
id: string;
|
|
76
|
+
|
|
77
|
+
/** Human-readable title */
|
|
78
|
+
title: string;
|
|
79
|
+
|
|
80
|
+
/** Detailed markdown message to show the agent */
|
|
81
|
+
message: string;
|
|
82
|
+
|
|
83
|
+
/** Severity level for prioritization */
|
|
84
|
+
severity: "warning" | "error";
|
|
85
|
+
|
|
86
|
+
/** Timestamp when violation was detected */
|
|
87
|
+
timestamp: number;
|
|
88
|
+
|
|
89
|
+
/** Which heuristic detected this */
|
|
90
|
+
heuristicId: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Result from evaluating a heuristic.
|
|
95
|
+
* null = no violation, HeuristicViolation = rule was broken
|
|
96
|
+
*/
|
|
97
|
+
export type HeuristicResult = HeuristicViolation | null;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* A heuristic is a pure, synchronous function that checks a rule.
|
|
101
|
+
* CRITICAL: Must be pure (no I/O, no async, no side effects)
|
|
102
|
+
*/
|
|
103
|
+
export interface Heuristic {
|
|
104
|
+
/** Unique identifier for this heuristic */
|
|
105
|
+
id: string;
|
|
106
|
+
|
|
107
|
+
/** Human-readable name */
|
|
108
|
+
name: string;
|
|
109
|
+
|
|
110
|
+
/** Description of what this heuristic checks */
|
|
111
|
+
description: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Evaluate the heuristic against the current context.
|
|
115
|
+
* MUST be pure and synchronous.
|
|
116
|
+
* MUST NOT throw exceptions (use try/catch in implementation).
|
|
117
|
+
*
|
|
118
|
+
* @param context - Precomputed O(1) context
|
|
119
|
+
* @returns Violation if rule broken, null otherwise
|
|
120
|
+
*/
|
|
121
|
+
evaluate: (context: HeuristicContext) => HeuristicResult;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Configuration for the heuristic engine
|
|
126
|
+
*/
|
|
127
|
+
export interface HeuristicEngineConfig {
|
|
128
|
+
/** Maximum warnings to show per LLM step (default: 3) */
|
|
129
|
+
maxWarningsPerStep?: number;
|
|
130
|
+
|
|
131
|
+
/** Enable debug logging */
|
|
132
|
+
debug?: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Internal state for tracking violations
|
|
137
|
+
*/
|
|
138
|
+
export interface ViolationState {
|
|
139
|
+
/** Pending violations waiting to be injected */
|
|
140
|
+
pending: HeuristicViolation[];
|
|
141
|
+
|
|
142
|
+
/** Violations shown in this RAL (for deduplication) */
|
|
143
|
+
shown: Set<string>;
|
|
144
|
+
}
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { fileExists, readJsonFile, writeJsonFile, ensureDirectory } from "@/lib/fs";
|
|
3
|
+
import { config } from "@/services/ConfigService";
|
|
4
|
+
import { resolveApiKey } from "@/services/config/types";
|
|
5
|
+
import { logger } from "@/utils/logger";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for image generation using OpenRouter
|
|
9
|
+
*/
|
|
10
|
+
export interface ImageConfig {
|
|
11
|
+
provider: "openrouter"; // Only OpenRouter is supported
|
|
12
|
+
model: string; // Model ID (e.g., "black-forest-labs/flux.2-pro")
|
|
13
|
+
defaultAspectRatio?: string; // Default aspect ratio (e.g., "16:9", "1:1", "9:16")
|
|
14
|
+
defaultImageSize?: string; // Default image size (e.g., "1K", "2K", "4K")
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Options for image generation
|
|
19
|
+
*/
|
|
20
|
+
export interface ImageGenerationOptions {
|
|
21
|
+
aspectRatio?: string;
|
|
22
|
+
imageSize?: string;
|
|
23
|
+
model?: string; // Override the default model
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Result of image generation
|
|
28
|
+
*/
|
|
29
|
+
export interface ImageResult {
|
|
30
|
+
base64: string;
|
|
31
|
+
mimeType: string;
|
|
32
|
+
model: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ImageConfigOptions {
|
|
36
|
+
metadataPath?: string;
|
|
37
|
+
projectPath?: string;
|
|
38
|
+
scope?: "auto" | "project" | "global";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Available OpenRouter image-capable models
|
|
43
|
+
*/
|
|
44
|
+
export const OPENROUTER_IMAGE_MODELS: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
value: string;
|
|
47
|
+
description: string;
|
|
48
|
+
}> = [
|
|
49
|
+
{
|
|
50
|
+
name: "FLUX.2 Pro",
|
|
51
|
+
value: "black-forest-labs/flux.2-pro",
|
|
52
|
+
description: "High quality text-to-image",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "FLUX.2 Max",
|
|
56
|
+
value: "black-forest-labs/flux.2-max",
|
|
57
|
+
description: "Top-tier quality",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "FLUX.2 Klein",
|
|
61
|
+
value: "black-forest-labs/flux.2-klein-4b",
|
|
62
|
+
description: "Fast, cost-effective",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "Gemini 2.5 Flash Image",
|
|
66
|
+
value: "google/gemini-2.5-flash-image",
|
|
67
|
+
description: "Multimodal with contextual understanding",
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Valid aspect ratios for OpenRouter image generation
|
|
73
|
+
*/
|
|
74
|
+
export const ASPECT_RATIOS = [
|
|
75
|
+
"1:1",
|
|
76
|
+
"16:9",
|
|
77
|
+
"9:16",
|
|
78
|
+
"4:3",
|
|
79
|
+
"3:4",
|
|
80
|
+
"3:2",
|
|
81
|
+
"2:3",
|
|
82
|
+
] as const;
|
|
83
|
+
export type AspectRatio = (typeof ASPECT_RATIOS)[number];
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Valid image sizes for OpenRouter image generation
|
|
87
|
+
*/
|
|
88
|
+
export const IMAGE_SIZES = ["1K", "2K", "4K"] as const;
|
|
89
|
+
export type ImageSize = (typeof IMAGE_SIZES)[number];
|
|
90
|
+
|
|
91
|
+
const IMAGE_CONFIG_FILE = "image.json";
|
|
92
|
+
const DEFAULT_CONFIG: ImageConfig = {
|
|
93
|
+
provider: "openrouter",
|
|
94
|
+
model: "black-forest-labs/flux.2-pro",
|
|
95
|
+
defaultAspectRatio: "1:1",
|
|
96
|
+
defaultImageSize: "2K",
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Service for AI image generation using OpenRouter via AI SDK
|
|
101
|
+
*
|
|
102
|
+
* OpenRouter uses the multimodal chat pattern - images are generated
|
|
103
|
+
* via generateText and returned as file parts in the response.
|
|
104
|
+
*/
|
|
105
|
+
export class ImageGenerationService {
|
|
106
|
+
private imageConfig: ImageConfig;
|
|
107
|
+
private apiKey: string;
|
|
108
|
+
|
|
109
|
+
private constructor(imageConfig: ImageConfig, apiKey: string) {
|
|
110
|
+
this.imageConfig = imageConfig;
|
|
111
|
+
this.apiKey = apiKey;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Create an ImageGenerationService with configuration
|
|
116
|
+
*/
|
|
117
|
+
static async create(
|
|
118
|
+
customConfig?: ImageConfig,
|
|
119
|
+
options?: ImageConfigOptions
|
|
120
|
+
): Promise<ImageGenerationService> {
|
|
121
|
+
const imageConfig = customConfig || (await ImageGenerationService.loadConfiguration(options));
|
|
122
|
+
|
|
123
|
+
// Load API key from providers.json - OpenRouter only
|
|
124
|
+
const apiKey = await ImageGenerationService.loadProviderApiKey("openrouter");
|
|
125
|
+
if (!apiKey) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
"OpenRouter API key required for image generation. Configure with 'tenex setup providers'."
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
logger.debug(`Creating image generation service: openrouter/${imageConfig.model}`);
|
|
132
|
+
return new ImageGenerationService(imageConfig, apiKey);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Generate an image from a text prompt using OpenRouter's multimodal chat pattern
|
|
137
|
+
*/
|
|
138
|
+
async generateImage(
|
|
139
|
+
prompt: string,
|
|
140
|
+
options: ImageGenerationOptions = {}
|
|
141
|
+
): Promise<ImageResult> {
|
|
142
|
+
const modelId = options.model || this.imageConfig.model;
|
|
143
|
+
const aspectRatio = options.aspectRatio || this.imageConfig.defaultAspectRatio || "1:1";
|
|
144
|
+
const imageSize = options.imageSize || this.imageConfig.defaultImageSize || "2K";
|
|
145
|
+
|
|
146
|
+
logger.info(`Generating image with openrouter/${modelId}`, {
|
|
147
|
+
prompt: prompt.slice(0, 100) + (prompt.length > 100 ? "..." : ""),
|
|
148
|
+
aspectRatio,
|
|
149
|
+
imageSize,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Dynamic import of dependencies
|
|
153
|
+
const { createOpenRouter } = await import("@openrouter/ai-sdk-provider");
|
|
154
|
+
const { generateText } = await import("ai");
|
|
155
|
+
|
|
156
|
+
const openrouter = createOpenRouter({
|
|
157
|
+
apiKey: this.apiKey,
|
|
158
|
+
headers: {
|
|
159
|
+
"X-Title": "TENEX",
|
|
160
|
+
"HTTP-Referer": "https://tenex.chat/",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
const result = await generateText({
|
|
166
|
+
model: openrouter.chat(modelId),
|
|
167
|
+
prompt,
|
|
168
|
+
providerOptions: {
|
|
169
|
+
openrouter: {
|
|
170
|
+
image_config: {
|
|
171
|
+
aspect_ratio: aspectRatio,
|
|
172
|
+
image_size: imageSize,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Extract image from response using the multimodal chat pattern
|
|
179
|
+
// OpenRouter returns images as file parts in the response content
|
|
180
|
+
const step = result.steps[0];
|
|
181
|
+
if (!step) {
|
|
182
|
+
throw new Error("No response step received from model");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Guard against missing response/messages
|
|
186
|
+
if (!step.response) {
|
|
187
|
+
throw new Error("No response object in step - unexpected API response format");
|
|
188
|
+
}
|
|
189
|
+
const message = step.response.messages?.[0];
|
|
190
|
+
if (!message) {
|
|
191
|
+
throw new Error("No message in response - model may have returned an empty response");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Find the file part containing the image
|
|
195
|
+
// Content can be string or array of parts
|
|
196
|
+
const content = message.content;
|
|
197
|
+
if (typeof content === "string") {
|
|
198
|
+
throw new Error("Model returned text instead of an image. Try a different image-capable model.");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Type for OpenRouter response content parts (not fully covered by AI SDK types)
|
|
202
|
+
type ContentPart = { type: string; mediaType?: string; data?: string; text?: string };
|
|
203
|
+
const contentParts = content as ContentPart[];
|
|
204
|
+
|
|
205
|
+
const imagePart = contentParts.find(
|
|
206
|
+
(part) => part.type === "file" && part.mediaType?.startsWith("image/")
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
if (!imagePart) {
|
|
210
|
+
// Check if we got text response instead
|
|
211
|
+
const textPart = contentParts.find((part) => part.type === "text");
|
|
212
|
+
if (textPart) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`Model returned text instead of image: "${textPart.text?.slice(0, 100) || 'unknown'}". ` +
|
|
215
|
+
"This model may not support image generation."
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
throw new Error("No image found in model response");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!imagePart.data) {
|
|
222
|
+
throw new Error("Image part found but contains no data");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
logger.info(`Image generated successfully`, {
|
|
226
|
+
model: modelId,
|
|
227
|
+
mediaType: imagePart.mediaType,
|
|
228
|
+
hasData: !!imagePart.data,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
base64: imagePart.data,
|
|
233
|
+
mimeType: imagePart.mediaType || "image/png",
|
|
234
|
+
model: modelId,
|
|
235
|
+
};
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// Handle common API errors with cause preservation
|
|
238
|
+
if (error instanceof Error) {
|
|
239
|
+
const errorMessage = error.message.toLowerCase();
|
|
240
|
+
|
|
241
|
+
if (errorMessage.includes("content_policy") || errorMessage.includes("safety")) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
"Image generation blocked: The prompt was rejected due to content policy. " +
|
|
244
|
+
"Please modify your prompt to comply with content guidelines.",
|
|
245
|
+
{ cause: error }
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (errorMessage.includes("rate_limit") || errorMessage.includes("429")) {
|
|
250
|
+
throw new Error(
|
|
251
|
+
"Rate limit exceeded: Too many image generation requests. " +
|
|
252
|
+
"Please wait a moment before trying again.",
|
|
253
|
+
{ cause: error }
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (errorMessage.includes("billing") || errorMessage.includes("quota") || errorMessage.includes("insufficient")) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
"Billing issue: Your OpenRouter account may have exceeded its quota or " +
|
|
260
|
+
"have insufficient credits. Please check your OpenRouter account.",
|
|
261
|
+
{ cause: error }
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (errorMessage.includes("model") && errorMessage.includes("not found")) {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Model "${modelId}" not found. Run 'tenex setup image' to select a valid model.`,
|
|
268
|
+
{ cause: error }
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Re-throw other errors
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Load image configuration
|
|
280
|
+
*/
|
|
281
|
+
static async loadConfiguration(options?: ImageConfigOptions): Promise<ImageConfig> {
|
|
282
|
+
try {
|
|
283
|
+
const basePaths = ImageGenerationService.resolveConfigBases(options);
|
|
284
|
+
|
|
285
|
+
for (const basePath of basePaths) {
|
|
286
|
+
const configPath = path.join(basePath, IMAGE_CONFIG_FILE);
|
|
287
|
+
if (!(await fileExists(configPath))) continue;
|
|
288
|
+
|
|
289
|
+
const rawConfig = await readJsonFile<ImageConfig>(configPath);
|
|
290
|
+
logger.debug(`Loaded image config from ${configPath}`);
|
|
291
|
+
return { ...DEFAULT_CONFIG, ...rawConfig };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
logger.debug("No image configuration found, using defaults");
|
|
295
|
+
return DEFAULT_CONFIG;
|
|
296
|
+
} catch (error) {
|
|
297
|
+
logger.warn("Failed to load image configuration, using defaults", { error });
|
|
298
|
+
return DEFAULT_CONFIG;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Save image configuration
|
|
304
|
+
*/
|
|
305
|
+
static async saveConfiguration(
|
|
306
|
+
imageConfig: ImageConfig,
|
|
307
|
+
scope: "global" | "project" = "global",
|
|
308
|
+
options?: ImageConfigOptions
|
|
309
|
+
): Promise<void> {
|
|
310
|
+
const basePath =
|
|
311
|
+
scope === "global"
|
|
312
|
+
? config.getGlobalPath()
|
|
313
|
+
: ImageGenerationService.resolveProjectBase(options) ||
|
|
314
|
+
config.getProjectPath(process.cwd());
|
|
315
|
+
|
|
316
|
+
const configPath = path.join(basePath, IMAGE_CONFIG_FILE);
|
|
317
|
+
|
|
318
|
+
// Don't save API key to file - it's stored in providers.json
|
|
319
|
+
const configToSave: ImageConfig = {
|
|
320
|
+
provider: "openrouter",
|
|
321
|
+
model: imageConfig.model,
|
|
322
|
+
defaultAspectRatio: imageConfig.defaultAspectRatio,
|
|
323
|
+
defaultImageSize: imageConfig.defaultImageSize,
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
await ensureDirectory(basePath);
|
|
327
|
+
await writeJsonFile(configPath, configToSave);
|
|
328
|
+
|
|
329
|
+
logger.info(
|
|
330
|
+
`Image configuration saved to ${scope} config: openrouter/${imageConfig.model}`
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Load provider API key from providers.json
|
|
336
|
+
*/
|
|
337
|
+
private static async loadProviderApiKey(providerId: string): Promise<string | undefined> {
|
|
338
|
+
try {
|
|
339
|
+
const globalPath = config.getGlobalPath();
|
|
340
|
+
const providersConfig = await config.loadTenexProviders(globalPath);
|
|
341
|
+
return resolveApiKey(providersConfig.providers[providerId]?.apiKey);
|
|
342
|
+
} catch (error) {
|
|
343
|
+
logger.debug(`Failed to load API key for ${providerId}`, { error });
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Check if OpenRouter is configured with API key
|
|
350
|
+
*/
|
|
351
|
+
static async isConfigured(): Promise<boolean> {
|
|
352
|
+
const apiKey = await ImageGenerationService.loadProviderApiKey("openrouter");
|
|
353
|
+
return !!apiKey;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Get the current configuration (for display purposes)
|
|
358
|
+
*/
|
|
359
|
+
getConfig(): ImageConfig {
|
|
360
|
+
return { ...this.imageConfig };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
private static resolveConfigBases(options?: ImageConfigOptions): string[] {
|
|
364
|
+
const scope = options?.scope ?? "auto";
|
|
365
|
+
const bases: string[] = [];
|
|
366
|
+
|
|
367
|
+
if (scope !== "global") {
|
|
368
|
+
const projectBase = ImageGenerationService.resolveProjectBase(options);
|
|
369
|
+
if (projectBase) {
|
|
370
|
+
bases.push(projectBase);
|
|
371
|
+
} else if (!options) {
|
|
372
|
+
bases.push(config.getProjectPath(process.cwd()));
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
bases.push(config.getGlobalPath());
|
|
377
|
+
return bases;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private static resolveProjectBase(options?: ImageConfigOptions): string | undefined {
|
|
381
|
+
if (options?.metadataPath) {
|
|
382
|
+
return options.metadataPath;
|
|
383
|
+
}
|
|
384
|
+
if (options?.projectPath) {
|
|
385
|
+
return config.getProjectPath(options.projectPath);
|
|
386
|
+
}
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export {
|
|
2
|
+
ImageGenerationService,
|
|
3
|
+
type ImageConfig,
|
|
4
|
+
type ImageGenerationOptions,
|
|
5
|
+
type ImageResult,
|
|
6
|
+
type ImageConfigOptions,
|
|
7
|
+
type AspectRatio,
|
|
8
|
+
type ImageSize,
|
|
9
|
+
OPENROUTER_IMAGE_MODELS,
|
|
10
|
+
ASPECT_RATIOS,
|
|
11
|
+
IMAGE_SIZES,
|
|
12
|
+
} from "./ImageGenerationService";
|