@within-7/minto 0.3.9 → 0.4.0
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/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +461 -657
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +684 -94
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +425 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +457 -65
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +891 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +146 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +590 -565
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +26 -11
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +123 -48
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +11 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +21 -3
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +81 -68
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +299 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +300 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +20 -9
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +367 -9
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +8 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +84 -11
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +3 -5
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +91 -15
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +27 -151
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +68 -29
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +249 -57
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +77 -12
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +162 -16
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { getTheme } from "../../utils/theme.js";
|
|
4
|
-
import { Select } from "../CustomSelect/select.js";
|
|
2
|
+
import { Text, useInput } from "ink";
|
|
5
3
|
import { getModelManager } from "../../utils/model.js";
|
|
6
4
|
import { useExitOnCtrlCD } from "../../hooks/useExitOnCtrlCD.js";
|
|
7
5
|
import {
|
|
@@ -10,9 +8,7 @@ import {
|
|
|
10
8
|
setModelPointer
|
|
11
9
|
} from "../../utils/config.js";
|
|
12
10
|
import models, { providers } from "../../constants/models.js";
|
|
13
|
-
import TextInput from "../TextInput.js";
|
|
14
11
|
import OpenAI from "openai";
|
|
15
|
-
import chalk from "chalk";
|
|
16
12
|
import { verifyApiKey } from "../../services/claude.js";
|
|
17
13
|
import { fetchCustomModels } from "../../services/openai.js";
|
|
18
14
|
import {
|
|
@@ -20,44 +16,32 @@ import {
|
|
|
20
16
|
validateGPT5Config
|
|
21
17
|
} from "../../services/gpt5ConnectionTest.js";
|
|
22
18
|
import { SEMANTIC_COLORS } from "../../constants/colors.js";
|
|
23
|
-
import {
|
|
19
|
+
import { isOpenAICompatibleProvider } from "../../constants/providers.js";
|
|
20
|
+
import { getEffectiveCapabilities } from "../../constants/providerRegistry.js";
|
|
21
|
+
import { t } from "../../i18n/index.js";
|
|
22
|
+
import { SimpleSelector } from "../SimpleSelector/SimpleSelector.js";
|
|
23
|
+
import { InfoPanel } from "../InfoPanel/InfoPanel.js";
|
|
24
|
+
import { BrandTextInput } from "./BrandTextInput.js";
|
|
24
25
|
import {
|
|
25
26
|
CONTEXT_LENGTH_OPTIONS,
|
|
26
27
|
DEFAULT_CONTEXT_LENGTH,
|
|
27
28
|
MAX_TOKENS_OPTIONS,
|
|
28
29
|
DEFAULT_MAX_TOKENS
|
|
29
30
|
} from "./constants.js";
|
|
30
|
-
import { useEscapeNavigation } from "./hooks/index.js";
|
|
31
|
-
function printModelConfig() {
|
|
32
|
-
const config = getGlobalConfig();
|
|
33
|
-
const modelProfiles = config.modelProfiles || [];
|
|
34
|
-
const activeProfiles = modelProfiles.filter((p) => p.isActive);
|
|
35
|
-
if (activeProfiles.length === 0) {
|
|
36
|
-
console.log(chalk.gray(" \u23BF No active model profiles configured"));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const profileSummary = activeProfiles.map((p) => `${p.name} (${p.provider}: ${p.modelName})`).join(" | ");
|
|
40
|
-
console.log(chalk.gray(` \u23BF ${profileSummary}`));
|
|
41
|
-
}
|
|
42
31
|
function ModelSelector({
|
|
43
32
|
onDone: onDoneProp,
|
|
44
33
|
abortController,
|
|
45
34
|
targetPointer,
|
|
46
35
|
isOnboarding = false,
|
|
47
36
|
onCancel,
|
|
48
|
-
skipModelType = false
|
|
37
|
+
skipModelType = false,
|
|
38
|
+
editingModel
|
|
49
39
|
}) {
|
|
50
40
|
const config = getGlobalConfig();
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
const exitState = useExitOnCtrlCD(() => process.exit(0));
|
|
57
|
-
const getInitialScreen = () => {
|
|
58
|
-
return "provider";
|
|
59
|
-
};
|
|
60
|
-
const [screenStack, setScreenStack] = useState([getInitialScreen()]);
|
|
41
|
+
const onDone = onDoneProp;
|
|
42
|
+
useExitOnCtrlCD(() => process.exit(0));
|
|
43
|
+
const isEditMode = !!editingModel;
|
|
44
|
+
const [screenStack, setScreenStack] = useState([isEditMode ? "testAndSave" : "provider"]);
|
|
61
45
|
const currentScreen = screenStack[screenStack.length - 1];
|
|
62
46
|
const navigateTo = (screen) => {
|
|
63
47
|
setScreenStack((prev) => [...prev, screen]);
|
|
@@ -70,22 +54,26 @@ function ModelSelector({
|
|
|
70
54
|
}
|
|
71
55
|
};
|
|
72
56
|
const [selectedProvider, setSelectedProvider] = useState(
|
|
73
|
-
config.primaryProvider ?? "anthropic"
|
|
57
|
+
editingModel?.provider ?? config.primaryProvider ?? "anthropic"
|
|
74
58
|
);
|
|
75
59
|
const [anthropicProviderType, setAnthropicProviderType] = useState("official");
|
|
76
|
-
const [selectedModel, setSelectedModel] = useState(
|
|
77
|
-
|
|
60
|
+
const [selectedModel, setSelectedModel] = useState(
|
|
61
|
+
editingModel?.modelName ?? ""
|
|
62
|
+
);
|
|
63
|
+
const [apiKey, setApiKey] = useState(editingModel?.apiKey ?? "");
|
|
78
64
|
const [maxTokens, setMaxTokens] = useState(
|
|
79
|
-
config.maxTokens?.toString()
|
|
65
|
+
editingModel?.maxTokens?.toString() ?? config.maxTokens?.toString() ?? DEFAULT_MAX_TOKENS.toString()
|
|
80
66
|
);
|
|
81
67
|
const [maxTokensMode, setMaxTokensMode] = useState(
|
|
82
68
|
"preset"
|
|
83
69
|
);
|
|
84
70
|
const [selectedMaxTokensPreset, setSelectedMaxTokensPreset] = useState(config.maxTokens || DEFAULT_MAX_TOKENS);
|
|
85
|
-
const [reasoningEffort, setReasoningEffort] = useState(
|
|
86
|
-
|
|
71
|
+
const [reasoningEffort, setReasoningEffort] = useState(
|
|
72
|
+
editingModel?.reasoningEffort ?? "medium"
|
|
73
|
+
);
|
|
74
|
+
const [supportsReasoningEffort, setSupportsReasoningEffort] = useState(!!editingModel?.reasoningEffort);
|
|
87
75
|
const [contextLength, setContextLength] = useState(
|
|
88
|
-
DEFAULT_CONTEXT_LENGTH
|
|
76
|
+
editingModel?.contextLength ?? DEFAULT_CONTEXT_LENGTH
|
|
89
77
|
);
|
|
90
78
|
const [activeFieldIndex, setActiveFieldIndex] = useState(0);
|
|
91
79
|
const [maxTokensCursorOffset, setMaxTokensCursorOffset] = useState(0);
|
|
@@ -95,12 +83,13 @@ function ModelSelector({
|
|
|
95
83
|
const [modelSearchQuery, setModelSearchQuery] = useState("");
|
|
96
84
|
const [modelSearchCursorOffset, setModelSearchCursorOffset] = useState(0);
|
|
97
85
|
const [cursorOffset, setCursorOffset] = useState(0);
|
|
98
|
-
const [apiKeyEdited, setApiKeyEdited] = useState(
|
|
86
|
+
const [apiKeyEdited, setApiKeyEdited] = useState(isEditMode);
|
|
99
87
|
const [fetchRetryCount, setFetchRetryCount] = useState(0);
|
|
100
88
|
const [isRetrying, setIsRetrying] = useState(false);
|
|
101
89
|
const [isTestingConnection, setIsTestingConnection] = useState(false);
|
|
102
90
|
const [connectionTestResult, setConnectionTestResult] = useState(null);
|
|
103
91
|
const [validationError, setValidationError] = useState(null);
|
|
92
|
+
const [isManualModelEntry, setIsManualModelEntry] = useState(false);
|
|
104
93
|
const [resourceName, setResourceName] = useState("");
|
|
105
94
|
const [resourceNameCursorOffset, setResourceNameCursorOffset] = useState(0);
|
|
106
95
|
const [customModelName, setCustomModelName] = useState("");
|
|
@@ -111,7 +100,9 @@ function ModelSelector({
|
|
|
111
100
|
const [ollamaBaseUrlCursorOffset, setOllamaBaseUrlCursorOffset] = useState(0);
|
|
112
101
|
const [customBaseUrl, setCustomBaseUrl] = useState("");
|
|
113
102
|
const [customBaseUrlCursorOffset, setCustomBaseUrlCursorOffset] = useState(0);
|
|
114
|
-
const [providerBaseUrl, setProviderBaseUrl] = useState(
|
|
103
|
+
const [providerBaseUrl, setProviderBaseUrl] = useState(
|
|
104
|
+
editingModel?.baseURL ?? ""
|
|
105
|
+
);
|
|
115
106
|
const [providerBaseUrlCursorOffset, setProviderBaseUrlCursorOffset] = useState(0);
|
|
116
107
|
const reasoningEffortOptions = [
|
|
117
108
|
{ label: "Low - Faster responses, less thorough reasoning", value: "low" },
|
|
@@ -148,6 +139,11 @@ function ModelSelector({
|
|
|
148
139
|
setContextLength(DEFAULT_CONTEXT_LENGTH);
|
|
149
140
|
}
|
|
150
141
|
}, [currentScreen, contextLength]);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (currentScreen === "testAndSave" && !isEditMode && !isTestingConnection && !connectionTestResult) {
|
|
144
|
+
handleConnectionTest();
|
|
145
|
+
}
|
|
146
|
+
}, [currentScreen]);
|
|
151
147
|
const ourModelNames = new Set(
|
|
152
148
|
(models[selectedProvider] || []).map(
|
|
153
149
|
(model) => model.model
|
|
@@ -240,7 +236,8 @@ function ModelSelector({
|
|
|
240
236
|
"anthropic-version": "2023-06-01",
|
|
241
237
|
"Content-Type": "application/json",
|
|
242
238
|
Authorization: `Bearer ${apiKey2}`
|
|
243
|
-
}
|
|
239
|
+
},
|
|
240
|
+
signal: AbortSignal.timeout(3e4)
|
|
244
241
|
});
|
|
245
242
|
if (!response.ok) {
|
|
246
243
|
if (response.status === 401) {
|
|
@@ -305,10 +302,6 @@ function ModelSelector({
|
|
|
305
302
|
}));
|
|
306
303
|
} catch (error) {
|
|
307
304
|
lastError = error;
|
|
308
|
-
console.log(
|
|
309
|
-
`Anthropic API failed for ${provider}, trying OpenAI format:`,
|
|
310
|
-
error
|
|
311
|
-
);
|
|
312
305
|
}
|
|
313
306
|
try {
|
|
314
307
|
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
@@ -322,10 +315,6 @@ function ModelSelector({
|
|
|
322
315
|
}));
|
|
323
316
|
} catch (error) {
|
|
324
317
|
lastError = error;
|
|
325
|
-
console.log(
|
|
326
|
-
`OpenAI API failed for ${provider}, falling back to manual input:`,
|
|
327
|
-
error
|
|
328
|
-
);
|
|
329
318
|
}
|
|
330
319
|
let errorMessage = `Failed to fetch ${provider} models using both Anthropic and OpenAI API formats`;
|
|
331
320
|
if (lastError) {
|
|
@@ -622,7 +611,8 @@ function ModelSelector({
|
|
|
622
611
|
async function fetchGeminiModels() {
|
|
623
612
|
try {
|
|
624
613
|
const response = await fetch(
|
|
625
|
-
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}
|
|
614
|
+
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`,
|
|
615
|
+
{ signal: AbortSignal.timeout(3e4) }
|
|
626
616
|
);
|
|
627
617
|
if (!response.ok) {
|
|
628
618
|
const errorData = await response.json();
|
|
@@ -650,7 +640,9 @@ function ModelSelector({
|
|
|
650
640
|
}
|
|
651
641
|
async function fetchOllamaModels() {
|
|
652
642
|
try {
|
|
653
|
-
const response = await fetch(`${ollamaBaseUrl}/models
|
|
643
|
+
const response = await fetch(`${ollamaBaseUrl}/models`, {
|
|
644
|
+
signal: AbortSignal.timeout(3e4)
|
|
645
|
+
});
|
|
654
646
|
if (!response.ok) {
|
|
655
647
|
throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
|
|
656
648
|
}
|
|
@@ -732,7 +724,8 @@ function ModelSelector({
|
|
|
732
724
|
const showResp = await fetch(`${ollamaRoot}/api/show`, {
|
|
733
725
|
method: "POST",
|
|
734
726
|
headers: { "Content-Type": "application/json" },
|
|
735
|
-
body: JSON.stringify({ name: m.model })
|
|
727
|
+
body: JSON.stringify({ name: m.model }),
|
|
728
|
+
signal: AbortSignal.timeout(3e4)
|
|
736
729
|
});
|
|
737
730
|
if (showResp.ok) {
|
|
738
731
|
const showData = await showResp.json();
|
|
@@ -763,7 +756,6 @@ function ModelSelector({
|
|
|
763
756
|
} else {
|
|
764
757
|
setModelLoadError(`Error loading Ollama models: ${errorMessage}`);
|
|
765
758
|
}
|
|
766
|
-
console.error("Error fetching Ollama models:", error);
|
|
767
759
|
return [];
|
|
768
760
|
}
|
|
769
761
|
}
|
|
@@ -787,7 +779,6 @@ function ModelSelector({
|
|
|
787
779
|
return models2;
|
|
788
780
|
} catch (error) {
|
|
789
781
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
790
|
-
console.log(`Model fetch attempt ${attempt} failed:`, lastError.message);
|
|
791
782
|
if (attempt === MAX_RETRIES) {
|
|
792
783
|
break;
|
|
793
784
|
}
|
|
@@ -915,7 +906,6 @@ function ModelSelector({
|
|
|
915
906
|
navigateTo("model");
|
|
916
907
|
return fetchedModels;
|
|
917
908
|
} catch (error) {
|
|
918
|
-
console.error("Error fetching models:", error);
|
|
919
909
|
throw error;
|
|
920
910
|
} finally {
|
|
921
911
|
setIsLoadingModels(false);
|
|
@@ -923,12 +913,15 @@ function ModelSelector({
|
|
|
923
913
|
}
|
|
924
914
|
function handleApiKeySubmit(key) {
|
|
925
915
|
setApiKey(key);
|
|
916
|
+
if (isEditMode) {
|
|
917
|
+
goBack();
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
926
920
|
if (selectedProvider === "azure") {
|
|
927
921
|
navigateTo("resourceName");
|
|
928
922
|
return;
|
|
929
923
|
}
|
|
930
|
-
fetchModelsWithRetry().catch((
|
|
931
|
-
console.error("Final error after retries:", error);
|
|
924
|
+
fetchModelsWithRetry().catch(() => {
|
|
932
925
|
});
|
|
933
926
|
}
|
|
934
927
|
function handleResourceNameSubmit(name) {
|
|
@@ -946,11 +939,20 @@ function ModelSelector({
|
|
|
946
939
|
function handleCustomBaseUrlSubmit(url) {
|
|
947
940
|
const cleanUrl = url.replace(/\/+$/, "");
|
|
948
941
|
setCustomBaseUrl(cleanUrl);
|
|
942
|
+
setProviderBaseUrl(cleanUrl);
|
|
943
|
+
if (isEditMode) {
|
|
944
|
+
goBack();
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
949
947
|
navigateTo("apiKey");
|
|
950
948
|
}
|
|
951
949
|
function handleProviderBaseUrlSubmit(url) {
|
|
952
950
|
const cleanUrl = url.replace(/\/+$/, "");
|
|
953
951
|
setProviderBaseUrl(cleanUrl);
|
|
952
|
+
if (isEditMode) {
|
|
953
|
+
goBack();
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
954
956
|
if (selectedProvider === "ollama") {
|
|
955
957
|
setOllamaBaseUrl(cleanUrl);
|
|
956
958
|
setIsLoadingModels(true);
|
|
@@ -980,6 +982,7 @@ function ModelSelector({
|
|
|
980
982
|
function handleCustomModelSubmit(model) {
|
|
981
983
|
setCustomModelName(model);
|
|
982
984
|
setSelectedModel(model);
|
|
985
|
+
setIsManualModelEntry(true);
|
|
983
986
|
setSupportsReasoningEffort(false);
|
|
984
987
|
setReasoningEffort(null);
|
|
985
988
|
setMaxTokensMode("preset");
|
|
@@ -991,6 +994,7 @@ function ModelSelector({
|
|
|
991
994
|
}
|
|
992
995
|
function handleModelSelection(model) {
|
|
993
996
|
setSelectedModel(model);
|
|
997
|
+
setIsManualModelEntry(false);
|
|
994
998
|
const modelInfo = availableModels.find((m) => m.model === model);
|
|
995
999
|
setSupportsReasoningEffort(modelInfo?.supports_reasoning_effort || false);
|
|
996
1000
|
if (!modelInfo?.supports_reasoning_effort) {
|
|
@@ -1025,6 +1029,17 @@ function ModelSelector({
|
|
|
1025
1029
|
setActiveFieldIndex(0);
|
|
1026
1030
|
}
|
|
1027
1031
|
const handleModelParamsSubmit = () => {
|
|
1032
|
+
if (isEditMode) {
|
|
1033
|
+
goBack();
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
if (!isManualModelEntry) {
|
|
1037
|
+
const modelInfo = availableModels.find((m) => m.model === selectedModel);
|
|
1038
|
+
if (modelInfo?.context_length || modelInfo?.max_input_tokens) {
|
|
1039
|
+
navigateTo("testAndSave");
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1028
1043
|
if (!CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength)) {
|
|
1029
1044
|
setContextLength(DEFAULT_CONTEXT_LENGTH);
|
|
1030
1045
|
}
|
|
@@ -1040,26 +1055,9 @@ function ModelSelector({
|
|
|
1040
1055
|
} else if (selectedProvider === "custom-openai") {
|
|
1041
1056
|
testBaseURL = customBaseUrl;
|
|
1042
1057
|
}
|
|
1043
|
-
|
|
1044
|
-
"minimax",
|
|
1045
|
-
"kimi",
|
|
1046
|
-
"deepseek",
|
|
1047
|
-
"siliconflow",
|
|
1048
|
-
"qwen",
|
|
1049
|
-
"glm",
|
|
1050
|
-
"baidu-qianfan",
|
|
1051
|
-
"openai",
|
|
1052
|
-
"mistral",
|
|
1053
|
-
"xai",
|
|
1054
|
-
"groq",
|
|
1055
|
-
"custom-openai"
|
|
1056
|
-
].includes(selectedProvider);
|
|
1057
|
-
if (isOpenAICompatible) {
|
|
1058
|
+
if (isOpenAICompatibleProvider(selectedProvider)) {
|
|
1058
1059
|
const isGPT5 = selectedModel?.toLowerCase().includes("gpt-5");
|
|
1059
1060
|
if (isGPT5) {
|
|
1060
|
-
console.log(
|
|
1061
|
-
`\u{1F680} Using specialized GPT-5 connection test for model: ${selectedModel}`
|
|
1062
|
-
);
|
|
1063
1061
|
const configValidation = validateGPT5Config({
|
|
1064
1062
|
model: selectedModel,
|
|
1065
1063
|
apiKey,
|
|
@@ -1152,20 +1150,19 @@ function ModelSelector({
|
|
|
1152
1150
|
temperature: 0,
|
|
1153
1151
|
stream: false
|
|
1154
1152
|
};
|
|
1155
|
-
if (selectedModel &&
|
|
1156
|
-
|
|
1157
|
-
if (testPayload.max_tokens) {
|
|
1158
|
-
testPayload.
|
|
1153
|
+
if (selectedModel && selectedProvider) {
|
|
1154
|
+
const caps = getEffectiveCapabilities(selectedProvider, selectedModel);
|
|
1155
|
+
if (caps.maxTokensField !== "max_tokens" && testPayload.max_tokens) {
|
|
1156
|
+
testPayload[caps.maxTokensField] = testPayload.max_tokens;
|
|
1159
1157
|
delete testPayload.max_tokens;
|
|
1160
|
-
console.log(
|
|
1161
|
-
`Transformed max_tokens \u2192 max_completion_tokens: ${testPayload.max_completion_tokens}`
|
|
1162
|
-
);
|
|
1163
1158
|
}
|
|
1164
|
-
if (
|
|
1165
|
-
|
|
1166
|
-
|
|
1159
|
+
if (caps.temperatureRange === "omit") {
|
|
1160
|
+
delete testPayload.temperature;
|
|
1161
|
+
} else if (typeof caps.temperatureRange === "object") {
|
|
1162
|
+
testPayload.temperature = Math.min(
|
|
1163
|
+
testPayload.temperature,
|
|
1164
|
+
caps.temperatureRange.max
|
|
1167
1165
|
);
|
|
1168
|
-
testPayload.temperature = 1;
|
|
1169
1166
|
}
|
|
1170
1167
|
}
|
|
1171
1168
|
const headers = {
|
|
@@ -1180,14 +1177,11 @@ function ModelSelector({
|
|
|
1180
1177
|
const response = await fetch(testURL, {
|
|
1181
1178
|
method: "POST",
|
|
1182
1179
|
headers,
|
|
1183
|
-
body: JSON.stringify(testPayload)
|
|
1180
|
+
body: JSON.stringify(testPayload),
|
|
1181
|
+
signal: AbortSignal.timeout(3e4)
|
|
1184
1182
|
});
|
|
1185
1183
|
if (response.ok) {
|
|
1186
1184
|
const data = await response.json();
|
|
1187
|
-
console.log(
|
|
1188
|
-
"[DEBUG] Connection test response:",
|
|
1189
|
-
JSON.stringify(data, null, 2)
|
|
1190
|
-
);
|
|
1191
1185
|
let responseContent = "";
|
|
1192
1186
|
if (data.choices && data.choices.length > 0) {
|
|
1193
1187
|
responseContent = data.choices[0]?.message?.content || "";
|
|
@@ -1196,7 +1190,6 @@ function ModelSelector({
|
|
|
1196
1190
|
} else if (data.output) {
|
|
1197
1191
|
responseContent = data.output?.text || data.output || "";
|
|
1198
1192
|
}
|
|
1199
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1200
1193
|
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1201
1194
|
if (containsYes) {
|
|
1202
1195
|
return {
|
|
@@ -1251,9 +1244,6 @@ function ModelSelector({
|
|
|
1251
1244
|
// Fast response for connection test
|
|
1252
1245
|
}
|
|
1253
1246
|
};
|
|
1254
|
-
console.log(`\u{1F527} Testing GPT-5 Responses API for model: ${selectedModel}`);
|
|
1255
|
-
console.log(`\u{1F527} Test URL: ${testURL}`);
|
|
1256
|
-
console.log(`\u{1F527} Test payload:`, JSON.stringify(testPayload, null, 2));
|
|
1257
1247
|
const headers = {
|
|
1258
1248
|
"Content-Type": "application/json",
|
|
1259
1249
|
Authorization: `Bearer ${apiKey}`
|
|
@@ -1262,21 +1252,17 @@ function ModelSelector({
|
|
|
1262
1252
|
const response = await fetch(testURL, {
|
|
1263
1253
|
method: "POST",
|
|
1264
1254
|
headers,
|
|
1265
|
-
body: JSON.stringify(testPayload)
|
|
1255
|
+
body: JSON.stringify(testPayload),
|
|
1256
|
+
signal: AbortSignal.timeout(3e4)
|
|
1266
1257
|
});
|
|
1267
1258
|
if (response.ok) {
|
|
1268
1259
|
const data = await response.json();
|
|
1269
|
-
console.log(
|
|
1270
|
-
"[DEBUG] Responses API connection test response:",
|
|
1271
|
-
JSON.stringify(data, null, 2)
|
|
1272
|
-
);
|
|
1273
1260
|
let responseContent = "";
|
|
1274
1261
|
if (data.output_text) {
|
|
1275
1262
|
responseContent = data.output_text;
|
|
1276
1263
|
} else if (data.output) {
|
|
1277
1264
|
responseContent = typeof data.output === "string" ? data.output : data.output.text || "";
|
|
1278
1265
|
}
|
|
1279
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1280
1266
|
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1281
1267
|
if (containsYes) {
|
|
1282
1268
|
return {
|
|
@@ -1296,10 +1282,6 @@ function ModelSelector({
|
|
|
1296
1282
|
} else {
|
|
1297
1283
|
const errorData = await response.json().catch(() => null);
|
|
1298
1284
|
const errorMessage = errorData?.error?.message || errorData?.message || response.statusText;
|
|
1299
|
-
console.log(
|
|
1300
|
-
`\u{1F6A8} GPT-5 Responses API Error (${response.status}):`,
|
|
1301
|
-
errorData
|
|
1302
|
-
);
|
|
1303
1285
|
let details = `Responses API Error: ${errorMessage}`;
|
|
1304
1286
|
if (response.status === 400 && errorMessage.includes("max_tokens")) {
|
|
1305
1287
|
details += "\n\u{1F527} Note: This appears to be a parameter compatibility issue. The fallback to Chat Completions should handle this.";
|
|
@@ -1327,9 +1309,6 @@ function ModelSelector({
|
|
|
1327
1309
|
async function testProviderSpecificEndpoint(baseURL) {
|
|
1328
1310
|
if (selectedProvider === "anthropic" || selectedProvider === "bigdream") {
|
|
1329
1311
|
try {
|
|
1330
|
-
console.log(
|
|
1331
|
-
`[DEBUG] Testing ${selectedProvider} connection using official Anthropic SDK...`
|
|
1332
|
-
);
|
|
1333
1312
|
let testBaseURL = void 0;
|
|
1334
1313
|
if (selectedProvider === "bigdream") {
|
|
1335
1314
|
testBaseURL = baseURL || "https://api-key.info";
|
|
@@ -1357,7 +1336,6 @@ function ModelSelector({
|
|
|
1357
1336
|
};
|
|
1358
1337
|
}
|
|
1359
1338
|
} catch (error) {
|
|
1360
|
-
console.log(`[DEBUG] ${selectedProvider} connection test error:`, error);
|
|
1361
1339
|
return {
|
|
1362
1340
|
success: false,
|
|
1363
1341
|
message: `\u274C ${selectedProvider} connection failed`,
|
|
@@ -1375,14 +1353,13 @@ function ModelSelector({
|
|
|
1375
1353
|
async function handleConnectionTest() {
|
|
1376
1354
|
const result = await testConnection();
|
|
1377
1355
|
setConnectionTestResult(result);
|
|
1378
|
-
if (result.success) {
|
|
1379
|
-
setTimeout(() => {
|
|
1380
|
-
navigateTo("confirmation");
|
|
1381
|
-
}, 2e3);
|
|
1382
|
-
}
|
|
1383
1356
|
}
|
|
1384
1357
|
const handleContextLengthSubmit = () => {
|
|
1385
|
-
|
|
1358
|
+
if (isEditMode) {
|
|
1359
|
+
goBack();
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
navigateTo("testAndSave");
|
|
1386
1363
|
};
|
|
1387
1364
|
async function saveConfiguration(provider, model) {
|
|
1388
1365
|
let baseURL = providerBaseUrl || providers[provider]?.baseURL || "";
|
|
@@ -1429,6 +1406,24 @@ function ModelSelector({
|
|
|
1429
1406
|
}
|
|
1430
1407
|
async function handleConfirmation() {
|
|
1431
1408
|
setValidationError(null);
|
|
1409
|
+
if (isEditMode && editingModel) {
|
|
1410
|
+
try {
|
|
1411
|
+
const modelManager = getModelManager();
|
|
1412
|
+
modelManager.updateModel(editingModel.modelName, {
|
|
1413
|
+
baseURL: providerBaseUrl || editingModel.baseURL,
|
|
1414
|
+
apiKey: apiKey || editingModel.apiKey,
|
|
1415
|
+
maxTokens: parseInt(maxTokens) || editingModel.maxTokens,
|
|
1416
|
+
contextLength: contextLength || editingModel.contextLength,
|
|
1417
|
+
reasoningEffort
|
|
1418
|
+
});
|
|
1419
|
+
onDone();
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
setValidationError(
|
|
1422
|
+
error instanceof Error ? error.message : "Failed to update model"
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1432
1427
|
const modelId = await saveConfiguration(selectedProvider, selectedModel);
|
|
1433
1428
|
if (!modelId) {
|
|
1434
1429
|
return;
|
|
@@ -1450,10 +1445,20 @@ function ModelSelector({
|
|
|
1450
1445
|
onDone();
|
|
1451
1446
|
}
|
|
1452
1447
|
} else {
|
|
1448
|
+
if (currentScreen === "testAndSave") {
|
|
1449
|
+
setConnectionTestResult(null);
|
|
1450
|
+
setIsTestingConnection(false);
|
|
1451
|
+
setValidationError(null);
|
|
1452
|
+
}
|
|
1453
|
+
const prevScreen = screenStack[screenStack.length - 2];
|
|
1454
|
+
if (prevScreen === "modelParams") {
|
|
1455
|
+
const formFields = getFormFieldsForModelParams();
|
|
1456
|
+
const submitIndex = formFields.findIndex((f) => f.name === "submit");
|
|
1457
|
+
setActiveFieldIndex(Math.max(0, submitIndex - 1));
|
|
1458
|
+
}
|
|
1453
1459
|
setScreenStack((prev) => prev.slice(0, -1));
|
|
1454
1460
|
}
|
|
1455
1461
|
};
|
|
1456
|
-
useEscapeNavigation(handleBack, abortController);
|
|
1457
1462
|
function handleCursorOffsetChange(offset) {
|
|
1458
1463
|
setCursorOffset(offset);
|
|
1459
1464
|
}
|
|
@@ -1468,7 +1473,13 @@ function ModelSelector({
|
|
|
1468
1473
|
function handleModelSearchCursorOffsetChange(offset) {
|
|
1469
1474
|
setModelSearchCursorOffset(offset);
|
|
1470
1475
|
}
|
|
1476
|
+
const textScreens = ["apiKey", "baseUrl", "resourceName", "modelInput"];
|
|
1471
1477
|
useInput((input, key) => {
|
|
1478
|
+
if (!textScreens.includes(currentScreen)) return;
|
|
1479
|
+
if (key.escape) {
|
|
1480
|
+
handleBack();
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1472
1483
|
if (currentScreen === "apiKey" && key.return) {
|
|
1473
1484
|
if (apiKey) {
|
|
1474
1485
|
handleApiKeySubmit(apiKey);
|
|
@@ -1480,8 +1491,7 @@ function ModelSelector({
|
|
|
1480
1491
|
navigateTo("modelInput");
|
|
1481
1492
|
return;
|
|
1482
1493
|
}
|
|
1483
|
-
fetchModelsWithRetry().catch((
|
|
1484
|
-
console.error("Final error after retries:", error);
|
|
1494
|
+
fetchModelsWithRetry().catch(() => {
|
|
1485
1495
|
});
|
|
1486
1496
|
return;
|
|
1487
1497
|
}
|
|
@@ -1505,76 +1515,6 @@ function ModelSelector({
|
|
|
1505
1515
|
}
|
|
1506
1516
|
return;
|
|
1507
1517
|
}
|
|
1508
|
-
if (currentScreen === "confirmation" && key.return) {
|
|
1509
|
-
handleConfirmation().catch((error) => {
|
|
1510
|
-
console.error("Error in handleConfirmation:", error);
|
|
1511
|
-
setValidationError(
|
|
1512
|
-
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1513
|
-
);
|
|
1514
|
-
});
|
|
1515
|
-
return;
|
|
1516
|
-
}
|
|
1517
|
-
if (currentScreen === "connectionTest") {
|
|
1518
|
-
if (key.return) {
|
|
1519
|
-
if (!isTestingConnection && !connectionTestResult) {
|
|
1520
|
-
handleConnectionTest();
|
|
1521
|
-
} else if (connectionTestResult && connectionTestResult.success) {
|
|
1522
|
-
navigateTo("confirmation");
|
|
1523
|
-
} else if (connectionTestResult && !connectionTestResult.success) {
|
|
1524
|
-
handleConnectionTest();
|
|
1525
|
-
}
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
if (currentScreen === "contextLength") {
|
|
1530
|
-
if (key.return) {
|
|
1531
|
-
handleContextLengthSubmit();
|
|
1532
|
-
return;
|
|
1533
|
-
}
|
|
1534
|
-
if (key.upArrow) {
|
|
1535
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1536
|
-
(opt) => opt.value === contextLength
|
|
1537
|
-
);
|
|
1538
|
-
const newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1539
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1540
|
-
) || 0 : CONTEXT_LENGTH_OPTIONS.length - 1;
|
|
1541
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
if (key.downArrow) {
|
|
1545
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1546
|
-
(opt) => opt.value === contextLength
|
|
1547
|
-
);
|
|
1548
|
-
const newIndex = currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1549
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1550
|
-
) || 0 : (currentIndex + 1) % CONTEXT_LENGTH_OPTIONS.length;
|
|
1551
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
if (currentScreen === "apiKey" && (key.ctrl && input === "v" || key.meta && input === "v")) {
|
|
1556
|
-
setModelLoadError(
|
|
1557
|
-
"Please use your terminal's paste functionality or type the API key manually"
|
|
1558
|
-
);
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
if (currentScreen === "modelParams" && key.tab) {
|
|
1562
|
-
const formFields = getFormFieldsForModelParams();
|
|
1563
|
-
setActiveFieldIndex((current) => (current + 1) % formFields.length);
|
|
1564
|
-
return;
|
|
1565
|
-
}
|
|
1566
|
-
if (currentScreen === "modelParams" && key.return) {
|
|
1567
|
-
const formFields = getFormFieldsForModelParams();
|
|
1568
|
-
const currentField = formFields[activeFieldIndex];
|
|
1569
|
-
if (currentField.name === "submit" || activeFieldIndex === formFields.length - 1) {
|
|
1570
|
-
handleModelParamsSubmit();
|
|
1571
|
-
} else if (currentField.component === "select") {
|
|
1572
|
-
setActiveFieldIndex(
|
|
1573
|
-
(current) => Math.min(current + 1, formFields.length - 1)
|
|
1574
|
-
);
|
|
1575
|
-
}
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
1518
|
});
|
|
1579
1519
|
function getFormFieldsForModelParams() {
|
|
1580
1520
|
return [
|
|
@@ -1607,433 +1547,518 @@ function ModelSelector({
|
|
|
1607
1547
|
];
|
|
1608
1548
|
}
|
|
1609
1549
|
if (currentScreen === "apiKey") {
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1550
|
+
const providerLabel = getProviderLabel(selectedProvider, 0).split(" (")[0];
|
|
1551
|
+
const apiKeyUrls = {
|
|
1552
|
+
kimi: "https://platform.moonshot.cn/console/api-keys",
|
|
1553
|
+
deepseek: "https://platform.deepseek.com/api_keys",
|
|
1554
|
+
siliconflow: "https://cloud.siliconflow.cn/i/oJWsm6io",
|
|
1555
|
+
qwen: "https://bailian.console.aliyun.com/?tab=model#/api-key",
|
|
1556
|
+
glm: "https://open.bigmodel.cn (API Keys section)",
|
|
1557
|
+
minimax: "https://www.minimax.io/platform/user-center/basic-information",
|
|
1558
|
+
"baidu-qianfan": "https://console.bce.baidu.com/iam/#/iam/accesslist",
|
|
1559
|
+
openai: "https://platform.openai.com/api-keys"
|
|
1560
|
+
};
|
|
1561
|
+
let apiKeyUrl = apiKeyUrls[selectedProvider] || "";
|
|
1562
|
+
if (selectedProvider === "anthropic") {
|
|
1563
|
+
apiKeyUrl = anthropicProviderType === "official" ? "https://console.anthropic.com/settings/keys" : anthropicProviderType === "bigdream" ? "https://api-key.info/register?aff=MSl4" : anthropicProviderType === "opendev" ? "https://api.openai-next.com/register/?aff_code=4xo7" : "your custom API provider";
|
|
1564
|
+
}
|
|
1565
|
+
const supportsManualInput = selectedProvider === "anthropic" || selectedProvider === "kimi" || selectedProvider === "deepseek" || selectedProvider === "qwen" || selectedProvider === "glm" || selectedProvider === "minimax" || selectedProvider === "baidu-qianfan" || selectedProvider === "siliconflow" || selectedProvider === "custom-openai";
|
|
1566
|
+
const tabHintText = supportsManualInput ? t("modelSelector.apiKeyTabHintManual") : t("modelSelector.apiKeyTabHintSkip");
|
|
1567
|
+
const apiKeyHint = apiKeyUrl ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.info }, apiKeyUrl)) : void 0;
|
|
1568
|
+
return /* @__PURE__ */ React.createElement(
|
|
1569
|
+
BrandTextInput,
|
|
1613
1570
|
{
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
columns: 500,
|
|
1631
|
-
cursorOffset,
|
|
1632
|
-
onChangeCursorOffset: handleCursorOffsetChange,
|
|
1633
|
-
showCursor: true
|
|
1634
|
-
}
|
|
1635
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: apiKey ? theme.suggestion : SEMANTIC_COLORS.dim }, "[Submit API Key]"), /* @__PURE__ */ React.createElement(Text, null, " ", "- Press Enter or click to continue with this API key"))), isLoadingModels && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Loading available models...")), modelLoadError && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue,", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Tab"), " to", " ", selectedProvider === "anthropic" || selectedProvider === "kimi" || selectedProvider === "deepseek" || selectedProvider === "qwen" || selectedProvider === "glm" || selectedProvider === "minimax" || selectedProvider === "baidu-qianfan" || selectedProvider === "siliconflow" || selectedProvider === "custom-openai" ? "skip to manual model input" : "skip using a key", ", or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1636
|
-
));
|
|
1571
|
+
title: `${t("modelSelector.apiKeyTitle")} \u2014 ${providerLabel}`,
|
|
1572
|
+
description: t("modelSelector.apiKeyDesc"),
|
|
1573
|
+
placeholder: "sk-...",
|
|
1574
|
+
value: apiKey,
|
|
1575
|
+
onChange: handleApiKeyChange,
|
|
1576
|
+
onSubmit: handleApiKeySubmit,
|
|
1577
|
+
mask: "*",
|
|
1578
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1579
|
+
isLoading: isLoadingModels,
|
|
1580
|
+
loadingText: "Loading available models...",
|
|
1581
|
+
hint: apiKeyHint,
|
|
1582
|
+
footerHint: `Enter continue \xB7 Tab ${tabHintText} \xB7 Esc back`,
|
|
1583
|
+
cursorOffset,
|
|
1584
|
+
onChangeCursorOffset: handleCursorOffsetChange
|
|
1585
|
+
}
|
|
1586
|
+
);
|
|
1637
1587
|
}
|
|
1638
1588
|
if (currentScreen === "model") {
|
|
1639
|
-
const
|
|
1640
|
-
|
|
1641
|
-
|
|
1589
|
+
const providerLabel = getProviderLabel(
|
|
1590
|
+
selectedProvider,
|
|
1591
|
+
availableModels.length
|
|
1592
|
+
).split(" (")[0];
|
|
1593
|
+
const modelSelectorItems = modelOptions.map((opt) => ({
|
|
1594
|
+
id: opt.value,
|
|
1595
|
+
label: opt.label
|
|
1596
|
+
}));
|
|
1597
|
+
const subtitle = modelOptions.length > 0 ? `${modelOptions.length}/${availableModels.length} models` : availableModels.length > 0 ? t("modelSelector.noModelsMatch") : t("modelSelector.noModelsAvailable");
|
|
1598
|
+
return /* @__PURE__ */ React.createElement(
|
|
1599
|
+
SimpleSelector,
|
|
1642
1600
|
{
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Selection", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1651
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select a model from", " ", getProviderLabel(
|
|
1652
|
-
selectedProvider,
|
|
1653
|
-
availableModels.length
|
|
1654
|
-
).split(" (")[0], " ", "for ", modelTypeText, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This model profile can be assigned to different pointers (main, task, reasoning, quick) for various use cases.")), /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Search models:"), /* @__PURE__ */ React.createElement(
|
|
1655
|
-
TextInput,
|
|
1656
|
-
{
|
|
1657
|
-
placeholder: "Type to filter models...",
|
|
1658
|
-
value: modelSearchQuery,
|
|
1659
|
-
onChange: handleModelSearchChange,
|
|
1660
|
-
columns: 100,
|
|
1661
|
-
cursorOffset: modelSearchCursorOffset,
|
|
1662
|
-
onChangeCursorOffset: handleModelSearchCursorOffsetChange,
|
|
1663
|
-
showCursor: true,
|
|
1664
|
-
focus: true
|
|
1665
|
-
}
|
|
1666
|
-
)), modelOptions.length > 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1667
|
-
Select,
|
|
1668
|
-
{
|
|
1669
|
-
options: modelOptions,
|
|
1670
|
-
onChange: handleModelSelection
|
|
1671
|
-
}
|
|
1672
|
-
), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Showing ", modelOptions.length, " of ", availableModels.length, " ", "models")) : /* @__PURE__ */ React.createElement(Box, null, availableModels.length > 0 ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "No models match your search. Try a different query.") : /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "No models available for this provider.")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to API key input")))
|
|
1673
|
-
));
|
|
1601
|
+
title: `${t("modelSelector.modelSelectionTitle")} \u2014 ${providerLabel}`,
|
|
1602
|
+
subtitle,
|
|
1603
|
+
items: modelSelectorItems,
|
|
1604
|
+
onSelect: (item) => handleModelSelection(item.id),
|
|
1605
|
+
onClose: handleBack
|
|
1606
|
+
}
|
|
1607
|
+
);
|
|
1674
1608
|
}
|
|
1675
1609
|
if (currentScreen === "modelParams") {
|
|
1676
1610
|
const formFields = getFormFieldsForModelParams();
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
{
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
},
|
|
1687
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Parameters", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1688
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Configure parameters for ", selectedModel, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Use ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Tab"), " to navigate between fields. Press", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to submit.")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, formFields.map((field, index) => /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1, key: field.name }, field.component !== "button" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1689
|
-
Text,
|
|
1690
|
-
{
|
|
1691
|
-
bold: true,
|
|
1692
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1693
|
-
},
|
|
1694
|
-
field.label
|
|
1695
|
-
), field.description && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, field.description)) : /* @__PURE__ */ React.createElement(
|
|
1696
|
-
Text,
|
|
1697
|
-
{
|
|
1698
|
-
bold: true,
|
|
1699
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1700
|
-
},
|
|
1701
|
-
field.label
|
|
1702
|
-
), /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, activeFieldIndex === index ? field.component === "select" ? field.name === "maxTokens" ? /* @__PURE__ */ React.createElement(
|
|
1703
|
-
Select,
|
|
1611
|
+
const currentField = formFields[activeFieldIndex];
|
|
1612
|
+
if (currentField?.name === "maxTokens") {
|
|
1613
|
+
const maxTokensItems = MAX_TOKENS_OPTIONS.map((opt) => ({
|
|
1614
|
+
id: opt.value.toString(),
|
|
1615
|
+
label: opt.label,
|
|
1616
|
+
isCurrent: opt.value === parseInt(maxTokens)
|
|
1617
|
+
}));
|
|
1618
|
+
return /* @__PURE__ */ React.createElement(
|
|
1619
|
+
SimpleSelector,
|
|
1704
1620
|
{
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1621
|
+
title: `${t("modelSelector.modelParamsTitle")} \u2014 ${t("modelSelector.maxTokens")}`,
|
|
1622
|
+
subtitle: selectedModel,
|
|
1623
|
+
items: maxTokensItems,
|
|
1624
|
+
onSelect: (item) => {
|
|
1625
|
+
const numValue = parseInt(item.id);
|
|
1708
1626
|
setMaxTokens(numValue.toString());
|
|
1709
1627
|
setSelectedMaxTokensPreset(numValue);
|
|
1710
|
-
setMaxTokensCursorOffset(
|
|
1711
|
-
|
|
1712
|
-
);
|
|
1713
|
-
setTimeout(() => {
|
|
1714
|
-
setActiveFieldIndex(index + 1);
|
|
1715
|
-
}, 100);
|
|
1628
|
+
setMaxTokensCursorOffset(numValue.toString().length);
|
|
1629
|
+
setActiveFieldIndex(activeFieldIndex + 1);
|
|
1716
1630
|
},
|
|
1717
|
-
|
|
1631
|
+
onClose: handleBack
|
|
1718
1632
|
}
|
|
1719
|
-
)
|
|
1720
|
-
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
if (currentField?.name === "reasoningEffort") {
|
|
1636
|
+
const effortItems = reasoningEffortOptions.map((opt) => ({
|
|
1637
|
+
id: opt.value,
|
|
1638
|
+
label: opt.label,
|
|
1639
|
+
isCurrent: opt.value === reasoningEffort
|
|
1640
|
+
}));
|
|
1641
|
+
return /* @__PURE__ */ React.createElement(
|
|
1642
|
+
SimpleSelector,
|
|
1721
1643
|
{
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1644
|
+
title: `${t("modelSelector.modelParamsTitle")} \u2014 ${t("modelSelector.reasoningEffort")}`,
|
|
1645
|
+
subtitle: selectedModel,
|
|
1646
|
+
items: effortItems,
|
|
1647
|
+
onSelect: (item) => {
|
|
1648
|
+
setReasoningEffort(item.id);
|
|
1649
|
+
setActiveFieldIndex(activeFieldIndex + 1);
|
|
1728
1650
|
},
|
|
1729
|
-
|
|
1651
|
+
onClose: () => {
|
|
1652
|
+
setActiveFieldIndex(0);
|
|
1653
|
+
}
|
|
1730
1654
|
}
|
|
1731
|
-
)
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
handleModelParamsSubmit();
|
|
1658
|
+
return null;
|
|
1735
1659
|
}
|
|
1736
1660
|
if (currentScreen === "resourceName") {
|
|
1737
|
-
return /* @__PURE__ */ React.createElement(
|
|
1738
|
-
|
|
1661
|
+
return /* @__PURE__ */ React.createElement(
|
|
1662
|
+
BrandTextInput,
|
|
1739
1663
|
{
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
placeholder: "myazureresource",
|
|
1752
|
-
value: resourceName,
|
|
1753
|
-
onChange: setResourceName,
|
|
1754
|
-
onSubmit: handleResourceNameSubmit,
|
|
1755
|
-
columns: 100,
|
|
1756
|
-
cursorOffset: resourceNameCursorOffset,
|
|
1757
|
-
onChangeCursorOffset: setResourceNameCursorOffset,
|
|
1758
|
-
showCursor: true
|
|
1759
|
-
}
|
|
1760
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1761
|
-
Text,
|
|
1762
|
-
{
|
|
1763
|
-
color: resourceName ? theme.suggestion : SEMANTIC_COLORS.dim
|
|
1764
|
-
},
|
|
1765
|
-
"[Submit Resource Name]"
|
|
1766
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1767
|
-
));
|
|
1664
|
+
title: t("modelSelector.resourceNameTitle"),
|
|
1665
|
+
description: t("modelSelector.resourceNameDesc"),
|
|
1666
|
+
placeholder: "myazureresource",
|
|
1667
|
+
value: resourceName,
|
|
1668
|
+
onChange: setResourceName,
|
|
1669
|
+
onSubmit: handleResourceNameSubmit,
|
|
1670
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1671
|
+
cursorOffset: resourceNameCursorOffset,
|
|
1672
|
+
onChangeCursorOffset: setResourceNameCursorOffset
|
|
1673
|
+
}
|
|
1674
|
+
);
|
|
1768
1675
|
}
|
|
1769
1676
|
if (currentScreen === "baseUrl") {
|
|
1770
1677
|
const isCustomOpenAI = selectedProvider === "custom-openai";
|
|
1771
1678
|
if (isCustomOpenAI) {
|
|
1772
|
-
return /* @__PURE__ */ React.createElement(
|
|
1773
|
-
|
|
1679
|
+
return /* @__PURE__ */ React.createElement(
|
|
1680
|
+
BrandTextInput,
|
|
1774
1681
|
{
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
onSubmit: handleCustomBaseUrlSubmit,
|
|
1790
|
-
columns: 100,
|
|
1791
|
-
cursorOffset: customBaseUrlCursorOffset,
|
|
1792
|
-
onChangeCursorOffset: setCustomBaseUrlCursorOffset,
|
|
1793
|
-
showCursor: !isLoadingModels,
|
|
1794
|
-
focus: !isLoadingModels
|
|
1795
|
-
}
|
|
1796
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1797
|
-
Text,
|
|
1798
|
-
{
|
|
1799
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1800
|
-
},
|
|
1801
|
-
"[Submit Base URL]"
|
|
1802
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1803
|
-
));
|
|
1682
|
+
title: t("modelSelector.customApiTitle"),
|
|
1683
|
+
description: t("modelSelector.customApiDesc"),
|
|
1684
|
+
placeholder: "https://api.example.com/v1",
|
|
1685
|
+
value: customBaseUrl,
|
|
1686
|
+
onChange: setCustomBaseUrl,
|
|
1687
|
+
onSubmit: handleCustomBaseUrlSubmit,
|
|
1688
|
+
isLoading: isLoadingModels,
|
|
1689
|
+
loadingText: "Connecting...",
|
|
1690
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1691
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1692
|
+
cursorOffset: customBaseUrlCursorOffset,
|
|
1693
|
+
onChangeCursorOffset: setCustomBaseUrlCursorOffset
|
|
1694
|
+
}
|
|
1695
|
+
);
|
|
1804
1696
|
}
|
|
1805
1697
|
const providerName = providers[selectedProvider]?.name || selectedProvider;
|
|
1806
1698
|
const defaultUrl = providers[selectedProvider]?.baseURL || "";
|
|
1807
|
-
|
|
1808
|
-
|
|
1699
|
+
const desc = selectedProvider === "ollama" ? t("modelSelector.baseUrlOllamaDesc") : `${t("modelSelector.baseUrlDesc")} You can modify this URL or press Enter to use the default.`;
|
|
1700
|
+
return /* @__PURE__ */ React.createElement(
|
|
1701
|
+
BrandTextInput,
|
|
1809
1702
|
{
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
onSubmit: handleProviderBaseUrlSubmit,
|
|
1825
|
-
columns: 100,
|
|
1826
|
-
cursorOffset: providerBaseUrlCursorOffset,
|
|
1827
|
-
onChangeCursorOffset: setProviderBaseUrlCursorOffset,
|
|
1828
|
-
showCursor: !isLoadingModels,
|
|
1829
|
-
focus: !isLoadingModels
|
|
1830
|
-
}
|
|
1831
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1832
|
-
Text,
|
|
1833
|
-
{
|
|
1834
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1835
|
-
},
|
|
1836
|
-
"[Submit Base URL]"
|
|
1837
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), isLoadingModels && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, selectedProvider === "ollama" ? "Connecting to Ollama server..." : `Connecting to ${providerName}...`)), modelLoadError && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1838
|
-
));
|
|
1703
|
+
title: `${t("modelSelector.baseUrlTitle")} \u2014 ${providerName}`,
|
|
1704
|
+
description: desc,
|
|
1705
|
+
placeholder: defaultUrl,
|
|
1706
|
+
value: providerBaseUrl,
|
|
1707
|
+
onChange: setProviderBaseUrl,
|
|
1708
|
+
onSubmit: handleProviderBaseUrlSubmit,
|
|
1709
|
+
isLoading: isLoadingModels,
|
|
1710
|
+
loadingText: selectedProvider === "ollama" ? "Connecting to Ollama server..." : `Connecting to ${providerName}...`,
|
|
1711
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1712
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1713
|
+
cursorOffset: providerBaseUrlCursorOffset,
|
|
1714
|
+
onChangeCursorOffset: setProviderBaseUrlCursorOffset
|
|
1715
|
+
}
|
|
1716
|
+
);
|
|
1839
1717
|
}
|
|
1840
1718
|
if (currentScreen === "modelInput") {
|
|
1841
|
-
const
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
if (selectedProvider === "azure") {
|
|
1847
|
-
screenTitle = "Azure Model Setup";
|
|
1848
|
-
description = `Enter your Azure OpenAI deployment name for ${modelTypeText}:`;
|
|
1849
|
-
examples = 'For example: "gpt-4", "gpt-35-turbo", etc.';
|
|
1850
|
-
placeholder = "gpt-4";
|
|
1851
|
-
} else if (selectedProvider === "anthropic") {
|
|
1852
|
-
screenTitle = "Claude Model Setup";
|
|
1853
|
-
description = `Enter the Claude model name for ${modelTypeText}:`;
|
|
1854
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1855
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1856
|
-
} else if (selectedProvider === "bigdream") {
|
|
1857
|
-
screenTitle = "BigDream Model Setup";
|
|
1858
|
-
description = `Enter the BigDream model name for ${modelTypeText}:`;
|
|
1859
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1860
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1861
|
-
} else if (selectedProvider === "kimi") {
|
|
1862
|
-
screenTitle = "Kimi Model Setup";
|
|
1863
|
-
description = `Enter the Kimi model name for ${modelTypeText}:`;
|
|
1864
|
-
examples = 'For example: "kimi-k2-0711-preview"';
|
|
1865
|
-
placeholder = "kimi-k2-0711-preview";
|
|
1866
|
-
} else if (selectedProvider === "deepseek") {
|
|
1867
|
-
screenTitle = "DeepSeek Model Setup";
|
|
1868
|
-
description = `Enter the DeepSeek model name for ${modelTypeText}:`;
|
|
1869
|
-
examples = 'For example: "deepseek-chat", "deepseek-coder", "deepseek-reasoner", etc.';
|
|
1870
|
-
placeholder = "deepseek-chat";
|
|
1871
|
-
} else if (selectedProvider === "siliconflow") {
|
|
1872
|
-
screenTitle = "SiliconFlow Model Setup";
|
|
1873
|
-
description = `Enter the SiliconFlow model name for ${modelTypeText}:`;
|
|
1874
|
-
examples = 'For example: "Qwen/Qwen2.5-72B-Instruct", "meta-llama/Meta-Llama-3.1-8B-Instruct", etc.';
|
|
1875
|
-
placeholder = "Qwen/Qwen2.5-72B-Instruct";
|
|
1876
|
-
} else if (selectedProvider === "qwen") {
|
|
1877
|
-
screenTitle = "Qwen Model Setup";
|
|
1878
|
-
description = `Enter the Qwen model name for ${modelTypeText}:`;
|
|
1879
|
-
examples = 'For example: "qwen-plus", "qwen-turbo", "qwen-max", etc.';
|
|
1880
|
-
placeholder = "qwen-plus";
|
|
1881
|
-
} else if (selectedProvider === "glm") {
|
|
1882
|
-
screenTitle = "GLM Model Setup";
|
|
1883
|
-
description = `Enter the GLM model name for ${modelTypeText}:`;
|
|
1884
|
-
examples = 'For example: "glm-4", "glm-4v", "glm-3-turbo", etc.';
|
|
1885
|
-
placeholder = "glm-4";
|
|
1886
|
-
} else if (selectedProvider === "minimax") {
|
|
1887
|
-
screenTitle = "MiniMax Model Setup";
|
|
1888
|
-
description = `Enter the MiniMax model name for ${modelTypeText}:`;
|
|
1889
|
-
examples = 'For example: "abab6.5s-chat", "abab6.5g-chat", "abab5.5s-chat", etc.';
|
|
1890
|
-
placeholder = "abab6.5s-chat";
|
|
1891
|
-
} else if (selectedProvider === "baidu-qianfan") {
|
|
1892
|
-
screenTitle = "Baidu Qianfan Model Setup";
|
|
1893
|
-
description = `Enter the Baidu Qianfan model name for ${modelTypeText}:`;
|
|
1894
|
-
examples = 'For example: "ERNIE-4.0-8K", "ERNIE-3.5-8K", "ERNIE-Speed-128K", etc.';
|
|
1895
|
-
placeholder = "ERNIE-4.0-8K";
|
|
1896
|
-
} else if (selectedProvider === "custom-openai") {
|
|
1897
|
-
screenTitle = "Custom API Model Setup";
|
|
1898
|
-
description = `Enter the model name for ${modelTypeText}:`;
|
|
1899
|
-
examples = "Enter the exact model name as supported by your API endpoint.";
|
|
1900
|
-
placeholder = "model-name";
|
|
1901
|
-
}
|
|
1902
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1903
|
-
Box,
|
|
1904
|
-
{
|
|
1905
|
-
flexDirection: "column",
|
|
1906
|
-
gap: 1,
|
|
1907
|
-
borderStyle: "round",
|
|
1908
|
-
borderColor: theme.secondaryBorder,
|
|
1909
|
-
paddingX: 2,
|
|
1910
|
-
paddingY: 1
|
|
1719
|
+
const modelInputConfig = {
|
|
1720
|
+
azure: {
|
|
1721
|
+
title: "Azure Model Setup",
|
|
1722
|
+
placeholder: "gpt-4",
|
|
1723
|
+
examples: 'e.g. "gpt-4", "gpt-35-turbo"'
|
|
1911
1724
|
},
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
placeholder,
|
|
1917
|
-
value: customModelName,
|
|
1918
|
-
onChange: setCustomModelName,
|
|
1919
|
-
onSubmit: handleCustomModelSubmit,
|
|
1920
|
-
columns: 100,
|
|
1921
|
-
cursorOffset: customModelNameCursorOffset,
|
|
1922
|
-
onChangeCursorOffset: setCustomModelNameCursorOffset,
|
|
1923
|
-
showCursor: true
|
|
1924
|
-
}
|
|
1925
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1926
|
-
Text,
|
|
1927
|
-
{
|
|
1928
|
-
color: customModelName ? theme.suggestion : SEMANTIC_COLORS.dim
|
|
1929
|
-
},
|
|
1930
|
-
"[Submit Model Name]"
|
|
1931
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1932
|
-
));
|
|
1933
|
-
}
|
|
1934
|
-
if (currentScreen === "contextLength") {
|
|
1935
|
-
const selectedOption = CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength) || CONTEXT_LENGTH_OPTIONS[2];
|
|
1936
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1937
|
-
Box,
|
|
1938
|
-
{
|
|
1939
|
-
flexDirection: "column",
|
|
1940
|
-
gap: 1,
|
|
1941
|
-
borderStyle: "round",
|
|
1942
|
-
borderColor: theme.secondaryBorder,
|
|
1943
|
-
paddingX: 2,
|
|
1944
|
-
paddingY: 1
|
|
1725
|
+
anthropic: {
|
|
1726
|
+
title: "Claude Model Setup",
|
|
1727
|
+
placeholder: "claude-3-5-sonnet-latest",
|
|
1728
|
+
examples: 'e.g. "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"'
|
|
1945
1729
|
},
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
}
|
|
1951
|
-
|
|
1730
|
+
bigdream: {
|
|
1731
|
+
title: "BigDream Model Setup",
|
|
1732
|
+
placeholder: "claude-3-5-sonnet-latest",
|
|
1733
|
+
examples: 'e.g. "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"'
|
|
1734
|
+
},
|
|
1735
|
+
kimi: {
|
|
1736
|
+
title: "Kimi Model Setup",
|
|
1737
|
+
placeholder: "kimi-k2-0711-preview",
|
|
1738
|
+
examples: 'e.g. "kimi-k2-0711-preview"'
|
|
1739
|
+
},
|
|
1740
|
+
deepseek: {
|
|
1741
|
+
title: "DeepSeek Model Setup",
|
|
1742
|
+
placeholder: "deepseek-chat",
|
|
1743
|
+
examples: 'e.g. "deepseek-chat", "deepseek-coder", "deepseek-reasoner"'
|
|
1744
|
+
},
|
|
1745
|
+
siliconflow: {
|
|
1746
|
+
title: "SiliconFlow Model Setup",
|
|
1747
|
+
placeholder: "Qwen/Qwen2.5-72B-Instruct",
|
|
1748
|
+
examples: 'e.g. "Qwen/Qwen2.5-72B-Instruct"'
|
|
1749
|
+
},
|
|
1750
|
+
qwen: {
|
|
1751
|
+
title: "Qwen Model Setup",
|
|
1752
|
+
placeholder: "qwen-plus",
|
|
1753
|
+
examples: 'e.g. "qwen-plus", "qwen-turbo", "qwen-max"'
|
|
1754
|
+
},
|
|
1755
|
+
glm: {
|
|
1756
|
+
title: "GLM Model Setup",
|
|
1757
|
+
placeholder: "glm-4",
|
|
1758
|
+
examples: 'e.g. "glm-4", "glm-4v", "glm-3-turbo"'
|
|
1759
|
+
},
|
|
1760
|
+
minimax: {
|
|
1761
|
+
title: "MiniMax Model Setup",
|
|
1762
|
+
placeholder: "abab6.5s-chat",
|
|
1763
|
+
examples: 'e.g. "abab6.5s-chat", "abab6.5g-chat"'
|
|
1764
|
+
},
|
|
1765
|
+
"baidu-qianfan": {
|
|
1766
|
+
title: "Baidu Qianfan Model Setup",
|
|
1767
|
+
placeholder: "ERNIE-4.0-8K",
|
|
1768
|
+
examples: 'e.g. "ERNIE-4.0-8K", "ERNIE-3.5-8K"'
|
|
1769
|
+
},
|
|
1770
|
+
"custom-openai": {
|
|
1771
|
+
title: "Custom API Model Setup",
|
|
1772
|
+
placeholder: "model-name",
|
|
1773
|
+
examples: "Enter the exact model name supported by your API endpoint."
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
const cfg = modelInputConfig[selectedProvider] || {
|
|
1777
|
+
title: t("modelSelector.modelInputTitle"),
|
|
1778
|
+
placeholder: "gpt-4",
|
|
1779
|
+
examples: 'e.g. "gpt-4", "gpt-3.5-turbo"'
|
|
1780
|
+
};
|
|
1781
|
+
return /* @__PURE__ */ React.createElement(
|
|
1782
|
+
BrandTextInput,
|
|
1783
|
+
{
|
|
1784
|
+
title: cfg.title,
|
|
1785
|
+
description: cfg.examples,
|
|
1786
|
+
placeholder: cfg.placeholder,
|
|
1787
|
+
value: customModelName,
|
|
1788
|
+
onChange: setCustomModelName,
|
|
1789
|
+
onSubmit: handleCustomModelSubmit,
|
|
1790
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1791
|
+
cursorOffset: customModelNameCursorOffset,
|
|
1792
|
+
onChangeCursorOffset: setCustomModelNameCursorOffset
|
|
1793
|
+
}
|
|
1794
|
+
);
|
|
1952
1795
|
}
|
|
1953
|
-
if (currentScreen === "
|
|
1954
|
-
const
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1796
|
+
if (currentScreen === "contextLength") {
|
|
1797
|
+
const contextItems = CONTEXT_LENGTH_OPTIONS.map((opt) => ({
|
|
1798
|
+
id: opt.value.toString(),
|
|
1799
|
+
label: opt.value === DEFAULT_CONTEXT_LENGTH ? `${opt.label} (${t("modelSelector.recommended")})` : opt.label,
|
|
1800
|
+
isCurrent: opt.value === contextLength
|
|
1801
|
+
}));
|
|
1802
|
+
return /* @__PURE__ */ React.createElement(
|
|
1803
|
+
SimpleSelector,
|
|
1959
1804
|
{
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
},
|
|
1967
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Connection Test", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1968
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Testing connection to ", providerDisplayName, "..."), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This will verify your configuration by sending a test request to the API.", selectedProvider === "minimax" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Newline, null), "For MiniMax, we'll test both v2 and v1 endpoints to find the best one."))), !connectionTestResult && !isTestingConnection && /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Press Enter"), " to start the connection test")), isTestingConnection && /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "\u{1F504} Testing connection...")), connectionTestResult && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1, paddingX: 1 }, /* @__PURE__ */ React.createElement(
|
|
1969
|
-
Text,
|
|
1970
|
-
{
|
|
1971
|
-
color: connectionTestResult.success ? theme.success : "red"
|
|
1805
|
+
title: t("modelSelector.contextLengthTitle"),
|
|
1806
|
+
subtitle: t("modelSelector.contextLengthDesc"),
|
|
1807
|
+
items: contextItems,
|
|
1808
|
+
onSelect: (item) => {
|
|
1809
|
+
setContextLength(parseInt(item.id));
|
|
1810
|
+
handleContextLengthSubmit();
|
|
1972
1811
|
},
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
)
|
|
1812
|
+
onClose: handleBack
|
|
1813
|
+
}
|
|
1814
|
+
);
|
|
1976
1815
|
}
|
|
1977
|
-
if (currentScreen === "
|
|
1816
|
+
if (currentScreen === "testAndSave") {
|
|
1978
1817
|
const providerDisplayName = getProviderLabel(selectedProvider, 0).split(
|
|
1979
1818
|
" ("
|
|
1980
1819
|
)[0];
|
|
1981
1820
|
const showsApiKey = selectedProvider !== "ollama";
|
|
1982
|
-
|
|
1983
|
-
|
|
1821
|
+
const contextLengthLabel = CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength)?.label || `${contextLength.toLocaleString()} tokens`;
|
|
1822
|
+
if (isEditMode) {
|
|
1823
|
+
const editItems = [];
|
|
1824
|
+
if (showsApiKey) {
|
|
1825
|
+
editItems.push({
|
|
1826
|
+
id: "__edit_apiKey__",
|
|
1827
|
+
label: "API Key",
|
|
1828
|
+
description: apiKey ? `****${apiKey.slice(-4)}` : "(not set)",
|
|
1829
|
+
category: t("modelSelector.testAndSaveDesc")
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
if (selectedProvider === "custom-openai" || providerBaseUrl !== providers[selectedProvider]?.baseURL) {
|
|
1833
|
+
editItems.push({
|
|
1834
|
+
id: "__edit_baseUrl__",
|
|
1835
|
+
label: "Base URL",
|
|
1836
|
+
description: providerBaseUrl || customBaseUrl || "(not set)",
|
|
1837
|
+
category: t("modelSelector.testAndSaveDesc")
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
editItems.push({
|
|
1841
|
+
id: "__edit_modelParams__",
|
|
1842
|
+
label: "Max Tokens",
|
|
1843
|
+
description: maxTokens,
|
|
1844
|
+
category: t("modelSelector.testAndSaveDesc")
|
|
1845
|
+
});
|
|
1846
|
+
editItems.push({
|
|
1847
|
+
id: "__edit_contextLength__",
|
|
1848
|
+
label: "Context Length",
|
|
1849
|
+
description: contextLengthLabel,
|
|
1850
|
+
category: t("modelSelector.testAndSaveDesc")
|
|
1851
|
+
});
|
|
1852
|
+
if (connectionTestResult) {
|
|
1853
|
+
editItems.push({
|
|
1854
|
+
id: "__test_status__",
|
|
1855
|
+
label: "Connection",
|
|
1856
|
+
description: connectionTestResult.message,
|
|
1857
|
+
statusIcon: connectionTestResult.success ? "\u2713" : "\u2715",
|
|
1858
|
+
statusColor: connectionTestResult.success ? SEMANTIC_COLORS.success : SEMANTIC_COLORS.error,
|
|
1859
|
+
category: t("modelSelector.testAndSaveDesc")
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
editItems.push({
|
|
1863
|
+
id: "__save__",
|
|
1864
|
+
label: t("modelSelector.confirmationSave"),
|
|
1865
|
+
category: t("commands.model.actionsCategory"),
|
|
1866
|
+
statusIcon: "\u2713",
|
|
1867
|
+
statusColor: SEMANTIC_COLORS.success
|
|
1868
|
+
});
|
|
1869
|
+
editItems.push({
|
|
1870
|
+
id: "__test__",
|
|
1871
|
+
label: t("modelSelector.connectionTestRetry"),
|
|
1872
|
+
category: t("commands.model.actionsCategory")
|
|
1873
|
+
});
|
|
1874
|
+
const editTitle = t("commands.model.editTitle").replace(
|
|
1875
|
+
"{model}",
|
|
1876
|
+
editingModel?.name ?? selectedModel
|
|
1877
|
+
);
|
|
1878
|
+
const editOverlay = isTestingConnection ? {
|
|
1879
|
+
type: "loading",
|
|
1880
|
+
message: t("modelSelector.autoTesting")
|
|
1881
|
+
} : validationError ? { type: "error", message: validationError } : null;
|
|
1882
|
+
return /* @__PURE__ */ React.createElement(
|
|
1883
|
+
SimpleSelector,
|
|
1884
|
+
{
|
|
1885
|
+
title: editTitle,
|
|
1886
|
+
items: editItems,
|
|
1887
|
+
groupByCategory: true,
|
|
1888
|
+
onSelect: (item) => {
|
|
1889
|
+
if (item.id === "__edit_apiKey__") {
|
|
1890
|
+
navigateTo("apiKey");
|
|
1891
|
+
} else if (item.id === "__edit_baseUrl__") {
|
|
1892
|
+
navigateTo("baseUrl");
|
|
1893
|
+
} else if (item.id === "__edit_modelParams__") {
|
|
1894
|
+
setActiveFieldIndex(0);
|
|
1895
|
+
navigateTo("modelParams");
|
|
1896
|
+
} else if (item.id === "__edit_contextLength__") {
|
|
1897
|
+
navigateTo("contextLength");
|
|
1898
|
+
} else if (item.id === "__save__") {
|
|
1899
|
+
handleConfirmation().catch((error) => {
|
|
1900
|
+
setValidationError(
|
|
1901
|
+
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1902
|
+
);
|
|
1903
|
+
});
|
|
1904
|
+
} else if (item.id === "__test__") {
|
|
1905
|
+
setConnectionTestResult(null);
|
|
1906
|
+
handleConnectionTest();
|
|
1907
|
+
}
|
|
1908
|
+
},
|
|
1909
|
+
onClose: handleBack,
|
|
1910
|
+
statusOverlay: editOverlay
|
|
1911
|
+
}
|
|
1912
|
+
);
|
|
1913
|
+
}
|
|
1914
|
+
const configItems = [
|
|
1915
|
+
{ label: "Provider", value: providerDisplayName },
|
|
1916
|
+
...selectedProvider === "azure" ? [{ label: "Resource Name", value: resourceName }] : [],
|
|
1917
|
+
...selectedProvider === "ollama" ? [{ label: "Server URL", value: ollamaBaseUrl }] : [],
|
|
1918
|
+
...selectedProvider === "custom-openai" ? [{ label: "API Base URL", value: customBaseUrl }] : [],
|
|
1919
|
+
{ label: "Model", value: selectedModel },
|
|
1920
|
+
...apiKey && showsApiKey ? [{ label: "API Key", value: `****${apiKey.slice(-4)}` }] : [],
|
|
1921
|
+
...maxTokens ? [{ label: "Max Tokens", value: maxTokens }] : [],
|
|
1922
|
+
{ label: "Context Length", value: contextLengthLabel },
|
|
1923
|
+
...supportsReasoningEffort ? [{ label: "Reasoning Effort", value: reasoningEffort }] : []
|
|
1924
|
+
];
|
|
1925
|
+
if (connectionTestResult) {
|
|
1926
|
+
configItems.push({
|
|
1927
|
+
label: "Connection",
|
|
1928
|
+
value: connectionTestResult.message,
|
|
1929
|
+
valueColor: connectionTestResult.success ? SEMANTIC_COLORS.success : SEMANTIC_COLORS.error
|
|
1930
|
+
});
|
|
1931
|
+
if (connectionTestResult.details && !connectionTestResult.success) {
|
|
1932
|
+
configItems.push({
|
|
1933
|
+
label: "Details",
|
|
1934
|
+
value: connectionTestResult.details
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
const testAndSaveSections = [
|
|
1984
1939
|
{
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1940
|
+
title: t("modelSelector.testAndSaveDesc"),
|
|
1941
|
+
items: configItems
|
|
1942
|
+
}
|
|
1943
|
+
];
|
|
1944
|
+
if (validationError) {
|
|
1945
|
+
testAndSaveSections.unshift({
|
|
1946
|
+
title: t("modelSelector.configError"),
|
|
1947
|
+
items: [
|
|
1948
|
+
{
|
|
1949
|
+
label: "Error",
|
|
1950
|
+
value: validationError,
|
|
1951
|
+
valueColor: SEMANTIC_COLORS.error
|
|
1952
|
+
}
|
|
1953
|
+
]
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
const testAndSaveActions = [];
|
|
1957
|
+
if (connectionTestResult?.success) {
|
|
1958
|
+
testAndSaveActions.push({
|
|
1959
|
+
key: "return",
|
|
1960
|
+
keyLabel: "Enter",
|
|
1961
|
+
description: t("modelSelector.confirmationSave"),
|
|
1962
|
+
onPress: () => {
|
|
1963
|
+
handleConfirmation().catch((error) => {
|
|
1964
|
+
setValidationError(
|
|
1965
|
+
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1966
|
+
);
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
});
|
|
1970
|
+
} else if (connectionTestResult && !connectionTestResult.success) {
|
|
1971
|
+
testAndSaveActions.push({
|
|
1972
|
+
key: "return",
|
|
1973
|
+
keyLabel: "Enter",
|
|
1974
|
+
description: t("modelSelector.connectionTestRetry"),
|
|
1975
|
+
onPress: () => {
|
|
1976
|
+
setConnectionTestResult(null);
|
|
1977
|
+
handleConnectionTest();
|
|
1978
|
+
}
|
|
1979
|
+
});
|
|
1980
|
+
testAndSaveActions.push({
|
|
1981
|
+
key: "s",
|
|
1982
|
+
keyLabel: "s",
|
|
1983
|
+
description: t("modelSelector.saveAnyway"),
|
|
1984
|
+
onPress: () => {
|
|
1985
|
+
handleConfirmation().catch((error) => {
|
|
1986
|
+
setValidationError(
|
|
1987
|
+
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1988
|
+
);
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
const testAndSaveOverlay = isTestingConnection ? {
|
|
1994
|
+
type: "loading",
|
|
1995
|
+
message: t("modelSelector.autoTesting")
|
|
1996
|
+
} : null;
|
|
1997
|
+
return /* @__PURE__ */ React.createElement(
|
|
1998
|
+
InfoPanel,
|
|
1999
|
+
{
|
|
2000
|
+
title: t("modelSelector.testAndSaveTitle"),
|
|
2001
|
+
sections: testAndSaveSections,
|
|
2002
|
+
actions: testAndSaveActions,
|
|
2003
|
+
onClose: handleBack,
|
|
2004
|
+
statusOverlay: testAndSaveOverlay
|
|
2005
|
+
}
|
|
2006
|
+
);
|
|
1997
2007
|
}
|
|
1998
2008
|
if (currentScreen === "anthropicSubMenu") {
|
|
1999
|
-
const
|
|
2000
|
-
{ label: "Official Anthropic API", value: "official" },
|
|
2001
|
-
{ label: "BigDream (Community Proxy)", value: "bigdream" },
|
|
2002
|
-
{ label: "OpenDev (Community Proxy)", value: "opendev" },
|
|
2003
|
-
{ label: "Custom Anthropic-Compatible API", value: "custom" }
|
|
2004
|
-
];
|
|
2005
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
2006
|
-
Box,
|
|
2009
|
+
const anthropicItems = [
|
|
2007
2010
|
{
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
borderColor: theme.secondaryBorder,
|
|
2012
|
-
paddingX: 2,
|
|
2013
|
-
paddingY: 1
|
|
2011
|
+
id: "official",
|
|
2012
|
+
label: t("modelSelector.anthropicOfficial"),
|
|
2013
|
+
description: t("modelSelector.anthropicOfficialDesc")
|
|
2014
2014
|
},
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2015
|
+
{
|
|
2016
|
+
id: "bigdream",
|
|
2017
|
+
label: t("modelSelector.anthropicBigdream"),
|
|
2018
|
+
description: t("modelSelector.anthropicBigdreamDesc")
|
|
2019
|
+
},
|
|
2020
|
+
{
|
|
2021
|
+
id: "opendev",
|
|
2022
|
+
label: t("modelSelector.anthropicOpendev"),
|
|
2023
|
+
description: t("modelSelector.anthropicOpendevDesc")
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
id: "custom",
|
|
2027
|
+
label: t("modelSelector.anthropicCustom"),
|
|
2028
|
+
description: t("modelSelector.anthropicCustomDesc")
|
|
2029
|
+
}
|
|
2030
|
+
];
|
|
2031
|
+
return /* @__PURE__ */ React.createElement(
|
|
2032
|
+
SimpleSelector,
|
|
2033
|
+
{
|
|
2034
|
+
title: t("modelSelector.anthropicSubMenu"),
|
|
2035
|
+
subtitle: t("modelSelector.anthropicSubMenuDesc"),
|
|
2036
|
+
items: anthropicItems,
|
|
2037
|
+
onSelect: (item) => handleAnthropicProviderSelection(
|
|
2038
|
+
item.id
|
|
2039
|
+
),
|
|
2040
|
+
onClose: handleBack
|
|
2041
|
+
}
|
|
2042
|
+
);
|
|
2024
2043
|
}
|
|
2044
|
+
const providerSelectorItems = providerOptions.map((opt) => ({
|
|
2045
|
+
id: opt.value,
|
|
2046
|
+
label: opt.label
|
|
2047
|
+
}));
|
|
2025
2048
|
return /* @__PURE__ */ React.createElement(
|
|
2026
|
-
|
|
2049
|
+
SimpleSelector,
|
|
2027
2050
|
{
|
|
2028
|
-
title: "
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2051
|
+
title: t("modelSelector.providerSelection"),
|
|
2052
|
+
subtitle: t("modelSelector.providerSelectionDesc"),
|
|
2053
|
+
items: providerSelectorItems,
|
|
2054
|
+
onSelect: (item) => handleProviderSelection(item.id),
|
|
2055
|
+
onClose: () => {
|
|
2056
|
+
if (onCancel) {
|
|
2057
|
+
onCancel();
|
|
2058
|
+
} else {
|
|
2059
|
+
onDone();
|
|
2035
2060
|
}
|
|
2036
|
-
|
|
2061
|
+
}
|
|
2037
2062
|
}
|
|
2038
2063
|
);
|
|
2039
2064
|
}
|