diff --git a/crates/switchyard-translation/src/codecs/anthropic/buffered.rs b/crates/switchyard-translation/src/codecs/anthropic/buffered.rs index 9282c71ccf..f690b0c650 100644 --- a/crates/switchyard-translation/src/codecs/anthropic/buffered.rs +++ b/crates/switchyard-translation/src/codecs/anthropic/buffered.rs @@ -314,10 +314,19 @@ impl FormatCodec for AnthropicMessagesCodec { { body.insert("thinking".to_string(), thinking.clone()); } - if let Some(effort) = &request.reasoning.effort { - body.entry("thinking".to_string()) - .or_insert_with(|| json!({"type": "adaptive"})); - body.insert("output_config".to_string(), json!({"effort": effort})); + // OpenAI also accepts "none" and "minimal", which Anthropic rejects as efforts. + match request.reasoning.effort.as_deref() { + Some("none") => { + body.entry("thinking".to_string()) + .or_insert_with(|| json!({"type": "disabled"})); + } + Some(effort) => { + let effort = if effort == "minimal" { "low" } else { effort }; + body.entry("thinking".to_string()) + .or_insert_with(|| json!({"type": "adaptive"})); + body.insert("output_config".to_string(), json!({"effort": effort})); + } + None => {} } if let Some(response_format) = &request.output.response_format && let Some(format) = encode_anthropic_output_format( diff --git a/crates/switchyard-translation/tests/request_translation.rs b/crates/switchyard-translation/tests/request_translation.rs index 18e1ce4f33..9e72a80291 100644 --- a/crates/switchyard-translation/tests/request_translation.rs +++ b/crates/switchyard-translation/tests/request_translation.rs @@ -2879,6 +2879,29 @@ fn openai_request_translates_system_developer_and_reasoning_to_anthropic() -> Te output["messages"][0]["content"][0], json!({"type": "text", "text": "Describe"}) ); + + // OpenAI also accepts "none" and "minimal", which Anthropic rejects as efforts. + for (effort, thinking, anthropic_effort) in [ + ("none", json!({"type": "disabled"}), None), + ("minimal", json!({"type": "adaptive"}), Some(json!("low"))), + ] { + let mut body = body.clone(); + body["reasoning_effort"] = json!(effort); + let output = engine + .translate_request( + WireFormat::OpenAiChat, + WireFormat::AnthropicMessages, + &body, + &TranslationPolicy::default(), + )? + .body; + assert_eq!(output["thinking"], thinking, "{effort}"); + assert_eq!( + output["output_config"].get("effort"), + anthropic_effort.as_ref(), + "{effort}" + ); + } Ok(()) }