diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index 8fe545a3272..098be7082d3 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -890,7 +890,16 @@ def bedrock_runtime_chat_completions_enforces_response_format(model: str) -> boo BEDROCK_CONVERSE_ONLY_REQUEST_KEYS: Final = frozenset( - ("guardrailConfig", "performanceConfig", "serviceTier", "requestMetadata", "outputConfig", "thinking") + ( + "guardrailConfig", + "performanceConfig", + "serviceTier", + "requestMetadata", + "outputConfig", + "thinking", + "additionalModelRequestFields", + "top_k", + ) ) @@ -910,7 +919,8 @@ def bedrock_request_needs_converse(model: str, request_params: Mapping[str, obje """Whether a request on a runtime-Chat-Completions model must still be served by Converse. Converse-shaped body keys (``BEDROCK_CONVERSE_ONLY_REQUEST_KEYS``, the Anthropic-style ``thinking`` - block included, which only Converse forwards as ``additionalModelRequestFields``) have no field on + block and the ``additionalModelRequestFields`` / ``top_k`` extension params included, which only Converse + forwards as ``additionalModelRequestFields`` and ``inferenceConfig``) have no field on AWS's native OpenAI surface, operator-owned request metadata is only written onto the Converse body, function tools (``tools`` or legacy ``functions``) on a model without ``supports_bedrock_runtime_chat_completions_tools_with_reasoning`` are rejected there unless diff --git a/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py b/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py index 061df201c15..17c0f8d3c1d 100644 --- a/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py +++ b/tests/unit/llms/bedrock/chat/chat_completions/test_bedrock_chat_completions_transformation.py @@ -258,6 +258,18 @@ def test_guardrail_config_falls_back_to_converse(local_cost_map, model): assert BedrockModelInfo.get_bedrock_route(model, {"guardrailConfig": None}) == "chat_completions" +@pytest.mark.parametrize("model", ["openai.gpt-oss-20b-1:0", "us.xai.grok-4.6"]) +@pytest.mark.parametrize( + "request_params", + [{"additionalModelRequestFields": {"reasoning_effort": "high"}}, {"top_k": 40}], + ids=["additionalModelRequestFields", "top_k"], +) +def test_converse_extension_params_fall_back_to_converse(local_cost_map, model, request_params): + assert bedrock_request_needs_converse(model, request_params) is True + assert BedrockModelInfo.get_bedrock_route(model, request_params) == "converse" + assert BedrockModelInfo.get_bedrock_route(model, {key: None for key in request_params}) == "chat_completions" + + @pytest.mark.parametrize( "request_params, expected_route", [