diff --git a/open-sse/config/providers/registry/siliconflow/index.ts b/open-sse/config/providers/registry/siliconflow/index.ts index a869c969e3..46dd572b2d 100644 --- a/open-sse/config/providers/registry/siliconflow/index.ts +++ b/open-sse/config/providers/registry/siliconflow/index.ts @@ -9,15 +9,79 @@ export const siliconflowProvider: RegistryEntry = { authType: "apikey", authHeader: "bearer", models: [ + // DeepSeek { id: "deepseek-ai/DeepSeek-V3.2", name: "DeepSeek V3.2" }, + { id: "deepseek-ai/DeepSeek-V3.2-Exp", name: "DeepSeek V3.2 Exp" }, { id: "deepseek-ai/DeepSeek-V3.1", name: "DeepSeek V3.1" }, + { id: "deepseek-ai/DeepSeek-V3.1-Terminus", name: "DeepSeek V3.1 Terminus" }, + { id: "deepseek-ai/DeepSeek-V3", name: "DeepSeek V3" }, { id: "deepseek-ai/DeepSeek-R1", name: "DeepSeek R1" }, - { id: "Qwen/Qwen3-235B-A22B-Instruct-2507", name: "Qwen3 235B" }, - { id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", name: "Qwen3 Coder 480B" }, + { id: "deepseek-ai/deepseek-vl2", name: "DeepSeek VL2" }, + { id: "nex-agi/DeepSeek-V3.1-Nex-N1", name: "DeepSeek V3.1 Nex N1" }, + // Qwen + { id: "Qwen/Qwen3.6-35B-A3B", name: "Qwen 3.6 35B A3B" }, + { id: "Qwen/Qwen3.6-27B", name: "Qwen 3.6 27B" }, + { id: "Qwen/Qwen3.5-397B-A17B", name: "Qwen 3.5 397B A17B" }, + { id: "Qwen/Qwen3.5-122B-A10B", name: "Qwen 3.5 122B A10B" }, + { id: "Qwen/Qwen3.5-35B-A3B", name: "Qwen 3.5 35B A3B" }, + { id: "Qwen/Qwen3.5-27B", name: "Qwen 3.5 27B" }, + { id: "Qwen/Qwen3.5-9B", name: "Qwen 3.5 9B" }, + { id: "Qwen/Qwen3-Next-80B-A3B-Instruct", name: "Qwen3 Next 80B Instruct" }, + { id: "Qwen/Qwen3-Next-80B-A3B-Thinking", name: "Qwen3 Next 80B Thinking" }, + { id: "Qwen/Qwen3-235B-A22B", name: "Qwen3 235B A22B" }, + { id: "Qwen/Qwen3-235B-A22B-Instruct-2507", name: "Qwen3 235B A22B Instruct" }, + { id: "Qwen/Qwen3-235B-A22B-Thinking-2507", name: "Qwen3 235B A22B Thinking" }, { id: "Qwen/Qwen3-32B", name: "Qwen3 32B" }, - { id: "moonshotai/Kimi-K2.5", name: "Kimi K2.5" }, + { id: "Qwen/Qwen3-30B-A3B-Instruct-2507", name: "Qwen3 30B A3B Instruct" }, + { id: "Qwen/Qwen3-30B-A3B-Thinking-2507", name: "Qwen3 30B A3B Thinking" }, + { id: "Qwen/Qwen3-14B", name: "Qwen3 14B" }, + { id: "Qwen/Qwen3-8B", name: "Qwen3 8B" }, + { id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", name: "Qwen3 Coder 480B" }, + { id: "Qwen/Qwen3-Coder-30B-A3B-Instruct", name: "Qwen3 Coder 30B" }, + { id: "Qwen/Qwen3-Omni-30B-A3B-Instruct", name: "Qwen3 Omni 30B Instruct" }, + { id: "Qwen/Qwen3-Omni-30B-A3B-Thinking", name: "Qwen3 Omni 30B Thinking" }, + { id: "Qwen/Qwen3-Omni-30B-A3B-Captioner", name: "Qwen3 Omni 30B Captioner" }, + { id: "Qwen/Qwen2.5-72B-Instruct", name: "Qwen 2.5 72B" }, + { id: "Qwen/Qwen2.5-72B-Instruct-128K", name: "Qwen 2.5 72B 128K" }, + { id: "Qwen/Qwen2.5-32B-Instruct", name: "Qwen 2.5 32B" }, + { id: "Qwen/Qwen2.5-14B-Instruct", name: "Qwen 2.5 14B" }, + { id: "Qwen/Qwen2.5-7B-Instruct", name: "Qwen 2.5 7B" }, + { id: "Qwen/Qwen2.5-VL-7B-Instruct", name: "Qwen 2.5 VL 7B" }, + // GLM + { id: "zai-org/GLM-5.1", name: "GLM 5.1" }, + { id: "zai-org/GLM-5", name: "GLM 5" }, + { id: "zai-org/GLM-5V-Turbo", name: "GLM 5V Turbo" }, { id: "zai-org/GLM-4.7", name: "GLM 4.7" }, + { id: "zai-org/GLM-4.6", name: "GLM 4.6" }, + { id: "zai-org/GLM-4.6V", name: "GLM 4.6V" }, + { id: "zai-org/GLM-4.5", name: "GLM 4.5" }, + { id: "zai-org/GLM-4.5-Air", name: "GLM 4.5 Air" }, + { id: "zai-org/GLM-4.5V", name: "GLM 4.5V" }, + { id: "THUDM/GLM-4-32B-0414", name: "GLM 4 32B" }, + { id: "THUDM/GLM-4-9B-0414", name: "GLM 4 9B" }, + { id: "THUDM/GLM-Z1-32B-0414", name: "GLM Z1 32B" }, + { id: "THUDM/GLM-Z1-9B-0414", name: "GLM Z1 9B" }, + // Kimi + { id: "moonshotai/Kimi-K2.6", name: "Kimi K2.6" }, + { id: "moonshotai/Kimi-K2.5", name: "Kimi K2.5" }, + { id: "moonshotai/Kimi-K2-Instruct", name: "Kimi K2 Instruct" }, + { id: "moonshotai/Kimi-K2-Instruct-0905", name: "Kimi K2 Instruct 0905" }, + { id: "moonshotai/Kimi-K2-Thinking", name: "Kimi K2 Thinking" }, + // Other { id: "openai/gpt-oss-120b", name: "GPT OSS 120B" }, + { id: "openai/gpt-oss-20b", name: "GPT OSS 20B" }, { id: "baidu/ERNIE-4.5-300B-A47B", name: "ERNIE 4.5 300B" }, + { id: "tencent/Hunyuan-A13B-Instruct", name: "Hunyuan A13B" }, + { id: "tencent/Hunyuan-MT-7B", name: "Hunyuan MT 7B" }, + { id: "tencent/Hy3-preview", name: "Hunyuan Hy3 Preview" }, + { id: "meta-llama/Meta-Llama-3.1-8B-Instruct", name: "Llama 3.1 8B" }, + { id: "MiniMaxAI/MiniMax-M2.5", name: "MiniMax M2.5" }, + { id: "MiniMaxAI/MiniMax-M2.1", name: "MiniMax M2.1" }, + { id: "inclusionAI/Ling-flash-2.0", name: "Ling Flash 2.0" }, + { id: "inclusionAI/Ling-mini-2.0", name: "Ling Mini 2.0" }, + { id: "inclusionAI/Ring-flash-2.0", name: "Ring Flash 2.0" }, + { id: "google/gemma-4-31B-it", name: "Gemma 4 31B" }, + { id: "google/gemma-4-26B-A4B-it", name: "Gemma 4 26B" }, + { id: "ByteDance-Seed/Seed-OSS-36B-Instruct", name: "Seed OSS 36B" }, ], }; diff --git a/tests/unit/siliconflow-registry-models.test.ts b/tests/unit/siliconflow-registry-models.test.ts new file mode 100644 index 0000000000..02ed5dfe25 --- /dev/null +++ b/tests/unit/siliconflow-registry-models.test.ts @@ -0,0 +1,61 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { siliconflowProvider } from "../../open-sse/config/providers/registry/siliconflow/index.ts"; + +test("siliconflow registry uses the .com baseUrl", () => { + assert.ok( + siliconflowProvider.baseUrl.startsWith("https://api.siliconflow.com/"), + `expected .com baseUrl, got ${siliconflowProvider.baseUrl}` + ); +}); + +test("siliconflow registry includes the synced net-new model IDs", () => { + const ids = new Set(siliconflowProvider.models.map((m) => m.id)); + + // Net-new IDs introduced by the upstream model-list sync — each was MISSING + // from OmniRoute's registry before the port (failing-before assertion). + const expectedNewIds = [ + "zai-org/GLM-5.1", + "zai-org/GLM-5", + "moonshotai/Kimi-K2.6", + "moonshotai/Kimi-K2-Thinking", + "Qwen/Qwen3.6-35B-A3B", + "Qwen/Qwen3.5-397B-A17B", + "MiniMaxAI/MiniMax-M2.5", + "MiniMaxAI/MiniMax-M2.1", + "tencent/Hunyuan-A13B-Instruct", + "google/gemma-4-31B-it", + "inclusionAI/Ling-flash-2.0", + "ByteDance-Seed/Seed-OSS-36B-Instruct", + "openai/gpt-oss-20b", + ]; + + for (const id of expectedNewIds) { + assert.ok(ids.has(id), `expected model id "${id}" to be present`); + } +}); + +test("siliconflow registry preserves the pre-existing model IDs", () => { + const ids = new Set(siliconflowProvider.models.map((m) => m.id)); + for (const id of [ + "deepseek-ai/DeepSeek-V3.2", + "deepseek-ai/DeepSeek-R1", + "zai-org/GLM-4.7", + "moonshotai/Kimi-K2.5", + "baidu/ERNIE-4.5-300B-A47B", + ]) { + assert.ok(ids.has(id), `expected pre-existing model id "${id}" to remain`); + } +}); + +test("siliconflow registry has no duplicate model IDs", () => { + const ids = siliconflowProvider.models.map((m) => m.id); + const seen = new Set(); + const duplicates: string[] = []; + for (const id of ids) { + if (seen.has(id)) duplicates.push(id); + seen.add(id); + } + assert.deepEqual(duplicates, [], `duplicate model IDs found: ${duplicates.join(", ")}`); +});