From 4c8334c6fd6593b76be8acfac4bb7a4a12cd1681 Mon Sep 17 00:00:00 2001 From: Jim Northrup Date: Mon, 16 Feb 2026 08:53:08 -0600 Subject: [PATCH] fix: Don't add ?beta=true to OpenAI Chat Completions endpoints (#1052) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes Nvidia provider and other providers using apiFormat="openai_chat". The ClaudeAdapter::build_url() method was incorrectly adding ?beta=true to both /v1/messages and /v1/chat/completions endpoints. This caused the Nvidia provider to fail because: 1. Nvidia uses apiFormat="openai_chat" 2. Requests are transformed to OpenAI format and sent to /v1/chat/completions 3. The URL gets ?beta=true appended (Anthropic-specific parameter) 4. Nvidia's API rejects requests with this parameter Fix: - Only add ?beta=true to /v1/messages endpoint - Exclude /v1/chat/completions from getting this parameter Tested: - Anthropic /v1/messages still gets ?beta=true ✓ - OpenAI Chat Completions /v1/chat/completions does NOT get ?beta=true ✓ - All 13 Claude adapter tests pass ✓ Co-authored-by: jnorthrup --- src-tauri/src/proxy/providers/claude.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/proxy/providers/claude.rs b/src-tauri/src/proxy/providers/claude.rs index ac8b2c8e4..82f365d3b 100644 --- a/src-tauri/src/proxy/providers/claude.rs +++ b/src-tauri/src/proxy/providers/claude.rs @@ -263,10 +263,13 @@ impl ProviderAdapter for ClaudeAdapter { base = base.replace("/v1/v1", "/v1"); } - // 为 Claude 相关端点添加 ?beta=true 参数 + // 为 Claude 原生 /v1/messages 端点添加 ?beta=true 参数 // 这是某些上游服务(如 DuckCoding)验证请求来源的关键参数 - // 注:openai_chat 模式下会转发到 /v1/chat/completions,此处也需要保持一致 - if (endpoint.contains("/v1/messages") || endpoint.contains("/v1/chat/completions")) + // 注意:不要为 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") @@ -513,6 +516,15 @@ mod tests { assert_eq!(url, "https://api.anthropic.com/v1/messages?foo=bar"); } + #[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"); + } + #[test] fn test_needs_transform() { let adapter = ClaudeAdapter::new();