Files
CC-Switch/src/config/codexProviderPresets.ts
T
Dex Miller 6dd809701b Refactor/simplify proxy logs (#585)
* 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
2026-01-11 20:50:54 +08:00

210 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Codex 预设供应商配置模板
*/
import { ProviderCategory } from "../types";
import type { PresetTheme } from "./claudeProviderPresets";
export interface CodexProviderPreset {
name: string;
websiteUrl: string;
// 第三方供应商可提供单独的获取 API Key 链接
apiKeyUrl?: string;
auth: Record<string, any>; // 将写入 ~/.codex/auth.json
config: string; // 将写入 ~/.codex/config.tomlTOML 字符串)
isOfficial?: boolean; // 标识是否为官方预设
isPartner?: boolean; // 标识是否为商业合作伙伴
partnerPromotionKey?: string; // 合作伙伴促销信息的 i18n key
category?: ProviderCategory; // 新增:分类
isCustomTemplate?: boolean; // 标识是否为自定义模板
// 新增:请求地址候选列表(用于地址管理/测速)
endpointCandidates?: string[];
// 新增:视觉主题配置
theme?: PresetTheme;
// 图标配置
icon?: string; // 图标名称
iconColor?: string; // 图标颜色
}
/**
* 生成第三方供应商的 auth.json
*/
export function generateThirdPartyAuth(apiKey: string): Record<string, any> {
return {
OPENAI_API_KEY: apiKey || "",
};
}
/**
* 生成第三方供应商的 config.toml
*/
export function generateThirdPartyConfig(
providerName: string,
baseUrl: string,
modelName = "gpt-5.1-codex",
): string {
// 清理供应商名称,确保符合TOML键名规范
const cleanProviderName =
providerName
.toLowerCase()
.replace(/[^a-z0-9_]/g, "_")
.replace(/^_+|_+$/g, "") || "custom";
return `model_provider = "${cleanProviderName}"
model = "${modelName}"
model_reasoning_effort = "high"
disable_response_storage = true
[model_providers.${cleanProviderName}]
name = "${cleanProviderName}"
base_url = "${baseUrl}"
wire_api = "responses"
requires_openai_auth = true`;
}
export const codexProviderPresets: CodexProviderPreset[] = [
{
name: "OpenAI Official",
websiteUrl: "https://chatgpt.com/codex",
isOfficial: true,
category: "official",
auth: {},
config: ``,
theme: {
icon: "codex",
backgroundColor: "#1F2937", // gray-800
textColor: "#FFFFFF",
},
icon: "openai",
iconColor: "#00A67E",
},
{
name: "Azure OpenAI",
websiteUrl:
"https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/codex",
category: "third_party",
isOfficial: true,
auth: generateThirdPartyAuth(""),
config: `model_provider = "azure"
model = "gpt-5.2"
model_reasoning_effort = "high"
disable_response_storage = true
[model_providers.azure]
name = "Azure OpenAI"
base_url = "https://YOUR_RESOURCE_NAME.openai.azure.com/openai"
env_key = "OPENAI_API_KEY"
query_params = { "api-version" = "2025-04-01-preview" }
wire_api = "responses"
requires_openai_auth = true`,
endpointCandidates: ["https://YOUR_RESOURCE_NAME.openai.azure.com/openai"],
theme: {
icon: "codex",
backgroundColor: "#0078D4",
textColor: "#FFFFFF",
},
icon: "azure",
iconColor: "#0078D4",
},
{
name: "AiHubMix",
websiteUrl: "https://aihubmix.com",
category: "aggregator",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"aihubmix",
"https://aihubmix.com/v1",
"gpt-5.2",
),
endpointCandidates: [
"https://aihubmix.com/v1",
"https://api.aihubmix.com/v1",
],
},
{
name: "DMXAPI",
websiteUrl: "https://www.dmxapi.cn",
category: "aggregator",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"dmxapi",
"https://www.dmxapi.cn/v1",
"gpt-5.2",
),
endpointCandidates: ["https://www.dmxapi.cn/v1"],
isPartner: true, // 合作伙伴
partnerPromotionKey: "dmxapi", // 促销信息 i18n key
},
{
name: "PackyCode",
websiteUrl: "https://www.packyapi.com",
apiKeyUrl: "https://www.packyapi.com/register?aff=cc-switch",
category: "third_party",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"packycode",
"https://www.packyapi.com/v1",
"gpt-5.2",
),
endpointCandidates: [
"https://www.packyapi.com/v1",
"https://api-slb.packyapi.com/v1",
],
isPartner: true, // 合作伙伴
partnerPromotionKey: "packycode", // 促销信息 i18n key
icon: "packycode",
},
{
name: "Cubence",
websiteUrl: "https://cubence.com",
apiKeyUrl: "https://cubence.com/signup?code=CCSWITCH&source=ccs",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"cubence",
"https://api.cubence.com/v1",
"gpt-5.2",
),
endpointCandidates: [
"https://api.cubence.com/v1",
"https://api-cf.cubence.com/v1",
"https://api-dmit.cubence.com/v1",
"https://api-bwg.cubence.com/v1",
],
category: "third_party",
isPartner: true, // 合作伙伴
partnerPromotionKey: "cubence", // 促销信息 i18n key
icon: "cubence",
iconColor: "#000000",
},
{
name: "AIGoCode",
websiteUrl: "https://aigocode.com",
apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH",
category: "third_party",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"aigocode",
"https://api.aigocode.com/openai",
"gpt-5.2",
),
endpointCandidates: ["https://api.aigocode.com"],
isPartner: true, // 合作伙伴
partnerPromotionKey: "aigocode", // 促销信息 i18n key
icon: "aigocode",
iconColor: "#5B7FFF",
},
{
name: "OpenRouter",
websiteUrl: "https://openrouter.ai",
apiKeyUrl: "https://openrouter.ai/keys",
auth: generateThirdPartyAuth(""),
config: generateThirdPartyConfig(
"openrouter",
"https://openrouter.ai/api/v1",
"gpt-5.2",
),
category: "aggregator",
icon: "openrouter",
iconColor: "#6566F1",
},
];