// 模型名称映射 use std::collections::HashMap; use once_cell::sync::Lazy; static CLAUDE_TO_GEMINI: Lazy> = Lazy::new(|| { let mut m = HashMap::new(); // 直接支持的模型 m.insert("claude-opus-4-5-thinking", "claude-opus-4-5-thinking"); m.insert("claude-sonnet-4-5", "claude-sonnet-4-5"); m.insert("claude-sonnet-4-5-thinking", "claude-sonnet-4-5-thinking"); // 别名映射 m.insert("claude-sonnet-4-5-20250929", "claude-sonnet-4-5-thinking"); m.insert("claude-3-5-sonnet-20241022", "claude-sonnet-4-5"); m.insert("claude-3-5-sonnet-20240620", "claude-sonnet-4-5"); m.insert("claude-opus-4", "claude-opus-4-5-thinking"); m.insert("claude-opus-4-5-20251101", "claude-opus-4-5-thinking"); m.insert("claude-haiku-4", "claude-sonnet-4-5"); m.insert("claude-3-haiku-20240307", "claude-sonnet-4-5"); m.insert("claude-haiku-4-5-20251001", "claude-sonnet-4-5"); // OpenAI 协议映射表 m.insert("gpt-4", "gemini-2.5-pro"); m.insert("gpt-4-turbo", "gemini-2.5-pro"); m.insert("gpt-4-turbo-preview", "gemini-2.5-pro"); m.insert("gpt-4-0125-preview", "gemini-2.5-pro"); m.insert("gpt-4-1106-preview", "gemini-2.5-pro"); m.insert("gpt-4-0613", "gemini-2.5-pro"); m.insert("gpt-4o", "gemini-2.5-pro"); m.insert("gpt-4o-2024-05-13", "gemini-2.5-pro"); m.insert("gpt-4o-2024-08-06", "gemini-2.5-pro"); m.insert("gpt-4o-mini", "gemini-2.5-flash"); m.insert("gpt-4o-mini-2024-07-18", "gemini-2.5-flash"); m.insert("gpt-3.5-turbo", "gemini-2.5-flash"); m.insert("gpt-3.5-turbo-16k", "gemini-2.5-flash"); m.insert("gpt-3.5-turbo-0125", "gemini-2.5-flash"); m.insert("gpt-3.5-turbo-1106", "gemini-2.5-flash"); m.insert("gpt-3.5-turbo-0613", "gemini-2.5-flash"); // Gemini 协议映射表 m.insert("gemini-2.5-flash-lite", "gemini-2.5-flash-lite"); m.insert("gemini-2.5-flash-thinking", "gemini-2.5-flash-thinking"); m.insert("gemini-3-pro-low", "gemini-3-pro-low"); m.insert("gemini-3-pro-high", "gemini-3-pro-high"); m.insert("gemini-3-pro-preview", "gemini-3-pro-preview"); m.insert("gemini-2.5-flash", "gemini-2.5-flash"); m.insert("gemini-3-flash", "gemini-3-flash"); m.insert("gemini-3-pro-image", "gemini-3-pro-image"); m }); pub fn map_claude_model_to_gemini(input: &str) -> String { // 1. Check exact match in map if let Some(mapped) = CLAUDE_TO_GEMINI.get(input) { return mapped.to_string(); } // 2. Pass-through known prefixes (gemini-, -thinking) to support dynamic suffixes if input.starts_with("gemini-") || input.contains("thinking") { return input.to_string(); } // 3. Fallback to default "claude-sonnet-4-5".to_string() } /// 核心模型路由解析引擎 /// 优先级:Custom Mapping (精确) > Group Mapping (家族) > System Mapping (内置插件) pub fn resolve_model_route( original_model: &str, custom_mapping: &std::collections::HashMap, openai_mapping: &std::collections::HashMap, anthropic_mapping: &std::collections::HashMap, ) -> String { // 1. 检查自定义精确映射 (优先级最高) if let Some(target) = custom_mapping.get(original_model) { crate::modules::logger::log_info(&format!("[Router] 使用自定义精确映射: {} -> {}", original_model, target)); return target.clone(); } let lower_model = original_model.to_lowercase(); // 2. 检查家族分组映射 (OpenAI 系) // GPT-4 系列 (含 GPT-4 经典, o1, o3 等, 排除 4o/mini/turbo) if (lower_model.starts_with("gpt-4") && !lower_model.contains("o") && !lower_model.contains("mini") && !lower_model.contains("turbo")) || lower_model.starts_with("o1-") || lower_model.starts_with("o3-") || lower_model == "gpt-4" { if let Some(target) = openai_mapping.get("gpt-4-series") { crate::modules::logger::log_info(&format!("[Router] 使用 GPT-4 系列映射: {} -> {}", original_model, target)); return target.clone(); } } // GPT-4o / 3.5 系列 (均衡与轻量, 含 4o, mini, turbo) if lower_model.contains("4o") || lower_model.starts_with("gpt-3.5") || (lower_model.contains("mini") && !lower_model.contains("gemini")) || lower_model.contains("turbo") { if let Some(target) = openai_mapping.get("gpt-4o-series") { crate::modules::logger::log_info(&format!("[Router] 使用 GPT-4o/3.5 系列映射: {} -> {}", original_model, target)); return target.clone(); } } // GPT-5 系列 (gpt-5, gpt-5.1, gpt-5.2 等) if lower_model.starts_with("gpt-5") { // 优先使用 gpt-5-series 映射,如果没有则使用 gpt-4-series if let Some(target) = openai_mapping.get("gpt-5-series") { crate::modules::logger::log_info(&format!("[Router] 使用 GPT-5 系列映射: {} -> {}", original_model, target)); return target.clone(); } if let Some(target) = openai_mapping.get("gpt-4-series") { crate::modules::logger::log_info(&format!("[Router] 使用 GPT-4 系列映射 (GPT-5 fallback): {} -> {}", original_model, target)); return target.clone(); } } // 3. 检查家族分组映射 (Anthropic 系) if lower_model.starts_with("claude-") { let family_key = if lower_model.contains("4-5") || lower_model.contains("4.5") { "claude-4.5-series" } else if lower_model.contains("3-5") || lower_model.contains("3.5") { "claude-3.5-series" } else { "claude-default" }; if let Some(target) = anthropic_mapping.get(family_key) { crate::modules::logger::log_warn(&format!("[Router] 使用 Anthropic 系列映射: {} -> {}", original_model, target)); return target.clone(); } // 兜底兼容旧版精确映射 if let Some(target) = anthropic_mapping.get(original_model) { return target.clone(); } } // 4. 下沉到系统默认映射逻辑 map_claude_model_to_gemini(original_model) } #[cfg(test)] mod tests { use super::*; #[test] fn test_model_mapping() { assert_eq!( map_claude_model_to_gemini("claude-3-5-sonnet-20241022"), "claude-sonnet-4-5" ); assert_eq!( map_claude_model_to_gemini("claude-opus-4"), "claude-opus-4-5-thinking" ); // Test gemini pass-through (should not be caught by "mini" rule) assert_eq!( map_claude_model_to_gemini("gemini-2.5-flash-mini-test"), "gemini-2.5-flash-mini-test" ); assert_eq!( map_claude_model_to_gemini("unknown-model"), "claude-sonnet-4-5" ); } }