From 14ff69bf90fd46aaa47303325842fe73ab0fc1fe Mon Sep 17 00:00:00 2001 From: decolua Date: Sat, 25 Apr 2026 17:00:39 +0700 Subject: [PATCH] - Added BytePlus Provider --- open-sse/config/providerModels.js | 10 ++++++++++ open-sse/config/providers.js | 5 +++++ open-sse/services/model.js | 2 ++ public/providers/byteplus.png | Bin 0 -> 2924 bytes src/app/api/providers/[id]/models/route.js | 1 + src/app/api/providers/[id]/test/testUtils.js | 6 ++++-- src/app/api/providers/validate/route.js | 9 +++++---- src/shared/constants/config.js | 1 + src/shared/constants/providers.js | 1 + 9 files changed, 29 insertions(+), 6 deletions(-) create mode 100755 public/providers/byteplus.png diff --git a/open-sse/config/providerModels.js b/open-sse/config/providerModels.js index 9fe764cb..f8ce257d 100644 --- a/open-sse/config/providerModels.js +++ b/open-sse/config/providerModels.js @@ -344,6 +344,16 @@ export const PROVIDER_MODELS = { { id: "GLM-4.7", name: "GLM-4.7" }, { id: "DeepSeek-V3.2", name: "DeepSeek-V3.2" }, ], + byteplus: [ + { id: "doubao-seed-2.0-pro", name: "Doubao Seed 2.0 Pro" }, + { id: "doubao-seed-2.0-code", name: "Doubao Seed 2.0 Code" }, + { 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: "glm-4.7", name: "GLM-4.7" }, + { id: "kimi-k2.5", name: "Kimi-K2.5" }, + { id: "gpt-oss-120b", name: "GPT-OSS-120B" }, + ], deepseek: [ { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" }, { id: "deepseek-chat", name: "DeepSeek V3.2 Chat" }, diff --git a/open-sse/config/providers.js b/open-sse/config/providers.js index 9e3ba5f7..3422a21e 100644 --- a/open-sse/config/providers.js +++ b/open-sse/config/providers.js @@ -161,6 +161,11 @@ export const PROVIDERS = { format: "openai", headers: {} }, + byteplus: { + baseUrl: "https://ark.ap-southeast.bytepluses.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 674d94a8..f4f0c54e 100644 --- a/open-sse/services/model.js +++ b/open-sse/services/model.js @@ -51,6 +51,8 @@ const ALIAS_TO_PROVIDER_ID = { chutes: "chutes", ark: "volcengine-ark", "volcengine-ark": "volcengine-ark", + byteplus: "byteplus", + bpm: "byteplus", cursor: "cursor", vx: "vertex", vertex: "vertex", diff --git a/public/providers/byteplus.png b/public/providers/byteplus.png new file mode 100755 index 0000000000000000000000000000000000000000..a5dc899d327c34e07842a8f7d5293042b6651709 GIT binary patch literal 2924 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 literal 0 HcmV?d00001 diff --git a/src/app/api/providers/[id]/models/route.js b/src/app/api/providers/[id]/models/route.js index 78ac8c5a..989845aa 100644 --- a/src/app/api/providers/[id]/models/route.js +++ b/src/app/api/providers/[id]/models/route.js @@ -150,6 +150,7 @@ const PROVIDER_MODELS_CONFIG = { parseResponse: (data) => data.data || [] }, "volcengine-ark": createOpenAIModelsConfig("https://ark.cn-beijing.volces.com/api/coding/v3/models"), + byteplus: createOpenAIModelsConfig("https://ark.ap-southeast.bytepluses.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 b27b50d7..7b647713 100644 --- a/src/app/api/providers/[id]/test/testUtils.js +++ b/src/app/api/providers/[id]/test/testUtils.js @@ -2,6 +2,7 @@ import { getProviderConnectionById, updateProviderConnection } from "@/lib/local import { resolveConnectionProxyConfig } from "@/lib/network/connectionProxy"; import { testProxyUrl } from "@/lib/network/proxyTest"; import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers"; +import { PROVIDER_ENDPOINTS } from "@/shared/constants/config"; import { getDefaultModel } from "open-sse/config/providerModels.js"; import { resolveOllamaLocalHost } from "open-sse/config/providers.js"; import { @@ -454,8 +455,9 @@ 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", { + case "volcengine-ark": + case "byteplus": { + const res = await fetchWithConnectionProxy(PROVIDER_ENDPOINTS[connection.provider], { 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" }] }), diff --git a/src/app/api/providers/validate/route.js b/src/app/api/providers/validate/route.js index 688e32e8..0a73eda9 100644 --- a/src/app/api/providers/validate/route.js +++ b/src/app/api/providers/validate/route.js @@ -3,6 +3,7 @@ import { getProviderNodeById } from "@/models"; import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider, isCustomEmbeddingProvider } from "@/shared/constants/providers"; import { getDefaultModel } from "open-sse/config/providerModels.js"; import { resolveOllamaLocalHost } from "open-sse/config/providers.js"; +import { PROVIDER_ENDPOINTS } from "@/shared/constants/config"; // POST /api/providers/validate - Validate API key with provider export async function POST(request) { @@ -211,16 +212,16 @@ 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", { + case "volcengine-ark": + case "byteplus": { + const res = await fetch(PROVIDER_ENDPOINTS[provider], { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "content-type": "application/json", }, body: JSON.stringify({ - model: testModel, + model: getDefaultModel(provider), max_tokens: 1, messages: [{ role: "user", content: "test" }], }), diff --git a/src/shared/constants/config.js b/src/shared/constants/config.js index 5b52cb7e..ed260498 100644 --- a/src/shared/constants/config.js +++ b/src/shared/constants/config.js @@ -67,6 +67,7 @@ export const PROVIDER_ENDPOINTS = { 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", + byteplus: "https://ark.ap-southeast.bytepluses.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 84ec8990..a9c06d6c 100644 --- a/src/shared/constants/providers.js +++ b/src/shared/constants/providers.js @@ -60,6 +60,7 @@ export const APIKEY_PROVIDERS = { 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" }, + byteplus: { id: "byteplus", alias: "bpm", name: "BytePlus ModelArk", icon: "cloud", color: "#2563EB", textIcon: "BP", website: "https://console.byteplus.com/ark", serviceKinds: ["llm"] }, 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" } },