diff --git a/litellm-rust/crates/llms/src/anthropic/messages/transformation.rs b/litellm-rust/crates/llms/src/anthropic/messages/transformation.rs index 74ac35752ab..1fb41481453 100644 --- a/litellm-rust/crates/llms/src/anthropic/messages/transformation.rs +++ b/litellm-rust/crates/llms/src/anthropic/messages/transformation.rs @@ -110,7 +110,10 @@ impl BaseMessagesConfig for AnthropicMessagesConfig { } fn request_headers(&self, headers: Headers, request: &MessagesRequest) -> Headers { - update_headers_with_anthropic_beta(headers, request) + merge_beta_headers( + update_headers_with_anthropic_beta(headers, request), + safeguards_betas(&request.params), + ) } } @@ -198,6 +201,20 @@ fn uses_structured_output(params: &MessagesOptionalParams) -> bool { .is_some_and(|config| config.format.is_some()) } +fn safeguards_betas(params: &MessagesOptionalParams) -> BetaSet { + carries_safeguards(params) + .then_some(AnthropicBeta::DangerousToolUse20260903) + .into_iter() + .collect() +} + +fn carries_safeguards(params: &MessagesOptionalParams) -> bool { + params + .extra + .get("safeguards") + .is_some_and(|value| !value.is_null()) +} + fn messages_carry_output_config(messages: &[Message]) -> bool { messages .iter() @@ -1052,6 +1069,12 @@ mod tests { json!({"messages": [{"role": "user", "content": "hi", "output_config": {"effort": "low"}}]}), &[("anthropic-beta", "claude-code-20250219,context-management-2025-06-27,effort-2025-11-24,interleaved-thinking-2025-05-14,per-turn-control-2026-07-01")], )] + #[case::safeguards_add_the_dangerous_tool_use_beta( + &[("anthropic-beta", "claude-code-20250219")], + json!({"safeguards": [{"type": "dangerous_tool_use"}]}), + &[("anthropic-beta", "claude-code-20250219,dangerous-tool-use-2026-09-03")], + )] + #[case::null_safeguards_add_no_beta(&[("x-api-key", "k")], json!({"safeguards": null}), &[("x-api-key", "k")])] fn request_headers_merge_the_feature_betas( #[case] input: &[(&str, &str)], #[case] fields: Value,