diff --git a/src/components/providers/forms/ProviderForm.tsx b/src/components/providers/forms/ProviderForm.tsx index 2da87ac65..e47a3313f 100644 --- a/src/components/providers/forms/ProviderForm.tsx +++ b/src/components/providers/forms/ProviderForm.tsx @@ -877,6 +877,13 @@ export function ProviderForm({ if (appId === "gemini") { resetGeminiConfig({}, {}); } + // OpenCode 自定义模式:重置为空配置 + if (appId === "opencode") { + setOpencodeNpm("@ai-sdk/openai-compatible"); + setOpencodeBaseUrl(""); + setOpencodeApiKey(""); + setOpencodeModels({}); + } return; } @@ -930,6 +937,28 @@ export function ProviderForm({ return; } + // OpenCode preset handling + if (appId === "opencode") { + const preset = entry.preset as OpenCodeProviderPreset; + const config = preset.settingsConfig; + + // Update OpenCode-specific states + setOpencodeNpm(config.npm || "@ai-sdk/openai-compatible"); + setOpencodeBaseUrl(config.options?.baseURL || ""); + setOpencodeApiKey(config.options?.apiKey || ""); + setOpencodeModels(config.models || {}); + + // Update form fields + form.reset({ + name: preset.name, + websiteUrl: preset.websiteUrl ?? "", + settingsConfig: JSON.stringify(config, null, 2), + icon: preset.icon ?? "", + iconColor: preset.iconColor ?? "", + }); + return; + } + const preset = entry.preset as ProviderPreset; const config = applyTemplateValues( preset.settingsConfig, diff --git a/src/config/opencodeProviderPresets.ts b/src/config/opencodeProviderPresets.ts index bb18b6f5b..f262e2143 100644 --- a/src/config/opencodeProviderPresets.ts +++ b/src/config/opencodeProviderPresets.ts @@ -41,93 +41,7 @@ export const opencodeNpmPackages = [ * OpenCode 供应商预设列表 */ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ - // ========== 官方供应商 ========== - { - name: "OpenAI", - websiteUrl: "https://platform.openai.com", - apiKeyUrl: "https://platform.openai.com/api-keys", - settingsConfig: { - npm: "@ai-sdk/openai", - options: { - apiKey: "{env:OPENAI_API_KEY}", - }, - models: { - "gpt-4o": { name: "GPT-4o" }, - "gpt-4o-mini": { name: "GPT-4o Mini" }, - "o1": { name: "o1" }, - "o1-mini": { name: "o1 Mini" }, - "o3-mini": { name: "o3 Mini" }, - }, - }, - isOfficial: true, - category: "official", - icon: "openai", - iconColor: "#00A67E", - templateValues: { - apiKey: { - label: "API Key", - placeholder: "sk-...", - editorValue: "", - }, - }, - }, - { - name: "Anthropic", - websiteUrl: "https://console.anthropic.com", - apiKeyUrl: "https://console.anthropic.com/settings/keys", - settingsConfig: { - npm: "@ai-sdk/anthropic", - options: { - apiKey: "{env:ANTHROPIC_API_KEY}", - }, - models: { - "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, - "claude-3-5-sonnet-20241022": { name: "Claude 3.5 Sonnet" }, - "claude-3-5-haiku-20241022": { name: "Claude 3.5 Haiku" }, - "claude-3-opus-20240229": { name: "Claude 3 Opus" }, - }, - }, - isOfficial: true, - category: "official", - icon: "anthropic", - iconColor: "#D4915D", - templateValues: { - apiKey: { - label: "API Key", - placeholder: "sk-ant-...", - editorValue: "", - }, - }, - }, - { - name: "Google (Gemini)", - websiteUrl: "https://ai.google.dev", - apiKeyUrl: "https://aistudio.google.com/app/apikey", - settingsConfig: { - npm: "@ai-sdk/google", - options: { - apiKey: "{env:GOOGLE_GENERATIVE_AI_API_KEY}", - }, - models: { - "gemini-2.0-flash": { name: "Gemini 2.0 Flash" }, - "gemini-2.0-flash-lite": { name: "Gemini 2.0 Flash Lite" }, - "gemini-1.5-pro": { name: "Gemini 1.5 Pro" }, - "gemini-1.5-flash": { name: "Gemini 1.5 Flash" }, - }, - }, - isOfficial: true, - category: "official", - icon: "gemini", - iconColor: "#4285F4", - templateValues: { - apiKey: { - label: "API Key", - placeholder: "AIza...", - editorValue: "", - }, - }, - }, - + // ========== 国产官方 ========== { name: "DeepSeek", @@ -139,7 +53,7 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ apiKey: "{env:DEEPSEEK_API_KEY}", }, models: { - "deepseek-chat": { name: "DeepSeek V3" }, + "deepseek-chat": { name: "DeepSeek V3.2" }, "deepseek-reasoner": { name: "DeepSeek R1" }, }, }, @@ -155,23 +69,296 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ }, }, { - name: "Mistral", - websiteUrl: "https://mistral.ai", - apiKeyUrl: "https://console.mistral.ai/api-keys", + name: "Zhipu GLM", + websiteUrl: "https://open.bigmodel.cn", + apiKeyUrl: "https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII", settingsConfig: { - npm: "@ai-sdk/mistral", + npm: "@ai-sdk/openai-compatible", + name: "Zhipu GLM", options: { - apiKey: "{env:MISTRAL_API_KEY}", + baseURL: "https://open.bigmodel.cn/api/paas/v4", + apiKey: "", }, models: { - "mistral-large-latest": { name: "Mistral Large" }, - "mistral-small-latest": { name: "Mistral Small" }, - "codestral-latest": { name: "Codestral" }, + "glm-4.7": { name: "GLM-4.7" }, }, }, - category: "official", - icon: "mistral", - iconColor: "#FF7000", + category: "cn_official", + isPartner: true, + partnerPromotionKey: "zhipu", + icon: "zhipu", + iconColor: "#0F62FE", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://open.bigmodel.cn/api/paas/v4", + defaultValue: "https://open.bigmodel.cn/api/paas/v4", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "Z.ai GLM", + websiteUrl: "https://z.ai", + apiKeyUrl: "https://z.ai/subscribe?ic=8JVLJQFSKB", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Z.ai GLM", + options: { + baseURL: "https://api.z.ai/v1", + apiKey: "", + }, + models: { + "glm-4.7": { name: "GLM-4.7" }, + }, + }, + category: "cn_official", + isPartner: true, + partnerPromotionKey: "zhipu", + icon: "zhipu", + iconColor: "#0F62FE", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://api.z.ai/v1", + defaultValue: "https://api.z.ai/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "Qwen Coder", + websiteUrl: "https://bailian.console.aliyun.com", + apiKeyUrl: "https://bailian.console.aliyun.com/#/api-key", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Qwen Coder", + options: { + baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1", + apiKey: "", + }, + models: { + "qwen3-max": { name: "Qwen3 Max" }, + }, + }, + category: "cn_official", + icon: "qwen", + iconColor: "#FF6A00", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://dashscope.aliyuncs.com/compatible-mode/v1", + defaultValue: "https://dashscope.aliyuncs.com/compatible-mode/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "sk-...", + editorValue: "", + }, + }, + }, + { + name: "Kimi k2", + websiteUrl: "https://platform.moonshot.cn/console", + apiKeyUrl: "https://platform.moonshot.cn/console/api-keys", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Kimi k2", + options: { + baseURL: "https://api.moonshot.cn/v1", + apiKey: "", + }, + models: { + "kimi-k2-thinking": { name: "Kimi K2 Thinking" }, + }, + }, + category: "cn_official", + icon: "kimi", + iconColor: "#6366F1", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://api.moonshot.cn/v1", + defaultValue: "https://api.moonshot.cn/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "sk-...", + editorValue: "", + }, + }, + }, + { + name: "Kimi For Coding", + websiteUrl: "https://www.kimi.com/coding/docs/", + apiKeyUrl: "https://platform.moonshot.cn/console/api-keys", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Kimi For Coding", + options: { + baseURL: "https://api.kimi.com/v1", + apiKey: "", + }, + models: { + "kimi-for-coding": { name: "Kimi For Coding" }, + }, + }, + category: "cn_official", + icon: "kimi", + iconColor: "#6366F1", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://api.kimi.com/v1", + defaultValue: "https://api.kimi.com/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "sk-...", + editorValue: "", + }, + }, + }, + { + name: "ModelScope", + websiteUrl: "https://modelscope.cn", + apiKeyUrl: "https://modelscope.cn/my/myaccesstoken", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "ModelScope", + options: { + baseURL: "https://api-inference.modelscope.cn/v1", + apiKey: "", + }, + models: { + "ZhipuAI/GLM-4.7": { name: "GLM-4.7" }, + }, + }, + category: "aggregator", + icon: "modelscope", + iconColor: "#624AFF", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://api-inference.modelscope.cn/v1", + defaultValue: "https://api-inference.modelscope.cn/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "KAT-Coder", + websiteUrl: "https://console.streamlake.ai", + apiKeyUrl: "https://console.streamlake.ai/console/api-key", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "KAT-Coder", + options: { + baseURL: + "https://vanchin.streamlake.ai/api/gateway/v1/endpoints/${ENDPOINT_ID}/openai", + apiKey: "", + }, + models: { + "KAT-Coder-Pro V1": { name: "KAT-Coder Pro V1" }, + "KAT-Coder-Air V1": { name: "KAT-Coder Air V1" }, + }, + }, + category: "cn_official", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://vanchin.streamlake.ai/api/gateway/v1/endpoints/${ENDPOINT_ID}/openai", + defaultValue: "https://vanchin.streamlake.ai/api/gateway/v1/endpoints/${ENDPOINT_ID}/openai", + editorValue: "", + }, + ENDPOINT_ID: { + label: "Vanchin Endpoint ID", + placeholder: "ep-xxx-xxx", + defaultValue: "", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "Longcat", + websiteUrl: "https://longcat.chat/platform", + apiKeyUrl: "https://longcat.chat/platform/api_keys", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Longcat", + options: { + baseURL: "https://api.longcat.chat/v1", + apiKey: "", + }, + models: { + "LongCat-Flash-Chat": { name: "LongCat Flash Chat" }, + }, + }, + category: "cn_official", + icon: "longcat", + iconColor: "#29E154", + templateValues: { + baseURL: { + label: "Base URL", + placeholder: "https://api.longcat.chat/v1", + defaultValue: "https://api.longcat.chat/v1", + editorValue: "", + }, + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "MiniMax", + websiteUrl: "https://platform.minimaxi.com", + apiKeyUrl: "https://platform.minimaxi.com/subscribe/coding-plan", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "MiniMax", + options: { + baseURL: "https://api.minimaxi.com/v1", + apiKey: "", + }, + models: { + "MiniMax-M2.1": { name: "MiniMax M2.1" }, + "MiniMax-Text-01": { name: "MiniMax Text 01" }, + }, + }, + category: "cn_official", + isPartner: true, + partnerPromotionKey: "minimax_cn", + theme: { + backgroundColor: "#f64551", + textColor: "#FFFFFF", + }, + icon: "minimax", + iconColor: "#FF6B6B", templateValues: { apiKey: { label: "API Key", @@ -181,27 +368,287 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ }, }, { - name: "Groq", - websiteUrl: "https://groq.com", - apiKeyUrl: "https://console.groq.com/keys", + name: "MiniMax en", + websiteUrl: "https://platform.minimax.io", + apiKeyUrl: "https://platform.minimax.io/subscribe/coding-plan", settingsConfig: { - npm: "@ai-sdk/groq", + npm: "@ai-sdk/openai-compatible", + name: "MiniMax en", options: { - apiKey: "{env:GROQ_API_KEY}", + baseURL: "https://api.minimax.io/v1", + apiKey: "", }, models: { - "llama-3.3-70b-versatile": { name: "Llama 3.3 70B" }, - "llama-3.1-8b-instant": { name: "Llama 3.1 8B" }, - "mixtral-8x7b-32768": { name: "Mixtral 8x7B" }, + "MiniMax-M2.1": { name: "MiniMax M2.1" }, + "MiniMax-Text-01": { name: "MiniMax Text 01" }, }, }, - category: "official", - icon: "groq", - iconColor: "#F55036", + category: "cn_official", + isPartner: true, + partnerPromotionKey: "minimax_en", + theme: { + backgroundColor: "#f64551", + textColor: "#FFFFFF", + }, + icon: "minimax", + iconColor: "#FF6B6B", templateValues: { apiKey: { label: "API Key", - placeholder: "gsk_...", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "DouBaoSeed", + websiteUrl: "https://www.volcengine.com/product/doubao", + apiKeyUrl: "https://www.volcengine.com/product/doubao", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "DouBaoSeed", + options: { + baseURL: "https://ark.cn-beijing.volces.com/api/v3", + apiKey: "", + }, + models: { + "doubao-seed-code-preview-latest": { name: "Doubao Seed Code Preview" }, + }, + }, + category: "cn_official", + icon: "doubao", + iconColor: "#3370FF", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "BaiLing", + websiteUrl: "https://alipaytbox.yuque.com/sxs0ba/ling/get_started", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "BaiLing", + options: { + baseURL: "https://api.tbox.cn/v1", + apiKey: "", + }, + models: { + "Ling-1T": { name: "Ling 1T" }, + }, + }, + category: "cn_official", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "Xiaomi MiMo", + websiteUrl: "https://platform.xiaomimimo.com", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/api-keys", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Xiaomi MiMo", + options: { + baseURL: "https://api.xiaomimimo.com/v1", + apiKey: "", + }, + models: { + "mimo-v2-flash": { name: "MiMo V2 Flash" }, + }, + }, + category: "cn_official", + icon: "xiaomimimo", + iconColor: "#000000", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + + + // ========== 聚合网站 ========== + { + name: "AiHubMix", + websiteUrl: "https://aihubmix.com", + apiKeyUrl: "https://aihubmix.com", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "AiHubMix", + options: { + baseURL: "https://aihubmix.com/v1", + apiKey: "", + }, + models: { + "gpt-4o": { name: "GPT-4o" }, + "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, + "gemini-2.5-pro-preview": { name: "Gemini 2.5 Pro" }, + "deepseek-chat": { name: "DeepSeek V3" }, + }, + }, + category: "aggregator", + icon: "aihubmix", + iconColor: "#006FFB", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "DMXAPI", + websiteUrl: "https://www.dmxapi.cn", + apiKeyUrl: "https://www.dmxapi.cn", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "DMXAPI", + options: { + baseURL: "https://www.dmxapi.cn/v1", + apiKey: "", + }, + models: { + "gpt-4o": { name: "GPT-4o" }, + "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, + "deepseek-chat": { name: "DeepSeek V3" }, + }, + }, + category: "aggregator", + isPartner: true, + partnerPromotionKey: "dmxapi", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "OpenRouter", + websiteUrl: "https://openrouter.ai", + apiKeyUrl: "https://openrouter.ai/keys", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "OpenRouter", + options: { + baseURL: "https://openrouter.ai/api/v1", + apiKey: "", + }, + models: { + "anthropic/claude-sonnet-4": { name: "Claude Sonnet 4" }, + "openai/gpt-4o": { name: "GPT-4o" }, + "google/gemini-2.5-pro-preview": { name: "Gemini 2.5 Pro" }, + "deepseek/deepseek-chat": { name: "DeepSeek V3" }, + }, + }, + category: "aggregator", + icon: "openrouter", + iconColor: "#6566F1", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "sk-or-...", + editorValue: "", + }, + }, + }, + + // ========== 第三方合作伙伴 ========== + { + name: "PackyCode", + websiteUrl: "https://www.packyapi.com", + apiKeyUrl: "https://www.packyapi.com/register?aff=cc-switch", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "PackyCode", + options: { + baseURL: "https://www.packyapi.com/v1", + apiKey: "", + }, + models: { + "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, + "gpt-4o": { name: "GPT-4o" }, + "gemini-2.5-pro": { name: "Gemini 2.5 Pro" }, + }, + }, + category: "third_party", + isPartner: true, + partnerPromotionKey: "packycode", + icon: "packycode", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "Cubence", + websiteUrl: "https://cubence.com", + apiKeyUrl: "https://cubence.com/signup?code=CCSWITCH&source=ccs", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Cubence", + options: { + baseURL: "https://api.cubence.com/v1", + apiKey: "", + }, + models: { + "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, + "gpt-4o": { name: "GPT-4o" }, + }, + }, + category: "third_party", + isPartner: true, + partnerPromotionKey: "cubence", + icon: "cubence", + iconColor: "#000000", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", + editorValue: "", + }, + }, + }, + { + name: "AIGoCode", + websiteUrl: "https://aigocode.com", + apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "AIGoCode", + options: { + baseURL: "https://api.aigocode.com/v1", + apiKey: "", + }, + models: { + "claude-sonnet-4-20250514": { name: "Claude Sonnet 4" }, + "gpt-4o": { name: "GPT-4o" }, + }, + }, + category: "third_party", + isPartner: true, + partnerPromotionKey: "aigocode", + icon: "aigocode", + iconColor: "#5B7FFF", + templateValues: { + apiKey: { + label: "API Key", + placeholder: "", editorValue: "", }, },