From dcbb5dd013d754cb43853fce182e680273b63957 Mon Sep 17 00:00:00 2001 From: anton-codes-iac <25830178+anton-codes-iac@users.noreply.github.com> Date: Tue, 8 Sep 2026 14:49:50 +0200 Subject: [PATCH 1/3] fix(bedrock): route cross-region openai inference profiles to correct endpoint --- litellm/llms/bedrock/common_utils.py | 12 ++++++++- .../llms/bedrock/test_bedrock_common_utils.py | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index be4f0f32689..f58a3dc23dd 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -1132,6 +1132,10 @@ class BedrockModelInfo(BaseLLMModelInfo): "agentcore/": "agentcore", "async_invoke/": "async_invoke", "openai/": "openai", + "global.openai.": "openai", + "eu.openai.": "openai", + "apac.openai.": "openai", + "us.openai.": "openai", "mantle/": "mantle", } @@ -1256,7 +1260,13 @@ class BedrockModelInfo(BaseLLMModelInfo): Check if the model is an explicit openai route. Used for Bedrock imported models that use OpenAI Chat Completions format. """ - return BedrockModelInfo._model_has_route_prefix(model, "openai/") + return ( + BedrockModelInfo._model_has_route_prefix(model, "openai/") + or BedrockModelInfo._model_has_route_prefix(model, "global.openai.") + or BedrockModelInfo._model_has_route_prefix(model, "eu.openai.") + or BedrockModelInfo._model_has_route_prefix(model, "apac.openai.") + or BedrockModelInfo._model_has_route_prefix(model, "us.openai.") + ) @staticmethod def get_bedrock_provider_config_for_messages_api( diff --git a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py index 3f03305423a..6f3a3272b7b 100644 --- a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py +++ b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py @@ -871,3 +871,30 @@ def test_every_bedrock_config_get_error_class_keeps_provider_headers(config): def test_bedrock_get_error_class_audit_covers_every_surface(): assert len(_bedrock_configs_with_get_error_class()) >= 30 + +@pytest.mark.parametrize( + "model", + [ + "bedrock/global.openai.gpt-5.6-sol", + "bedrock/global.openai.gpt-5.6-terra", + "bedrock/global.openai.gpt-5.6-luna", + "bedrock/eu.openai.gpt-5.6-sol", + "bedrock/apac.openai.gpt-5.6-sol", + "bedrock/us.openai.gpt-5.6-sol", + ], +) +def test_bedrock_cross_region_openai_routing(model: str): + """ + Ensure cross-region OpenAI inference profiles on Bedrock route to the + OpenAI-compatible config instead of falling back to Bedrock Converse. + """ + import litellm + from litellm.llms.bedrock.common_utils import get_bedrock_chat_config + + # 1. Verify route identification + assert BedrockModelInfo.get_bedrock_route(model) == "openai" + assert BedrockModelInfo._explicit_openai_route(model) is True + + # 2. Verify config mapping + config = get_bedrock_chat_config(model) + assert isinstance(config, litellm.AmazonBedrockOpenAIConfig) From 0707ef7b684c1e461a41617b78edcaf9fc530e76 Mon Sep 17 00:00:00 2001 From: anton-codes-iac <25830178+anton-codes-iac@users.noreply.github.com> Date: Tue, 8 Sep 2026 15:16:47 +0200 Subject: [PATCH 2/3] test(bedrock): update inference profile tests for openai endpoint routing --- .../test_litellm/llms/bedrock/test_bedrock_common_utils.py | 2 -- .../bedrock/test_cross_region_inference_profile_mapping.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py index 6f3a3272b7b..ffb7d747739 100644 --- a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py +++ b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py @@ -891,10 +891,8 @@ def test_bedrock_cross_region_openai_routing(model: str): import litellm from litellm.llms.bedrock.common_utils import get_bedrock_chat_config - # 1. Verify route identification assert BedrockModelInfo.get_bedrock_route(model) == "openai" assert BedrockModelInfo._explicit_openai_route(model) is True - # 2. Verify config mapping config = get_bedrock_chat_config(model) assert isinstance(config, litellm.AmazonBedrockOpenAIConfig) diff --git a/tests/test_litellm/llms/bedrock/test_cross_region_inference_profile_mapping.py b/tests/test_litellm/llms/bedrock/test_cross_region_inference_profile_mapping.py index fda3c8ceb8f..6bb1df90f01 100644 --- a/tests/test_litellm/llms/bedrock/test_cross_region_inference_profile_mapping.py +++ b/tests/test_litellm/llms/bedrock/test_cross_region_inference_profile_mapping.py @@ -150,9 +150,9 @@ def test_proxy_cost_calculation_scenario(): @pytest.mark.parametrize("profile", GPT_5_6_PROFILES, ids=lambda p: p.model_id) -def test_bedrock_gpt_5_6_profiles_route_to_converse(profile, local_model_cost_map): - """GPT-5.6 is served by Converse on bedrock-runtime, never by Invoke.""" - assert BedrockModelInfo.get_bedrock_route(f"bedrock/{profile.model_id}") == "converse" +def test_bedrock_gpt_5_6_profiles_route_to_openai(profile, local_model_cost_map): + """GPT-5.6 is served by Openai on bedrock-runtime.""" + assert BedrockModelInfo.get_bedrock_route(f"bedrock/{profile.model_id}") == "openai" def test_bedrock_gpt_5_6_above_272k_tier_applies_to_cost(local_model_cost_map): From 2a5e77db4064c5215f55bfeb2b7c8b1629d7c106 Mon Sep 17 00:00:00 2001 From: anton-codes-iac <25830178+anton-codes-iac@users.noreply.github.com> Date: Sat, 12 Sep 2026 21:44:17 +0200 Subject: [PATCH 3/3] test(bedrock): add comprehensive coverage for cross-region openai and explicit converse overrides --- .../llms/bedrock/test_bedrock_common_utils.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py index ffb7d747739..f25dedebf8f 100644 --- a/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py +++ b/tests/test_litellm/llms/bedrock/test_bedrock_common_utils.py @@ -872,6 +872,7 @@ def test_every_bedrock_config_get_error_class_keeps_provider_headers(config): def test_bedrock_get_error_class_audit_covers_every_surface(): assert len(_bedrock_configs_with_get_error_class()) >= 30 + @pytest.mark.parametrize( "model", [ @@ -879,10 +880,18 @@ def test_bedrock_get_error_class_audit_covers_every_surface(): "bedrock/global.openai.gpt-5.6-terra", "bedrock/global.openai.gpt-5.6-luna", "bedrock/eu.openai.gpt-5.6-sol", + "bedrock/eu.openai.gpt-5.6-terra", + "bedrock/eu.openai.gpt-5.6-luna", "bedrock/apac.openai.gpt-5.6-sol", + "bedrock/apac.openai.gpt-5.6-terra", + "bedrock/apac.openai.gpt-5.6-luna", "bedrock/us.openai.gpt-5.6-sol", + "bedrock/us.openai.gpt-5.6-terra", + "bedrock/us.openai.gpt-5.6-luna", ], ) + + def test_bedrock_cross_region_openai_routing(model: str): """ Ensure cross-region OpenAI inference profiles on Bedrock route to the @@ -896,3 +905,24 @@ def test_bedrock_cross_region_openai_routing(model: str): config = get_bedrock_chat_config(model) assert isinstance(config, litellm.AmazonBedrockOpenAIConfig) + + +@pytest.mark.parametrize( + "model", + [ + "bedrock/converse/global.openai.gpt-5.6-sol", + "bedrock/converse/eu.openai.gpt-5.6-terra", + "bedrock/converse/us.openai.gpt-5.6-luna", + ], +) + + +def test_explicit_converse_prefix_overrides_openai_routing(model: str): + """ + Ensure that a user can still explicitly force the Converse API for an OpenAI model + by using the `converse/` prefix, which takes precedence in route_mappings. + """ + from litellm.llms.bedrock.common_utils import BedrockModelInfo + + # Verify the explicit prefix intercepts the routing before the openai mapping + assert BedrockModelInfo.get_bedrock_route(model) == "converse"