From 30e810abc5c7d1274de4d3f2044ac8b363b1c94a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 03:56:36 +0000 Subject: [PATCH] fix(rust): clarify Bedrock bridge configuration Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com> --- litellm-rust/crates/ai-gateway/src/messages/prepare.rs | 7 ++++--- litellm-rust/crates/core/src/messages/types.rs | 2 +- litellm-rust/crates/core/src/providers/bedrock/mod.rs | 1 + litellm/llms/custom_httpx/llm_http_handler.py | 1 - litellm/rust_bridge/messages.py | 4 ++-- .../anthropic_interface/test_rust_bridge_messages.py | 7 +++++++ 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/litellm-rust/crates/ai-gateway/src/messages/prepare.rs b/litellm-rust/crates/ai-gateway/src/messages/prepare.rs index 1230fa74641..2084503e667 100644 --- a/litellm-rust/crates/ai-gateway/src/messages/prepare.rs +++ b/litellm-rust/crates/ai-gateway/src/messages/prepare.rs @@ -1,6 +1,7 @@ use litellm_core::CoreError; use litellm_core::CoreResult; use litellm_core::messages::transformation::MessagesAuthStrategy; +use litellm_core::providers::bedrock::AWS_REGION_NAME; use litellm_core::routing_utils::provider::{CustomLlmProvider, get_custom_llm_provider}; use serde_json::Value; @@ -29,10 +30,10 @@ pub(super) fn prepare_messages_call( let config = messages_provider_config(provider) .ok_or_else(|| CoreError::InvalidProvider(provider.to_string()))?; + let region_override = request.aws_region_name; let env_lookup = |key: &str| { - if key == "AWS_REGION_NAME" { - return request - .aws_region_name + if key == AWS_REGION_NAME { + return region_override .map(str::to_string) .or_else(|| std::env::var(key).ok()); } diff --git a/litellm-rust/crates/core/src/messages/types.rs b/litellm-rust/crates/core/src/messages/types.rs index fa12ef374da..c8e025e5401 100644 --- a/litellm-rust/crates/core/src/messages/types.rs +++ b/litellm-rust/crates/core/src/messages/types.rs @@ -45,7 +45,7 @@ pub struct AnthropicMessage { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct AnthropicMessagesRequest { - #[serde(skip_serializing_if = "String::is_empty")] + #[serde(default, skip_serializing_if = "String::is_empty")] pub model: String, pub messages: Vec, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/litellm-rust/crates/core/src/providers/bedrock/mod.rs b/litellm-rust/crates/core/src/providers/bedrock/mod.rs index 1139407862f..499a7139004 100644 --- a/litellm-rust/crates/core/src/providers/bedrock/mod.rs +++ b/litellm-rust/crates/core/src/providers/bedrock/mod.rs @@ -6,4 +6,5 @@ pub mod audio_transcription; pub mod aws_base; mod constants; +pub use constants::AWS_REGION_NAME; pub mod messages; diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index 019d9b51372..08a6c37e644 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -2283,7 +2283,6 @@ class BaseLLMHTTPHandler: from litellm.rust_bridge import messages as rust_messages_bridge upstream_body = {key: value for key, value in request_body.items() if key != "stream"} - upstream_body.setdefault("model", model) try: rust_response = await rust_messages_bridge.amessages( model=model, diff --git a/litellm/rust_bridge/messages.py b/litellm/rust_bridge/messages.py index c87842acc57..8d918396043 100644 --- a/litellm/rust_bridge/messages.py +++ b/litellm/rust_bridge/messages.py @@ -111,7 +111,7 @@ def messages( custom_llm_provider=custom_llm_provider, extra_headers=extra_headers, timeout_seconds=timeout_to_seconds(timeout), - **({"aws_region_name": aws_region_name} if aws_region_name is not None else {}), + aws_region_name=aws_region_name, ) @@ -137,5 +137,5 @@ async def amessages( custom_llm_provider=custom_llm_provider, extra_headers=extra_headers, timeout_seconds=timeout_to_seconds(timeout), - **({"aws_region_name": aws_region_name} if aws_region_name is not None else {}), + aws_region_name=aws_region_name, ) diff --git a/tests/test_litellm/anthropic_interface/test_rust_bridge_messages.py b/tests/test_litellm/anthropic_interface/test_rust_bridge_messages.py index fbd7e36e298..527c43cd11f 100644 --- a/tests/test_litellm/anthropic_interface/test_rust_bridge_messages.py +++ b/tests/test_litellm/anthropic_interface/test_rust_bridge_messages.py @@ -46,6 +46,7 @@ class RecordingMessages: custom_llm_provider: str | None, extra_headers: dict[str, object] | None, timeout_seconds: float | None, + aws_region_name: str | None, ) -> dict[str, object]: self.calls.append( { @@ -56,6 +57,7 @@ class RecordingMessages: "custom_llm_provider": custom_llm_provider, "extra_headers": extra_headers, "timeout_seconds": timeout_seconds, + "aws_region_name": aws_region_name, } ) return dict(FAKE_MESSAGES_RESPONSE) @@ -74,6 +76,7 @@ class RecordingAsyncMessages: custom_llm_provider: str | None, extra_headers: dict[str, object] | None, timeout_seconds: float | None, + aws_region_name: str | None, ) -> dict[str, object]: self.calls.append( { @@ -84,6 +87,7 @@ class RecordingAsyncMessages: "custom_llm_provider": custom_llm_provider, "extra_headers": extra_headers, "timeout_seconds": timeout_seconds, + "aws_region_name": aws_region_name, } ) return dict(FAKE_MESSAGES_RESPONSE) @@ -192,6 +196,7 @@ def test_messages_wrapper_forwards_args_and_converts_timeout(): "custom_llm_provider": "azure_ai", "extra_headers": {"anthropic-beta": "token-efficient-tools-2025-02-19"}, "timeout_seconds": 42.0, + "aws_region_name": None, } @@ -213,6 +218,7 @@ async def test_amessages_wrapper_forwards_args(): assert response == FAKE_MESSAGES_RESPONSE assert bridge.calls[0]["model"] == "claude-sonnet-4-5" assert bridge.calls[0]["timeout_seconds"] == 12.5 + assert bridge.calls[0]["aws_region_name"] is None def _gate(**overrides): @@ -248,6 +254,7 @@ async def test_gate_invokes_rust_and_marks_response_header(): assert call["api_base"] == "https://resource.services.ai.azure.com/anthropic" assert call["extra_headers"] == {"x-api-key": "sk-azure", "anthropic-version": "2023-06-01"} assert call["timeout_seconds"] == 30.0 + assert call["aws_region_name"] is None @pytest.mark.asyncio