From d8f7217b71a050e16daccc2590cea335d5930fb0 Mon Sep 17 00:00:00 2001 From: Yujong Lee Date: Sun, 11 Oct 2026 22:28:19 +0000 Subject: [PATCH] fix(bedrock): prefer regional endpoint host regions Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../messages/transformation.rs | 40 ++++++++++++++++++- .../bedrock_mantle/messages/transformation.rs | 39 +++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/litellm-rust/crates/llms/src/bedrock/claude_platform/messages/transformation.rs b/litellm-rust/crates/llms/src/bedrock/claude_platform/messages/transformation.rs index 07c8b11edba..f9f5e4f7b22 100644 --- a/litellm-rust/crates/llms/src/bedrock/claude_platform/messages/transformation.rs +++ b/litellm-rust/crates/llms/src/bedrock/claude_platform/messages/transformation.rs @@ -194,7 +194,8 @@ fn platform_region( .strip_suffix(".api.aws") .map(str::to_string) }); - let region = resolve_aws_region(host_region.as_deref(), ¶ms.aws, env) + let region = host_region + .or_else(|| resolve_aws_region(None, ¶ms.aws, env)) .or_else(|| resolve_non_empty(None, env, &["AWS_DEFAULT_REGION"])) .ok_or_else(|| Error::Auth(AwsParams::REGION.missing("Claude Platform on AWS")))?; validated_region(region) @@ -320,6 +321,43 @@ mod tests { } } + #[rstest] + #[case::explicit_regional_endpoint( + "https://aws-external-anthropic.us-west-2.api.aws", + "us-east-1", + "us-west-2" + )] + fn public_regional_host_precedes_configured_region( + #[case] api_base: &str, + #[case] configured_region: &str, + #[case] expected_region: &str, + ) { + let params = LitellmParams { + api_base: Some(api_base.into()), + aws: AwsParams { + aws_region_name: Some(configured_region.into()), + ..Default::default() + }, + ..Default::default() + }; + let env = |name: &str| { + (name == "ANTHROPIC_AWS_WORKSPACE_ID").then(|| "workspace".into()) + }; + let url = BEDROCK_CLAUDE_PLATFORM_MESSAGES_CONFIG + .get_complete_url(None, "claude-test", ¶ms, false, &env) + .unwrap(); + let environment = BEDROCK_CLAUDE_PLATFORM_MESSAGES_CONFIG + .validate_environment(vec![], None, "claude-test", ¶ms, &env) + .unwrap(); + assert_eq!( + url, + "https://aws-external-anthropic.us-west-2.api.aws/v1/messages" + ); + assert!( + matches!(environment.auth, AuthScheme::AwsSigV4 { region, service: SERVICE, .. } if region == expected_region) + ); + } + #[rstest] #[case::default(json!({}), false)] #[case::override_empty(json!({"claude_platform_unsupported_params": []}), true)] diff --git a/litellm-rust/crates/llms/src/bedrock_mantle/messages/transformation.rs b/litellm-rust/crates/llms/src/bedrock_mantle/messages/transformation.rs index 1e7327d7811..215866fd1f9 100644 --- a/litellm-rust/crates/llms/src/bedrock_mantle/messages/transformation.rs +++ b/litellm-rust/crates/llms/src/bedrock_mantle/messages/transformation.rs @@ -250,9 +250,10 @@ fn mantle_region( params: &LitellmParams, env: &dyn Fn(&str) -> Option, ) -> Result { - let region = resolve_non_empty(params.aws.aws_region_name.as_deref(), &|_| None, &[]) + let region = mantle_base(base, params, env) + .and_then(|base| mantle_host_region(&base)) + .or_else(|| resolve_non_empty(params.aws.aws_region_name.as_deref(), &|_| None, &[])) .or_else(|| mantle_model(model).1) - .or_else(|| mantle_base(base, params, env).and_then(|base| mantle_host_region(&base))) .or_else(|| resolve_non_empty(None, env, REGION_ENVS)) .unwrap_or_else(|| "us-east-1".into()); validated_region(region) @@ -323,6 +324,40 @@ mod tests { ); } + #[rstest] + #[case::explicit_regional_endpoint( + "https://bedrock-mantle.us-west-2.api.aws", + "us-east-1", + "us-west-2" + )] + fn public_regional_host_precedes_configured_region( + #[case] api_base: &str, + #[case] configured_region: &str, + #[case] expected_region: &str, + ) { + let params = LitellmParams { + api_base: Some(api_base.into()), + aws: AwsParams { + aws_region_name: Some(configured_region.into()), + ..Default::default() + }, + ..Default::default() + }; + let url = BEDROCK_MANTLE_MESSAGES_CONFIG + .get_complete_url(None, "claude-test", ¶ms, false, &|_| None) + .unwrap(); + let environment = BEDROCK_MANTLE_MESSAGES_CONFIG + .validate_environment(vec![], None, "claude-test", ¶ms, &|_| None) + .unwrap(); + assert_eq!( + url, + "https://bedrock-mantle.us-west-2.api.aws/anthropic/v1/messages" + ); + assert!( + matches!(environment.auth, AuthScheme::AwsSigV4 { region, service: "bedrock", .. } if region == expected_region) + ); + } + #[rstest] #[case::aws_default_region("AWS_DEFAULT_REGION", "eu-west-1")] fn aws_default_region_selects_mantle_endpoint(