mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-05-06 22:01:44 +08:00
feat(provider): add TheRouter presets for Claude, Codex, and Gemini (#1891)
* feat(provider): add TheRouter presets for Claude and Codex * feat(provider): add TheRouter Gemini preset --------- Co-authored-by: max <me19@qq.com>
This commit is contained in:
@@ -671,6 +671,24 @@ export const providerPresets: ProviderPreset[] = [
|
||||
icon: "openrouter",
|
||||
iconColor: "#6566F1",
|
||||
},
|
||||
{
|
||||
name: "TheRouter",
|
||||
websiteUrl: "https://therouter.ai",
|
||||
apiKeyUrl: "https://dashboard.therouter.ai",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: "https://api.therouter.ai",
|
||||
ANTHROPIC_AUTH_TOKEN: "",
|
||||
ANTHROPIC_API_KEY: "",
|
||||
ANTHROPIC_MODEL: "anthropic/claude-sonnet-4.6",
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL: "anthropic/claude-haiku-4.5",
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL: "anthropic/claude-sonnet-4.6",
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL: "anthropic/claude-opus-4.6",
|
||||
},
|
||||
},
|
||||
category: "aggregator",
|
||||
endpointCandidates: ["https://api.therouter.ai"],
|
||||
},
|
||||
{
|
||||
name: "Novita AI",
|
||||
websiteUrl: "https://novita.ai",
|
||||
|
||||
@@ -365,4 +365,17 @@ requires_openai_auth = true`,
|
||||
icon: "openrouter",
|
||||
iconColor: "#6566F1",
|
||||
},
|
||||
{
|
||||
name: "TheRouter",
|
||||
websiteUrl: "https://therouter.ai",
|
||||
apiKeyUrl: "https://dashboard.therouter.ai",
|
||||
auth: generateThirdPartyAuth(""),
|
||||
config: generateThirdPartyConfig(
|
||||
"therouter",
|
||||
"https://api.therouter.ai/v1",
|
||||
"openai/gpt-5.3-codex",
|
||||
),
|
||||
endpointCandidates: ["https://api.therouter.ai/v1"],
|
||||
category: "aggregator",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -241,6 +241,22 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
||||
icon: "openrouter",
|
||||
iconColor: "#6566F1",
|
||||
},
|
||||
{
|
||||
name: "TheRouter",
|
||||
websiteUrl: "https://therouter.ai",
|
||||
apiKeyUrl: "https://dashboard.therouter.ai",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
GOOGLE_GEMINI_BASE_URL: "https://api.therouter.ai",
|
||||
GEMINI_MODEL: "gemini-2.5-pro",
|
||||
},
|
||||
},
|
||||
baseURL: "https://api.therouter.ai",
|
||||
model: "gemini-2.5-pro",
|
||||
description: "TheRouter",
|
||||
category: "aggregator",
|
||||
endpointCandidates: ["https://api.therouter.ai"],
|
||||
},
|
||||
{
|
||||
name: "自定义",
|
||||
websiteUrl: "",
|
||||
|
||||
66
tests/config/therouterProviderPresets.test.ts
Normal file
66
tests/config/therouterProviderPresets.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { providerPresets } from "@/config/claudeProviderPresets";
|
||||
import { codexProviderPresets } from "@/config/codexProviderPresets";
|
||||
import { geminiProviderPresets } from "@/config/geminiProviderPresets";
|
||||
|
||||
describe("TheRouter provider presets", () => {
|
||||
it("uses the Anthropic-compatible root endpoint for Claude", () => {
|
||||
const preset = providerPresets.find((item) => item.name === "TheRouter");
|
||||
|
||||
expect(preset).toBeDefined();
|
||||
expect(preset?.websiteUrl).toBe("https://therouter.ai");
|
||||
expect(preset?.apiKeyUrl).toBe("https://dashboard.therouter.ai");
|
||||
expect(preset?.category).toBe("aggregator");
|
||||
expect(preset?.endpointCandidates).toEqual(["https://api.therouter.ai"]);
|
||||
|
||||
const env = (preset?.settingsConfig as { env: Record<string, string> }).env;
|
||||
expect(env.ANTHROPIC_BASE_URL).toBe("https://api.therouter.ai");
|
||||
expect(env.ANTHROPIC_AUTH_TOKEN).toBe("");
|
||||
expect(env.ANTHROPIC_API_KEY).toBe("");
|
||||
expect(env.ANTHROPIC_MODEL).toBe("anthropic/claude-sonnet-4.6");
|
||||
expect(env.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe(
|
||||
"anthropic/claude-haiku-4.5",
|
||||
);
|
||||
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe(
|
||||
"anthropic/claude-sonnet-4.6",
|
||||
);
|
||||
expect(env.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe(
|
||||
"anthropic/claude-opus-4.6",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses the OpenAI-compatible v1 endpoint for Codex", () => {
|
||||
const preset = codexProviderPresets.find((item) => item.name === "TheRouter");
|
||||
|
||||
expect(preset).toBeDefined();
|
||||
expect(preset?.websiteUrl).toBe("https://therouter.ai");
|
||||
expect(preset?.apiKeyUrl).toBe("https://dashboard.therouter.ai");
|
||||
expect(preset?.category).toBe("aggregator");
|
||||
expect(preset?.endpointCandidates).toEqual([
|
||||
"https://api.therouter.ai/v1",
|
||||
]);
|
||||
expect(preset?.auth).toEqual({ OPENAI_API_KEY: "" });
|
||||
expect(preset?.config).toContain('model_provider = "therouter"');
|
||||
expect(preset?.config).toContain('model = "openai/gpt-5.3-codex"');
|
||||
expect(preset?.config).toContain(
|
||||
'base_url = "https://api.therouter.ai/v1"',
|
||||
);
|
||||
expect(preset?.config).toContain('wire_api = "responses"');
|
||||
});
|
||||
|
||||
it("uses the Gemini-native root endpoint for Gemini", () => {
|
||||
const preset = geminiProviderPresets.find((item) => item.name === "TheRouter");
|
||||
|
||||
expect(preset).toBeDefined();
|
||||
expect(preset?.websiteUrl).toBe("https://therouter.ai");
|
||||
expect(preset?.apiKeyUrl).toBe("https://dashboard.therouter.ai");
|
||||
expect(preset?.category).toBe("aggregator");
|
||||
expect(preset?.endpointCandidates).toEqual(["https://api.therouter.ai"]);
|
||||
expect(preset?.baseURL).toBe("https://api.therouter.ai");
|
||||
expect(preset?.model).toBe("gemini-2.5-pro");
|
||||
|
||||
const env = (preset?.settingsConfig as { env: Record<string, string> }).env;
|
||||
expect(env.GOOGLE_GEMINI_BASE_URL).toBe("https://api.therouter.ai");
|
||||
expect(env.GEMINI_MODEL).toBe("gemini-2.5-pro");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user