feat: add Chat Completions routing for 22 Codex third-party presets

Enable openai_chat routing with explicit model catalogs across the major
Chinese/Asian providers (DeepSeek, Zhipu GLM, Kimi, MiniMax, Baidu Qianfan,
Bailian, StepFun, Volcengine Agent Plan, BytePlus, DouBaoSeed, ModelScope,
Longcat, BaiLing, Xiaomi MiMo, SiliconFlow, Novita AI, Nvidia, etc.). Each
preset declares its context window so the UI can size catalog rows when the
preset is picked.

Also lands two consistency fixes uncovered along the way:
- Include setCodexCatalogModels in resetCodexConfig's useCallback deps to
  match the new third parameter it consumes.
- Realign TheRouter Codex test to the "custom" model_provider bucket
  established by the recent third-party unification; the previous assertion
  predated that refactor and had been failing on HEAD.
This commit is contained in:
Jason
2026-05-20 23:25:05 +08:00
parent ad8bdf16ae
commit f2935a3db9
6 changed files with 802 additions and 6 deletions
@@ -0,0 +1,212 @@
import { describe, expect, it } from "vitest";
import { codexProviderPresets } from "@/config/codexProviderPresets";
import {
extractCodexBaseUrl,
extractCodexModelName,
extractCodexWireApi,
} from "@/utils/providerConfigUtils";
const expectedChatPresets = new Map<
string,
{ baseUrl: string; contextWindows: Record<string, number> }
>([
[
"火山Agentplan",
{
baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3",
contextWindows: { "ark-code-latest": 256000 },
},
],
[
"BytePlus",
{
baseUrl: "https://ark.ap-southeast.bytepluses.com/api/coding/v3",
contextWindows: { "ark-code-latest": 256000 },
},
],
[
"DouBaoSeed",
{
baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
contextWindows: { "doubao-seed-2-0-code-preview-latest": 256000 },
},
],
[
"DeepSeek",
{
baseUrl: "https://api.deepseek.com",
contextWindows: {
"deepseek-v4-flash": 1000000,
"deepseek-v4-pro": 1000000,
},
},
],
[
"Zhipu GLM",
{
baseUrl: "https://open.bigmodel.cn/api/paas/v4",
contextWindows: { "glm-5": 200000 },
},
],
[
"Zhipu GLM en",
{
baseUrl: "https://api.z.ai/api/paas/v4",
contextWindows: { "glm-5": 200000 },
},
],
[
"Baidu Qianfan Coding Plan",
{
baseUrl: "https://qianfan.baidubce.com/v2/coding",
contextWindows: { "qianfan-code-latest": 131072 },
},
],
[
"Bailian",
{
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
contextWindows: {
"qwen3-coder-plus": 1000000,
"qwen3-max": 262144,
},
},
],
[
"Kimi",
{
baseUrl: "https://api.moonshot.cn/v1",
contextWindows: { "kimi-k2.6": 262144 },
},
],
[
"Kimi For Coding",
{
baseUrl: "https://api.kimi.com/coding/v1",
contextWindows: { "kimi-for-coding": 262144 },
},
],
[
"StepFun",
{
baseUrl: "https://api.stepfun.com/step_plan/v1",
contextWindows: {
"step-3.5-flash-2603": 262144,
"step-3.5-flash": 262144,
},
},
],
[
"StepFun en",
{
baseUrl: "https://api.stepfun.ai/step_plan/v1",
contextWindows: {
"step-3.5-flash-2603": 262144,
"step-3.5-flash": 262144,
},
},
],
[
"ModelScope",
{
baseUrl: "https://api-inference.modelscope.cn/v1",
contextWindows: { "ZhipuAI/GLM-5": 200000 },
},
],
[
"Longcat",
{
baseUrl: "https://api.longcat.chat/openai/v1",
contextWindows: { "LongCat-Flash-Chat": 262144 },
},
],
[
"MiniMax",
{
baseUrl: "https://api.minimaxi.com/v1",
contextWindows: { "MiniMax-M2.7": 200000 },
},
],
[
"MiniMax en",
{
baseUrl: "https://api.minimax.io/v1",
contextWindows: { "MiniMax-M2.7": 200000 },
},
],
[
"BaiLing",
{
baseUrl: "https://api.tbox.cn/api/llm/v1",
contextWindows: { "Ling-2.5-1T": 131072 },
},
],
[
"Xiaomi MiMo",
{
baseUrl: "https://api.xiaomimimo.com/v1",
contextWindows: { "mimo-v2.5-pro": 1048576 },
},
],
[
"Xiaomi MiMo Token Plan (China)",
{
baseUrl: "https://token-plan-cn.xiaomimimo.com/v1",
contextWindows: { "mimo-v2.5-pro": 1048576 },
},
],
[
"SiliconFlow",
{
baseUrl: "https://api.siliconflow.cn/v1",
contextWindows: { "Pro/MiniMaxAI/MiniMax-M2.7": 200000 },
},
],
[
"SiliconFlow en",
{
baseUrl: "https://api.siliconflow.com/v1",
contextWindows: { "MiniMaxAI/MiniMax-M2.7": 200000 },
},
],
[
"Novita AI",
{
baseUrl: "https://api.novita.ai/openai/v1",
contextWindows: { "zai-org/glm-5": 202800 },
},
],
[
"Nvidia",
{
baseUrl: "https://integrate.api.nvidia.com/v1",
contextWindows: { "moonshotai/kimi-k2.5": 262144 },
},
],
]);
describe("Codex Chat provider presets", () => {
it("marks migrated Chat Completions presets for local routing", () => {
for (const [name, expected] of expectedChatPresets) {
const preset = codexProviderPresets.find((item) => item.name === name);
expect(preset, `${name} preset`).toBeDefined();
expect(preset?.apiFormat).toBe("openai_chat");
expect(extractCodexBaseUrl(preset?.config)).toBe(expected.baseUrl);
expect(extractCodexWireApi(preset?.config)).toBe("responses");
expect(preset?.endpointCandidates).toContain(expected.baseUrl);
expect(preset?.modelCatalog?.length).toBeGreaterThan(0);
expect(extractCodexModelName(preset?.config)).toBe(
preset?.modelCatalog?.[0]?.model,
);
expect(
Object.fromEntries(
(preset?.modelCatalog ?? []).map((model) => [
model.model,
model.contextWindow,
]),
),
).toEqual(expected.contextWindows);
}
});
});
+8 -2
View File
@@ -46,8 +46,14 @@ describe("provider preset order", () => {
});
});
it("Codex 预设把 PatewayAI 放在胜算云后面", () => {
expectInOrder(namesOf(codexProviderPresets), ["Shengsuanyun", "PatewayAI"]);
it("Codex 预设按合作伙伴优先顺序排列", () => {
expectInOrder(namesOf(codexProviderPresets), [
"Shengsuanyun",
"PatewayAI",
"火山Agentplan",
"BytePlus",
"DouBaoSeed",
]);
});
it("OpenCode 预设把火山、BytePlus、DouBaoSeed 放在胜算云后面", () => {
@@ -40,7 +40,9 @@ describe("TheRouter provider presets", () => {
"https://api.therouter.ai/v1",
]);
expect(preset?.auth).toEqual({ OPENAI_API_KEY: "" });
expect(preset?.config).toContain('model_provider = "therouter"');
expect(preset?.config).toContain('model_provider = "custom"');
expect(preset?.config).toContain("[model_providers.custom]");
expect(preset?.config).toContain('name = "therouter"');
expect(preset?.config).toContain('model = "openai/gpt-5.3-codex"');
expect(preset?.config).toContain(
'base_url = "https://api.therouter.ai/v1"',