mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-02 18:41:35 +08:00
3a15420770
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.
404 lines
11 KiB
TypeScript
404 lines
11 KiB
TypeScript
import type { ProviderCategory } from "@/types";
|
|
|
|
/**
|
|
* Gemini 预设供应商的视觉主题配置
|
|
*/
|
|
export interface GeminiPresetTheme {
|
|
/** 图标类型:'gemini' | 'generic' */
|
|
icon?: "gemini" | "generic";
|
|
/** 背景色(选中状态),支持 hex 颜色 */
|
|
backgroundColor?: string;
|
|
/** 文字色(选中状态),支持 hex 颜色 */
|
|
textColor?: string;
|
|
}
|
|
|
|
export interface GeminiProviderPreset {
|
|
name: string;
|
|
nameKey?: string; // i18n key for localized display name
|
|
websiteUrl: string;
|
|
apiKeyUrl?: string;
|
|
settingsConfig: object;
|
|
baseURL?: string;
|
|
model?: string;
|
|
description?: string;
|
|
category?: ProviderCategory;
|
|
isPartner?: boolean;
|
|
partnerPromotionKey?: string;
|
|
endpointCandidates?: string[];
|
|
theme?: GeminiPresetTheme;
|
|
// 图标配置
|
|
icon?: string; // 图标名称
|
|
iconColor?: string; // 图标颜色
|
|
}
|
|
|
|
export const geminiProviderPresets: GeminiProviderPreset[] = [
|
|
{
|
|
name: "Google Official",
|
|
websiteUrl: "https://ai.google.dev/",
|
|
apiKeyUrl: "https://aistudio.google.com/apikey",
|
|
settingsConfig: {
|
|
env: {},
|
|
},
|
|
description: "Google 官方 Gemini API (OAuth)",
|
|
category: "official",
|
|
partnerPromotionKey: "google-official",
|
|
theme: {
|
|
icon: "gemini",
|
|
backgroundColor: "#4285F4",
|
|
textColor: "#FFFFFF",
|
|
},
|
|
icon: "gemini",
|
|
iconColor: "#4285F4",
|
|
},
|
|
{
|
|
name: "Shengsuanyun",
|
|
nameKey: "providerForm.presets.shengsuanyun",
|
|
websiteUrl: "https://www.shengsuanyun.com",
|
|
apiKeyUrl: "https://www.shengsuanyun.com/?from=CH_4HHXMRYF",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://router.shengsuanyun.com/api",
|
|
GEMINI_MODEL: "google/gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://router.shengsuanyun.com/api",
|
|
model: "google/gemini-3.5-flash",
|
|
description: "Shengsuanyun",
|
|
category: "aggregator",
|
|
isPartner: true,
|
|
partnerPromotionKey: "shengsuanyun",
|
|
icon: "shengsuanyun",
|
|
},
|
|
{
|
|
name: "PackyCode",
|
|
websiteUrl: "https://www.packyapi.com",
|
|
apiKeyUrl: "https://www.packyapi.com/register?aff=cc-switch",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://www.packyapi.com",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://www.packyapi.com",
|
|
model: "gemini-3.5-flash",
|
|
description: "PackyCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "packycode",
|
|
endpointCandidates: [
|
|
"https://api-slb.packyapi.com",
|
|
"https://www.packyapi.com",
|
|
],
|
|
icon: "packycode",
|
|
},
|
|
{
|
|
name: "APIKEY.FUN",
|
|
websiteUrl: "https://apikey.fun",
|
|
apiKeyUrl: "https://apikey.fun/register?aff=CCSwitch",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.apikey.fun",
|
|
GEMINI_API_KEY: "",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.apikey.fun",
|
|
model: "gemini-3.5-flash",
|
|
description: "APIKEY.FUN",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "apikeyfun",
|
|
endpointCandidates: ["https://api.apikey.fun", "https://slb.apikey.fun"],
|
|
icon: "apikeyfun",
|
|
},
|
|
{
|
|
name: "APINebula",
|
|
websiteUrl: "https://apinebula.com",
|
|
apiKeyUrl: "https://apinebula.com/02rw5X",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://apinebula.com",
|
|
GEMINI_API_KEY: "",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://apinebula.com",
|
|
model: "gemini-3.5-flash",
|
|
description: "APINebula",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "apinebula",
|
|
endpointCandidates: ["https://apinebula.com"],
|
|
icon: "apinebula",
|
|
},
|
|
{
|
|
name: "SudoCode",
|
|
websiteUrl: "https://sudocode.us",
|
|
apiKeyUrl: "https://sudocode.us",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://sudocode.us",
|
|
GEMINI_API_KEY: "",
|
|
GEMINI_MODEL: "gemini-3.1-flash-lite",
|
|
},
|
|
},
|
|
baseURL: "https://sudocode.us",
|
|
model: "gemini-3.1-flash-lite",
|
|
description: "SudoCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "sudocode",
|
|
endpointCandidates: ["https://sudocode.us", "https://sudocode.run"],
|
|
icon: "sudocode",
|
|
},
|
|
{
|
|
name: "Cubence",
|
|
websiteUrl: "https://cubence.com",
|
|
apiKeyUrl: "https://cubence.com/signup?code=CCSWITCH&source=ccs",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.cubence.com",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.cubence.com",
|
|
model: "gemini-3.5-flash",
|
|
description: "Cubence",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "cubence",
|
|
endpointCandidates: [
|
|
"https://api.cubence.com/v1",
|
|
"https://api-cf.cubence.com/v1",
|
|
"https://api-dmit.cubence.com/v1",
|
|
"https://api-bwg.cubence.com/v1",
|
|
],
|
|
icon: "cubence",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "AIGoCode",
|
|
websiteUrl: "https://aigocode.com",
|
|
apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.aigocode.com",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.aigocode.com",
|
|
model: "gemini-3.5-flash",
|
|
description: "AIGoCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "aigocode",
|
|
endpointCandidates: ["https://api.aigocode.com"],
|
|
icon: "aigocode",
|
|
iconColor: "#5B7FFF",
|
|
},
|
|
{
|
|
name: "AICodeMirror",
|
|
websiteUrl: "https://www.aicodemirror.com",
|
|
apiKeyUrl: "https://www.aicodemirror.com/register?invitecode=9915W3",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.aicodemirror.com/api/gemini",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.aicodemirror.com/api/gemini",
|
|
model: "gemini-3.5-flash",
|
|
description: "AICodeMirror",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "aicodemirror",
|
|
endpointCandidates: [
|
|
"https://api.aicodemirror.com/api/gemini",
|
|
"https://api.claudecode.net.cn/api/gemini",
|
|
],
|
|
icon: "aicodemirror",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "CrazyRouter",
|
|
websiteUrl: "https://www.crazyrouter.com",
|
|
apiKeyUrl: "https://www.crazyrouter.com/register?aff=OZcm&ref=cc-switch",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://cn.crazyrouter.com",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://cn.crazyrouter.com",
|
|
model: "gemini-3.5-flash",
|
|
description: "CrazyRouter",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "crazyrouter",
|
|
endpointCandidates: ["https://cn.crazyrouter.com"],
|
|
icon: "crazyrouter",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "SSSAiCode",
|
|
websiteUrl: "https://www.sssaicode.com",
|
|
apiKeyUrl: "https://www.sssaicode.com/register?ref=DCP0SM",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://node-hk.sssaicode.com/api",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://node-hk.sssaicode.com/api",
|
|
model: "gemini-3.5-flash",
|
|
description: "SSSAiCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "sssaicode",
|
|
endpointCandidates: [
|
|
"https://node-hk.sssaicode.com/api",
|
|
"https://claude2.sssaicode.com/api",
|
|
"https://anti.sssaicode.com/api",
|
|
],
|
|
icon: "sssaicode",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "CTok.ai",
|
|
websiteUrl: "https://ctok.ai",
|
|
apiKeyUrl: "https://ctok.ai",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.ctok.ai/v1beta",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.ctok.ai/v1beta",
|
|
model: "gemini-3.5-flash",
|
|
description: "CTok",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "ctok",
|
|
endpointCandidates: ["https://api.ctok.ai/v1beta"],
|
|
icon: "ctok",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "E-FlowCode",
|
|
websiteUrl: "https://e-flowcode.cc",
|
|
apiKeyUrl: "https://e-flowcode.cc",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://e-flowcode.cc",
|
|
GEMINI_API_KEY: "",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
config: {
|
|
general: {
|
|
previewFeatures: true,
|
|
sessionRetention: {
|
|
enabled: true,
|
|
maxAge: "30d",
|
|
warningAcknowledged: true,
|
|
},
|
|
},
|
|
mcpServers: {},
|
|
security: {
|
|
auth: {
|
|
selectedType: "gemini-api-key",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
baseURL: "https://e-flowcode.cc",
|
|
model: "gemini-3.5-flash",
|
|
description: "E-FlowCode",
|
|
category: "third_party",
|
|
endpointCandidates: ["https://e-flowcode.cc"],
|
|
icon: "eflowcode",
|
|
iconColor: "#000000",
|
|
},
|
|
{
|
|
name: "LemonData",
|
|
websiteUrl: "https://lemondata.cc",
|
|
apiKeyUrl: "https://lemondata.cc/r/FFX1ZDUP",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://api.lemondata.cc",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.lemondata.cc",
|
|
model: "gemini-3.5-flash",
|
|
description: "LemonData",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "lemondata",
|
|
endpointCandidates: ["https://api.lemondata.cc"],
|
|
icon: "lemondata",
|
|
},
|
|
{
|
|
name: "OpenRouter",
|
|
websiteUrl: "https://openrouter.ai",
|
|
apiKeyUrl: "https://openrouter.ai/keys",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "https://openrouter.ai/api",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://openrouter.ai/api",
|
|
model: "gemini-3.5-flash",
|
|
description: "OpenRouter",
|
|
category: "aggregator",
|
|
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-3.5-flash",
|
|
},
|
|
},
|
|
baseURL: "https://api.therouter.ai",
|
|
model: "gemini-3.5-flash",
|
|
description: "TheRouter",
|
|
category: "aggregator",
|
|
endpointCandidates: ["https://api.therouter.ai"],
|
|
},
|
|
{
|
|
name: "自定义",
|
|
websiteUrl: "",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "",
|
|
GEMINI_MODEL: "gemini-3.5-flash",
|
|
},
|
|
},
|
|
model: "gemini-3.5-flash",
|
|
description: "自定义 Gemini API 端点",
|
|
category: "custom",
|
|
},
|
|
];
|
|
|
|
export function getGeminiPresetByName(
|
|
name: string,
|
|
): GeminiProviderPreset | undefined {
|
|
return geminiProviderPresets.find((preset) => preset.name === name);
|
|
}
|
|
|
|
export function getGeminiPresetByUrl(
|
|
url: string,
|
|
): GeminiProviderPreset | undefined {
|
|
if (!url) return undefined;
|
|
return geminiProviderPresets.find(
|
|
(preset) =>
|
|
preset.baseURL &&
|
|
url.toLowerCase().includes(preset.baseURL.toLowerCase()),
|
|
);
|
|
}
|