diff --git a/open-sse/config/providerModels.js b/open-sse/config/providerModels.js index b913360a..17fc91e3 100644 --- a/open-sse/config/providerModels.js +++ b/open-sse/config/providerModels.js @@ -327,6 +327,19 @@ export const PROVIDER_MODELS = { { id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" }, { id: "glm-4.7", name: "GLM 4.7" }, ], + "volcengine-ark": [ + { id: "Doubao-Seed-2.0-Code", name: "Doubao-Seed-2.0-Code" }, + { id: "Doubao-Seed-2.0-pro", name: "Doubao-Seed-2.0-pro" }, + { id: "Doubao-Seed-2.0-lite", name: "Doubao-Seed-2.0-lite" }, + { id: "Doubao-Seed-Code", name: "Doubao-Seed-Code" }, + { id: "GLM-5.1", name: "GLM-5.1" }, + { id: "MiniMax-M2.7", name: "MiniMax-M2.7" }, + { id: "Kimi-K2.6", name: "Kimi-K2.6" }, + { id: "MiniMax-M2.5", name: "MiniMax-M2.5" }, + { id: "Kimi-K2.5", name: "Kimi-K2.5" }, + { id: "GLM-4.7", name: "GLM-4.7" }, + { id: "DeepSeek-V3.2", name: "DeepSeek-V3.2" }, + ], deepseek: [ { id: "deepseek-chat", name: "DeepSeek V3.2 Chat" }, { id: "deepseek-reasoner", name: "DeepSeek V3.2 Reasoner" }, diff --git a/open-sse/config/providers.js b/open-sse/config/providers.js index 3c5dabdc..e118bd1a 100644 --- a/open-sse/config/providers.js +++ b/open-sse/config/providers.js @@ -156,6 +156,11 @@ export const PROVIDERS = { format: "openai", headers: {} }, + "volcengine-ark": { + baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions", + format: "openai", + headers: {} + }, github: { baseUrl: "https://api.githubcopilot.com/chat/completions", responsesUrl: "https://api.githubcopilot.com/responses", diff --git a/open-sse/services/model.js b/open-sse/services/model.js index ebe8d90b..674d94a8 100644 --- a/open-sse/services/model.js +++ b/open-sse/services/model.js @@ -49,6 +49,8 @@ const ALIAS_TO_PROVIDER_ID = { nanobanana: "nanobanana", ch: "chutes", chutes: "chutes", + ark: "volcengine-ark", + "volcengine-ark": "volcengine-ark", cursor: "cursor", vx: "vertex", vertex: "vertex", diff --git a/public/providers/volcengine-ark.png b/public/providers/volcengine-ark.png new file mode 100644 index 00000000..60625a16 Binary files /dev/null and b/public/providers/volcengine-ark.png differ diff --git a/src/app/api/providers/[id]/models/route.js b/src/app/api/providers/[id]/models/route.js index 3dcde342..78ac8c5a 100644 --- a/src/app/api/providers/[id]/models/route.js +++ b/src/app/api/providers/[id]/models/route.js @@ -149,6 +149,7 @@ const PROVIDER_MODELS_CONFIG = { authPrefix: "Bearer ", parseResponse: (data) => data.data || [] }, + "volcengine-ark": createOpenAIModelsConfig("https://ark.cn-beijing.volces.com/api/coding/v3/models"), // OpenAI-compatible API key providers deepseek: createOpenAIModelsConfig("https://api.deepseek.com/models"), diff --git a/src/app/api/providers/[id]/test/testUtils.js b/src/app/api/providers/[id]/test/testUtils.js index b5e54ef9..67745da5 100644 --- a/src/app/api/providers/[id]/test/testUtils.js +++ b/src/app/api/providers/[id]/test/testUtils.js @@ -439,6 +439,15 @@ async function testApiKeyConnection(connection, effectiveProxy = null) { const valid = res.status !== 401 && res.status !== 403; return { valid, error: valid ? null : "Invalid API key" }; } + case "volcengine-ark": { + const res = await fetchWithConnectionProxy("https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions", { + method: "POST", + headers: { "Authorization": `Bearer ${connection.apiKey}`, "content-type": "application/json" }, + body: JSON.stringify({ model: getDefaultModel(connection.provider), max_tokens: 1, messages: [{ role: "user", content: "test" }] }), + }, effectiveProxy); + const valid = res.status !== 401 && res.status !== 403; + return { valid, error: valid ? null : "Invalid API key" }; + } case "deepseek": { const res = await fetchWithConnectionProxy("https://api.deepseek.com/models", { headers: { Authorization: `Bearer ${connection.apiKey}` } }, effectiveProxy); return { valid: res.ok, error: res.ok ? null : "Invalid API key" }; diff --git a/src/app/api/providers/validate/route.js b/src/app/api/providers/validate/route.js index 6e518ff6..23bdc1d2 100644 --- a/src/app/api/providers/validate/route.js +++ b/src/app/api/providers/validate/route.js @@ -151,6 +151,23 @@ export async function POST(request) { } break; } + case "volcengine-ark": { + const testModel = getDefaultModel(provider); + const res = await fetch("https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions", { + method: "POST", + headers: { + "Authorization": `Bearer ${apiKey}`, + "content-type": "application/json", + }, + body: JSON.stringify({ + model: testModel, + max_tokens: 1, + messages: [{ role: "user", content: "test" }], + }), + }); + isValid = res.status !== 401 && res.status !== 403; + break; + } case "deepseek": case "groq": diff --git a/src/shared/constants/config.js b/src/shared/constants/config.js index cf9003e2..73f334ad 100644 --- a/src/shared/constants/config.js +++ b/src/shared/constants/config.js @@ -56,6 +56,7 @@ export const PROVIDER_ENDPOINTS = { "minimax-cn": "https://api.minimaxi.com/anthropic/v1/messages", alicode: "https://coding.dashscope.aliyuncs.com/v1/chat/completions", "alicode-intl": "https://coding-intl.dashscope.aliyuncs.com/v1/chat/completions", + "volcengine-ark": "https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions", openai: "https://api.openai.com/v1/chat/completions", anthropic: "https://api.anthropic.com/v1/messages", gemini: "https://generativelanguage.googleapis.com/v1beta/models", diff --git a/src/shared/constants/providers.js b/src/shared/constants/providers.js index a024080e..6830be8b 100644 --- a/src/shared/constants/providers.js +++ b/src/shared/constants/providers.js @@ -59,6 +59,7 @@ export const APIKEY_PROVIDERS = { "minimax-cn": { id: "minimax-cn", alias: "minimax-cn", name: "Minimax (China)", icon: "memory", color: "#DC2626", textIcon: "MC", website: "https://www.minimaxi.com" }, alicode: { id: "alicode", alias: "alicode", name: "Alibaba", icon: "cloud", color: "#FF6A00", textIcon: "ALi" }, "alicode-intl": { id: "alicode-intl", alias: "alicode-intl", name: "Alibaba Intl", icon: "cloud", color: "#FF6A00", textIcon: "ALi" }, + "volcengine-ark": { id: "volcengine-ark", alias: "ark", name: "Volcengine Ark", icon: "cloud", color: "#1677FF", textIcon: "ARK", website: "https://ark.cn-beijing.volces.com" }, openai: { id: "openai", alias: "openai", name: "OpenAI", icon: "auto_awesome", color: "#10A37F", textIcon: "OA", website: "https://platform.openai.com", serviceKinds: ["llm", "embedding", "tts", "image", "imageToText", "webSearch"], thinkingConfig: THINKING_CONFIG.effort }, anthropic: { id: "anthropic", alias: "anthropic", name: "Anthropic", icon: "smart_toy", color: "#D97757", textIcon: "AN", website: "https://console.anthropic.com", serviceKinds: ["llm", "imageToText"] }, "opencode-go": { id: "opencode-go", alias: "ocg", name: "OpenCode Go", icon: "terminal", color: "#E87040", textIcon: "OC", website: "https://opencode.ai/auth", notice: { text: "OpenCode Go subscription: $5/mo (then $10/mo). Access to Kimi, GLM, Qwen, MiMo, MiniMax models.", apiKeyUrl: "https://opencode.ai/auth" } },