diff --git a/src-tauri/src/proxy/forwarder.rs b/src-tauri/src/proxy/forwarder.rs index bc3d8aeb0..f89b1969b 100644 --- a/src-tauri/src/proxy/forwarder.rs +++ b/src-tauri/src/proxy/forwarder.rs @@ -1170,21 +1170,6 @@ fn split_endpoint_and_query(endpoint: &str) -> (&str, Option<&str>) { .map_or((endpoint, None), |(path, query)| (path, Some(query))) } -fn filter_beta_query(query: Option<&str>) -> Option { - let filtered = query.map(|query| { - query - .split('&') - .filter(|pair| !pair.is_empty() && !pair.starts_with("beta=")) - .collect::>() - .join("&") - }); - - match filtered.as_deref() { - Some("") | None => None, - Some(_) => filtered, - } -} - fn is_claude_messages_path(path: &str) -> bool { matches!(path, "/v1/messages" | "/claude/v1/messages") } @@ -1195,14 +1180,10 @@ fn rewrite_claude_transform_endpoint( is_copilot: bool, ) -> (String, Option) { let (path, query) = split_endpoint_and_query(endpoint); - let filtered_query = if is_claude_messages_path(path) { - filter_beta_query(query) - } else { - query.map(ToString::to_string) - }; + let passthrough_query = query.map(ToString::to_string); if !is_claude_messages_path(path) { - return (endpoint.to_string(), filtered_query); + return (endpoint.to_string(), passthrough_query); } let target_path = if is_copilot { @@ -1213,12 +1194,12 @@ fn rewrite_claude_transform_endpoint( "/v1/chat/completions" }; - let rewritten = match filtered_query.as_deref() { + let rewritten = match passthrough_query.as_deref() { Some(query) if !query.is_empty() => format!("{target_path}?{query}"), _ => target_path.to_string(), }; - (rewritten, filtered_query) + (rewritten, passthrough_query) } fn append_query_to_full_url(base_url: &str, query: Option<&str>) -> String { @@ -1343,9 +1324,9 @@ mod tests { } #[test] - fn rewrite_claude_transform_endpoint_strips_beta_for_chat_completions() { + fn rewrite_claude_transform_endpoint_preserves_query_for_chat_completions() { let (endpoint, passthrough_query) = rewrite_claude_transform_endpoint( - "/v1/messages?beta=true&foo=bar", + "/v1/messages?foo=bar", "openai_chat", false, ); @@ -1355,9 +1336,9 @@ mod tests { } #[test] - fn rewrite_claude_transform_endpoint_strips_only_beta_for_responses() { + fn rewrite_claude_transform_endpoint_preserves_query_for_responses() { let (endpoint, passthrough_query) = rewrite_claude_transform_endpoint( - "/claude/v1/messages?beta=true&x-id=1", + "/claude/v1/messages?x-id=1", "openai_responses", false, ); @@ -1369,7 +1350,7 @@ mod tests { #[test] fn rewrite_claude_transform_endpoint_uses_copilot_path() { let (endpoint, passthrough_query) = - rewrite_claude_transform_endpoint("/v1/messages?beta=true&x-id=1", "anthropic", true); + rewrite_claude_transform_endpoint("/v1/messages?x-id=1", "anthropic", true); assert_eq!(endpoint, "/chat/completions?x-id=1"); assert_eq!(passthrough_query.as_deref(), Some("x-id=1")); diff --git a/src-tauri/src/proxy/providers/claude.rs b/src-tauri/src/proxy/providers/claude.rs index 2c0034ec1..512105e74 100644 --- a/src-tauri/src/proxy/providers/claude.rs +++ b/src-tauri/src/proxy/providers/claude.rs @@ -299,8 +299,6 @@ impl ProviderAdapter for ClaudeAdapter { // 现在 OpenRouter 已推出 Claude Code 兼容接口,因此默认直接透传 endpoint。 // 如需回退旧逻辑,可在 forwarder 中根据 needs_transform 改写 endpoint。 // - // `?beta=true` 由客户端请求决定,代理不再硬编码追加。 - let mut base = format!( "{}/{}", base_url.trim_end_matches('/'), @@ -312,24 +310,7 @@ impl ProviderAdapter for ClaudeAdapter { base = base.replace("/v1/v1", "/v1"); } - // GitHub Copilot 不需要 ?beta=true 参数 - if base_url.contains("githubcopilot.com") { - return base; - } - - // 为 Claude 原生 /v1/messages 端点添加 ?beta=true 参数 - // 这是某些上游服务(如 DuckCoding)验证请求来源的关键参数 - // 注意:不要为 OpenAI Chat Completions (/v1/chat/completions) 添加此参数 - // 当 apiFormat="openai_chat" 时,请求会转发到 /v1/chat/completions, - // 但该端点是 OpenAI 标准,不支持 ?beta=true 参数 - if endpoint.contains("/v1/messages") - && !endpoint.contains("/v1/chat/completions") - && !endpoint.contains('?') - { - format!("{base}?beta=true") - } else { - base - } + base } fn add_auth_headers(&self, request: RequestBuilder, auth: &AuthInfo) -> RequestBuilder { @@ -578,14 +559,14 @@ mod tests { fn test_build_url_anthropic() { let adapter = ClaudeAdapter::new(); let url = adapter.build_url("https://api.anthropic.com", "/v1/messages"); - assert_eq!(url, "https://api.anthropic.com/v1/messages?beta=true"); + assert_eq!(url, "https://api.anthropic.com/v1/messages"); } #[test] fn test_build_url_openrouter() { let adapter = ClaudeAdapter::new(); let url = adapter.build_url("https://openrouter.ai/api", "/v1/messages"); - assert_eq!(url, "https://openrouter.ai/api/v1/messages?beta=true"); + assert_eq!(url, "https://openrouter.ai/api/v1/messages"); } #[test] @@ -612,8 +593,6 @@ mod tests { #[test] fn test_build_url_no_beta_for_openai_chat_completions() { let adapter = ClaudeAdapter::new(); - // OpenAI Chat Completions 端点不添加 ?beta=true - // 这是 Nvidia 等 apiFormat="openai_chat" 供应商使用的端点 let url = adapter.build_url("https://integrate.api.nvidia.com", "/v1/chat/completions"); assert_eq!(url, "https://integrate.api.nvidia.com/v1/chat/completions"); } diff --git a/src-tauri/src/services/stream_check.rs b/src-tauri/src/services/stream_check.rs index 2fa4c3c9b..c9b3bc5fa 100644 --- a/src-tauri/src/services/stream_check.rs +++ b/src-tauri/src/services/stream_check.rs @@ -738,9 +738,9 @@ impl StreamCheckService { format!("{base}/v1/chat/completions") } } else if base.ends_with("/v1") { - format!("{base}/messages?beta=true") + format!("{base}/messages") } else { - format!("{base}/v1/messages?beta=true") + format!("{base}/v1/messages") } } } @@ -903,6 +903,6 @@ mod tests { false, ); - assert_eq!(url, "https://api.anthropic.com/v1/messages?beta=true"); + assert_eq!(url, "https://api.anthropic.com/v1/messages"); } }