Files
cc-switch/tests/config/therouterOpenCodeOpenClawPresets.test.ts
Jason 3a15420770 Update default models and pricing across presets
Bump default model names project-wide: gpt-5.4 -> gpt-5.5,
gemini-3.x -> gemini-3.5-flash, glm-5 -> glm-5.1, and
grok-code-fast-1 -> grok-build-0.1 across all provider presets
(claude, codex, gemini, hermes, openclaw, opencode, universal),
Gemini config, and stream check defaults.

Pricing:
- Seed gemini-3.5-flash, gemini-3.1-flash-lite, step-3.5-flash-2603,
  doubao-seed-2.0-code, mimo-v2.5(/pro), qwen3-coder-480b, grok-build-0.1.
- Correct deepseek-v4-flash/pro, glm-5/5.1, grok pricing.
- Add repair_current_model_pricing: idempotent pass that fixes only
  rows still equal to the outdated built-in values, preserving any
  user-customized prices (seed uses INSERT OR IGNORE and cannot update
  existing rows).

Fixes from review:
- opencode: drop duplicate gemini-3.5-flash variant (unreachable via
  .find), keep the entry with the full minimal/low/medium/high set.
- Align stale display names/costs to gemini-3.5-flash (hermes, openclaw,
  opencode); openclaw cost -> {1.5, 9, 0.15} to match seed.
- i18n (zh/en/ja/zh-TW): refresh OMO category tooltips for new model
  names; fix writing tooltip to Kimi K2.5 to match its recommended.

Update tests accordingly and add a regression test asserting unique
model ids in the Google opencode preset variants.
2026-05-29 22:52:25 +08:00

86 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
OPENCODE_PRESET_MODEL_VARIANTS,
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.5-flash");
expect(models["google/gemini-3.5-flash"]?.name).toBe("Gemini 3.5 Flash");
});
it("uses OpenAI completions config for OpenClaw", () => {
const preset = openclawProviderPresets.find(
(item) => item.name === "TheRouter",
);
const openClawModels = preset?.settingsConfig.models ?? [];
const modelIds = openClawModels.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.5-flash",
]),
);
expect(
openClawModels.find((model) => model.id === "google/gemini-3.5-flash"),
).toMatchObject({
name: "Gemini 3.5 Flash",
cost: { input: 1.5, output: 9, cacheRead: 0.15 },
});
expect(preset?.suggestedDefaults?.model).toEqual({
primary: "therouter/anthropic/claude-sonnet-4.6",
fallbacks: [
"therouter/openai/gpt-5.2",
"therouter/google/gemini-3.5-flash",
],
});
});
it("keeps Google OpenCode preset model ids unique", () => {
const googleModels = OPENCODE_PRESET_MODEL_VARIANTS["@ai-sdk/google"];
const ids = googleModels.map((model) => model.id);
const geminiFlashModels = googleModels.filter(
(model) => model.id === "gemini-3.5-flash",
);
expect(new Set(ids).size).toBe(ids.length);
expect(geminiFlashModels).toHaveLength(1);
expect(geminiFlashModels[0]).toMatchObject({
name: "Gemini 3.5 Flash",
variants: {
minimal: expect.any(Object),
low: expect.any(Object),
medium: expect.any(Object),
high: expect.any(Object),
},
});
});
});