Skip to content

Commit 14e71dd

Browse files
cmzzmax
andauthored
feat(provider): add TheRouter presets for OpenCode and OpenClaw (farion1231#1892)
Co-authored-by: max <me19@qq.com>
1 parent 95c5809 commit 14e71dd

3 files changed

Lines changed: 147 additions & 0 deletions

File tree

src/config/openclawProviderPresets.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,72 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
719719
},
720720
},
721721
},
722+
{
723+
name: "TheRouter",
724+
websiteUrl: "https://therouter.ai",
725+
apiKeyUrl: "https://dashboard.therouter.ai",
726+
settingsConfig: {
727+
baseUrl: "https://api.therouter.ai/v1",
728+
apiKey: "",
729+
api: "openai-completions",
730+
models: [
731+
{
732+
id: "anthropic/claude-sonnet-4.6",
733+
name: "Claude Sonnet 4.6",
734+
contextWindow: 1000000,
735+
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
736+
},
737+
{
738+
id: "openai/gpt-5.3-codex",
739+
name: "GPT-5.3 Codex",
740+
contextWindow: 400000,
741+
cost: { input: 5, output: 40, cacheRead: 0.5 },
742+
},
743+
{
744+
id: "openai/gpt-5.2",
745+
name: "GPT-5.2",
746+
contextWindow: 400000,
747+
cost: { input: 1.75, output: 14, cacheRead: 0.175 },
748+
},
749+
{
750+
id: "google/gemini-3-flash-preview",
751+
name: "Gemini 3 Flash Preview",
752+
contextWindow: 1000000,
753+
cost: { input: 0.5, output: 3, cacheRead: 0.05 },
754+
},
755+
{
756+
id: "qwen/qwen3-coder-480b",
757+
name: "Qwen3 Coder 480B",
758+
contextWindow: 262144,
759+
cost: { input: 0.6, output: 2.35 },
760+
},
761+
],
762+
},
763+
category: "aggregator",
764+
templateValues: {
765+
apiKey: {
766+
label: "API Key",
767+
placeholder: "sk-...",
768+
editorValue: "",
769+
},
770+
},
771+
suggestedDefaults: {
772+
model: {
773+
primary: "therouter/anthropic/claude-sonnet-4.6",
774+
fallbacks: [
775+
"therouter/openai/gpt-5.2",
776+
"therouter/google/gemini-3-flash-preview",
777+
],
778+
},
779+
modelCatalog: {
780+
"therouter/anthropic/claude-sonnet-4.6": { alias: "Sonnet" },
781+
"therouter/openai/gpt-5.2": { alias: "GPT-5.2" },
782+
"therouter/google/gemini-3-flash-preview": { alias: "Gemini Flash" },
783+
"therouter/openai/gpt-5.3-codex": { alias: "Codex" },
784+
"therouter/qwen/qwen3-coder-480b": { alias: "Qwen Coder" },
785+
},
786+
},
787+
},
722788
{
723789
name: "ModelScope",
724790
websiteUrl: "https://modelscope.cn",

src/config/opencodeProviderPresets.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,37 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [
879879
},
880880
},
881881
},
882+
{
883+
name: "TheRouter",
884+
websiteUrl: "https://therouter.ai",
885+
apiKeyUrl: "https://dashboard.therouter.ai",
886+
settingsConfig: {
887+
npm: "@ai-sdk/openai-compatible",
888+
name: "TheRouter",
889+
options: {
890+
baseURL: "https://api.therouter.ai/v1",
891+
apiKey: "",
892+
setCacheKey: true,
893+
},
894+
models: {
895+
"anthropic/claude-sonnet-4.6": { name: "Claude Sonnet 4.6" },
896+
"openai/gpt-5.3-codex": { name: "GPT-5.3 Codex" },
897+
"openai/gpt-5.2": { name: "GPT-5.2" },
898+
"google/gemini-3-flash-preview": {
899+
name: "Gemini 3 Flash Preview",
900+
},
901+
"qwen/qwen3-coder-480b": { name: "Qwen3 Coder 480B" },
902+
},
903+
},
904+
category: "aggregator",
905+
templateValues: {
906+
apiKey: {
907+
label: "API Key",
908+
placeholder: "sk-...",
909+
editorValue: "",
910+
},
911+
},
912+
},
882913
{
883914
name: "Novita AI",
884915
websiteUrl: "https://novita.ai",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { describe, expect, it } from "vitest";
2+
import { opencodeProviderPresets } from "@/config/opencodeProviderPresets";
3+
import { openclawProviderPresets } from "@/config/openclawProviderPresets";
4+
5+
describe("TheRouter OpenCode and OpenClaw presets", () => {
6+
it("uses OpenAI-compatible config for OpenCode", () => {
7+
const preset = opencodeProviderPresets.find((item) => item.name === "TheRouter");
8+
const models = preset?.settingsConfig.models ?? {};
9+
10+
expect(preset).toBeDefined();
11+
expect(preset?.websiteUrl).toBe("https://therouter.ai");
12+
expect(preset?.apiKeyUrl).toBe("https://dashboard.therouter.ai");
13+
expect(preset?.category).toBe("aggregator");
14+
expect(preset?.settingsConfig.npm).toBe("@ai-sdk/openai-compatible");
15+
expect(preset?.settingsConfig.options?.baseURL).toBe(
16+
"https://api.therouter.ai/v1",
17+
);
18+
expect(preset?.settingsConfig.options?.setCacheKey).toBe(true);
19+
expect(models).toHaveProperty("openai/gpt-5.3-codex");
20+
expect(models).toHaveProperty("anthropic/claude-sonnet-4.6");
21+
expect(models).toHaveProperty("google/gemini-3-flash-preview");
22+
});
23+
24+
it("uses OpenAI completions config for OpenClaw", () => {
25+
const preset = openclawProviderPresets.find((item) => item.name === "TheRouter");
26+
const modelIds = (preset?.settingsConfig.models ?? []).map((model) => model.id);
27+
28+
expect(preset).toBeDefined();
29+
expect(preset?.websiteUrl).toBe("https://therouter.ai");
30+
expect(preset?.apiKeyUrl).toBe("https://dashboard.therouter.ai");
31+
expect(preset?.category).toBe("aggregator");
32+
expect(preset?.settingsConfig.baseUrl).toBe("https://api.therouter.ai/v1");
33+
expect(preset?.settingsConfig.api).toBe("openai-completions");
34+
expect(modelIds).toEqual(
35+
expect.arrayContaining([
36+
"anthropic/claude-sonnet-4.6",
37+
"openai/gpt-5.3-codex",
38+
"openai/gpt-5.2",
39+
"google/gemini-3-flash-preview",
40+
]),
41+
);
42+
expect(preset?.suggestedDefaults?.model).toEqual({
43+
primary: "therouter/anthropic/claude-sonnet-4.6",
44+
fallbacks: [
45+
"therouter/openai/gpt-5.2",
46+
"therouter/google/gemini-3-flash-preview",
47+
],
48+
});
49+
});
50+
});

0 commit comments

Comments
 (0)