From 7bb7f8883c90f49ebaf3d9dcd8f743ac83ab0a49 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Mon, 29 Dec 2025 10:40:18 -0300 Subject: [PATCH] Fix Azure Claude to use Anthropic API format (x-api-key, /v1/messages) --- src/llm/claude.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/llm/claude.rs b/src/llm/claude.rs index 1c45d698..bd497f7a 100644 --- a/src/llm/claude.rs +++ b/src/llm/claude.rs @@ -93,11 +93,8 @@ impl ClaudeClient { fn build_url(&self) -> String { if self.is_azure { - format!( - "{}/deployments/{}/messages?api-version=2024-06-01", - self.base_url.trim_end_matches('/'), - self.deployment_name - ) + // Azure Claude exposes Anthropic API directly at /v1/messages + format!("{}/v1/messages", self.base_url.trim_end_matches('/')) } else { format!("{}/v1/messages", self.base_url.trim_end_matches('/')) } @@ -106,17 +103,13 @@ impl ClaudeClient { fn build_headers(&self, api_key: &str) -> reqwest::header::HeaderMap { let mut headers = reqwest::header::HeaderMap::new(); - if self.is_azure { - if let Ok(val) = api_key.parse() { - headers.insert("api-key", val); - } - } else { - if let Ok(val) = api_key.parse() { - headers.insert("x-api-key", val); - } - if let Ok(val) = "2023-06-01".parse() { - headers.insert("anthropic-version", val); - } + // Both Azure Claude and direct Anthropic use the same headers + // Azure Claude proxies the Anthropic API format + if let Ok(val) = api_key.parse() { + headers.insert("x-api-key", val); + } + if let Ok(val) = "2023-06-01".parse() { + headers.insert("anthropic-version", val); } if let Ok(val) = "application/json".parse() { @@ -432,8 +425,8 @@ mod tests { "claude-opus-4-5".to_string(), ); let url = client.build_url(); - assert!(url.contains("deployments/claude-opus-4-5/messages")); - assert!(url.contains("api-version=")); + // Azure Claude uses Anthropic API format directly + assert!(url.contains("/v1/messages")); } #[test]