feat(provider): add TheRouter presets for OpenCode and OpenClaw (#1892)

Co-authored-by: max <me19@qq.com>
This commit is contained in:
Max
2026-04-10 21:47:18 +08:00
committed by GitHub
parent 489c7c75ea
commit 68df60bd4a
3 changed files with 147 additions and 0 deletions

View File

@@ -719,6 +719,72 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
},
},
},
{
name: "TheRouter",
websiteUrl: "https://therouter.ai",
apiKeyUrl: "https://dashboard.therouter.ai",
settingsConfig: {
baseUrl: "https://api.therouter.ai/v1",
apiKey: "",
api: "openai-completions",
models: [
{
id: "anthropic/claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
contextWindow: 1000000,
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
},
{
id: "openai/gpt-5.3-codex",
name: "GPT-5.3 Codex",
contextWindow: 400000,
cost: { input: 5, output: 40, cacheRead: 0.5 },
},
{
id: "openai/gpt-5.2",
name: "GPT-5.2",
contextWindow: 400000,
cost: { input: 1.75, output: 14, cacheRead: 0.175 },
},
{
id: "google/gemini-3-flash-preview",
name: "Gemini 3 Flash Preview",
contextWindow: 1000000,
cost: { input: 0.5, output: 3, cacheRead: 0.05 },
},
{
id: "qwen/qwen3-coder-480b",
name: "Qwen3 Coder 480B",
contextWindow: 262144,
cost: { input: 0.6, output: 2.35 },
},
],
},
category: "aggregator",
templateValues: {
apiKey: {
label: "API Key",
placeholder: "sk-...",
editorValue: "",
},
},
suggestedDefaults: {
model: {
primary: "therouter/anthropic/claude-sonnet-4.6",
fallbacks: [
"therouter/openai/gpt-5.2",
"therouter/google/gemini-3-flash-preview",
],
},
modelCatalog: {
"therouter/anthropic/claude-sonnet-4.6": { alias: "Sonnet" },
"therouter/openai/gpt-5.2": { alias: "GPT-5.2" },
"therouter/google/gemini-3-flash-preview": { alias: "Gemini Flash" },
"therouter/openai/gpt-5.3-codex": { alias: "Codex" },
"therouter/qwen/qwen3-coder-480b": { alias: "Qwen Coder" },
},
},
},
{
name: "ModelScope",
websiteUrl: "https://modelscope.cn",

View File

@@ -879,6 +879,37 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [
},
},
},
{
name: "TheRouter",
websiteUrl: "https://therouter.ai",
apiKeyUrl: "https://dashboard.therouter.ai",
settingsConfig: {
npm: "@ai-sdk/openai-compatible",
name: "TheRouter",
options: {
baseURL: "https://api.therouter.ai/v1",
apiKey: "",
setCacheKey: true,
},
models: {
"anthropic/claude-sonnet-4.6": { name: "Claude Sonnet 4.6" },
"openai/gpt-5.3-codex": { name: "GPT-5.3 Codex" },
"openai/gpt-5.2": { name: "GPT-5.2" },
"google/gemini-3-flash-preview": {
name: "Gemini 3 Flash Preview",
},
"qwen/qwen3-coder-480b": { name: "Qwen3 Coder 480B" },
},
},
category: "aggregator",
templateValues: {
apiKey: {
label: "API Key",
placeholder: "sk-...",
editorValue: "",
},
},
},
{
name: "Novita AI",
websiteUrl: "https://novita.ai",

View File

@@ -0,0 +1,50 @@
import { describe, expect, it } from "vitest";
import { opencodeProviderPresets } from "@/config/opencodeProviderPresets";
import { openclawProviderPresets } from "@/config/openclawProviderPresets";
describe("TheRouter OpenCode and OpenClaw presets", () => {
it("uses OpenAI-compatible config for OpenCode", () => {
const preset = opencodeProviderPresets.find((item) => item.name === "TheRouter");
const models = preset?.settingsConfig.models ?? {};
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?.settingsConfig.npm).toBe("@ai-sdk/openai-compatible");
expect(preset?.settingsConfig.options?.baseURL).toBe(
"https://api.therouter.ai/v1",
);
expect(preset?.settingsConfig.options?.setCacheKey).toBe(true);
expect(models).toHaveProperty("openai/gpt-5.3-codex");
expect(models).toHaveProperty("anthropic/claude-sonnet-4.6");
expect(models).toHaveProperty("google/gemini-3-flash-preview");
});
it("uses OpenAI completions config for OpenClaw", () => {
const preset = openclawProviderPresets.find((item) => item.name === "TheRouter");
const modelIds = (preset?.settingsConfig.models ?? []).map((model) => model.id);
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?.settingsConfig.baseUrl).toBe("https://api.therouter.ai/v1");
expect(preset?.settingsConfig.api).toBe("openai-completions");
expect(modelIds).toEqual(
expect.arrayContaining([
"anthropic/claude-sonnet-4.6",
"openai/gpt-5.3-codex",
"openai/gpt-5.2",
"google/gemini-3-flash-preview",
]),
);
expect(preset?.suggestedDefaults?.model).toEqual({
primary: "therouter/anthropic/claude-sonnet-4.6",
fallbacks: [
"therouter/openai/gpt-5.2",
"therouter/google/gemini-3-flash-preview",
],
});
});
});