diff --git a/src-tauri/src/codex_config.rs b/src-tauri/src/codex_config.rs index a9b75a237..3b79035cd 100644 --- a/src-tauri/src/codex_config.rs +++ b/src-tauri/src/codex_config.rs @@ -2655,7 +2655,7 @@ web_search = "disabled" ("gpt-5.5", "https://www.packyapi.com/v1"), ("gpt-5-codex", "https://aihubmix.com/v1"), ( - "doubao-seed-2-1-pro", + "doubao-seed-2-1-pro-260628", "https://ark.cn-beijing.volces.com/api/v3", ), ("Pro/moonshotai/Kimi-K2.6", "https://api.siliconflow.cn/v1"), diff --git a/src-tauri/src/services/usage_stats.rs b/src-tauri/src/services/usage_stats.rs index e336735d8..a1d75bd21 100644 --- a/src-tauri/src/services/usage_stats.rs +++ b/src-tauri/src/services/usage_stats.rs @@ -2197,8 +2197,24 @@ fn strip_model_date_suffix(model_id: &str) -> Option { } let (base, suffix) = model_id.rsplit_once('-')?; - (!base.is_empty() && suffix.len() == 8 && suffix.chars().all(|c| c.is_ascii_digit())) - .then(|| base.to_string()) + if base.is_empty() || !suffix.chars().all(|c| c.is_ascii_digit()) { + return None; + } + // 8 位 YYYYMMDD(如 -20250615;OpenAI / Claude / 通义千问等)。 + if suffix.len() == 8 { + return Some(base.to_string()); + } + // 6 位 YYMMDD(如 -260628;火山方舟 doubao-seed-*、部分国产厂商)。 + // 6 位比 8 位更易误伤非日期尾巴(如 -123456 的版本号),故额外校验 + // 月 01-12、日 01-31 才剥离;剥不动时退回 None 由上层精确匹配兜底。 + if suffix.len() == 6 { + let month: u32 = suffix[2..4].parse().unwrap_or(0); + let day: u32 = suffix[4..6].parse().unwrap_or(0); + if (1..=12).contains(&month) && (1..=31).contains(&day) { + return Some(base.to_string()); + } + } + None } fn strip_reasoning_effort_suffix(model_id: &str) -> Option { @@ -3859,6 +3875,55 @@ mod tests { assert_eq!(strip_model_date_suffix("abc🚀12345678"), None); } + #[test] + fn test_strip_model_date_suffix_handles_six_digit_yymmdd() { + // 火山方舟 6 位 YYMMDD 后缀应被剥离(doubao 全系都用这种格式)。 + assert_eq!( + strip_model_date_suffix("doubao-seed-2-1-pro-260628").as_deref(), + Some("doubao-seed-2-1-pro") + ); + assert_eq!( + strip_model_date_suffix("doubao-seed-1-6-250615").as_deref(), + Some("doubao-seed-1-6") + ); + // 8 位 YYYYMMDD 仍照旧剥离。 + assert_eq!( + strip_model_date_suffix("claude-3-5-sonnet-20241022").as_deref(), + Some("claude-3-5-sonnet") + ); + // 月/日非法的 6 位尾巴(版本号等)不剥离,避免误伤。 + assert_eq!(strip_model_date_suffix("foo-bar-123456"), None); // 月=34 + assert_eq!(strip_model_date_suffix("widget-209900"), None); // 月=99 + assert_eq!(strip_model_date_suffix("gizmo-251200"), None); // 日=00 + } + + #[test] + fn test_pricing_resolves_volcengine_dated_model_to_bare_seed_row() -> Result<(), AppError> { + // 回归:火山真实用量带 6 位日期后缀(doubao-seed-2-1-pro-260628), + // 必须能归一化命中定价表里的裸名 seed 行(doubao-seed-2-1-pro),否则成本显示 $0。 + let db = Database::memory()?; + let conn = lock_conn!(db.conn); + + conn.execute( + "INSERT OR REPLACE INTO model_pricing ( + model_id, display_name, input_cost_per_million, output_cost_per_million, + cache_read_cost_per_million, cache_creation_cost_per_million + ) VALUES ('doubao-seed-2-1-pro', 'Doubao Seed 2.1 Pro', '0.84', '4.2', '0.17', '0')", + [], + )?; + + let row = find_model_pricing_row(&conn, "doubao-seed-2-1-pro-260628")?; + assert!( + row.is_some(), + "带日期的火山模型应通过 6 位日期剥离命中裸名定价行" + ); + let (input, output, ..) = row.unwrap(); + assert_eq!(input, "0.84"); + assert_eq!(output, "4.2"); + + Ok(()) + } + #[test] fn test_prefix_pricing_does_not_match_short_base_model_to_variant() -> Result<(), AppError> { let db = Database::memory()?; diff --git a/src/config/claudeDesktopProviderPresets.ts b/src/config/claudeDesktopProviderPresets.ts index efb803c4d..fbea0f41b 100644 --- a/src/config/claudeDesktopProviderPresets.ts +++ b/src/config/claudeDesktopProviderPresets.ts @@ -232,9 +232,9 @@ export const claudeDesktopProviderPresets: ClaudeDesktopProviderPreset[] = [ mode: "proxy", apiFormat: "anthropic", modelRoutes: brandedRoutes( - "doubao-seed-2-1-pro", - "doubao-seed-2-1-pro", - "doubao-seed-2-1-pro", + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-pro-260628", ), isPartner: true, partnerPromotionKey: "doubaoseed", diff --git a/src/config/claudeProviderPresets.ts b/src/config/claudeProviderPresets.ts index 54250c834..d39759e65 100644 --- a/src/config/claudeProviderPresets.ts +++ b/src/config/claudeProviderPresets.ts @@ -179,10 +179,10 @@ export const providerPresets: ProviderPreset[] = [ ANTHROPIC_BASE_URL: "https://ark.cn-beijing.volces.com/api/compatible", ANTHROPIC_AUTH_TOKEN: "", API_TIMEOUT_MS: "3000000", - ANTHROPIC_MODEL: "doubao-seed-2-1-pro", - ANTHROPIC_DEFAULT_SONNET_MODEL: "doubao-seed-2-1-pro", - ANTHROPIC_DEFAULT_OPUS_MODEL: "doubao-seed-2-1-pro", - ANTHROPIC_DEFAULT_HAIKU_MODEL: "doubao-seed-2-1-pro", + ANTHROPIC_MODEL: "doubao-seed-2-1-pro-260628", + ANTHROPIC_DEFAULT_SONNET_MODEL: "doubao-seed-2-1-pro-260628", + ANTHROPIC_DEFAULT_OPUS_MODEL: "doubao-seed-2-1-pro-260628", + ANTHROPIC_DEFAULT_HAIKU_MODEL: "doubao-seed-2-1-pro-260628", }, }, category: "cn_official", diff --git a/src/config/codexProviderPresets.ts b/src/config/codexProviderPresets.ts index 4c691a93d..1cc2861eb 100644 --- a/src/config/codexProviderPresets.ts +++ b/src/config/codexProviderPresets.ts @@ -212,7 +212,7 @@ export const codexProviderPresets: CodexProviderPreset[] = [ config: generateThirdPartyConfig( "doubaoseed", "https://ark.cn-beijing.volces.com/api/v3", - "doubao-seed-2-1-pro", + "doubao-seed-2-1-pro-260628", ), endpointCandidates: ["https://ark.cn-beijing.volces.com/api/v3"], // 火山方舟主数据面 /api/v3 原生支持 Responses API(/api/v3/responses),无需路由接管转换 @@ -221,7 +221,7 @@ export const codexProviderPresets: CodexProviderPreset[] = [ // 让 Codex 直连显示模型并避免 custom 工具被网关拒绝 modelCatalog: modelCatalog([ { - model: "doubao-seed-2-1-pro", + model: "doubao-seed-2-1-pro-260628", displayName: "Doubao Seed 2.1 Pro", contextWindow: 262144, }, diff --git a/src/config/hermesProviderPresets.ts b/src/config/hermesProviderPresets.ts index 5df935a52..f222669b8 100644 --- a/src/config/hermesProviderPresets.ts +++ b/src/config/hermesProviderPresets.ts @@ -219,7 +219,7 @@ export const hermesProviderPresets: HermesProviderPreset[] = [ api_mode: "anthropic_messages", models: [ { - id: "doubao-seed-2-1-pro", + id: "doubao-seed-2-1-pro-260628", name: "Doubao Seed 2.1 Pro", }, ], @@ -231,7 +231,7 @@ export const hermesProviderPresets: HermesProviderPreset[] = [ iconColor: "#3370FF", suggestedDefaults: { model: { - default: "doubao-seed-2-1-pro", + default: "doubao-seed-2-1-pro-260628", provider: "doubao_seed", }, }, diff --git a/src/config/openclawProviderPresets.ts b/src/config/openclawProviderPresets.ts index 3c9689124..0115678ca 100644 --- a/src/config/openclawProviderPresets.ts +++ b/src/config/openclawProviderPresets.ts @@ -228,7 +228,7 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [ api: "openai-completions", models: [ { - id: "doubao-seed-2-1-pro", + id: "doubao-seed-2-1-pro-260628", name: "DouBao Seed 2.1 Pro", contextWindow: 128000, cost: { input: 0.84, output: 4.2 }, @@ -248,9 +248,9 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [ }, }, suggestedDefaults: { - model: { primary: "doubaoseed/doubao-seed-2-1-pro" }, + model: { primary: "doubaoseed/doubao-seed-2-1-pro-260628" }, modelCatalog: { - "doubaoseed/doubao-seed-2-1-pro": { alias: "DouBao" }, + "doubaoseed/doubao-seed-2-1-pro-260628": { alias: "DouBao" }, }, }, }, diff --git a/src/config/opencodeProviderPresets.ts b/src/config/opencodeProviderPresets.ts index a8bdff6f4..bfc889e94 100644 --- a/src/config/opencodeProviderPresets.ts +++ b/src/config/opencodeProviderPresets.ts @@ -387,7 +387,7 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ setCacheKey: true, }, models: { - "doubao-seed-2-1-pro": { + "doubao-seed-2-1-pro-260628": { name: "Doubao Seed 2.1 Pro", }, }, diff --git a/tests/config/codexChatProviderPresets.test.ts b/tests/config/codexChatProviderPresets.test.ts index 47cae427e..1dae7a2d1 100644 --- a/tests/config/codexChatProviderPresets.test.ts +++ b/tests/config/codexChatProviderPresets.test.ts @@ -158,7 +158,10 @@ describe("Codex Chat provider presets", () => { string, { contextWindows: Record } >([ - ["DouBaoSeed", { contextWindows: { "doubao-seed-2-1-pro": 262144 } }], + [ + "DouBaoSeed", + { contextWindows: { "doubao-seed-2-1-pro-260628": 262144 } }, + ], ["Bailian", { contextWindows: { "qwen3-coder-plus": 1048576 } }], ["Longcat", { contextWindows: { "LongCat-2.0-Preview": 1048576 } }], ["MiniMax", { contextWindows: { "MiniMax-M3": 1000000 } }],