mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-29 01:05:59 +08:00
6dd809701b
* refactor(proxy): simplify logging for better readability - Delete 17 verbose debug logs from handlers, streaming, and response_processor - Convert excessive INFO logs to DEBUG level for internal processing details - Add 2 critical INFO logs in forwarder.rs for failover scenarios: - Log when switching to next provider after failure - Log when all providers have been exhausted - Fix clippy uninlined_format_args warning This reduces log noise while maintaining visibility into key user-facing decisions. * fix: replace unsafe unwrap() calls with proper error handling - database/dao/mcp.rs: Use map_err for serde_json serialization - database/dao/providers.rs: Use map_err for settings_config and meta serialization - commands/misc.rs: Use expect() for compile-time regex pattern - services/prompt.rs: Use unwrap_or_default() for SystemTime - deeplink/provider.rs: Replace unwrap() with is_none_or pattern for Option checks Reduces potential panic points from 26 to 1 (static regex init, safe). * refactor(proxy): simplify verbose logging output - Remove response JSON full output logging in response_processor - Remove per-request INFO logs in provider_router (failover status, provider selection) - Change model mapping log from INFO to DEBUG - Change usage logging failure from INFO to WARN - Remove redundant debug logs for circuit breaker operations Reduces log noise significantly while preserving important warnings and errors. * feat(proxy): add structured log codes for i18n support Add error code system to proxy module logs for multi-language support: - CB-001~006: Circuit breaker state transitions and triggers - SRV-001~004: Proxy server lifecycle events - FWD-001~002: Request forwarding and failover - FO-001~005: Failover switch operations - USG-001~002: Usage logging errors Log format: [CODE] Chinese message Frontend/log tools can map codes to any language. New file: src/proxy/log_codes.rs - centralized code definitions * chore: bump version to 3.9.1 * style: format code with prettier and rustfmt * fix(ui): allow number inputs to be fully cleared before saving - Convert numeric state to string type for controlled inputs - Use isNaN() check instead of || fallback to allow 0 values - Apply fix to ProxyPanel, CircuitBreakerConfigPanel, AutoFailoverConfigPanel, and ModelTestConfigPanel * feat(pricing): support @ separator in model name matching - Refactor model name cleaning into chained method calls - Add @ to - replacement (e.g., gpt-5.2-codex@low → gpt-5.2-codex-low) - Add test case for @ separator matching * fix(proxy): improve validation and error handling in proxy config panels - Add StopTimeout/StopFailed error types for proper stop() error reporting - Replace silent clamp with validation-and-block in config panels - Add listenAddress format validation in ProxyPanel - Use log_codes constants instead of hardcoded strings - Use once_cell::Lazy for regex precompilation * fix(proxy): harden error handling and input validation - Handle RwLock poisoning in settings.rs with unwrap_or_else - Add fallback for dirs::home_dir() in config modules - Normalize localhost to 127.0.0.1 in ProxyPanel - Format IPv6 addresses with brackets for valid URLs - Strict port validation with pure digit regex - Treat NaN as validation failure in config panels - Log warning on cost_multiplier parse failure - Align timeoutSeconds range to [0, 300] across all panels
167 lines
4.3 KiB
TypeScript
167 lines
4.3 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;
|
|
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: "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-pro",
|
|
},
|
|
},
|
|
baseURL: "https://www.packyapi.com",
|
|
model: "gemini-3-pro",
|
|
description: "PackyCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "packycode",
|
|
endpointCandidates: [
|
|
"https://api-slb.packyapi.com",
|
|
"https://www.packyapi.com",
|
|
],
|
|
icon: "packycode",
|
|
},
|
|
{
|
|
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-pro",
|
|
},
|
|
},
|
|
baseURL: "https://api.cubence.com",
|
|
model: "gemini-3-pro",
|
|
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",
|
|
GEMINI_MODEL: "gemini-3-pro",
|
|
},
|
|
},
|
|
baseURL: "https://api.aigocode.com/gemini",
|
|
model: "gemini-3-pro",
|
|
description: "AIGoCode",
|
|
category: "third_party",
|
|
isPartner: true,
|
|
partnerPromotionKey: "aigocode",
|
|
endpointCandidates: ["https://api.aigocode.com/gemini"],
|
|
icon: "aigocode",
|
|
iconColor: "#5B7FFF",
|
|
},
|
|
{
|
|
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-pro-preview",
|
|
},
|
|
},
|
|
baseURL: "https://openrouter.ai/api",
|
|
model: "gemini-3-pro",
|
|
description: "OpenRouter",
|
|
category: "aggregator",
|
|
icon: "openrouter",
|
|
iconColor: "#6566F1",
|
|
},
|
|
{
|
|
name: "自定义",
|
|
websiteUrl: "",
|
|
settingsConfig: {
|
|
env: {
|
|
GOOGLE_GEMINI_BASE_URL: "",
|
|
GEMINI_MODEL: "gemini-3-pro",
|
|
},
|
|
},
|
|
model: "gemini-3-pro",
|
|
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()),
|
|
);
|
|
}
|