@shareai-lab/kode 1.2.0 → 2.0.2
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 +25 -388
- package/cli-acp.js +82 -0
- package/cli.js +89 -79
- package/dist/REPL-GIU4ZIXM.js +42 -0
- package/dist/acp-H3VJ77YG.js +1357 -0
- package/dist/acp-H3VJ77YG.js.map +7 -0
- package/dist/agentsValidate-XP3CFN6F.js +373 -0
- package/dist/agentsValidate-XP3CFN6F.js.map +7 -0
- package/dist/ask-3G5H5KD5.js +125 -0
- package/dist/ask-3G5H5KD5.js.map +7 -0
- package/dist/autoUpdater-DNRMJWFQ.js +17 -0
- package/dist/chunk-2KWKUXLT.js +490 -0
- package/dist/chunk-2KWKUXLT.js.map +7 -0
- package/dist/chunk-2PMO2FS2.js +1097 -0
- package/dist/chunk-2PMO2FS2.js.map +7 -0
- package/dist/chunk-3RUXVV4S.js +23 -0
- package/dist/chunk-3RUXVV4S.js.map +7 -0
- package/dist/chunk-3TXNP6HH.js +240 -0
- package/dist/chunk-3TXNP6HH.js.map +7 -0
- package/dist/chunk-4GAIJGRH.js +472 -0
- package/dist/chunk-4GAIJGRH.js.map +7 -0
- package/dist/chunk-4RTX4AG4.js +249 -0
- package/dist/chunk-4RTX4AG4.js.map +7 -0
- package/dist/chunk-54DNHKOD.js +511 -0
- package/dist/chunk-54DNHKOD.js.map +7 -0
- package/dist/chunk-67PY5IX6.js +34 -0
- package/dist/chunk-67PY5IX6.js.map +7 -0
- package/dist/chunk-6DRDLOLP.js +2613 -0
- package/dist/chunk-6DRDLOLP.js.map +7 -0
- package/dist/chunk-7CQVZNQV.js +1609 -0
- package/dist/chunk-7CQVZNQV.js.map +7 -0
- package/dist/chunk-ABLVTESJ.js +19 -0
- package/dist/chunk-ABLVTESJ.js.map +7 -0
- package/dist/{utils/config.js → chunk-AIMIPK4B.js} +351 -171
- package/dist/chunk-AIMIPK4B.js.map +7 -0
- package/dist/{utils/autoUpdater.js → chunk-BHGTA6JQ.js} +38 -21
- package/dist/chunk-BHGTA6JQ.js.map +7 -0
- package/dist/chunk-CIG63V4E.js +72 -0
- package/dist/chunk-CIG63V4E.js.map +7 -0
- package/dist/chunk-E6YNABER.js +24 -0
- package/dist/chunk-E6YNABER.js.map +7 -0
- package/dist/chunk-EH34V7CY.js +191 -0
- package/dist/chunk-EH34V7CY.js.map +7 -0
- package/dist/{cost-tracker.js → chunk-EZXMVTDU.js} +51 -32
- package/dist/chunk-EZXMVTDU.js.map +7 -0
- package/dist/chunk-FH5CHM6L.js +148 -0
- package/dist/chunk-FH5CHM6L.js.map +7 -0
- package/dist/chunk-G6I7XROM.js +138 -0
- package/dist/chunk-G6I7XROM.js.map +7 -0
- package/dist/chunk-HN4E4UUQ.js +96 -0
- package/dist/chunk-HN4E4UUQ.js.map +7 -0
- package/dist/chunk-HSPVVDIW.js +30198 -0
- package/dist/chunk-HSPVVDIW.js.map +7 -0
- package/dist/{services/systemReminder.js → chunk-IE2CG2TV.js} +221 -59
- package/dist/chunk-IE2CG2TV.js.map +7 -0
- package/dist/chunk-JC6NCUG5.js +11 -0
- package/dist/chunk-K2MI4TPB.js +1256 -0
- package/dist/chunk-K2MI4TPB.js.map +7 -0
- package/dist/chunk-KAA5BGMQ.js +12 -0
- package/dist/chunk-KAA5BGMQ.js.map +7 -0
- package/dist/chunk-MN77D2F7.js +2931 -0
- package/dist/chunk-MN77D2F7.js.map +7 -0
- package/dist/chunk-NPFOMITO.js +21 -0
- package/dist/chunk-NPFOMITO.js.map +7 -0
- package/dist/chunk-NQLEUHMS.js +196 -0
- package/dist/chunk-NQLEUHMS.js.map +7 -0
- package/dist/chunk-OIFQB3S4.js +515 -0
- package/dist/chunk-OIFQB3S4.js.map +7 -0
- package/dist/chunk-OWTG2W3A.js +164 -0
- package/dist/chunk-OWTG2W3A.js.map +7 -0
- package/dist/chunk-OZNRLY3E.js +735 -0
- package/dist/chunk-OZNRLY3E.js.map +7 -0
- package/dist/{utils/debugLogger.js → chunk-QYFKRZQC.js} +107 -204
- package/dist/chunk-QYFKRZQC.js.map +7 -0
- package/dist/chunk-S3J2TLV6.js +16 -0
- package/dist/chunk-S3J2TLV6.js.map +7 -0
- package/dist/chunk-S6HRABTA.js +95 -0
- package/dist/chunk-S6HRABTA.js.map +7 -0
- package/dist/{utils/theme.js → chunk-SDGKPKDK.js} +28 -6
- package/dist/chunk-SDGKPKDK.js.map +7 -0
- package/dist/chunk-SRZZFAS7.js +766 -0
- package/dist/chunk-SRZZFAS7.js.map +7 -0
- package/dist/chunk-UKHTVRJM.js +47 -0
- package/dist/chunk-UKHTVRJM.js.map +7 -0
- package/dist/chunk-UYXEDKOZ.js +24 -0
- package/dist/chunk-UYXEDKOZ.js.map +7 -0
- package/dist/chunk-VBXVYQYY.js +145 -0
- package/dist/chunk-VBXVYQYY.js.map +7 -0
- package/dist/chunk-WVHORZQ5.js +17 -0
- package/dist/chunk-WVHORZQ5.js.map +7 -0
- package/dist/chunk-WWUWDNWW.js +49 -0
- package/dist/chunk-WWUWDNWW.js.map +7 -0
- package/dist/{utils/model.js → chunk-Z33T5YN5.js} +194 -227
- package/dist/chunk-Z33T5YN5.js.map +7 -0
- package/dist/{services/openai.js → chunk-ZQU3TXLC.js} +168 -234
- package/dist/chunk-ZQU3TXLC.js.map +7 -0
- package/dist/cli-SRV2INSL.js +3917 -0
- package/dist/cli-SRV2INSL.js.map +7 -0
- package/dist/commands-TWH6PGVG.js +46 -0
- package/dist/config-6ZMBCL23.js +81 -0
- package/dist/context-JQIOOI4W.js +30 -0
- package/dist/costTracker-6SL26FDB.js +19 -0
- package/dist/customCommands-DNEJS3ZU.js +25 -0
- package/dist/customCommands-DNEJS3ZU.js.map +7 -0
- package/dist/env-OFAXZ3XG.js +22 -0
- package/dist/env-OFAXZ3XG.js.map +7 -0
- package/dist/index.js +34 -5
- package/dist/index.js.map +4 -4
- package/dist/kodeAgentSessionId-X6XWQW7B.js +13 -0
- package/dist/kodeAgentSessionId-X6XWQW7B.js.map +7 -0
- package/dist/kodeAgentSessionLoad-6N27AC5K.js +18 -0
- package/dist/kodeAgentSessionLoad-6N27AC5K.js.map +7 -0
- package/dist/kodeAgentSessionResume-HUSAEO24.js +16 -0
- package/dist/kodeAgentSessionResume-HUSAEO24.js.map +7 -0
- package/dist/kodeAgentStreamJson-NXFN7TXH.js +13 -0
- package/dist/kodeAgentStreamJson-NXFN7TXH.js.map +7 -0
- package/dist/kodeAgentStreamJsonSession-GRWG3SPE.js +131 -0
- package/dist/kodeAgentStreamJsonSession-GRWG3SPE.js.map +7 -0
- package/dist/kodeAgentStructuredStdio-HGWJT7CU.js +10 -0
- package/dist/kodeAgentStructuredStdio-HGWJT7CU.js.map +7 -0
- package/dist/kodeHooks-TDMXFWSO.js +36 -0
- package/dist/kodeHooks-TDMXFWSO.js.map +7 -0
- package/dist/llm-XVXWYOHK.js +3118 -0
- package/dist/llm-XVXWYOHK.js.map +7 -0
- package/dist/llmLazy-7TD5N7XP.js +15 -0
- package/dist/llmLazy-7TD5N7XP.js.map +7 -0
- package/dist/loader-AUXIJTY6.js +28 -0
- package/dist/loader-AUXIJTY6.js.map +7 -0
- package/dist/mcp-BXJ3K7NZ.js +49 -0
- package/dist/mcp-BXJ3K7NZ.js.map +7 -0
- package/dist/{services/mentionProcessor.js → mentionProcessor-YD7YXYGF.js} +61 -50
- package/dist/mentionProcessor-YD7YXYGF.js.map +7 -0
- package/dist/messages-OFUJSPRV.js +63 -0
- package/dist/messages-OFUJSPRV.js.map +7 -0
- package/dist/model-KPYCXWBK.js +30 -0
- package/dist/model-KPYCXWBK.js.map +7 -0
- package/dist/openai-5G5D5Q4B.js +29 -0
- package/dist/openai-5G5D5Q4B.js.map +7 -0
- package/dist/outputStyles-HLDXFQK3.js +28 -0
- package/dist/outputStyles-HLDXFQK3.js.map +7 -0
- package/dist/package.json +1 -1
- package/dist/pluginRuntime-FPTKK6NY.js +218 -0
- package/dist/pluginRuntime-FPTKK6NY.js.map +7 -0
- package/dist/pluginValidation-DSFXZ4GF.js +17 -0
- package/dist/pluginValidation-DSFXZ4GF.js.map +7 -0
- package/dist/prompts-LWLAJRS2.js +48 -0
- package/dist/prompts-LWLAJRS2.js.map +7 -0
- package/dist/query-HVPWL27C.js +50 -0
- package/dist/query-HVPWL27C.js.map +7 -0
- package/dist/responsesStreaming-AW344PQO.js +10 -0
- package/dist/responsesStreaming-AW344PQO.js.map +7 -0
- package/dist/ripgrep-YOPCY2GO.js +17 -0
- package/dist/ripgrep-YOPCY2GO.js.map +7 -0
- package/dist/skillMarketplace-PSNKDINM.js +37 -0
- package/dist/skillMarketplace-PSNKDINM.js.map +7 -0
- package/dist/state-KNRWP3FO.js +16 -0
- package/dist/state-KNRWP3FO.js.map +7 -0
- package/dist/theme-7S2QN2FO.js +14 -0
- package/dist/theme-7S2QN2FO.js.map +7 -0
- package/dist/toolPermissionContext-65L65VEZ.js +17 -0
- package/dist/toolPermissionContext-65L65VEZ.js.map +7 -0
- package/dist/toolPermissionSettings-GPOBH4IV.js +18 -0
- package/dist/toolPermissionSettings-GPOBH4IV.js.map +7 -0
- package/dist/tools-FZU2FZBD.js +47 -0
- package/dist/tools-FZU2FZBD.js.map +7 -0
- package/dist/userInput-VHNBN2MW.js +311 -0
- package/dist/userInput-VHNBN2MW.js.map +7 -0
- package/dist/uuid-QN2CNKKN.js +9 -0
- package/dist/uuid-QN2CNKKN.js.map +7 -0
- package/package.json +43 -14
- package/scripts/binary-utils.cjs +62 -0
- package/scripts/cli-acp-wrapper.cjs +82 -0
- package/scripts/cli-wrapper.cjs +105 -0
- package/scripts/postinstall.js +135 -9
- package/LICENSE +0 -201
- package/README.zh-CN.md +0 -312
- package/dist/ProjectOnboarding.js +0 -99
- package/dist/ProjectOnboarding.js.map +0 -7
- package/dist/Tool.js +0 -1
- package/dist/commands/agents.js +0 -2087
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/approvedTools.js +0 -36
- package/dist/commands/approvedTools.js.map +0 -7
- package/dist/commands/bug.js +0 -21
- package/dist/commands/bug.js.map +0 -7
- package/dist/commands/clear.js +0 -37
- package/dist/commands/clear.js.map +0 -7
- package/dist/commands/compact.js +0 -104
- package/dist/commands/compact.js.map +0 -7
- package/dist/commands/config.js +0 -20
- package/dist/commands/config.js.map +0 -7
- package/dist/commands/cost.js +0 -19
- package/dist/commands/cost.js.map +0 -7
- package/dist/commands/ctx_viz.js +0 -152
- package/dist/commands/ctx_viz.js.map +0 -7
- package/dist/commands/doctor.js +0 -25
- package/dist/commands/doctor.js.map +0 -7
- package/dist/commands/help.js +0 -20
- package/dist/commands/help.js.map +0 -7
- package/dist/commands/init.js +0 -38
- package/dist/commands/init.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -34
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/model.js +0 -41
- package/dist/commands/model.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/refreshCommands.js +0 -37
- package/dist/commands/refreshCommands.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/resume.js +0 -35
- package/dist/commands/resume.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/commands/terminalSetup.js +0 -163
- package/dist/commands/terminalSetup.js.map +0 -7
- package/dist/commands.js +0 -84
- package/dist/commands.js.map +0 -7
- package/dist/components/ApproveApiKey.js +0 -74
- package/dist/components/ApproveApiKey.js.map +0 -7
- package/dist/components/AsciiLogo.js +0 -12
- package/dist/components/AsciiLogo.js.map +0 -7
- package/dist/components/AutoUpdater.js +0 -74
- package/dist/components/AutoUpdater.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/Config.js +0 -166
- package/dist/components/Config.js.map +0 -7
- package/dist/components/ConsoleOAuthFlow.js +0 -188
- package/dist/components/ConsoleOAuthFlow.js.map +0 -7
- package/dist/components/Cost.js +0 -13
- package/dist/components/Cost.js.map +0 -7
- package/dist/components/CostThresholdDialog.js +0 -38
- package/dist/components/CostThresholdDialog.js.map +0 -7
- package/dist/components/CustomSelect/option-map.js +0 -32
- package/dist/components/CustomSelect/option-map.js.map +0 -7
- package/dist/components/CustomSelect/select-option.js +0 -34
- package/dist/components/CustomSelect/select-option.js.map +0 -7
- package/dist/components/CustomSelect/select.js +0 -64
- package/dist/components/CustomSelect/select.js.map +0 -7
- package/dist/components/CustomSelect/theme.js +0 -1
- package/dist/components/CustomSelect/use-select-state.js +0 -220
- package/dist/components/CustomSelect/use-select-state.js.map +0 -7
- package/dist/components/CustomSelect/use-select.js +0 -21
- package/dist/components/CustomSelect/use-select.js.map +0 -7
- package/dist/components/FallbackToolUseRejectedMessage.js +0 -11
- package/dist/components/FallbackToolUseRejectedMessage.js.map +0 -7
- package/dist/components/FileEditToolUpdatedMessage.js +0 -32
- package/dist/components/FileEditToolUpdatedMessage.js.map +0 -7
- package/dist/components/Help.js +0 -41
- package/dist/components/Help.js.map +0 -7
- package/dist/components/HighlightedCode.js +0 -30
- package/dist/components/HighlightedCode.js.map +0 -7
- package/dist/components/InvalidConfigDialog.js +0 -83
- package/dist/components/InvalidConfigDialog.js.map +0 -7
- package/dist/components/Link.js +0 -18
- package/dist/components/Link.js.map +0 -7
- package/dist/components/LogSelector.js +0 -50
- package/dist/components/LogSelector.js.map +0 -7
- package/dist/components/Logo.js +0 -94
- package/dist/components/Logo.js.map +0 -7
- package/dist/components/MCPServerApprovalDialog.js +0 -79
- package/dist/components/MCPServerApprovalDialog.js.map +0 -7
- package/dist/components/MCPServerDialogCopy.js +0 -11
- package/dist/components/MCPServerDialogCopy.js.map +0 -7
- package/dist/components/MCPServerMultiselectDialog.js +0 -80
- package/dist/components/MCPServerMultiselectDialog.js.map +0 -7
- package/dist/components/Message.js +0 -146
- package/dist/components/Message.js.map +0 -7
- package/dist/components/MessageResponse.js +0 -9
- package/dist/components/MessageResponse.js.map +0 -7
- package/dist/components/MessageSelector.js +0 -133
- package/dist/components/MessageSelector.js.map +0 -7
- package/dist/components/ModeIndicator.js +0 -38
- package/dist/components/ModeIndicator.js.map +0 -7
- package/dist/components/ModelConfig.js +0 -208
- package/dist/components/ModelConfig.js.map +0 -7
- package/dist/components/ModelListManager.js +0 -140
- package/dist/components/ModelListManager.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -1985
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/components/Onboarding.js +0 -153
- package/dist/components/Onboarding.js.map +0 -7
- package/dist/components/PressEnterToContinue.js +0 -10
- package/dist/components/PressEnterToContinue.js.map +0 -7
- package/dist/components/PromptInput.js +0 -488
- package/dist/components/PromptInput.js.map +0 -7
- package/dist/components/SentryErrorBoundary.js +0 -27
- package/dist/components/SentryErrorBoundary.js.map +0 -7
- package/dist/components/Spinner.js +0 -101
- package/dist/components/Spinner.js.map +0 -7
- package/dist/components/StickerRequestForm.js +0 -7
- package/dist/components/StickerRequestForm.js.map +0 -7
- package/dist/components/StructuredDiff.js +0 -148
- package/dist/components/StructuredDiff.js.map +0 -7
- package/dist/components/TextInput.js +0 -100
- package/dist/components/TextInput.js.map +0 -7
- package/dist/components/TodoItem.js +0 -35
- package/dist/components/TodoItem.js.map +0 -7
- package/dist/components/TokenWarning.js +0 -19
- package/dist/components/TokenWarning.js.map +0 -7
- package/dist/components/ToolUseLoader.js +0 -24
- package/dist/components/ToolUseLoader.js.map +0 -7
- package/dist/components/TrustDialog.js +0 -76
- package/dist/components/TrustDialog.js.map +0 -7
- package/dist/components/binary-feedback/BinaryFeedback.js +0 -50
- package/dist/components/binary-feedback/BinaryFeedback.js.map +0 -7
- package/dist/components/binary-feedback/BinaryFeedbackOption.js +0 -94
- package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +0 -7
- package/dist/components/binary-feedback/BinaryFeedbackView.js +0 -139
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +0 -7
- package/dist/components/binary-feedback/utils.js +0 -161
- package/dist/components/binary-feedback/utils.js.map +0 -7
- package/dist/components/messages/AssistantBashOutputMessage.js +0 -23
- package/dist/components/messages/AssistantBashOutputMessage.js.map +0 -7
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js +0 -36
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +0 -7
- package/dist/components/messages/AssistantRedactedThinkingMessage.js +0 -12
- package/dist/components/messages/AssistantRedactedThinkingMessage.js.map +0 -7
- package/dist/components/messages/AssistantTextMessage.js +0 -78
- package/dist/components/messages/AssistantTextMessage.js.map +0 -7
- package/dist/components/messages/AssistantThinkingMessage.js +0 -27
- package/dist/components/messages/AssistantThinkingMessage.js.map +0 -7
- package/dist/components/messages/AssistantToolUseMessage.js +0 -91
- package/dist/components/messages/AssistantToolUseMessage.js.map +0 -7
- package/dist/components/messages/TaskProgressMessage.js +0 -11
- package/dist/components/messages/TaskProgressMessage.js.map +0 -7
- package/dist/components/messages/TaskToolMessage.js +0 -39
- package/dist/components/messages/TaskToolMessage.js.map +0 -7
- package/dist/components/messages/UserBashInputMessage.js +0 -18
- package/dist/components/messages/UserBashInputMessage.js.map +0 -7
- package/dist/components/messages/UserCommandMessage.js +0 -20
- package/dist/components/messages/UserCommandMessage.js.map +0 -7
- package/dist/components/messages/UserKodingInputMessage.js +0 -18
- package/dist/components/messages/UserKodingInputMessage.js.map +0 -7
- package/dist/components/messages/UserPromptMessage.js +0 -20
- package/dist/components/messages/UserPromptMessage.js.map +0 -7
- package/dist/components/messages/UserTextMessage.js +0 -25
- package/dist/components/messages/UserTextMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +0 -10
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/UserToolErrorMessage.js +0 -15
- package/dist/components/messages/UserToolResultMessage/UserToolErrorMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +0 -25
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +0 -47
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +0 -23
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +0 -7
- package/dist/components/messages/UserToolResultMessage/utils.js +0 -42
- package/dist/components/messages/UserToolResultMessage/utils.js.map +0 -7
- package/dist/components/permissions/BashPermissionRequest/BashPermissionRequest.js +0 -112
- package/dist/components/permissions/BashPermissionRequest/BashPermissionRequest.js.map +0 -7
- package/dist/components/permissions/FallbackPermissionRequest.js +0 -131
- package/dist/components/permissions/FallbackPermissionRequest.js.map +0 -7
- package/dist/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js +0 -159
- package/dist/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js.map +0 -7
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js +0 -58
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +0 -7
- package/dist/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js +0 -153
- package/dist/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js.map +0 -7
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js +0 -70
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +0 -7
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +0 -212
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +0 -7
- package/dist/components/permissions/PermissionRequest.js +0 -70
- package/dist/components/permissions/PermissionRequest.js.map +0 -7
- package/dist/components/permissions/PermissionRequestTitle.js +0 -52
- package/dist/components/permissions/PermissionRequestTitle.js.map +0 -7
- package/dist/components/permissions/hooks.js +0 -28
- package/dist/components/permissions/hooks.js.map +0 -7
- package/dist/components/permissions/toolUseOptions.js +0 -46
- package/dist/components/permissions/toolUseOptions.js.map +0 -7
- package/dist/components/permissions/utils.js +0 -21
- package/dist/components/permissions/utils.js.map +0 -7
- package/dist/constants/betas.js +0 -11
- package/dist/constants/betas.js.map +0 -7
- package/dist/constants/claude-asterisk-ascii-art.js +0 -242
- package/dist/constants/claude-asterisk-ascii-art.js.map +0 -7
- package/dist/constants/figures.js +0 -6
- package/dist/constants/figures.js.map +0 -7
- package/dist/constants/keys.js +0 -7
- package/dist/constants/keys.js.map +0 -7
- package/dist/constants/macros.js +0 -13
- package/dist/constants/macros.js.map +0 -7
- package/dist/constants/modelCapabilities.js +0 -154
- package/dist/constants/modelCapabilities.js.map +0 -7
- package/dist/constants/models.js +0 -1034
- package/dist/constants/models.js.map +0 -7
- package/dist/constants/oauth.js +0 -18
- package/dist/constants/oauth.js.map +0 -7
- package/dist/constants/product.js +0 -26
- package/dist/constants/product.js.map +0 -7
- package/dist/constants/prompts.js +0 -168
- package/dist/constants/prompts.js.map +0 -7
- package/dist/constants/releaseNotes.js +0 -9
- package/dist/constants/releaseNotes.js.map +0 -7
- package/dist/context/PermissionContext.js +0 -111
- package/dist/context/PermissionContext.js.map +0 -7
- package/dist/context.js +0 -259
- package/dist/context.js.map +0 -7
- package/dist/cost-tracker.js.map +0 -7
- package/dist/entrypoints/cli.js +0 -1107
- package/dist/entrypoints/cli.js.map +0 -7
- package/dist/entrypoints/mcp.js +0 -150
- package/dist/entrypoints/mcp.js.map +0 -7
- package/dist/history.js +0 -25
- package/dist/history.js.map +0 -7
- package/dist/hooks/useApiKeyVerification.js +0 -12
- package/dist/hooks/useApiKeyVerification.js.map +0 -7
- package/dist/hooks/useArrowKeyHistory.js +0 -50
- package/dist/hooks/useArrowKeyHistory.js.map +0 -7
- package/dist/hooks/useCanUseTool.js +0 -112
- package/dist/hooks/useCanUseTool.js.map +0 -7
- package/dist/hooks/useCancelRequest.js +0 -30
- package/dist/hooks/useCancelRequest.js.map +0 -7
- package/dist/hooks/useDoublePress.js +0 -31
- package/dist/hooks/useDoublePress.js.map +0 -7
- package/dist/hooks/useExitOnCtrlCD.js +0 -26
- package/dist/hooks/useExitOnCtrlCD.js.map +0 -7
- package/dist/hooks/useInterval.js +0 -18
- package/dist/hooks/useInterval.js.map +0 -7
- package/dist/hooks/useLogMessages.js +0 -14
- package/dist/hooks/useLogMessages.js.map +0 -7
- package/dist/hooks/useLogStartupTime.js +0 -15
- package/dist/hooks/useLogStartupTime.js.map +0 -7
- package/dist/hooks/useNotifyAfterTimeout.js +0 -42
- package/dist/hooks/useNotifyAfterTimeout.js.map +0 -7
- package/dist/hooks/usePermissionRequestLogging.js +0 -28
- package/dist/hooks/usePermissionRequestLogging.js.map +0 -7
- package/dist/hooks/useTerminalSize.js +0 -38
- package/dist/hooks/useTerminalSize.js.map +0 -7
- package/dist/hooks/useTextInput.js +0 -250
- package/dist/hooks/useTextInput.js.map +0 -7
- package/dist/hooks/useUnifiedCompletion.js +0 -929
- package/dist/hooks/useUnifiedCompletion.js.map +0 -7
- package/dist/messages.js +0 -33
- package/dist/messages.js.map +0 -7
- package/dist/permissions.js +0 -194
- package/dist/permissions.js.map +0 -7
- package/dist/query.js +0 -492
- package/dist/query.js.map +0 -7
- package/dist/screens/ConfigureNpmPrefix.js +0 -128
- package/dist/screens/ConfigureNpmPrefix.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
- package/dist/screens/LogList.js +0 -55
- package/dist/screens/LogList.js.map +0 -7
- package/dist/screens/REPL.js +0 -593
- package/dist/screens/REPL.js.map +0 -7
- package/dist/screens/ResumeConversation.js +0 -56
- package/dist/screens/ResumeConversation.js.map +0 -7
- package/dist/services/adapters/base.js +0 -29
- package/dist/services/adapters/base.js.map +0 -7
- package/dist/services/adapters/chatCompletions.js +0 -69
- package/dist/services/adapters/chatCompletions.js.map +0 -7
- package/dist/services/adapters/responsesAPI.js +0 -126
- package/dist/services/adapters/responsesAPI.js.map +0 -7
- package/dist/services/browserMocks.js +0 -48
- package/dist/services/browserMocks.js.map +0 -7
- package/dist/services/claude.js +0 -1605
- package/dist/services/claude.js.map +0 -7
- package/dist/services/customCommands.js +0 -359
- package/dist/services/customCommands.js.map +0 -7
- package/dist/services/fileFreshness.js +0 -280
- package/dist/services/fileFreshness.js.map +0 -7
- package/dist/services/gpt5ConnectionTest.js +0 -248
- package/dist/services/gpt5ConnectionTest.js.map +0 -7
- package/dist/services/mcpClient.js +0 -435
- package/dist/services/mcpClient.js.map +0 -7
- package/dist/services/mcpServerApproval.js +0 -55
- package/dist/services/mcpServerApproval.js.map +0 -7
- package/dist/services/mentionProcessor.js.map +0 -7
- package/dist/services/modelAdapterFactory.js +0 -47
- package/dist/services/modelAdapterFactory.js.map +0 -7
- package/dist/services/notifier.js +0 -35
- package/dist/services/notifier.js.map +0 -7
- package/dist/services/oauth.js +0 -259
- package/dist/services/oauth.js.map +0 -7
- package/dist/services/openai.js.map +0 -7
- package/dist/services/responseStateManager.js +0 -68
- package/dist/services/responseStateManager.js.map +0 -7
- package/dist/services/sentry.js +0 -9
- package/dist/services/sentry.js.map +0 -7
- package/dist/services/statsig.js +0 -112
- package/dist/services/statsig.js.map +0 -7
- package/dist/services/statsigStorage.js +0 -75
- package/dist/services/statsigStorage.js.map +0 -7
- package/dist/services/systemReminder.js.map +0 -7
- package/dist/services/vcr.js +0 -133
- package/dist/services/vcr.js.map +0 -7
- package/dist/tools/ArchitectTool/ArchitectTool.js +0 -119
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +0 -7
- package/dist/tools/ArchitectTool/prompt.js +0 -18
- package/dist/tools/ArchitectTool/prompt.js.map +0 -7
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +0 -423
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +0 -7
- package/dist/tools/BashTool/BashTool.js +0 -188
- package/dist/tools/BashTool/BashTool.js.map +0 -7
- package/dist/tools/BashTool/BashToolResultMessage.js +0 -21
- package/dist/tools/BashTool/BashToolResultMessage.js.map +0 -7
- package/dist/tools/BashTool/OutputLine.js +0 -30
- package/dist/tools/BashTool/OutputLine.js.map +0 -7
- package/dist/tools/BashTool/prompt.js +0 -179
- package/dist/tools/BashTool/prompt.js.map +0 -7
- package/dist/tools/BashTool/utils.js +0 -51
- package/dist/tools/BashTool/utils.js.map +0 -7
- package/dist/tools/FileEditTool/FileEditTool.js +0 -228
- package/dist/tools/FileEditTool/FileEditTool.js.map +0 -7
- package/dist/tools/FileEditTool/prompt.js +0 -54
- package/dist/tools/FileEditTool/prompt.js.map +0 -7
- package/dist/tools/FileEditTool/utils.js +0 -42
- package/dist/tools/FileEditTool/utils.js.map +0 -7
- package/dist/tools/FileReadTool/FileReadTool.js +0 -272
- package/dist/tools/FileReadTool/FileReadTool.js.map +0 -7
- package/dist/tools/FileReadTool/prompt.js +0 -10
- package/dist/tools/FileReadTool/prompt.js.map +0 -7
- package/dist/tools/FileWriteTool/FileWriteTool.js +0 -204
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +0 -7
- package/dist/tools/FileWriteTool/prompt.js +0 -14
- package/dist/tools/FileWriteTool/prompt.js.map +0 -7
- package/dist/tools/GlobTool/GlobTool.js +0 -88
- package/dist/tools/GlobTool/GlobTool.js.map +0 -7
- package/dist/tools/GlobTool/prompt.js +0 -12
- package/dist/tools/GlobTool/prompt.js.map +0 -7
- package/dist/tools/GrepTool/GrepTool.js +0 -107
- package/dist/tools/GrepTool/GrepTool.js.map +0 -7
- package/dist/tools/GrepTool/prompt.js +0 -15
- package/dist/tools/GrepTool/prompt.js.map +0 -7
- package/dist/tools/MCPTool/MCPTool.js +0 -90
- package/dist/tools/MCPTool/MCPTool.js.map +0 -7
- package/dist/tools/MCPTool/prompt.js +0 -7
- package/dist/tools/MCPTool/prompt.js.map +0 -7
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +0 -103
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +0 -7
- package/dist/tools/MemoryReadTool/prompt.js +0 -7
- package/dist/tools/MemoryReadTool/prompt.js.map +0 -7
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +0 -77
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +0 -7
- package/dist/tools/MemoryWriteTool/prompt.js +0 -7
- package/dist/tools/MemoryWriteTool/prompt.js.map +0 -7
- package/dist/tools/MultiEditTool/MultiEditTool.js +0 -308
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +0 -7
- package/dist/tools/MultiEditTool/prompt.js +0 -48
- package/dist/tools/MultiEditTool/prompt.js.map +0 -7
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +0 -238
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +0 -7
- package/dist/tools/NotebookEditTool/prompt.js +0 -7
- package/dist/tools/NotebookEditTool/prompt.js.map +0 -7
- package/dist/tools/NotebookReadTool/NotebookReadTool.js +0 -212
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +0 -7
- package/dist/tools/NotebookReadTool/prompt.js +0 -7
- package/dist/tools/NotebookReadTool/prompt.js.map +0 -7
- package/dist/tools/StickerRequestTool/StickerRequestTool.js +0 -86
- package/dist/tools/StickerRequestTool/StickerRequestTool.js.map +0 -7
- package/dist/tools/StickerRequestTool/prompt.js +0 -23
- package/dist/tools/StickerRequestTool/prompt.js.map +0 -7
- package/dist/tools/TaskTool/TaskTool.js +0 -351
- package/dist/tools/TaskTool/TaskTool.js.map +0 -7
- package/dist/tools/TaskTool/constants.js +0 -5
- package/dist/tools/TaskTool/constants.js.map +0 -7
- package/dist/tools/TaskTool/prompt.js +0 -82
- package/dist/tools/TaskTool/prompt.js.map +0 -7
- package/dist/tools/ThinkTool/ThinkTool.js +0 -48
- package/dist/tools/ThinkTool/ThinkTool.js.map +0 -7
- package/dist/tools/ThinkTool/prompt.js +0 -16
- package/dist/tools/ThinkTool/prompt.js.map +0 -7
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +0 -216
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +0 -7
- package/dist/tools/TodoWriteTool/prompt.js +0 -66
- package/dist/tools/TodoWriteTool/prompt.js.map +0 -7
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +0 -137
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +0 -7
- package/dist/tools/URLFetcherTool/cache.js +0 -45
- package/dist/tools/URLFetcherTool/cache.js.map +0 -7
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js +0 -42
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +0 -7
- package/dist/tools/URLFetcherTool/prompt.js +0 -22
- package/dist/tools/URLFetcherTool/prompt.js.map +0 -7
- package/dist/tools/WebSearchTool/WebSearchTool.js +0 -86
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +0 -7
- package/dist/tools/WebSearchTool/prompt.js +0 -17
- package/dist/tools/WebSearchTool/prompt.js.map +0 -7
- package/dist/tools/WebSearchTool/searchProviders.js +0 -48
- package/dist/tools/WebSearchTool/searchProviders.js.map +0 -7
- package/dist/tools/lsTool/lsTool.js +0 -201
- package/dist/tools/lsTool/lsTool.js.map +0 -7
- package/dist/tools/lsTool/prompt.js +0 -5
- package/dist/tools/lsTool/prompt.js.map +0 -7
- package/dist/tools.js +0 -64
- package/dist/tools.js.map +0 -7
- package/dist/types/PermissionMode.js +0 -82
- package/dist/types/PermissionMode.js.map +0 -7
- package/dist/types/RequestContext.js +0 -47
- package/dist/types/RequestContext.js.map +0 -7
- package/dist/types/common.d.js +0 -1
- package/dist/types/conversation.js +0 -1
- package/dist/types/logs.js +0 -1
- package/dist/types/modelCapabilities.js +0 -1
- package/dist/types/notebook.js +0 -1
- package/dist/utils/Cursor.js +0 -313
- package/dist/utils/Cursor.js.map +0 -7
- package/dist/utils/PersistentShell.js +0 -382
- package/dist/utils/PersistentShell.js.map +0 -7
- package/dist/utils/advancedFuzzyMatcher.js +0 -206
- package/dist/utils/advancedFuzzyMatcher.js.map +0 -7
- package/dist/utils/agentLoader.js +0 -199
- package/dist/utils/agentLoader.js.map +0 -7
- package/dist/utils/agentStorage.js +0 -59
- package/dist/utils/agentStorage.js.map +0 -7
- package/dist/utils/array.js +0 -7
- package/dist/utils/array.js.map +0 -7
- package/dist/utils/ask.js +0 -77
- package/dist/utils/ask.js.map +0 -7
- package/dist/utils/auth.js +0 -11
- package/dist/utils/auth.js.map +0 -7
- package/dist/utils/autoCompactCore.js +0 -149
- package/dist/utils/autoCompactCore.js.map +0 -7
- package/dist/utils/autoUpdater.js.map +0 -7
- package/dist/utils/betas.js +0 -21
- package/dist/utils/betas.js.map +0 -7
- package/dist/utils/browser.js +0 -15
- package/dist/utils/browser.js.map +0 -7
- package/dist/utils/cleanup.js +0 -54
- package/dist/utils/cleanup.js.map +0 -7
- package/dist/utils/commands.js +0 -207
- package/dist/utils/commands.js.map +0 -7
- package/dist/utils/commonUnixCommands.js +0 -687
- package/dist/utils/commonUnixCommands.js.map +0 -7
- package/dist/utils/config.js.map +0 -7
- package/dist/utils/conversationRecovery.js +0 -35
- package/dist/utils/conversationRecovery.js.map +0 -7
- package/dist/utils/debugLogger.js.map +0 -7
- package/dist/utils/diff.js +0 -32
- package/dist/utils/diff.js.map +0 -7
- package/dist/utils/env.js +0 -44
- package/dist/utils/env.js.map +0 -7
- package/dist/utils/errors.js +0 -23
- package/dist/utils/errors.js.map +0 -7
- package/dist/utils/exampleCommands.js +0 -80
- package/dist/utils/exampleCommands.js.map +0 -7
- package/dist/utils/execFileNoThrow.js +0 -44
- package/dist/utils/execFileNoThrow.js.map +0 -7
- package/dist/utils/expertChatStorage.js +0 -78
- package/dist/utils/expertChatStorage.js.map +0 -7
- package/dist/utils/file.js +0 -282
- package/dist/utils/file.js.map +0 -7
- package/dist/utils/fileRecoveryCore.js +0 -41
- package/dist/utils/fileRecoveryCore.js.map +0 -7
- package/dist/utils/format.js +0 -41
- package/dist/utils/format.js.map +0 -7
- package/dist/utils/fuzzyMatcher.js +0 -252
- package/dist/utils/fuzzyMatcher.js.map +0 -7
- package/dist/utils/generators.js +0 -46
- package/dist/utils/generators.js.map +0 -7
- package/dist/utils/git.js +0 -83
- package/dist/utils/git.js.map +0 -7
- package/dist/utils/globalLogger.js +0 -54
- package/dist/utils/globalLogger.js.map +0 -7
- package/dist/utils/http.js +0 -7
- package/dist/utils/http.js.map +0 -7
- package/dist/utils/imagePaste.js +0 -29
- package/dist/utils/imagePaste.js.map +0 -7
- package/dist/utils/json.js +0 -16
- package/dist/utils/json.js.map +0 -7
- package/dist/utils/log.js +0 -298
- package/dist/utils/log.js.map +0 -7
- package/dist/utils/markdown.js +0 -187
- package/dist/utils/markdown.js.map +0 -7
- package/dist/utils/messageContextManager.js +0 -195
- package/dist/utils/messageContextManager.js.map +0 -7
- package/dist/utils/messages.js +0 -633
- package/dist/utils/messages.js.map +0 -7
- package/dist/utils/model.js.map +0 -7
- package/dist/utils/permissions/filesystem.js +0 -80
- package/dist/utils/permissions/filesystem.js.map +0 -7
- package/dist/utils/responseState.js +0 -20
- package/dist/utils/responseState.js.map +0 -7
- package/dist/utils/ripgrep.js +0 -131
- package/dist/utils/ripgrep.js.map +0 -7
- package/dist/utils/secureFile.js +0 -483
- package/dist/utils/secureFile.js.map +0 -7
- package/dist/utils/sessionState.js +0 -31
- package/dist/utils/sessionState.js.map +0 -7
- package/dist/utils/state.js +0 -24
- package/dist/utils/state.js.map +0 -7
- package/dist/utils/style.js +0 -31
- package/dist/utils/style.js.map +0 -7
- package/dist/utils/terminal.js +0 -43
- package/dist/utils/terminal.js.map +0 -7
- package/dist/utils/theme.js.map +0 -7
- package/dist/utils/thinking.js +0 -103
- package/dist/utils/thinking.js.map +0 -7
- package/dist/utils/todoStorage.js +0 -291
- package/dist/utils/todoStorage.js.map +0 -7
- package/dist/utils/tokens.js +0 -30
- package/dist/utils/tokens.js.map +0 -7
- package/dist/utils/toolExecutionController.js +0 -109
- package/dist/utils/toolExecutionController.js.map +0 -7
- package/dist/utils/unaryLogging.js +0 -14
- package/dist/utils/unaryLogging.js.map +0 -7
- package/dist/utils/user.js +0 -40
- package/dist/utils/user.js.map +0 -7
- package/dist/utils/validate.js +0 -132
- package/dist/utils/validate.js.map +0 -7
- /package/dist/{Tool.js.map → REPL-GIU4ZIXM.js.map} +0 -0
- /package/dist/{components/CustomSelect/theme.js.map → autoUpdater-DNRMJWFQ.js.map} +0 -0
- /package/dist/{types/common.d.js.map → chunk-JC6NCUG5.js.map} +0 -0
- /package/dist/{types/conversation.js.map → commands-TWH6PGVG.js.map} +0 -0
- /package/dist/{types/logs.js.map → config-6ZMBCL23.js.map} +0 -0
- /package/dist/{types/modelCapabilities.js.map → context-JQIOOI4W.js.map} +0 -0
- /package/dist/{types/notebook.js.map → costTracker-6SL26FDB.js.map} +0 -0
|
@@ -1,1985 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef } from "react";
|
|
2
|
-
import { Box, Text, useInput } from "ink";
|
|
3
|
-
import { getTheme } from "../utils/theme.js";
|
|
4
|
-
import { Select } from "./CustomSelect/select.js";
|
|
5
|
-
import { Newline } from "ink";
|
|
6
|
-
import { getModelManager } from "../utils/model.js";
|
|
7
|
-
function ScreenContainer({
|
|
8
|
-
title,
|
|
9
|
-
exitState,
|
|
10
|
-
children
|
|
11
|
-
}) {
|
|
12
|
-
const theme = getTheme();
|
|
13
|
-
return /* @__PURE__ */ React.createElement(
|
|
14
|
-
Box,
|
|
15
|
-
{
|
|
16
|
-
flexDirection: "column",
|
|
17
|
-
gap: 1,
|
|
18
|
-
borderStyle: "round",
|
|
19
|
-
borderColor: theme.secondaryBorder,
|
|
20
|
-
paddingX: 2,
|
|
21
|
-
paddingY: 1
|
|
22
|
-
},
|
|
23
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, title, " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
24
|
-
children
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
import { useExitOnCtrlCD } from "../hooks/useExitOnCtrlCD.js";
|
|
28
|
-
import {
|
|
29
|
-
getGlobalConfig,
|
|
30
|
-
setAllPointersToModel,
|
|
31
|
-
setModelPointer
|
|
32
|
-
} from "../utils/config.js";
|
|
33
|
-
import models, { providers } from "../constants/models.js";
|
|
34
|
-
import TextInput from "./TextInput.js";
|
|
35
|
-
import OpenAI from "openai";
|
|
36
|
-
import chalk from "chalk";
|
|
37
|
-
import { verifyApiKey } from "../services/claude.js";
|
|
38
|
-
import { fetchCustomModels } from "../services/openai.js";
|
|
39
|
-
import { testGPT5Connection, validateGPT5Config } from "../services/gpt5ConnectionTest.js";
|
|
40
|
-
const CONTEXT_LENGTH_OPTIONS = [
|
|
41
|
-
{ label: "32K tokens", value: 32e3 },
|
|
42
|
-
{ label: "64K tokens", value: 64e3 },
|
|
43
|
-
{ label: "128K tokens", value: 128e3 },
|
|
44
|
-
{ label: "200K tokens", value: 2e5 },
|
|
45
|
-
{ label: "256K tokens", value: 256e3 },
|
|
46
|
-
{ label: "300K tokens", value: 3e5 },
|
|
47
|
-
{ label: "512K tokens", value: 512e3 },
|
|
48
|
-
{ label: "1000K tokens", value: 1e6 },
|
|
49
|
-
{ label: "2000K tokens", value: 2e6 },
|
|
50
|
-
{ label: "3000K tokens", value: 3e6 },
|
|
51
|
-
{ label: "5000K tokens", value: 5e6 },
|
|
52
|
-
{ label: "10000K tokens", value: 1e7 }
|
|
53
|
-
];
|
|
54
|
-
const DEFAULT_CONTEXT_LENGTH = 128e3;
|
|
55
|
-
const MAX_TOKENS_OPTIONS = [
|
|
56
|
-
{ label: "1K tokens", value: 1024 },
|
|
57
|
-
{ label: "2K tokens", value: 2048 },
|
|
58
|
-
{ label: "4K tokens", value: 4096 },
|
|
59
|
-
{ label: "8K tokens (recommended)", value: 8192 },
|
|
60
|
-
{ label: "16K tokens", value: 16384 },
|
|
61
|
-
{ label: "32K tokens", value: 32768 },
|
|
62
|
-
{ label: "64K tokens", value: 65536 },
|
|
63
|
-
{ label: "128K tokens", value: 131072 }
|
|
64
|
-
];
|
|
65
|
-
const DEFAULT_MAX_TOKENS = 8192;
|
|
66
|
-
function useEscapeNavigation(onEscape, abortController) {
|
|
67
|
-
const handledRef = useRef(false);
|
|
68
|
-
useInput(
|
|
69
|
-
(input, key) => {
|
|
70
|
-
if (key.escape && !handledRef.current) {
|
|
71
|
-
handledRef.current = true;
|
|
72
|
-
setTimeout(() => {
|
|
73
|
-
handledRef.current = false;
|
|
74
|
-
}, 100);
|
|
75
|
-
onEscape();
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{ isActive: true }
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
function printModelConfig() {
|
|
82
|
-
const config = getGlobalConfig();
|
|
83
|
-
const modelProfiles = config.modelProfiles || [];
|
|
84
|
-
const activeProfiles = modelProfiles.filter((p) => p.isActive);
|
|
85
|
-
if (activeProfiles.length === 0) {
|
|
86
|
-
console.log(chalk.gray(" \u23BF No active model profiles configured"));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const profileSummary = activeProfiles.map((p) => `${p.name} (${p.provider}: ${p.modelName})`).join(" | ");
|
|
90
|
-
console.log(chalk.gray(` \u23BF ${profileSummary}`));
|
|
91
|
-
}
|
|
92
|
-
function ModelSelector({
|
|
93
|
-
onDone: onDoneProp,
|
|
94
|
-
abortController,
|
|
95
|
-
targetPointer,
|
|
96
|
-
isOnboarding = false,
|
|
97
|
-
onCancel,
|
|
98
|
-
skipModelType = false
|
|
99
|
-
}) {
|
|
100
|
-
const config = getGlobalConfig();
|
|
101
|
-
const theme = getTheme();
|
|
102
|
-
const onDone = () => {
|
|
103
|
-
printModelConfig();
|
|
104
|
-
onDoneProp();
|
|
105
|
-
};
|
|
106
|
-
const exitState = useExitOnCtrlCD(() => process.exit(0));
|
|
107
|
-
const getInitialScreen = () => {
|
|
108
|
-
return "provider";
|
|
109
|
-
};
|
|
110
|
-
const [screenStack, setScreenStack] = useState([getInitialScreen()]);
|
|
111
|
-
const currentScreen = screenStack[screenStack.length - 1];
|
|
112
|
-
const navigateTo = (screen) => {
|
|
113
|
-
setScreenStack((prev) => [...prev, screen]);
|
|
114
|
-
};
|
|
115
|
-
const goBack = () => {
|
|
116
|
-
if (screenStack.length > 1) {
|
|
117
|
-
setScreenStack((prev) => prev.slice(0, -1));
|
|
118
|
-
} else {
|
|
119
|
-
onDone();
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
const [selectedProvider, setSelectedProvider] = useState(
|
|
123
|
-
config.primaryProvider ?? "anthropic"
|
|
124
|
-
);
|
|
125
|
-
const [anthropicProviderType, setAnthropicProviderType] = useState("official");
|
|
126
|
-
const [selectedModel, setSelectedModel] = useState("");
|
|
127
|
-
const [apiKey, setApiKey] = useState("");
|
|
128
|
-
const [maxTokens, setMaxTokens] = useState(
|
|
129
|
-
config.maxTokens?.toString() || DEFAULT_MAX_TOKENS.toString()
|
|
130
|
-
);
|
|
131
|
-
const [maxTokensMode, setMaxTokensMode] = useState(
|
|
132
|
-
"preset"
|
|
133
|
-
);
|
|
134
|
-
const [selectedMaxTokensPreset, setSelectedMaxTokensPreset] = useState(config.maxTokens || DEFAULT_MAX_TOKENS);
|
|
135
|
-
const [reasoningEffort, setReasoningEffort] = useState("medium");
|
|
136
|
-
const [supportsReasoningEffort, setSupportsReasoningEffort] = useState(false);
|
|
137
|
-
const [contextLength, setContextLength] = useState(
|
|
138
|
-
DEFAULT_CONTEXT_LENGTH
|
|
139
|
-
);
|
|
140
|
-
const [activeFieldIndex, setActiveFieldIndex] = useState(0);
|
|
141
|
-
const [maxTokensCursorOffset, setMaxTokensCursorOffset] = useState(0);
|
|
142
|
-
const [availableModels, setAvailableModels] = useState([]);
|
|
143
|
-
const [isLoadingModels, setIsLoadingModels] = useState(false);
|
|
144
|
-
const [modelLoadError, setModelLoadError] = useState(null);
|
|
145
|
-
const [modelSearchQuery, setModelSearchQuery] = useState("");
|
|
146
|
-
const [modelSearchCursorOffset, setModelSearchCursorOffset] = useState(0);
|
|
147
|
-
const [cursorOffset, setCursorOffset] = useState(0);
|
|
148
|
-
const [apiKeyEdited, setApiKeyEdited] = useState(false);
|
|
149
|
-
const [fetchRetryCount, setFetchRetryCount] = useState(0);
|
|
150
|
-
const [isRetrying, setIsRetrying] = useState(false);
|
|
151
|
-
const [isTestingConnection, setIsTestingConnection] = useState(false);
|
|
152
|
-
const [connectionTestResult, setConnectionTestResult] = useState(null);
|
|
153
|
-
const [validationError, setValidationError] = useState(null);
|
|
154
|
-
const [resourceName, setResourceName] = useState("");
|
|
155
|
-
const [resourceNameCursorOffset, setResourceNameCursorOffset] = useState(0);
|
|
156
|
-
const [customModelName, setCustomModelName] = useState("");
|
|
157
|
-
const [customModelNameCursorOffset, setCustomModelNameCursorOffset] = useState(0);
|
|
158
|
-
const [ollamaBaseUrl, setOllamaBaseUrl] = useState(
|
|
159
|
-
"http://localhost:11434/v1"
|
|
160
|
-
);
|
|
161
|
-
const [ollamaBaseUrlCursorOffset, setOllamaBaseUrlCursorOffset] = useState(0);
|
|
162
|
-
const [customBaseUrl, setCustomBaseUrl] = useState("");
|
|
163
|
-
const [customBaseUrlCursorOffset, setCustomBaseUrlCursorOffset] = useState(0);
|
|
164
|
-
const [providerBaseUrl, setProviderBaseUrl] = useState("");
|
|
165
|
-
const [providerBaseUrlCursorOffset, setProviderBaseUrlCursorOffset] = useState(0);
|
|
166
|
-
const reasoningEffortOptions = [
|
|
167
|
-
{ label: "Low - Faster responses, less thorough reasoning", value: "low" },
|
|
168
|
-
{ label: "Medium - Balanced speed and reasoning depth", value: "medium" },
|
|
169
|
-
{
|
|
170
|
-
label: "High - Slower responses, more thorough reasoning",
|
|
171
|
-
value: "high"
|
|
172
|
-
}
|
|
173
|
-
];
|
|
174
|
-
const availableProviders = Object.keys(providers).filter(
|
|
175
|
-
(provider) => provider !== "bigdream" && provider !== "opendev"
|
|
176
|
-
);
|
|
177
|
-
const providerOptions = availableProviders.map((provider) => {
|
|
178
|
-
const modelCount = models[provider]?.length || 0;
|
|
179
|
-
const label = getProviderLabel(provider, modelCount);
|
|
180
|
-
return {
|
|
181
|
-
label,
|
|
182
|
-
value: provider
|
|
183
|
-
};
|
|
184
|
-
});
|
|
185
|
-
useEffect(() => {
|
|
186
|
-
if (!apiKeyEdited && selectedProvider) {
|
|
187
|
-
if (process.env[selectedProvider.toUpperCase() + "_API_KEY"]) {
|
|
188
|
-
setApiKey(
|
|
189
|
-
process.env[selectedProvider.toUpperCase() + "_API_KEY"]
|
|
190
|
-
);
|
|
191
|
-
} else {
|
|
192
|
-
setApiKey("");
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}, [selectedProvider, apiKey, apiKeyEdited]);
|
|
196
|
-
useEffect(() => {
|
|
197
|
-
if (currentScreen === "contextLength" && !CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength)) {
|
|
198
|
-
setContextLength(DEFAULT_CONTEXT_LENGTH);
|
|
199
|
-
}
|
|
200
|
-
}, [currentScreen, contextLength]);
|
|
201
|
-
const ourModelNames = new Set(
|
|
202
|
-
(models[selectedProvider] || []).map(
|
|
203
|
-
(model) => model.model
|
|
204
|
-
)
|
|
205
|
-
);
|
|
206
|
-
const filteredModels = modelSearchQuery ? availableModels.filter(
|
|
207
|
-
(model) => model.model?.toLowerCase().includes(modelSearchQuery.toLowerCase())
|
|
208
|
-
) : availableModels;
|
|
209
|
-
const sortModelsByPriority = (models2) => {
|
|
210
|
-
const priorityKeywords = [
|
|
211
|
-
"claude",
|
|
212
|
-
"kimi",
|
|
213
|
-
"deepseek",
|
|
214
|
-
"minimax",
|
|
215
|
-
"o3",
|
|
216
|
-
"gpt",
|
|
217
|
-
"qwen"
|
|
218
|
-
];
|
|
219
|
-
return models2.sort((a, b) => {
|
|
220
|
-
const aModelLower = a.model?.toLowerCase() || "";
|
|
221
|
-
const bModelLower = b.model?.toLowerCase() || "";
|
|
222
|
-
const aHasPriority = priorityKeywords.some(
|
|
223
|
-
(keyword) => aModelLower.includes(keyword)
|
|
224
|
-
);
|
|
225
|
-
const bHasPriority = priorityKeywords.some(
|
|
226
|
-
(keyword) => bModelLower.includes(keyword)
|
|
227
|
-
);
|
|
228
|
-
if (aHasPriority && !bHasPriority) return -1;
|
|
229
|
-
if (!aHasPriority && bHasPriority) return 1;
|
|
230
|
-
return a.model.localeCompare(b.model);
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
const sortedFilteredModels = sortModelsByPriority(filteredModels);
|
|
234
|
-
const modelOptions = sortedFilteredModels.map((model) => {
|
|
235
|
-
const isInOurModels = ourModelNames.has(model.model);
|
|
236
|
-
return {
|
|
237
|
-
label: `${model.model}${getModelDetails(model)}`,
|
|
238
|
-
value: model.model
|
|
239
|
-
};
|
|
240
|
-
});
|
|
241
|
-
function getModelDetails(model) {
|
|
242
|
-
const details = [];
|
|
243
|
-
if (model.max_tokens) {
|
|
244
|
-
details.push(`${formatNumber(model.max_tokens)} tokens`);
|
|
245
|
-
}
|
|
246
|
-
if (model.supports_vision) {
|
|
247
|
-
details.push("vision");
|
|
248
|
-
}
|
|
249
|
-
if (model.supports_function_calling) {
|
|
250
|
-
details.push("tools");
|
|
251
|
-
}
|
|
252
|
-
return details.length > 0 ? ` (${details.join(", ")})` : "";
|
|
253
|
-
}
|
|
254
|
-
function formatNumber(num) {
|
|
255
|
-
if (num >= 1e6) {
|
|
256
|
-
return `${(num / 1e6).toFixed(1)}M`;
|
|
257
|
-
} else if (num >= 1e3) {
|
|
258
|
-
return `${(num / 1e3).toFixed(0)}K`;
|
|
259
|
-
}
|
|
260
|
-
return num.toString();
|
|
261
|
-
}
|
|
262
|
-
function getProviderLabel(provider, modelCount) {
|
|
263
|
-
if (providers[provider]) {
|
|
264
|
-
return `${providers[provider].name} ${providers[provider].status === "wip" ? "(WIP)" : ""} (${modelCount} models)`;
|
|
265
|
-
}
|
|
266
|
-
return `${provider}`;
|
|
267
|
-
}
|
|
268
|
-
function handleProviderSelection(provider) {
|
|
269
|
-
const providerType = provider;
|
|
270
|
-
setSelectedProvider(providerType);
|
|
271
|
-
if (provider === "custom") {
|
|
272
|
-
saveConfiguration(providerType, selectedModel || "");
|
|
273
|
-
onDone();
|
|
274
|
-
} else if (provider === "anthropic") {
|
|
275
|
-
navigateTo("anthropicSubMenu");
|
|
276
|
-
} else {
|
|
277
|
-
const defaultBaseUrl = providers[providerType]?.baseURL || "";
|
|
278
|
-
setProviderBaseUrl(defaultBaseUrl);
|
|
279
|
-
navigateTo("baseUrl");
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
async function fetchAnthropicModels2(baseURL, apiKey2) {
|
|
283
|
-
try {
|
|
284
|
-
const response = await fetch(`${baseURL}/v1/models`, {
|
|
285
|
-
method: "GET",
|
|
286
|
-
headers: {
|
|
287
|
-
"x-api-key": apiKey2,
|
|
288
|
-
"anthropic-version": "2023-06-01",
|
|
289
|
-
"Content-Type": "application/json",
|
|
290
|
-
"Authorization": `Bearer ${apiKey2}`
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
if (!response.ok) {
|
|
294
|
-
if (response.status === 401) {
|
|
295
|
-
throw new Error(
|
|
296
|
-
"Invalid API key. Please check your API key and try again."
|
|
297
|
-
);
|
|
298
|
-
} else if (response.status === 403) {
|
|
299
|
-
throw new Error("API key does not have permission to access models.");
|
|
300
|
-
} else if (response.status === 404) {
|
|
301
|
-
throw new Error(
|
|
302
|
-
"API endpoint not found. This provider may not support model listing."
|
|
303
|
-
);
|
|
304
|
-
} else if (response.status === 429) {
|
|
305
|
-
throw new Error(
|
|
306
|
-
"Too many requests. Please wait a moment and try again."
|
|
307
|
-
);
|
|
308
|
-
} else if (response.status >= 500) {
|
|
309
|
-
throw new Error(
|
|
310
|
-
"API service is temporarily unavailable. Please try again later."
|
|
311
|
-
);
|
|
312
|
-
} else {
|
|
313
|
-
throw new Error(`Unable to connect to API (${response.status}).`);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
const data = await response.json();
|
|
317
|
-
let models2 = [];
|
|
318
|
-
if (data && data.data && Array.isArray(data.data)) {
|
|
319
|
-
models2 = data.data;
|
|
320
|
-
} else if (Array.isArray(data)) {
|
|
321
|
-
models2 = data;
|
|
322
|
-
} else if (data && data.models && Array.isArray(data.models)) {
|
|
323
|
-
models2 = data.models;
|
|
324
|
-
} else {
|
|
325
|
-
throw new Error("API returned unexpected response format.");
|
|
326
|
-
}
|
|
327
|
-
return models2;
|
|
328
|
-
} catch (error) {
|
|
329
|
-
if (error instanceof Error && (error.message.includes("API key") || error.message.includes("API endpoint") || error.message.includes("API service") || error.message.includes("response format"))) {
|
|
330
|
-
throw error;
|
|
331
|
-
}
|
|
332
|
-
if (error instanceof Error && error.message.includes("fetch")) {
|
|
333
|
-
throw new Error(
|
|
334
|
-
"Unable to connect to the API. Please check the base URL and your internet connection."
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
throw new Error(
|
|
338
|
-
"Failed to fetch models from API. Please check your configuration and try again."
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
async function fetchAnthropicCompatibleModelsWithFallback(baseURL, provider, apiKeyUrl) {
|
|
343
|
-
let lastError = null;
|
|
344
|
-
try {
|
|
345
|
-
const models2 = await fetchAnthropicModels2(baseURL, apiKey);
|
|
346
|
-
return models2.map((model) => ({
|
|
347
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
348
|
-
provider,
|
|
349
|
-
max_tokens: model.max_tokens || 8192,
|
|
350
|
-
supports_vision: model.supports_vision || true,
|
|
351
|
-
supports_function_calling: model.supports_function_calling || true,
|
|
352
|
-
supports_reasoning_effort: false
|
|
353
|
-
}));
|
|
354
|
-
} catch (error) {
|
|
355
|
-
lastError = error;
|
|
356
|
-
console.log(
|
|
357
|
-
`Anthropic API failed for ${provider}, trying OpenAI format:`,
|
|
358
|
-
error
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
try {
|
|
362
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
363
|
-
return models2.map((model) => ({
|
|
364
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
365
|
-
provider,
|
|
366
|
-
max_tokens: model.max_tokens || 8192,
|
|
367
|
-
supports_vision: model.supports_vision || false,
|
|
368
|
-
supports_function_calling: model.supports_function_calling || true,
|
|
369
|
-
supports_reasoning_effort: false
|
|
370
|
-
}));
|
|
371
|
-
} catch (error) {
|
|
372
|
-
lastError = error;
|
|
373
|
-
console.log(
|
|
374
|
-
`OpenAI API failed for ${provider}, falling back to manual input:`,
|
|
375
|
-
error
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
let errorMessage = `Failed to fetch ${provider} models using both Anthropic and OpenAI API formats`;
|
|
379
|
-
if (lastError) {
|
|
380
|
-
errorMessage = lastError.message;
|
|
381
|
-
}
|
|
382
|
-
if (errorMessage.includes("API key")) {
|
|
383
|
-
errorMessage += `
|
|
384
|
-
|
|
385
|
-
\u{1F4A1} Tip: Get your API key from ${apiKeyUrl}`;
|
|
386
|
-
} else if (errorMessage.includes("permission")) {
|
|
387
|
-
errorMessage += `
|
|
388
|
-
|
|
389
|
-
\u{1F4A1} Tip: Make sure your API key has access to the ${provider} API`;
|
|
390
|
-
} else if (errorMessage.includes("connection")) {
|
|
391
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
392
|
-
}
|
|
393
|
-
setModelLoadError(errorMessage);
|
|
394
|
-
throw new Error(errorMessage);
|
|
395
|
-
}
|
|
396
|
-
async function fetchAnthropicCompatibleProviderModels() {
|
|
397
|
-
let defaultBaseURL;
|
|
398
|
-
let apiKeyUrl;
|
|
399
|
-
let actualProvider;
|
|
400
|
-
switch (anthropicProviderType) {
|
|
401
|
-
case "official":
|
|
402
|
-
defaultBaseURL = "https://api.anthropic.com";
|
|
403
|
-
apiKeyUrl = "https://console.anthropic.com/settings/keys";
|
|
404
|
-
actualProvider = "anthropic";
|
|
405
|
-
break;
|
|
406
|
-
case "bigdream":
|
|
407
|
-
defaultBaseURL = "https://api-key.info";
|
|
408
|
-
apiKeyUrl = "https://api-key.info/register?aff=MSl4";
|
|
409
|
-
actualProvider = "bigdream";
|
|
410
|
-
break;
|
|
411
|
-
case "opendev":
|
|
412
|
-
defaultBaseURL = "https://api.openai-next.com";
|
|
413
|
-
apiKeyUrl = "https://api.openai-next.com/register/?aff_code=4xo7";
|
|
414
|
-
actualProvider = "opendev";
|
|
415
|
-
break;
|
|
416
|
-
case "custom":
|
|
417
|
-
defaultBaseURL = providerBaseUrl;
|
|
418
|
-
apiKeyUrl = "your custom API provider";
|
|
419
|
-
actualProvider = "anthropic";
|
|
420
|
-
break;
|
|
421
|
-
default:
|
|
422
|
-
throw new Error(
|
|
423
|
-
`Unsupported Anthropic provider type: ${anthropicProviderType}`
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
const baseURL = anthropicProviderType === "custom" ? providerBaseUrl : providerBaseUrl || defaultBaseURL;
|
|
427
|
-
return await fetchAnthropicCompatibleModelsWithFallback(
|
|
428
|
-
baseURL,
|
|
429
|
-
actualProvider,
|
|
430
|
-
apiKeyUrl
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
async function fetchKimiModels() {
|
|
434
|
-
try {
|
|
435
|
-
const baseURL = providerBaseUrl || "https://api.moonshot.cn/v1";
|
|
436
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
437
|
-
const kimiModels = models2.map((model) => ({
|
|
438
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
439
|
-
provider: "kimi",
|
|
440
|
-
max_tokens: model.max_tokens || 8192,
|
|
441
|
-
supports_vision: false,
|
|
442
|
-
// Default to false, could be enhanced
|
|
443
|
-
supports_function_calling: true,
|
|
444
|
-
supports_reasoning_effort: false
|
|
445
|
-
}));
|
|
446
|
-
return kimiModels;
|
|
447
|
-
} catch (error) {
|
|
448
|
-
let errorMessage = "Failed to fetch Kimi models";
|
|
449
|
-
if (error instanceof Error) {
|
|
450
|
-
errorMessage = error.message;
|
|
451
|
-
}
|
|
452
|
-
if (errorMessage.includes("API key")) {
|
|
453
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://platform.moonshot.cn/console/api-keys";
|
|
454
|
-
} else if (errorMessage.includes("permission")) {
|
|
455
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the Kimi API";
|
|
456
|
-
} else if (errorMessage.includes("connection")) {
|
|
457
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
458
|
-
}
|
|
459
|
-
setModelLoadError(errorMessage);
|
|
460
|
-
throw error;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
async function fetchDeepSeekModels() {
|
|
464
|
-
try {
|
|
465
|
-
const baseURL = providerBaseUrl || "https://api.deepseek.com";
|
|
466
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
467
|
-
const deepseekModels = models2.map((model) => ({
|
|
468
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
469
|
-
provider: "deepseek",
|
|
470
|
-
max_tokens: model.max_tokens || 8192,
|
|
471
|
-
supports_vision: false,
|
|
472
|
-
// Default to false, could be enhanced
|
|
473
|
-
supports_function_calling: true,
|
|
474
|
-
supports_reasoning_effort: false
|
|
475
|
-
}));
|
|
476
|
-
return deepseekModels;
|
|
477
|
-
} catch (error) {
|
|
478
|
-
let errorMessage = "Failed to fetch DeepSeek models";
|
|
479
|
-
if (error instanceof Error) {
|
|
480
|
-
errorMessage = error.message;
|
|
481
|
-
}
|
|
482
|
-
if (errorMessage.includes("API key")) {
|
|
483
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://platform.deepseek.com/api_keys";
|
|
484
|
-
} else if (errorMessage.includes("permission")) {
|
|
485
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the DeepSeek API";
|
|
486
|
-
} else if (errorMessage.includes("connection")) {
|
|
487
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
488
|
-
}
|
|
489
|
-
setModelLoadError(errorMessage);
|
|
490
|
-
throw error;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
async function fetchSiliconFlowModels() {
|
|
494
|
-
try {
|
|
495
|
-
const baseURL = providerBaseUrl || "https://api.siliconflow.cn/v1";
|
|
496
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
497
|
-
const siliconflowModels = models2.map((model) => ({
|
|
498
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
499
|
-
provider: "siliconflow",
|
|
500
|
-
max_tokens: model.max_tokens || 8192,
|
|
501
|
-
supports_vision: false,
|
|
502
|
-
// Default to false, could be enhanced
|
|
503
|
-
supports_function_calling: true,
|
|
504
|
-
supports_reasoning_effort: false
|
|
505
|
-
}));
|
|
506
|
-
return siliconflowModels;
|
|
507
|
-
} catch (error) {
|
|
508
|
-
let errorMessage = "Failed to fetch SiliconFlow models";
|
|
509
|
-
if (error instanceof Error) {
|
|
510
|
-
errorMessage = error.message;
|
|
511
|
-
}
|
|
512
|
-
if (errorMessage.includes("API key")) {
|
|
513
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://cloud.siliconflow.cn/i/oJWsm6io";
|
|
514
|
-
} else if (errorMessage.includes("permission")) {
|
|
515
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the SiliconFlow API";
|
|
516
|
-
} else if (errorMessage.includes("connection")) {
|
|
517
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
518
|
-
}
|
|
519
|
-
setModelLoadError(errorMessage);
|
|
520
|
-
throw error;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
async function fetchQwenModels() {
|
|
524
|
-
try {
|
|
525
|
-
const baseURL = providerBaseUrl || "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
526
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
527
|
-
const qwenModels = models2.map((model) => ({
|
|
528
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
529
|
-
provider: "qwen",
|
|
530
|
-
max_tokens: model.max_tokens || 8192,
|
|
531
|
-
supports_vision: false,
|
|
532
|
-
supports_function_calling: true,
|
|
533
|
-
supports_reasoning_effort: false
|
|
534
|
-
}));
|
|
535
|
-
return qwenModels;
|
|
536
|
-
} catch (error) {
|
|
537
|
-
let errorMessage = "Failed to fetch Qwen models";
|
|
538
|
-
if (error instanceof Error) {
|
|
539
|
-
errorMessage = error.message;
|
|
540
|
-
}
|
|
541
|
-
if (errorMessage.includes("API key")) {
|
|
542
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://bailian.console.aliyun.com/?tab=model#/api-key";
|
|
543
|
-
} else if (errorMessage.includes("permission")) {
|
|
544
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the Qwen API";
|
|
545
|
-
} else if (errorMessage.includes("connection")) {
|
|
546
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
547
|
-
}
|
|
548
|
-
setModelLoadError(errorMessage);
|
|
549
|
-
throw error;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
async function fetchGLMModels() {
|
|
553
|
-
try {
|
|
554
|
-
const baseURL = providerBaseUrl || "https://open.bigmodel.cn/api/paas/v4";
|
|
555
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
556
|
-
const glmModels = models2.map((model) => ({
|
|
557
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
558
|
-
provider: "glm",
|
|
559
|
-
max_tokens: model.max_tokens || 8192,
|
|
560
|
-
supports_vision: false,
|
|
561
|
-
supports_function_calling: true,
|
|
562
|
-
supports_reasoning_effort: false
|
|
563
|
-
}));
|
|
564
|
-
return glmModels;
|
|
565
|
-
} catch (error) {
|
|
566
|
-
let errorMessage = "Failed to fetch GLM models";
|
|
567
|
-
if (error instanceof Error) {
|
|
568
|
-
errorMessage = error.message;
|
|
569
|
-
}
|
|
570
|
-
if (errorMessage.includes("API key")) {
|
|
571
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://open.bigmodel.cn (API Keys section)";
|
|
572
|
-
} else if (errorMessage.includes("permission")) {
|
|
573
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the GLM API";
|
|
574
|
-
} else if (errorMessage.includes("connection")) {
|
|
575
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
576
|
-
}
|
|
577
|
-
setModelLoadError(errorMessage);
|
|
578
|
-
throw error;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
async function fetchMinimaxModels() {
|
|
582
|
-
try {
|
|
583
|
-
const baseURL = providerBaseUrl || "https://api.minimaxi.com/v1";
|
|
584
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
585
|
-
const minimaxModels = models2.map((model) => ({
|
|
586
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
587
|
-
provider: "minimax",
|
|
588
|
-
max_tokens: model.max_tokens || 8192,
|
|
589
|
-
supports_vision: false,
|
|
590
|
-
supports_function_calling: true,
|
|
591
|
-
supports_reasoning_effort: false
|
|
592
|
-
}));
|
|
593
|
-
return minimaxModels;
|
|
594
|
-
} catch (error) {
|
|
595
|
-
let errorMessage = "Failed to fetch MiniMax models";
|
|
596
|
-
if (error instanceof Error) {
|
|
597
|
-
errorMessage = error.message;
|
|
598
|
-
}
|
|
599
|
-
if (errorMessage.includes("API key")) {
|
|
600
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://www.minimax.io/platform/user-center/basic-information";
|
|
601
|
-
} else if (errorMessage.includes("permission")) {
|
|
602
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the MiniMax API";
|
|
603
|
-
} else if (errorMessage.includes("connection")) {
|
|
604
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
605
|
-
}
|
|
606
|
-
setModelLoadError(errorMessage);
|
|
607
|
-
throw error;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
async function fetchBaiduQianfanModels() {
|
|
611
|
-
try {
|
|
612
|
-
const baseURL = providerBaseUrl || "https://qianfan.baidubce.com/v2";
|
|
613
|
-
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
614
|
-
const baiduModels = models2.map((model) => ({
|
|
615
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
616
|
-
provider: "baidu-qianfan",
|
|
617
|
-
max_tokens: model.max_tokens || 8192,
|
|
618
|
-
supports_vision: false,
|
|
619
|
-
supports_function_calling: true,
|
|
620
|
-
supports_reasoning_effort: false
|
|
621
|
-
}));
|
|
622
|
-
return baiduModels;
|
|
623
|
-
} catch (error) {
|
|
624
|
-
let errorMessage = "Failed to fetch Baidu Qianfan models";
|
|
625
|
-
if (error instanceof Error) {
|
|
626
|
-
errorMessage = error.message;
|
|
627
|
-
}
|
|
628
|
-
if (errorMessage.includes("API key")) {
|
|
629
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Get your API key from https://console.bce.baidu.com/iam/#/iam/accesslist";
|
|
630
|
-
} else if (errorMessage.includes("permission")) {
|
|
631
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure your API key has access to the Baidu Qianfan API";
|
|
632
|
-
} else if (errorMessage.includes("connection")) {
|
|
633
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check your internet connection and try again";
|
|
634
|
-
}
|
|
635
|
-
setModelLoadError(errorMessage);
|
|
636
|
-
throw error;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
async function fetchCustomOpenAIModels() {
|
|
640
|
-
try {
|
|
641
|
-
const models2 = await fetchCustomModels(customBaseUrl, apiKey);
|
|
642
|
-
const customModels = models2.map((model) => ({
|
|
643
|
-
model: model.modelName || model.id || model.name || model.model || "unknown",
|
|
644
|
-
provider: "custom-openai",
|
|
645
|
-
max_tokens: model.max_tokens || 4096,
|
|
646
|
-
supports_vision: false,
|
|
647
|
-
// Default to false, could be enhanced
|
|
648
|
-
supports_function_calling: true,
|
|
649
|
-
supports_reasoning_effort: false
|
|
650
|
-
}));
|
|
651
|
-
return customModels;
|
|
652
|
-
} catch (error) {
|
|
653
|
-
let errorMessage = "Failed to fetch custom API models";
|
|
654
|
-
if (error instanceof Error) {
|
|
655
|
-
errorMessage = error.message;
|
|
656
|
-
}
|
|
657
|
-
if (errorMessage.includes("API key")) {
|
|
658
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Check that your API key is valid for this endpoint";
|
|
659
|
-
} else if (errorMessage.includes("endpoint not found")) {
|
|
660
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Make sure the base URL ends with /v1 and supports OpenAI-compatible API";
|
|
661
|
-
} else if (errorMessage.includes("connect")) {
|
|
662
|
-
errorMessage += "\n\n\u{1F4A1} Tip: Verify the base URL is correct and accessible";
|
|
663
|
-
} else if (errorMessage.includes("response format")) {
|
|
664
|
-
errorMessage += "\n\n\u{1F4A1} Tip: This API may not be fully OpenAI-compatible";
|
|
665
|
-
}
|
|
666
|
-
setModelLoadError(errorMessage);
|
|
667
|
-
throw error;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
async function fetchGeminiModels() {
|
|
671
|
-
try {
|
|
672
|
-
const response = await fetch(
|
|
673
|
-
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`
|
|
674
|
-
);
|
|
675
|
-
if (!response.ok) {
|
|
676
|
-
const errorData = await response.json();
|
|
677
|
-
throw new Error(
|
|
678
|
-
errorData.error?.message || `API error: ${response.status}`
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
const { models: models2 } = await response.json();
|
|
682
|
-
const geminiModels = models2.filter(
|
|
683
|
-
(model) => model.supportedGenerationMethods.includes("generateContent")
|
|
684
|
-
).map((model) => ({
|
|
685
|
-
model: model.name.replace("models/", ""),
|
|
686
|
-
provider: "gemini",
|
|
687
|
-
max_tokens: model.outputTokenLimit,
|
|
688
|
-
supports_vision: model.supportedGenerationMethods.includes("generateContent"),
|
|
689
|
-
supports_function_calling: model.supportedGenerationMethods.includes("generateContent")
|
|
690
|
-
}));
|
|
691
|
-
return geminiModels;
|
|
692
|
-
} catch (error) {
|
|
693
|
-
setModelLoadError(
|
|
694
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
695
|
-
);
|
|
696
|
-
throw error;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
async function fetchOllamaModels() {
|
|
700
|
-
try {
|
|
701
|
-
const response = await fetch(`${ollamaBaseUrl}/models`);
|
|
702
|
-
if (!response.ok) {
|
|
703
|
-
throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
|
|
704
|
-
}
|
|
705
|
-
const responseData = await response.json();
|
|
706
|
-
let models2 = [];
|
|
707
|
-
if (responseData.data && Array.isArray(responseData.data)) {
|
|
708
|
-
models2 = responseData.data;
|
|
709
|
-
} else if (Array.isArray(responseData.models)) {
|
|
710
|
-
models2 = responseData.models;
|
|
711
|
-
} else if (Array.isArray(responseData)) {
|
|
712
|
-
models2 = responseData;
|
|
713
|
-
} else {
|
|
714
|
-
throw new Error(
|
|
715
|
-
"Invalid response from Ollama API: missing models array"
|
|
716
|
-
);
|
|
717
|
-
}
|
|
718
|
-
const ollamaModels = models2.map((model) => ({
|
|
719
|
-
model: model.name ?? model.modelName ?? (typeof model === "string" ? model : ""),
|
|
720
|
-
provider: "ollama",
|
|
721
|
-
max_tokens: 4096,
|
|
722
|
-
// Default value
|
|
723
|
-
supports_vision: false,
|
|
724
|
-
supports_function_calling: true,
|
|
725
|
-
supports_reasoning_effort: false
|
|
726
|
-
}));
|
|
727
|
-
const validModels = ollamaModels.filter((model) => model.model);
|
|
728
|
-
setAvailableModels(validModels);
|
|
729
|
-
if (validModels.length > 0) {
|
|
730
|
-
navigateTo("model");
|
|
731
|
-
} else {
|
|
732
|
-
setModelLoadError("No models found in your Ollama installation");
|
|
733
|
-
}
|
|
734
|
-
return validModels;
|
|
735
|
-
} catch (error) {
|
|
736
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
737
|
-
if (errorMessage.includes("fetch")) {
|
|
738
|
-
setModelLoadError(
|
|
739
|
-
`Could not connect to Ollama server at ${ollamaBaseUrl}. Make sure Ollama is running and the URL is correct.`
|
|
740
|
-
);
|
|
741
|
-
} else {
|
|
742
|
-
setModelLoadError(`Error loading Ollama models: ${errorMessage}`);
|
|
743
|
-
}
|
|
744
|
-
console.error("Error fetching Ollama models:", error);
|
|
745
|
-
return [];
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
async function fetchModelsWithRetry() {
|
|
749
|
-
const MAX_RETRIES = 2;
|
|
750
|
-
let lastError = null;
|
|
751
|
-
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
752
|
-
setFetchRetryCount(attempt);
|
|
753
|
-
setIsRetrying(attempt > 1);
|
|
754
|
-
if (attempt > 1) {
|
|
755
|
-
setModelLoadError(
|
|
756
|
-
`Attempt ${attempt}/${MAX_RETRIES}: Retrying model discovery...`
|
|
757
|
-
);
|
|
758
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
759
|
-
}
|
|
760
|
-
try {
|
|
761
|
-
const models2 = await fetchModels();
|
|
762
|
-
setFetchRetryCount(0);
|
|
763
|
-
setIsRetrying(false);
|
|
764
|
-
setModelLoadError(null);
|
|
765
|
-
return models2;
|
|
766
|
-
} catch (error) {
|
|
767
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
768
|
-
console.log(`Model fetch attempt ${attempt} failed:`, lastError.message);
|
|
769
|
-
if (attempt === MAX_RETRIES) {
|
|
770
|
-
break;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
setIsRetrying(false);
|
|
775
|
-
const errorMessage = lastError?.message || "Unknown error";
|
|
776
|
-
const supportsManualInput = [
|
|
777
|
-
"anthropic",
|
|
778
|
-
"kimi",
|
|
779
|
-
"deepseek",
|
|
780
|
-
"siliconflow",
|
|
781
|
-
"qwen",
|
|
782
|
-
"glm",
|
|
783
|
-
"minimax",
|
|
784
|
-
"baidu-qianfan",
|
|
785
|
-
"custom-openai"
|
|
786
|
-
].includes(selectedProvider);
|
|
787
|
-
if (supportsManualInput) {
|
|
788
|
-
setModelLoadError(
|
|
789
|
-
`Failed to auto-discover models after ${MAX_RETRIES} attempts: ${errorMessage}
|
|
790
|
-
|
|
791
|
-
\u26A1 Automatically switching to manual model configuration...`
|
|
792
|
-
);
|
|
793
|
-
setTimeout(() => {
|
|
794
|
-
setModelLoadError(null);
|
|
795
|
-
navigateTo("modelInput");
|
|
796
|
-
}, 2e3);
|
|
797
|
-
} else {
|
|
798
|
-
setModelLoadError(
|
|
799
|
-
`Failed to load models after ${MAX_RETRIES} attempts: ${errorMessage}`
|
|
800
|
-
);
|
|
801
|
-
}
|
|
802
|
-
return [];
|
|
803
|
-
}
|
|
804
|
-
async function fetchModels() {
|
|
805
|
-
setIsLoadingModels(true);
|
|
806
|
-
setModelLoadError(null);
|
|
807
|
-
try {
|
|
808
|
-
if (selectedProvider === "anthropic") {
|
|
809
|
-
const anthropicModels = await fetchAnthropicCompatibleProviderModels();
|
|
810
|
-
setAvailableModels(anthropicModels);
|
|
811
|
-
navigateTo("model");
|
|
812
|
-
return anthropicModels;
|
|
813
|
-
}
|
|
814
|
-
if (selectedProvider === "custom-openai") {
|
|
815
|
-
const customModels = await fetchCustomOpenAIModels();
|
|
816
|
-
setAvailableModels(customModels);
|
|
817
|
-
navigateTo("model");
|
|
818
|
-
return customModels;
|
|
819
|
-
}
|
|
820
|
-
if (selectedProvider === "gemini") {
|
|
821
|
-
const geminiModels = await fetchGeminiModels();
|
|
822
|
-
setAvailableModels(geminiModels);
|
|
823
|
-
navigateTo("model");
|
|
824
|
-
return geminiModels;
|
|
825
|
-
}
|
|
826
|
-
if (selectedProvider === "kimi") {
|
|
827
|
-
const kimiModels = await fetchKimiModels();
|
|
828
|
-
setAvailableModels(kimiModels);
|
|
829
|
-
navigateTo("model");
|
|
830
|
-
return kimiModels;
|
|
831
|
-
}
|
|
832
|
-
if (selectedProvider === "deepseek") {
|
|
833
|
-
const deepseekModels = await fetchDeepSeekModels();
|
|
834
|
-
setAvailableModels(deepseekModels);
|
|
835
|
-
navigateTo("model");
|
|
836
|
-
return deepseekModels;
|
|
837
|
-
}
|
|
838
|
-
if (selectedProvider === "siliconflow") {
|
|
839
|
-
const siliconflowModels = await fetchSiliconFlowModels();
|
|
840
|
-
setAvailableModels(siliconflowModels);
|
|
841
|
-
navigateTo("model");
|
|
842
|
-
return siliconflowModels;
|
|
843
|
-
}
|
|
844
|
-
if (selectedProvider === "qwen") {
|
|
845
|
-
const qwenModels = await fetchQwenModels();
|
|
846
|
-
setAvailableModels(qwenModels);
|
|
847
|
-
navigateTo("model");
|
|
848
|
-
return qwenModels;
|
|
849
|
-
}
|
|
850
|
-
if (selectedProvider === "glm") {
|
|
851
|
-
const glmModels = await fetchGLMModels();
|
|
852
|
-
setAvailableModels(glmModels);
|
|
853
|
-
navigateTo("model");
|
|
854
|
-
return glmModels;
|
|
855
|
-
}
|
|
856
|
-
if (selectedProvider === "baidu-qianfan") {
|
|
857
|
-
const baiduModels = await fetchBaiduQianfanModels();
|
|
858
|
-
setAvailableModels(baiduModels);
|
|
859
|
-
navigateTo("model");
|
|
860
|
-
return baiduModels;
|
|
861
|
-
}
|
|
862
|
-
if (selectedProvider === "azure") {
|
|
863
|
-
navigateTo("modelInput");
|
|
864
|
-
return [];
|
|
865
|
-
}
|
|
866
|
-
let baseURL = providerBaseUrl || providers[selectedProvider]?.baseURL;
|
|
867
|
-
if (selectedProvider === "custom-openai") {
|
|
868
|
-
baseURL = customBaseUrl;
|
|
869
|
-
}
|
|
870
|
-
const openai = new OpenAI({
|
|
871
|
-
apiKey: apiKey || "dummy-key-for-ollama",
|
|
872
|
-
// Ollama doesn't need a real key
|
|
873
|
-
baseURL,
|
|
874
|
-
dangerouslyAllowBrowser: true
|
|
875
|
-
});
|
|
876
|
-
const response = await openai.models.list();
|
|
877
|
-
const fetchedModels = [];
|
|
878
|
-
for (const model of response.data) {
|
|
879
|
-
const modelName = model.modelName || model.id || model.name || model.model || "unknown";
|
|
880
|
-
const modelInfo = models[selectedProvider]?.find(
|
|
881
|
-
(m) => m.model === modelName
|
|
882
|
-
);
|
|
883
|
-
fetchedModels.push({
|
|
884
|
-
model: modelName,
|
|
885
|
-
provider: selectedProvider,
|
|
886
|
-
max_tokens: modelInfo?.max_output_tokens,
|
|
887
|
-
supports_vision: modelInfo?.supports_vision || false,
|
|
888
|
-
supports_function_calling: modelInfo?.supports_function_calling || false,
|
|
889
|
-
supports_reasoning_effort: modelInfo?.supports_reasoning_effort || false
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
setAvailableModels(fetchedModels);
|
|
893
|
-
navigateTo("model");
|
|
894
|
-
return fetchedModels;
|
|
895
|
-
} catch (error) {
|
|
896
|
-
console.error("Error fetching models:", error);
|
|
897
|
-
throw error;
|
|
898
|
-
} finally {
|
|
899
|
-
setIsLoadingModels(false);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
function handleApiKeySubmit(key) {
|
|
903
|
-
setApiKey(key);
|
|
904
|
-
if (selectedProvider === "azure") {
|
|
905
|
-
navigateTo("resourceName");
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
fetchModelsWithRetry().catch((error) => {
|
|
909
|
-
console.error("Final error after retries:", error);
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
function handleResourceNameSubmit(name) {
|
|
913
|
-
setResourceName(name);
|
|
914
|
-
navigateTo("modelInput");
|
|
915
|
-
}
|
|
916
|
-
function handleOllamaBaseUrlSubmit(url) {
|
|
917
|
-
setOllamaBaseUrl(url);
|
|
918
|
-
setIsLoadingModels(true);
|
|
919
|
-
setModelLoadError(null);
|
|
920
|
-
fetchOllamaModels().finally(() => {
|
|
921
|
-
setIsLoadingModels(false);
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
function handleCustomBaseUrlSubmit(url) {
|
|
925
|
-
const cleanUrl = url.replace(/\/+$/, "");
|
|
926
|
-
setCustomBaseUrl(cleanUrl);
|
|
927
|
-
navigateTo("apiKey");
|
|
928
|
-
}
|
|
929
|
-
function handleProviderBaseUrlSubmit(url) {
|
|
930
|
-
const cleanUrl = url.replace(/\/+$/, "");
|
|
931
|
-
setProviderBaseUrl(cleanUrl);
|
|
932
|
-
if (selectedProvider === "ollama") {
|
|
933
|
-
setOllamaBaseUrl(cleanUrl);
|
|
934
|
-
setIsLoadingModels(true);
|
|
935
|
-
setModelLoadError(null);
|
|
936
|
-
fetchOllamaModels().finally(() => {
|
|
937
|
-
setIsLoadingModels(false);
|
|
938
|
-
});
|
|
939
|
-
} else {
|
|
940
|
-
navigateTo("apiKey");
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
function handleAnthropicProviderSelection(providerType) {
|
|
944
|
-
setAnthropicProviderType(providerType);
|
|
945
|
-
if (providerType === "custom") {
|
|
946
|
-
setProviderBaseUrl("");
|
|
947
|
-
navigateTo("baseUrl");
|
|
948
|
-
} else {
|
|
949
|
-
const defaultUrls = {
|
|
950
|
-
official: "https://api.anthropic.com",
|
|
951
|
-
bigdream: "https://api-key.info",
|
|
952
|
-
opendev: "https://api.openai-next.com"
|
|
953
|
-
};
|
|
954
|
-
setProviderBaseUrl(defaultUrls[providerType]);
|
|
955
|
-
navigateTo("apiKey");
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
function handleCustomModelSubmit(model) {
|
|
959
|
-
setCustomModelName(model);
|
|
960
|
-
setSelectedModel(model);
|
|
961
|
-
setSupportsReasoningEffort(false);
|
|
962
|
-
setReasoningEffort(null);
|
|
963
|
-
setMaxTokensMode("preset");
|
|
964
|
-
setSelectedMaxTokensPreset(DEFAULT_MAX_TOKENS);
|
|
965
|
-
setMaxTokens(DEFAULT_MAX_TOKENS.toString());
|
|
966
|
-
setMaxTokensCursorOffset(DEFAULT_MAX_TOKENS.toString().length);
|
|
967
|
-
navigateTo("modelParams");
|
|
968
|
-
setActiveFieldIndex(0);
|
|
969
|
-
}
|
|
970
|
-
function handleModelSelection(model) {
|
|
971
|
-
setSelectedModel(model);
|
|
972
|
-
const modelInfo = availableModels.find((m) => m.model === model);
|
|
973
|
-
setSupportsReasoningEffort(modelInfo?.supports_reasoning_effort || false);
|
|
974
|
-
if (!modelInfo?.supports_reasoning_effort) {
|
|
975
|
-
setReasoningEffort(null);
|
|
976
|
-
}
|
|
977
|
-
if (modelInfo?.max_tokens) {
|
|
978
|
-
const modelMaxTokens = modelInfo.max_tokens;
|
|
979
|
-
const matchingPreset = MAX_TOKENS_OPTIONS.find(
|
|
980
|
-
(option) => option.value === modelMaxTokens
|
|
981
|
-
);
|
|
982
|
-
if (matchingPreset) {
|
|
983
|
-
setMaxTokensMode("preset");
|
|
984
|
-
setSelectedMaxTokensPreset(modelMaxTokens);
|
|
985
|
-
setMaxTokens(modelMaxTokens.toString());
|
|
986
|
-
} else {
|
|
987
|
-
setMaxTokensMode("custom");
|
|
988
|
-
setMaxTokens(modelMaxTokens.toString());
|
|
989
|
-
}
|
|
990
|
-
setMaxTokensCursorOffset(modelMaxTokens.toString().length);
|
|
991
|
-
} else {
|
|
992
|
-
setMaxTokensMode("preset");
|
|
993
|
-
setSelectedMaxTokensPreset(DEFAULT_MAX_TOKENS);
|
|
994
|
-
setMaxTokens(DEFAULT_MAX_TOKENS.toString());
|
|
995
|
-
setMaxTokensCursorOffset(DEFAULT_MAX_TOKENS.toString().length);
|
|
996
|
-
}
|
|
997
|
-
navigateTo("modelParams");
|
|
998
|
-
setActiveFieldIndex(0);
|
|
999
|
-
}
|
|
1000
|
-
const handleModelParamsSubmit = () => {
|
|
1001
|
-
if (!CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength)) {
|
|
1002
|
-
setContextLength(DEFAULT_CONTEXT_LENGTH);
|
|
1003
|
-
}
|
|
1004
|
-
navigateTo("contextLength");
|
|
1005
|
-
};
|
|
1006
|
-
async function testConnection() {
|
|
1007
|
-
setIsTestingConnection(true);
|
|
1008
|
-
setConnectionTestResult(null);
|
|
1009
|
-
try {
|
|
1010
|
-
let testBaseURL = providerBaseUrl || providers[selectedProvider]?.baseURL || "";
|
|
1011
|
-
if (selectedProvider === "azure") {
|
|
1012
|
-
testBaseURL = `https://${resourceName}.openai.azure.com/openai/deployments/${selectedModel}`;
|
|
1013
|
-
} else if (selectedProvider === "custom-openai") {
|
|
1014
|
-
testBaseURL = customBaseUrl;
|
|
1015
|
-
}
|
|
1016
|
-
const isOpenAICompatible = [
|
|
1017
|
-
"minimax",
|
|
1018
|
-
"kimi",
|
|
1019
|
-
"deepseek",
|
|
1020
|
-
"siliconflow",
|
|
1021
|
-
"qwen",
|
|
1022
|
-
"glm",
|
|
1023
|
-
"baidu-qianfan",
|
|
1024
|
-
"openai",
|
|
1025
|
-
"mistral",
|
|
1026
|
-
"xai",
|
|
1027
|
-
"groq",
|
|
1028
|
-
"custom-openai"
|
|
1029
|
-
].includes(selectedProvider);
|
|
1030
|
-
if (isOpenAICompatible) {
|
|
1031
|
-
const isGPT5 = selectedModel?.toLowerCase().includes("gpt-5");
|
|
1032
|
-
if (isGPT5) {
|
|
1033
|
-
console.log(`\u{1F680} Using specialized GPT-5 connection test for model: ${selectedModel}`);
|
|
1034
|
-
const configValidation = validateGPT5Config({
|
|
1035
|
-
model: selectedModel,
|
|
1036
|
-
apiKey,
|
|
1037
|
-
baseURL: testBaseURL,
|
|
1038
|
-
maxTokens: parseInt(maxTokens) || 8192,
|
|
1039
|
-
provider: selectedProvider
|
|
1040
|
-
});
|
|
1041
|
-
if (!configValidation.valid) {
|
|
1042
|
-
return {
|
|
1043
|
-
success: false,
|
|
1044
|
-
message: "\u274C GPT-5 configuration validation failed",
|
|
1045
|
-
details: configValidation.errors.join("\n")
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
const gpt5Result = await testGPT5Connection({
|
|
1049
|
-
model: selectedModel,
|
|
1050
|
-
apiKey,
|
|
1051
|
-
baseURL: testBaseURL,
|
|
1052
|
-
maxTokens: parseInt(maxTokens) || 8192,
|
|
1053
|
-
provider: selectedProvider
|
|
1054
|
-
});
|
|
1055
|
-
return gpt5Result;
|
|
1056
|
-
}
|
|
1057
|
-
const endpointsToTry = [];
|
|
1058
|
-
if (selectedProvider === "minimax") {
|
|
1059
|
-
endpointsToTry.push(
|
|
1060
|
-
{
|
|
1061
|
-
path: "/text/chatcompletion_v2",
|
|
1062
|
-
name: "MiniMax v2 (recommended)"
|
|
1063
|
-
},
|
|
1064
|
-
{ path: "/chat/completions", name: "Standard OpenAI" }
|
|
1065
|
-
);
|
|
1066
|
-
} else {
|
|
1067
|
-
endpointsToTry.push({
|
|
1068
|
-
path: "/chat/completions",
|
|
1069
|
-
name: "Standard OpenAI"
|
|
1070
|
-
});
|
|
1071
|
-
}
|
|
1072
|
-
let lastError = null;
|
|
1073
|
-
for (const endpoint of endpointsToTry) {
|
|
1074
|
-
try {
|
|
1075
|
-
const testResult = await testChatEndpoint(
|
|
1076
|
-
testBaseURL,
|
|
1077
|
-
endpoint.path,
|
|
1078
|
-
endpoint.name
|
|
1079
|
-
);
|
|
1080
|
-
if (testResult.success) {
|
|
1081
|
-
return testResult;
|
|
1082
|
-
}
|
|
1083
|
-
lastError = testResult;
|
|
1084
|
-
} catch (error) {
|
|
1085
|
-
lastError = {
|
|
1086
|
-
success: false,
|
|
1087
|
-
message: `Failed to test ${endpoint.name}`,
|
|
1088
|
-
endpoint: endpoint.path,
|
|
1089
|
-
details: error instanceof Error ? error.message : String(error)
|
|
1090
|
-
};
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
return lastError || {
|
|
1094
|
-
success: false,
|
|
1095
|
-
message: "All endpoints failed",
|
|
1096
|
-
details: "No endpoints could be reached"
|
|
1097
|
-
};
|
|
1098
|
-
} else {
|
|
1099
|
-
return await testProviderSpecificEndpoint(testBaseURL);
|
|
1100
|
-
}
|
|
1101
|
-
} catch (error) {
|
|
1102
|
-
return {
|
|
1103
|
-
success: false,
|
|
1104
|
-
message: "Connection test failed",
|
|
1105
|
-
details: error instanceof Error ? error.message : String(error)
|
|
1106
|
-
};
|
|
1107
|
-
} finally {
|
|
1108
|
-
setIsTestingConnection(false);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
async function testChatEndpoint(baseURL, endpointPath, endpointName) {
|
|
1112
|
-
const testURL = `${baseURL.replace(/\/+$/, "")}${endpointPath}`;
|
|
1113
|
-
const testPayload = {
|
|
1114
|
-
model: selectedModel,
|
|
1115
|
-
messages: [
|
|
1116
|
-
{
|
|
1117
|
-
role: "user",
|
|
1118
|
-
content: 'Please respond with exactly "YES" (in capital letters) to confirm this connection is working.'
|
|
1119
|
-
}
|
|
1120
|
-
],
|
|
1121
|
-
max_tokens: Math.max(parseInt(maxTokens) || 8192, 8192),
|
|
1122
|
-
// Ensure minimum 8192 tokens for connection test
|
|
1123
|
-
temperature: 0,
|
|
1124
|
-
stream: false
|
|
1125
|
-
};
|
|
1126
|
-
if (selectedModel && selectedModel.toLowerCase().includes("gpt-5")) {
|
|
1127
|
-
console.log(`Applying GPT-5 parameter fix for model: ${selectedModel}`);
|
|
1128
|
-
if (testPayload.max_tokens) {
|
|
1129
|
-
testPayload.max_completion_tokens = testPayload.max_tokens;
|
|
1130
|
-
delete testPayload.max_tokens;
|
|
1131
|
-
console.log(`Transformed max_tokens \u2192 max_completion_tokens: ${testPayload.max_completion_tokens}`);
|
|
1132
|
-
}
|
|
1133
|
-
if (testPayload.temperature !== void 0 && testPayload.temperature !== 1) {
|
|
1134
|
-
console.log(`Adjusting temperature from ${testPayload.temperature} to 1 for GPT-5`);
|
|
1135
|
-
testPayload.temperature = 1;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
const headers = {
|
|
1139
|
-
"Content-Type": "application/json"
|
|
1140
|
-
};
|
|
1141
|
-
if (selectedProvider === "azure") {
|
|
1142
|
-
headers["api-key"] = apiKey;
|
|
1143
|
-
} else {
|
|
1144
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
1145
|
-
}
|
|
1146
|
-
try {
|
|
1147
|
-
const response = await fetch(testURL, {
|
|
1148
|
-
method: "POST",
|
|
1149
|
-
headers,
|
|
1150
|
-
body: JSON.stringify(testPayload)
|
|
1151
|
-
});
|
|
1152
|
-
if (response.ok) {
|
|
1153
|
-
const data = await response.json();
|
|
1154
|
-
console.log(
|
|
1155
|
-
"[DEBUG] Connection test response:",
|
|
1156
|
-
JSON.stringify(data, null, 2)
|
|
1157
|
-
);
|
|
1158
|
-
let responseContent = "";
|
|
1159
|
-
if (data.choices && data.choices.length > 0) {
|
|
1160
|
-
responseContent = data.choices[0]?.message?.content || "";
|
|
1161
|
-
} else if (data.reply) {
|
|
1162
|
-
responseContent = data.reply;
|
|
1163
|
-
} else if (data.output) {
|
|
1164
|
-
responseContent = data.output?.text || data.output || "";
|
|
1165
|
-
}
|
|
1166
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1167
|
-
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1168
|
-
if (containsYes) {
|
|
1169
|
-
return {
|
|
1170
|
-
success: true,
|
|
1171
|
-
message: `\u2705 Connection test passed with ${endpointName}`,
|
|
1172
|
-
endpoint: endpointPath,
|
|
1173
|
-
details: `Model responded correctly: "${responseContent.trim()}"`
|
|
1174
|
-
};
|
|
1175
|
-
} else {
|
|
1176
|
-
return {
|
|
1177
|
-
success: false,
|
|
1178
|
-
message: `\u26A0\uFE0F ${endpointName} connected but model response unexpected`,
|
|
1179
|
-
endpoint: endpointPath,
|
|
1180
|
-
details: `Expected "YES" but got: "${responseContent.trim() || "(empty response)"}"`
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
} else {
|
|
1184
|
-
const errorData = await response.json().catch(() => null);
|
|
1185
|
-
const errorMessage = errorData?.error?.message || errorData?.message || response.statusText;
|
|
1186
|
-
return {
|
|
1187
|
-
success: false,
|
|
1188
|
-
message: `\u274C ${endpointName} failed (${response.status})`,
|
|
1189
|
-
endpoint: endpointPath,
|
|
1190
|
-
details: `Error: ${errorMessage}`
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
} catch (error) {
|
|
1194
|
-
return {
|
|
1195
|
-
success: false,
|
|
1196
|
-
message: `\u274C ${endpointName} connection failed`,
|
|
1197
|
-
endpoint: endpointPath,
|
|
1198
|
-
details: error instanceof Error ? error.message : String(error)
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
async function testResponsesEndpoint(baseURL, endpointPath, endpointName) {
|
|
1203
|
-
const testURL = `${baseURL.replace(/\/+$/, "")}${endpointPath}`;
|
|
1204
|
-
const testPayload = {
|
|
1205
|
-
model: selectedModel,
|
|
1206
|
-
input: [
|
|
1207
|
-
{
|
|
1208
|
-
role: "user",
|
|
1209
|
-
content: 'Please respond with exactly "YES" (in capital letters) to confirm this connection is working.'
|
|
1210
|
-
}
|
|
1211
|
-
],
|
|
1212
|
-
max_completion_tokens: Math.max(parseInt(maxTokens) || 8192, 8192),
|
|
1213
|
-
temperature: 1,
|
|
1214
|
-
// GPT-5 only supports temperature=1
|
|
1215
|
-
// 🚀 Add reasoning configuration for better GPT-5 performance
|
|
1216
|
-
reasoning: {
|
|
1217
|
-
effort: "low"
|
|
1218
|
-
// Fast response for connection test
|
|
1219
|
-
}
|
|
1220
|
-
};
|
|
1221
|
-
console.log(`\u{1F527} Testing GPT-5 Responses API for model: ${selectedModel}`);
|
|
1222
|
-
console.log(`\u{1F527} Test URL: ${testURL}`);
|
|
1223
|
-
console.log(`\u{1F527} Test payload:`, JSON.stringify(testPayload, null, 2));
|
|
1224
|
-
const headers = {
|
|
1225
|
-
"Content-Type": "application/json",
|
|
1226
|
-
"Authorization": `Bearer ${apiKey}`
|
|
1227
|
-
};
|
|
1228
|
-
try {
|
|
1229
|
-
const response = await fetch(testURL, {
|
|
1230
|
-
method: "POST",
|
|
1231
|
-
headers,
|
|
1232
|
-
body: JSON.stringify(testPayload)
|
|
1233
|
-
});
|
|
1234
|
-
if (response.ok) {
|
|
1235
|
-
const data = await response.json();
|
|
1236
|
-
console.log(
|
|
1237
|
-
"[DEBUG] Responses API connection test response:",
|
|
1238
|
-
JSON.stringify(data, null, 2)
|
|
1239
|
-
);
|
|
1240
|
-
let responseContent = "";
|
|
1241
|
-
if (data.output_text) {
|
|
1242
|
-
responseContent = data.output_text;
|
|
1243
|
-
} else if (data.output) {
|
|
1244
|
-
responseContent = typeof data.output === "string" ? data.output : data.output.text || "";
|
|
1245
|
-
}
|
|
1246
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1247
|
-
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1248
|
-
if (containsYes) {
|
|
1249
|
-
return {
|
|
1250
|
-
success: true,
|
|
1251
|
-
message: `\u2705 Connection test passed with ${endpointName}`,
|
|
1252
|
-
endpoint: endpointPath,
|
|
1253
|
-
details: `GPT-5 responded correctly via Responses API: "${responseContent.trim()}"`
|
|
1254
|
-
};
|
|
1255
|
-
} else {
|
|
1256
|
-
return {
|
|
1257
|
-
success: false,
|
|
1258
|
-
message: `\u26A0\uFE0F ${endpointName} connected but model response unexpected`,
|
|
1259
|
-
endpoint: endpointPath,
|
|
1260
|
-
details: `Expected "YES" but got: "${responseContent.trim() || "(empty response)"}"`
|
|
1261
|
-
};
|
|
1262
|
-
}
|
|
1263
|
-
} else {
|
|
1264
|
-
const errorData = await response.json().catch(() => null);
|
|
1265
|
-
const errorMessage = errorData?.error?.message || errorData?.message || response.statusText;
|
|
1266
|
-
console.log(`\u{1F6A8} GPT-5 Responses API Error (${response.status}):`, errorData);
|
|
1267
|
-
let details = `Responses API Error: ${errorMessage}`;
|
|
1268
|
-
if (response.status === 400 && errorMessage.includes("max_tokens")) {
|
|
1269
|
-
details += "\n\u{1F527} Note: This appears to be a parameter compatibility issue. The fallback to Chat Completions should handle this.";
|
|
1270
|
-
} else if (response.status === 404) {
|
|
1271
|
-
details += "\n\u{1F527} Note: Responses API endpoint may not be available for this model or provider.";
|
|
1272
|
-
} else if (response.status === 401) {
|
|
1273
|
-
details += "\n\u{1F527} Note: API key authentication failed.";
|
|
1274
|
-
}
|
|
1275
|
-
return {
|
|
1276
|
-
success: false,
|
|
1277
|
-
message: `\u274C ${endpointName} failed (${response.status})`,
|
|
1278
|
-
endpoint: endpointPath,
|
|
1279
|
-
details
|
|
1280
|
-
};
|
|
1281
|
-
}
|
|
1282
|
-
} catch (error) {
|
|
1283
|
-
return {
|
|
1284
|
-
success: false,
|
|
1285
|
-
message: `\u274C ${endpointName} connection failed`,
|
|
1286
|
-
endpoint: endpointPath,
|
|
1287
|
-
details: error instanceof Error ? error.message : String(error)
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
async function testProviderSpecificEndpoint(baseURL) {
|
|
1292
|
-
if (selectedProvider === "anthropic" || selectedProvider === "bigdream") {
|
|
1293
|
-
try {
|
|
1294
|
-
console.log(
|
|
1295
|
-
`[DEBUG] Testing ${selectedProvider} connection using official Anthropic SDK...`
|
|
1296
|
-
);
|
|
1297
|
-
let testBaseURL = void 0;
|
|
1298
|
-
if (selectedProvider === "bigdream") {
|
|
1299
|
-
testBaseURL = baseURL || "https://api-key.info";
|
|
1300
|
-
} else if (selectedProvider === "anthropic") {
|
|
1301
|
-
testBaseURL = baseURL && baseURL !== "https://api.anthropic.com" ? baseURL : void 0;
|
|
1302
|
-
}
|
|
1303
|
-
const isValid = await verifyApiKey(apiKey, testBaseURL, selectedProvider);
|
|
1304
|
-
if (isValid) {
|
|
1305
|
-
return {
|
|
1306
|
-
success: true,
|
|
1307
|
-
message: `\u2705 ${selectedProvider} connection test passed`,
|
|
1308
|
-
endpoint: "/messages",
|
|
1309
|
-
details: "API key verified using official Anthropic SDK"
|
|
1310
|
-
};
|
|
1311
|
-
} else {
|
|
1312
|
-
return {
|
|
1313
|
-
success: false,
|
|
1314
|
-
message: `\u274C ${selectedProvider} API key verification failed`,
|
|
1315
|
-
endpoint: "/messages",
|
|
1316
|
-
details: "Invalid API key. Please check your API key and try again."
|
|
1317
|
-
};
|
|
1318
|
-
}
|
|
1319
|
-
} catch (error) {
|
|
1320
|
-
console.log(`[DEBUG] ${selectedProvider} connection test error:`, error);
|
|
1321
|
-
return {
|
|
1322
|
-
success: false,
|
|
1323
|
-
message: `\u274C ${selectedProvider} connection failed`,
|
|
1324
|
-
endpoint: "/messages",
|
|
1325
|
-
details: error instanceof Error ? error.message : String(error)
|
|
1326
|
-
};
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
return {
|
|
1330
|
-
success: true,
|
|
1331
|
-
message: `\u2705 Configuration saved for ${selectedProvider}`,
|
|
1332
|
-
details: "Provider-specific testing not implemented yet"
|
|
1333
|
-
};
|
|
1334
|
-
}
|
|
1335
|
-
async function handleConnectionTest() {
|
|
1336
|
-
const result = await testConnection();
|
|
1337
|
-
setConnectionTestResult(result);
|
|
1338
|
-
if (result.success) {
|
|
1339
|
-
setTimeout(() => {
|
|
1340
|
-
navigateTo("confirmation");
|
|
1341
|
-
}, 2e3);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
const handleContextLengthSubmit = () => {
|
|
1345
|
-
navigateTo("connectionTest");
|
|
1346
|
-
};
|
|
1347
|
-
async function saveConfiguration(provider, model) {
|
|
1348
|
-
let baseURL = providerBaseUrl || providers[provider]?.baseURL || "";
|
|
1349
|
-
let actualProvider = provider;
|
|
1350
|
-
if (provider === "anthropic") {
|
|
1351
|
-
switch (anthropicProviderType) {
|
|
1352
|
-
case "official":
|
|
1353
|
-
actualProvider = "anthropic";
|
|
1354
|
-
baseURL = baseURL || "https://api.anthropic.com";
|
|
1355
|
-
break;
|
|
1356
|
-
case "bigdream":
|
|
1357
|
-
actualProvider = "bigdream";
|
|
1358
|
-
baseURL = baseURL || "https://api-key.info";
|
|
1359
|
-
break;
|
|
1360
|
-
case "custom":
|
|
1361
|
-
actualProvider = "anthropic";
|
|
1362
|
-
break;
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
if (provider === "azure") {
|
|
1366
|
-
baseURL = `https://${resourceName}.openai.azure.com/openai/deployments/${model}`;
|
|
1367
|
-
} else if (provider === "custom-openai") {
|
|
1368
|
-
baseURL = customBaseUrl;
|
|
1369
|
-
}
|
|
1370
|
-
try {
|
|
1371
|
-
const modelManager = getModelManager();
|
|
1372
|
-
const modelConfig = {
|
|
1373
|
-
name: `${actualProvider} ${model}`,
|
|
1374
|
-
provider: actualProvider,
|
|
1375
|
-
modelName: model,
|
|
1376
|
-
baseURL,
|
|
1377
|
-
apiKey: apiKey || "",
|
|
1378
|
-
maxTokens: parseInt(maxTokens) || DEFAULT_MAX_TOKENS,
|
|
1379
|
-
contextLength: contextLength || DEFAULT_CONTEXT_LENGTH,
|
|
1380
|
-
reasoningEffort
|
|
1381
|
-
};
|
|
1382
|
-
return await modelManager.addModel(modelConfig);
|
|
1383
|
-
} catch (error) {
|
|
1384
|
-
setValidationError(
|
|
1385
|
-
error instanceof Error ? error.message : "Failed to add model"
|
|
1386
|
-
);
|
|
1387
|
-
return null;
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
async function handleConfirmation() {
|
|
1391
|
-
setValidationError(null);
|
|
1392
|
-
const modelId = await saveConfiguration(selectedProvider, selectedModel);
|
|
1393
|
-
if (!modelId) {
|
|
1394
|
-
return;
|
|
1395
|
-
}
|
|
1396
|
-
if (modelId && (isOnboarding || targetPointer)) {
|
|
1397
|
-
if (isOnboarding) {
|
|
1398
|
-
setAllPointersToModel(modelId);
|
|
1399
|
-
} else if (targetPointer) {
|
|
1400
|
-
setModelPointer(targetPointer, modelId);
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
onDone();
|
|
1404
|
-
}
|
|
1405
|
-
const handleBack = () => {
|
|
1406
|
-
if (currentScreen === "provider") {
|
|
1407
|
-
if (onCancel) {
|
|
1408
|
-
onCancel();
|
|
1409
|
-
} else {
|
|
1410
|
-
onDone();
|
|
1411
|
-
}
|
|
1412
|
-
} else {
|
|
1413
|
-
setScreenStack((prev) => prev.slice(0, -1));
|
|
1414
|
-
}
|
|
1415
|
-
};
|
|
1416
|
-
useEscapeNavigation(handleBack, abortController);
|
|
1417
|
-
function handleCursorOffsetChange(offset) {
|
|
1418
|
-
setCursorOffset(offset);
|
|
1419
|
-
}
|
|
1420
|
-
function handleApiKeyChange(value) {
|
|
1421
|
-
setApiKeyEdited(true);
|
|
1422
|
-
setApiKey(value);
|
|
1423
|
-
}
|
|
1424
|
-
function handleModelSearchChange(value) {
|
|
1425
|
-
setModelSearchQuery(value);
|
|
1426
|
-
setModelSearchCursorOffset(value.length);
|
|
1427
|
-
}
|
|
1428
|
-
function handleModelSearchCursorOffsetChange(offset) {
|
|
1429
|
-
setModelSearchCursorOffset(offset);
|
|
1430
|
-
}
|
|
1431
|
-
useInput((input, key) => {
|
|
1432
|
-
if (currentScreen === "apiKey" && key.return) {
|
|
1433
|
-
if (apiKey) {
|
|
1434
|
-
handleApiKeySubmit(apiKey);
|
|
1435
|
-
}
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
if (currentScreen === "apiKey" && key.tab) {
|
|
1439
|
-
if (selectedProvider === "anthropic" || selectedProvider === "kimi" || selectedProvider === "deepseek" || selectedProvider === "qwen" || selectedProvider === "glm" || selectedProvider === "minimax" || selectedProvider === "baidu-qianfan" || selectedProvider === "siliconflow" || selectedProvider === "custom-openai") {
|
|
1440
|
-
navigateTo("modelInput");
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
fetchModelsWithRetry().catch((error) => {
|
|
1444
|
-
console.error("Final error after retries:", error);
|
|
1445
|
-
});
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
if (currentScreen === "resourceName" && key.return) {
|
|
1449
|
-
if (resourceName) {
|
|
1450
|
-
handleResourceNameSubmit(resourceName);
|
|
1451
|
-
}
|
|
1452
|
-
return;
|
|
1453
|
-
}
|
|
1454
|
-
if (currentScreen === "baseUrl" && key.return) {
|
|
1455
|
-
if (selectedProvider === "custom-openai") {
|
|
1456
|
-
handleCustomBaseUrlSubmit(customBaseUrl);
|
|
1457
|
-
} else {
|
|
1458
|
-
handleProviderBaseUrlSubmit(providerBaseUrl);
|
|
1459
|
-
}
|
|
1460
|
-
return;
|
|
1461
|
-
}
|
|
1462
|
-
if (currentScreen === "modelInput" && key.return) {
|
|
1463
|
-
if (customModelName) {
|
|
1464
|
-
handleCustomModelSubmit(customModelName);
|
|
1465
|
-
}
|
|
1466
|
-
return;
|
|
1467
|
-
}
|
|
1468
|
-
if (currentScreen === "confirmation" && key.return) {
|
|
1469
|
-
handleConfirmation().catch((error) => {
|
|
1470
|
-
console.error("Error in handleConfirmation:", error);
|
|
1471
|
-
setValidationError(
|
|
1472
|
-
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1473
|
-
);
|
|
1474
|
-
});
|
|
1475
|
-
return;
|
|
1476
|
-
}
|
|
1477
|
-
if (currentScreen === "connectionTest") {
|
|
1478
|
-
if (key.return) {
|
|
1479
|
-
if (!isTestingConnection && !connectionTestResult) {
|
|
1480
|
-
handleConnectionTest();
|
|
1481
|
-
} else if (connectionTestResult && connectionTestResult.success) {
|
|
1482
|
-
navigateTo("confirmation");
|
|
1483
|
-
} else if (connectionTestResult && !connectionTestResult.success) {
|
|
1484
|
-
handleConnectionTest();
|
|
1485
|
-
}
|
|
1486
|
-
return;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
if (currentScreen === "contextLength") {
|
|
1490
|
-
if (key.return) {
|
|
1491
|
-
handleContextLengthSubmit();
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
if (key.upArrow) {
|
|
1495
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1496
|
-
(opt) => opt.value === contextLength
|
|
1497
|
-
);
|
|
1498
|
-
const newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1499
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1500
|
-
) || 0 : CONTEXT_LENGTH_OPTIONS.length - 1;
|
|
1501
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1502
|
-
return;
|
|
1503
|
-
}
|
|
1504
|
-
if (key.downArrow) {
|
|
1505
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1506
|
-
(opt) => opt.value === contextLength
|
|
1507
|
-
);
|
|
1508
|
-
const newIndex = currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1509
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1510
|
-
) || 0 : (currentIndex + 1) % CONTEXT_LENGTH_OPTIONS.length;
|
|
1511
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1512
|
-
return;
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
if (currentScreen === "apiKey" && (key.ctrl && input === "v" || key.meta && input === "v")) {
|
|
1516
|
-
setModelLoadError(
|
|
1517
|
-
"Please use your terminal's paste functionality or type the API key manually"
|
|
1518
|
-
);
|
|
1519
|
-
return;
|
|
1520
|
-
}
|
|
1521
|
-
if (currentScreen === "modelParams" && key.tab) {
|
|
1522
|
-
const formFields = getFormFieldsForModelParams();
|
|
1523
|
-
setActiveFieldIndex((current) => (current + 1) % formFields.length);
|
|
1524
|
-
return;
|
|
1525
|
-
}
|
|
1526
|
-
if (currentScreen === "modelParams" && key.return) {
|
|
1527
|
-
const formFields = getFormFieldsForModelParams();
|
|
1528
|
-
const currentField = formFields[activeFieldIndex];
|
|
1529
|
-
if (currentField.name === "submit" || activeFieldIndex === formFields.length - 1) {
|
|
1530
|
-
handleModelParamsSubmit();
|
|
1531
|
-
} else if (currentField.component === "select") {
|
|
1532
|
-
setActiveFieldIndex(
|
|
1533
|
-
(current) => Math.min(current + 1, formFields.length - 1)
|
|
1534
|
-
);
|
|
1535
|
-
}
|
|
1536
|
-
return;
|
|
1537
|
-
}
|
|
1538
|
-
});
|
|
1539
|
-
function getFormFieldsForModelParams() {
|
|
1540
|
-
return [
|
|
1541
|
-
{
|
|
1542
|
-
name: "maxTokens",
|
|
1543
|
-
label: "Maximum Tokens",
|
|
1544
|
-
description: "Select the maximum number of tokens to generate.",
|
|
1545
|
-
value: parseInt(maxTokens),
|
|
1546
|
-
component: "select",
|
|
1547
|
-
options: MAX_TOKENS_OPTIONS.map((option) => ({
|
|
1548
|
-
label: option.label,
|
|
1549
|
-
value: option.value.toString()
|
|
1550
|
-
})),
|
|
1551
|
-
defaultValue: maxTokens
|
|
1552
|
-
},
|
|
1553
|
-
...supportsReasoningEffort ? [
|
|
1554
|
-
{
|
|
1555
|
-
name: "reasoningEffort",
|
|
1556
|
-
label: "Reasoning Effort",
|
|
1557
|
-
description: "Controls reasoning depth for complex problems.",
|
|
1558
|
-
value: reasoningEffort,
|
|
1559
|
-
component: "select"
|
|
1560
|
-
}
|
|
1561
|
-
] : [],
|
|
1562
|
-
{
|
|
1563
|
-
name: "submit",
|
|
1564
|
-
label: "Continue \u2192",
|
|
1565
|
-
component: "button"
|
|
1566
|
-
}
|
|
1567
|
-
];
|
|
1568
|
-
}
|
|
1569
|
-
if (currentScreen === "apiKey") {
|
|
1570
|
-
const modelTypeText = "this model profile";
|
|
1571
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1572
|
-
Box,
|
|
1573
|
-
{
|
|
1574
|
-
flexDirection: "column",
|
|
1575
|
-
gap: 1,
|
|
1576
|
-
borderStyle: "round",
|
|
1577
|
-
borderColor: theme.secondaryBorder,
|
|
1578
|
-
paddingX: 2,
|
|
1579
|
-
paddingY: 1
|
|
1580
|
-
},
|
|
1581
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "API Key Setup", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1582
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Enter your ", getProviderLabel(selectedProvider, 0).split(" (")[0], " ", "API key for ", modelTypeText, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This key will be stored locally and used to access the", " ", selectedProvider, " API.", /* @__PURE__ */ React.createElement(Newline, null), "Your key is never sent to our servers.", /* @__PURE__ */ React.createElement(Newline, null), /* @__PURE__ */ React.createElement(Newline, null), selectedProvider === "kimi" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://platform.moonshot.cn/console/api-keys")), selectedProvider === "deepseek" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://platform.deepseek.com/api_keys")), selectedProvider === "siliconflow" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://cloud.siliconflow.cn/i/oJWsm6io")), selectedProvider === "qwen" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://bailian.console.aliyun.com/?tab=model#/api-key")), selectedProvider === "glm" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://open.bigmodel.cn (API Keys section)")), selectedProvider === "minimax" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://www.minimax.io/platform/user-center/basic-information")), selectedProvider === "baidu-qianfan" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://console.bce.baidu.com/iam/#/iam/accesslist")), selectedProvider === "anthropic" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, 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")), selectedProvider === "openai" && /* @__PURE__ */ React.createElement(React.Fragment, null, "\u{1F4A1} Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "https://platform.openai.com/api-keys")))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
1583
|
-
TextInput,
|
|
1584
|
-
{
|
|
1585
|
-
placeholder: "sk-...",
|
|
1586
|
-
value: apiKey,
|
|
1587
|
-
onChange: handleApiKeyChange,
|
|
1588
|
-
onSubmit: handleApiKeySubmit,
|
|
1589
|
-
mask: "*",
|
|
1590
|
-
columns: 500,
|
|
1591
|
-
cursorOffset,
|
|
1592
|
-
onChangeCursorOffset: handleCursorOffsetChange,
|
|
1593
|
-
showCursor: true
|
|
1594
|
-
}
|
|
1595
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion, dimColor: !apiKey }, "[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: "red" }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "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")))
|
|
1596
|
-
));
|
|
1597
|
-
}
|
|
1598
|
-
if (currentScreen === "model") {
|
|
1599
|
-
const modelTypeText = "this model profile";
|
|
1600
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1601
|
-
Box,
|
|
1602
|
-
{
|
|
1603
|
-
flexDirection: "column",
|
|
1604
|
-
gap: 1,
|
|
1605
|
-
borderStyle: "round",
|
|
1606
|
-
borderColor: theme.secondaryBorder,
|
|
1607
|
-
paddingX: 2,
|
|
1608
|
-
paddingY: 1
|
|
1609
|
-
},
|
|
1610
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Selection", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1611
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select a model from", " ", getProviderLabel(
|
|
1612
|
-
selectedProvider,
|
|
1613
|
-
availableModels.length
|
|
1614
|
-
).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(
|
|
1615
|
-
TextInput,
|
|
1616
|
-
{
|
|
1617
|
-
placeholder: "Type to filter models...",
|
|
1618
|
-
value: modelSearchQuery,
|
|
1619
|
-
onChange: handleModelSearchChange,
|
|
1620
|
-
columns: 100,
|
|
1621
|
-
cursorOffset: modelSearchCursorOffset,
|
|
1622
|
-
onChangeCursorOffset: handleModelSearchCursorOffsetChange,
|
|
1623
|
-
showCursor: true,
|
|
1624
|
-
focus: true
|
|
1625
|
-
}
|
|
1626
|
-
)), modelOptions.length > 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1627
|
-
Select,
|
|
1628
|
-
{
|
|
1629
|
-
options: modelOptions,
|
|
1630
|
-
onChange: handleModelSelection
|
|
1631
|
-
}
|
|
1632
|
-
), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Showing ", modelOptions.length, " of ", availableModels.length, " ", "models")) : /* @__PURE__ */ React.createElement(Box, null, availableModels.length > 0 ? /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "No models match your search. Try a different query.") : /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "No models available for this provider.")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to API key input")))
|
|
1633
|
-
));
|
|
1634
|
-
}
|
|
1635
|
-
if (currentScreen === "modelParams") {
|
|
1636
|
-
const formFields = getFormFieldsForModelParams();
|
|
1637
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1638
|
-
Box,
|
|
1639
|
-
{
|
|
1640
|
-
flexDirection: "column",
|
|
1641
|
-
gap: 1,
|
|
1642
|
-
borderStyle: "round",
|
|
1643
|
-
borderColor: theme.secondaryBorder,
|
|
1644
|
-
paddingX: 2,
|
|
1645
|
-
paddingY: 1
|
|
1646
|
-
},
|
|
1647
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Parameters", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1648
|
-
/* @__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(
|
|
1649
|
-
Text,
|
|
1650
|
-
{
|
|
1651
|
-
bold: true,
|
|
1652
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1653
|
-
},
|
|
1654
|
-
field.label
|
|
1655
|
-
), field.description && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, field.description)) : /* @__PURE__ */ React.createElement(
|
|
1656
|
-
Text,
|
|
1657
|
-
{
|
|
1658
|
-
bold: true,
|
|
1659
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1660
|
-
},
|
|
1661
|
-
field.label
|
|
1662
|
-
), /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, activeFieldIndex === index ? field.component === "select" ? field.name === "maxTokens" ? /* @__PURE__ */ React.createElement(
|
|
1663
|
-
Select,
|
|
1664
|
-
{
|
|
1665
|
-
options: field.options || [],
|
|
1666
|
-
onChange: (value) => {
|
|
1667
|
-
const numValue = parseInt(value);
|
|
1668
|
-
setMaxTokens(numValue.toString());
|
|
1669
|
-
setSelectedMaxTokensPreset(numValue);
|
|
1670
|
-
setMaxTokensCursorOffset(
|
|
1671
|
-
numValue.toString().length
|
|
1672
|
-
);
|
|
1673
|
-
setTimeout(() => {
|
|
1674
|
-
setActiveFieldIndex(index + 1);
|
|
1675
|
-
}, 100);
|
|
1676
|
-
},
|
|
1677
|
-
defaultValue: field.defaultValue
|
|
1678
|
-
}
|
|
1679
|
-
) : /* @__PURE__ */ React.createElement(
|
|
1680
|
-
Select,
|
|
1681
|
-
{
|
|
1682
|
-
options: reasoningEffortOptions,
|
|
1683
|
-
onChange: (value) => {
|
|
1684
|
-
setReasoningEffort(value);
|
|
1685
|
-
setTimeout(() => {
|
|
1686
|
-
setActiveFieldIndex(index + 1);
|
|
1687
|
-
}, 100);
|
|
1688
|
-
},
|
|
1689
|
-
defaultValue: reasoningEffort
|
|
1690
|
-
}
|
|
1691
|
-
) : null : field.name === "maxTokens" ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Current:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, MAX_TOKENS_OPTIONS.find(
|
|
1692
|
-
(opt) => opt.value === parseInt(maxTokens)
|
|
1693
|
-
)?.label || `${maxTokens} tokens`)) : field.name === "reasoningEffort" ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Current:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, reasoningEffort)) : null))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Tab"), " to navigate,", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue, or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back"))))
|
|
1694
|
-
));
|
|
1695
|
-
}
|
|
1696
|
-
if (currentScreen === "resourceName") {
|
|
1697
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1698
|
-
Box,
|
|
1699
|
-
{
|
|
1700
|
-
flexDirection: "column",
|
|
1701
|
-
gap: 1,
|
|
1702
|
-
borderStyle: "round",
|
|
1703
|
-
borderColor: theme.secondaryBorder,
|
|
1704
|
-
paddingX: 2,
|
|
1705
|
-
paddingY: 1
|
|
1706
|
-
},
|
|
1707
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Azure Resource Setup", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1708
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Enter your Azure OpenAI resource name:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This is the name of your Azure OpenAI resource (without the full domain).", /* @__PURE__ */ React.createElement(Newline, null), 'For example, if your endpoint is "https://myresource.openai.azure.com", enter "myresource".')), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
1709
|
-
TextInput,
|
|
1710
|
-
{
|
|
1711
|
-
placeholder: "myazureresource",
|
|
1712
|
-
value: resourceName,
|
|
1713
|
-
onChange: setResourceName,
|
|
1714
|
-
onSubmit: handleResourceNameSubmit,
|
|
1715
|
-
columns: 100,
|
|
1716
|
-
cursorOffset: resourceNameCursorOffset,
|
|
1717
|
-
onChangeCursorOffset: setResourceNameCursorOffset,
|
|
1718
|
-
showCursor: true
|
|
1719
|
-
}
|
|
1720
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion, dimColor: !resourceName }, "[Submit Resource Name]"), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1721
|
-
));
|
|
1722
|
-
}
|
|
1723
|
-
if (currentScreen === "baseUrl") {
|
|
1724
|
-
const isCustomOpenAI = selectedProvider === "custom-openai";
|
|
1725
|
-
if (isCustomOpenAI) {
|
|
1726
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1727
|
-
Box,
|
|
1728
|
-
{
|
|
1729
|
-
flexDirection: "column",
|
|
1730
|
-
gap: 1,
|
|
1731
|
-
borderStyle: "round",
|
|
1732
|
-
borderColor: theme.secondaryBorder,
|
|
1733
|
-
paddingX: 2,
|
|
1734
|
-
paddingY: 1
|
|
1735
|
-
},
|
|
1736
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Custom API Server Setup", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1737
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Enter your custom API URL:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This is the base URL for your OpenAI-compatible API.", /* @__PURE__ */ React.createElement(Newline, null), "For example: https://api.example.com/v1")), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
1738
|
-
TextInput,
|
|
1739
|
-
{
|
|
1740
|
-
placeholder: "https://api.example.com/v1",
|
|
1741
|
-
value: customBaseUrl,
|
|
1742
|
-
onChange: setCustomBaseUrl,
|
|
1743
|
-
onSubmit: handleCustomBaseUrlSubmit,
|
|
1744
|
-
columns: 100,
|
|
1745
|
-
cursorOffset: customBaseUrlCursorOffset,
|
|
1746
|
-
onChangeCursorOffset: setCustomBaseUrlCursorOffset,
|
|
1747
|
-
showCursor: !isLoadingModels,
|
|
1748
|
-
focus: !isLoadingModels
|
|
1749
|
-
}
|
|
1750
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1751
|
-
Text,
|
|
1752
|
-
{
|
|
1753
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1754
|
-
},
|
|
1755
|
-
"[Submit Base URL]"
|
|
1756
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1757
|
-
));
|
|
1758
|
-
}
|
|
1759
|
-
const providerName = providers[selectedProvider]?.name || selectedProvider;
|
|
1760
|
-
const defaultUrl = providers[selectedProvider]?.baseURL || "";
|
|
1761
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1762
|
-
Box,
|
|
1763
|
-
{
|
|
1764
|
-
flexDirection: "column",
|
|
1765
|
-
gap: 1,
|
|
1766
|
-
borderStyle: "round",
|
|
1767
|
-
borderColor: theme.secondaryBorder,
|
|
1768
|
-
paddingX: 2,
|
|
1769
|
-
paddingY: 1
|
|
1770
|
-
},
|
|
1771
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, providerName, " API Configuration", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1772
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Configure the API endpoint for ", providerName, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, selectedProvider === "ollama" ? /* @__PURE__ */ React.createElement(React.Fragment, null, "This is the URL of your Ollama server.", /* @__PURE__ */ React.createElement(Newline, null), "Default is http://localhost:11434/v1 for local Ollama installations.") : /* @__PURE__ */ React.createElement(React.Fragment, null, "This is the base URL for the ", providerName, " API.", /* @__PURE__ */ React.createElement(Newline, null), "You can modify this URL or press Enter to use the default."))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
1773
|
-
TextInput,
|
|
1774
|
-
{
|
|
1775
|
-
placeholder: defaultUrl,
|
|
1776
|
-
value: providerBaseUrl,
|
|
1777
|
-
onChange: setProviderBaseUrl,
|
|
1778
|
-
onSubmit: handleProviderBaseUrlSubmit,
|
|
1779
|
-
columns: 100,
|
|
1780
|
-
cursorOffset: providerBaseUrlCursorOffset,
|
|
1781
|
-
onChangeCursorOffset: setProviderBaseUrlCursorOffset,
|
|
1782
|
-
showCursor: !isLoadingModels,
|
|
1783
|
-
focus: !isLoadingModels
|
|
1784
|
-
}
|
|
1785
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1786
|
-
Text,
|
|
1787
|
-
{
|
|
1788
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1789
|
-
},
|
|
1790
|
-
"[Submit Base URL]"
|
|
1791
|
-
), /* @__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: "red" }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1792
|
-
));
|
|
1793
|
-
}
|
|
1794
|
-
if (currentScreen === "modelInput") {
|
|
1795
|
-
const modelTypeText = "this model profile";
|
|
1796
|
-
let screenTitle = "Manual Model Setup";
|
|
1797
|
-
let description = "Enter the model name manually";
|
|
1798
|
-
let placeholder = "gpt-4";
|
|
1799
|
-
let examples = 'For example: "gpt-4", "gpt-3.5-turbo", etc.';
|
|
1800
|
-
if (selectedProvider === "azure") {
|
|
1801
|
-
screenTitle = "Azure Model Setup";
|
|
1802
|
-
description = `Enter your Azure OpenAI deployment name for ${modelTypeText}:`;
|
|
1803
|
-
examples = 'For example: "gpt-4", "gpt-35-turbo", etc.';
|
|
1804
|
-
placeholder = "gpt-4";
|
|
1805
|
-
} else if (selectedProvider === "anthropic") {
|
|
1806
|
-
screenTitle = "Claude Model Setup";
|
|
1807
|
-
description = `Enter the Claude model name for ${modelTypeText}:`;
|
|
1808
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1809
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1810
|
-
} else if (selectedProvider === "bigdream") {
|
|
1811
|
-
screenTitle = "BigDream Model Setup";
|
|
1812
|
-
description = `Enter the BigDream model name for ${modelTypeText}:`;
|
|
1813
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1814
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1815
|
-
} else if (selectedProvider === "kimi") {
|
|
1816
|
-
screenTitle = "Kimi Model Setup";
|
|
1817
|
-
description = `Enter the Kimi model name for ${modelTypeText}:`;
|
|
1818
|
-
examples = 'For example: "kimi-k2-0711-preview"';
|
|
1819
|
-
placeholder = "kimi-k2-0711-preview";
|
|
1820
|
-
} else if (selectedProvider === "deepseek") {
|
|
1821
|
-
screenTitle = "DeepSeek Model Setup";
|
|
1822
|
-
description = `Enter the DeepSeek model name for ${modelTypeText}:`;
|
|
1823
|
-
examples = 'For example: "deepseek-chat", "deepseek-coder", "deepseek-reasoner", etc.';
|
|
1824
|
-
placeholder = "deepseek-chat";
|
|
1825
|
-
} else if (selectedProvider === "siliconflow") {
|
|
1826
|
-
screenTitle = "SiliconFlow Model Setup";
|
|
1827
|
-
description = `Enter the SiliconFlow model name for ${modelTypeText}:`;
|
|
1828
|
-
examples = 'For example: "Qwen/Qwen2.5-72B-Instruct", "meta-llama/Meta-Llama-3.1-8B-Instruct", etc.';
|
|
1829
|
-
placeholder = "Qwen/Qwen2.5-72B-Instruct";
|
|
1830
|
-
} else if (selectedProvider === "qwen") {
|
|
1831
|
-
screenTitle = "Qwen Model Setup";
|
|
1832
|
-
description = `Enter the Qwen model name for ${modelTypeText}:`;
|
|
1833
|
-
examples = 'For example: "qwen-plus", "qwen-turbo", "qwen-max", etc.';
|
|
1834
|
-
placeholder = "qwen-plus";
|
|
1835
|
-
} else if (selectedProvider === "glm") {
|
|
1836
|
-
screenTitle = "GLM Model Setup";
|
|
1837
|
-
description = `Enter the GLM model name for ${modelTypeText}:`;
|
|
1838
|
-
examples = 'For example: "glm-4", "glm-4v", "glm-3-turbo", etc.';
|
|
1839
|
-
placeholder = "glm-4";
|
|
1840
|
-
} else if (selectedProvider === "minimax") {
|
|
1841
|
-
screenTitle = "MiniMax Model Setup";
|
|
1842
|
-
description = `Enter the MiniMax model name for ${modelTypeText}:`;
|
|
1843
|
-
examples = 'For example: "abab6.5s-chat", "abab6.5g-chat", "abab5.5s-chat", etc.';
|
|
1844
|
-
placeholder = "abab6.5s-chat";
|
|
1845
|
-
} else if (selectedProvider === "baidu-qianfan") {
|
|
1846
|
-
screenTitle = "Baidu Qianfan Model Setup";
|
|
1847
|
-
description = `Enter the Baidu Qianfan model name for ${modelTypeText}:`;
|
|
1848
|
-
examples = 'For example: "ERNIE-4.0-8K", "ERNIE-3.5-8K", "ERNIE-Speed-128K", etc.';
|
|
1849
|
-
placeholder = "ERNIE-4.0-8K";
|
|
1850
|
-
} else if (selectedProvider === "custom-openai") {
|
|
1851
|
-
screenTitle = "Custom API Model Setup";
|
|
1852
|
-
description = `Enter the model name for ${modelTypeText}:`;
|
|
1853
|
-
examples = "Enter the exact model name as supported by your API endpoint.";
|
|
1854
|
-
placeholder = "model-name";
|
|
1855
|
-
}
|
|
1856
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1857
|
-
Box,
|
|
1858
|
-
{
|
|
1859
|
-
flexDirection: "column",
|
|
1860
|
-
gap: 1,
|
|
1861
|
-
borderStyle: "round",
|
|
1862
|
-
borderColor: theme.secondaryBorder,
|
|
1863
|
-
paddingX: 2,
|
|
1864
|
-
paddingY: 1
|
|
1865
|
-
},
|
|
1866
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, screenTitle, " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1867
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, description), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, selectedProvider === "azure" ? "This is the deployment name you configured in your Azure OpenAI resource." : selectedProvider === "anthropic" ? "This should be a valid Claude model identifier from Claude." : selectedProvider === "bigdream" ? "This should be a valid Claude model identifier supported by BigDream." : selectedProvider === "kimi" ? "This should be a valid Kimi model identifier from Moonshot AI." : selectedProvider === "deepseek" ? "This should be a valid DeepSeek model identifier." : selectedProvider === "siliconflow" ? "This should be a valid SiliconFlow model identifier." : selectedProvider === "qwen" ? "This should be a valid Qwen model identifier from Alibaba Cloud." : selectedProvider === "glm" ? "This should be a valid GLM model identifier from Zhipu AI." : selectedProvider === "minimax" ? "This should be a valid MiniMax model identifier." : selectedProvider === "baidu-qianfan" ? "This should be a valid Baidu Qianfan model identifier." : "This should match the model name supported by your API endpoint.", /* @__PURE__ */ React.createElement(Newline, null), examples)), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
1868
|
-
TextInput,
|
|
1869
|
-
{
|
|
1870
|
-
placeholder,
|
|
1871
|
-
value: customModelName,
|
|
1872
|
-
onChange: setCustomModelName,
|
|
1873
|
-
onSubmit: handleCustomModelSubmit,
|
|
1874
|
-
columns: 100,
|
|
1875
|
-
cursorOffset: customModelNameCursorOffset,
|
|
1876
|
-
onChangeCursorOffset: setCustomModelNameCursorOffset,
|
|
1877
|
-
showCursor: true
|
|
1878
|
-
}
|
|
1879
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion, dimColor: !customModelName }, "[Submit Model Name]"), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1880
|
-
));
|
|
1881
|
-
}
|
|
1882
|
-
if (currentScreen === "contextLength") {
|
|
1883
|
-
const selectedOption = CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength) || CONTEXT_LENGTH_OPTIONS[2];
|
|
1884
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1885
|
-
Box,
|
|
1886
|
-
{
|
|
1887
|
-
flexDirection: "column",
|
|
1888
|
-
gap: 1,
|
|
1889
|
-
borderStyle: "round",
|
|
1890
|
-
borderColor: theme.secondaryBorder,
|
|
1891
|
-
paddingX: 2,
|
|
1892
|
-
paddingY: 1
|
|
1893
|
-
},
|
|
1894
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Context Length Configuration", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1895
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Choose the context window length for your model:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This determines how much conversation history and context the model can process at once. Higher values allow for longer conversations but may increase costs.")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, CONTEXT_LENGTH_OPTIONS.map((option, index) => {
|
|
1896
|
-
const isSelected = option.value === contextLength;
|
|
1897
|
-
return /* @__PURE__ */ React.createElement(Box, { key: option.value, flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? "blue" : void 0 }, isSelected ? "\u2192 " : " ", option.label, option.value === DEFAULT_CONTEXT_LENGTH ? " (recommended)" : ""));
|
|
1898
|
-
})), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Selected:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, selectedOption.label))))
|
|
1899
|
-
), /* @__PURE__ */ React.createElement(Box, { marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2191/\u2193 to select \xB7 Enter to continue \xB7 Esc to go back")));
|
|
1900
|
-
}
|
|
1901
|
-
if (currentScreen === "connectionTest") {
|
|
1902
|
-
const providerDisplayName = getProviderLabel(selectedProvider, 0).split(
|
|
1903
|
-
" ("
|
|
1904
|
-
)[0];
|
|
1905
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1906
|
-
Box,
|
|
1907
|
-
{
|
|
1908
|
-
flexDirection: "column",
|
|
1909
|
-
gap: 1,
|
|
1910
|
-
borderStyle: "round",
|
|
1911
|
-
borderColor: theme.secondaryBorder,
|
|
1912
|
-
paddingX: 2,
|
|
1913
|
-
paddingY: 1
|
|
1914
|
-
},
|
|
1915
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Connection Test", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1916
|
-
/* @__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(
|
|
1917
|
-
Text,
|
|
1918
|
-
{
|
|
1919
|
-
color: connectionTestResult.success ? theme.success : "red"
|
|
1920
|
-
},
|
|
1921
|
-
connectionTestResult.message
|
|
1922
|
-
), connectionTestResult.endpoint && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Endpoint: ", connectionTestResult.endpoint), connectionTestResult.details && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Details: ", connectionTestResult.details), connectionTestResult.success ? /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "\u2705 Automatically proceeding to confirmation...")) : /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Press Enter"), " to retry test, or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to context length")))
|
|
1923
|
-
));
|
|
1924
|
-
}
|
|
1925
|
-
if (currentScreen === "confirmation") {
|
|
1926
|
-
const providerDisplayName = getProviderLabel(selectedProvider, 0).split(
|
|
1927
|
-
" ("
|
|
1928
|
-
)[0];
|
|
1929
|
-
const showsApiKey = selectedProvider !== "ollama";
|
|
1930
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1931
|
-
Box,
|
|
1932
|
-
{
|
|
1933
|
-
flexDirection: "column",
|
|
1934
|
-
gap: 1,
|
|
1935
|
-
borderStyle: "round",
|
|
1936
|
-
borderColor: theme.secondaryBorder,
|
|
1937
|
-
paddingX: 2,
|
|
1938
|
-
paddingY: 1
|
|
1939
|
-
},
|
|
1940
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Configuration Confirmation", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1941
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Confirm your model configuration:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Please review your selections before saving.")), validationError && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1, paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error, bold: true }, "\u26A0 Configuration Error:"), /* @__PURE__ */ React.createElement(Text, { color: theme.error }, validationError)), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1, paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Provider: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, providerDisplayName)), selectedProvider === "azure" && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Resource Name: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, resourceName)), selectedProvider === "ollama" && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Server URL: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, ollamaBaseUrl)), selectedProvider === "custom-openai" && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "API Base URL: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, customBaseUrl)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Model: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, selectedModel)), apiKey && showsApiKey && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "API Key: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "****", apiKey.slice(-4))), maxTokens && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Max Tokens: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, maxTokens)), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Context Length: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, CONTEXT_LENGTH_OPTIONS.find(
|
|
1942
|
-
(opt) => opt.value === contextLength
|
|
1943
|
-
)?.label || `${contextLength.toLocaleString()} tokens`)), supportsReasoningEffort && /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Reasoning Effort: "), /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, reasoningEffort))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to model parameters or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " ", "to save configuration")))
|
|
1944
|
-
));
|
|
1945
|
-
}
|
|
1946
|
-
if (currentScreen === "anthropicSubMenu") {
|
|
1947
|
-
const anthropicOptions = [
|
|
1948
|
-
{ label: "Official Anthropic API", value: "official" },
|
|
1949
|
-
{ label: "BigDream (Community Proxy)", value: "bigdream" },
|
|
1950
|
-
{ label: "OpenDev (Community Proxy)", value: "opendev" },
|
|
1951
|
-
{ label: "Custom Anthropic-Compatible API", value: "custom" }
|
|
1952
|
-
];
|
|
1953
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1954
|
-
Box,
|
|
1955
|
-
{
|
|
1956
|
-
flexDirection: "column",
|
|
1957
|
-
gap: 1,
|
|
1958
|
-
borderStyle: "round",
|
|
1959
|
-
borderColor: theme.secondaryBorder,
|
|
1960
|
-
paddingX: 2,
|
|
1961
|
-
paddingY: 1
|
|
1962
|
-
},
|
|
1963
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Claude Provider Selection", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1964
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Choose your Anthropic API access method for this model profile:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Official Anthropic API:"), " Direct access to Anthropic's official API", /* @__PURE__ */ React.createElement(Newline, null), "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "BigDream:"), " Community proxy providing Claude access", /* @__PURE__ */ React.createElement(Newline, null), "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Custom:"), " Your own Anthropic-compatible API endpoint")), /* @__PURE__ */ React.createElement(
|
|
1965
|
-
Select,
|
|
1966
|
-
{
|
|
1967
|
-
options: anthropicOptions,
|
|
1968
|
-
onChange: handleAnthropicProviderSelection
|
|
1969
|
-
}
|
|
1970
|
-
), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to provider selection")))
|
|
1971
|
-
));
|
|
1972
|
-
}
|
|
1973
|
-
return /* @__PURE__ */ React.createElement(
|
|
1974
|
-
ScreenContainer,
|
|
1975
|
-
{
|
|
1976
|
-
title: "Provider Selection",
|
|
1977
|
-
exitState,
|
|
1978
|
-
children: /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select your preferred AI provider for this model profile:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Choose the provider you want to use for this model profile.", /* @__PURE__ */ React.createElement(Newline, null), "This will determine which models are available to you.")), /* @__PURE__ */ React.createElement(Select, { options: providerOptions, onChange: handleProviderSelection }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "You can change this later by running", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "/model"), " again")))
|
|
1979
|
-
}
|
|
1980
|
-
);
|
|
1981
|
-
}
|
|
1982
|
-
export {
|
|
1983
|
-
ModelSelector
|
|
1984
|
-
};
|
|
1985
|
-
//# sourceMappingURL=ModelSelector.js.map
|