diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index 38dabafa441..b995a948dd8 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -426,8 +426,6 @@ class AmazonConverseConfig(BaseConfig): if "gpt-oss" in model: optional_params["reasoning_effort"] = reasoning_effort elif "openai.gpt-5" in model: - # Converse rejects Anthropic's `thinking` for OpenAI GPT-5.x; effort goes - # under additionalModelRequestFields as {"reasoning": {"effort": ...}}. optional_params.pop("thinking", None) optional_params["reasoning"] = {"effort": reasoning_effort} elif self._is_nova_2_model(model): @@ -561,7 +559,7 @@ class AmazonConverseConfig(BaseConfig): # only anthropic and mistral support tool choice config. otherwise (E.g. cohere) will fail the call - https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolChoice.html supported_params.append("tool_choice") - if "gpt-oss" in model: + if "gpt-oss" in model or "openai.gpt-5" in model or "openai.gpt-5" in base_model: supported_params.append("reasoning_effort") elif self._is_nova_2_model(model): # Nova 2 models support reasoning_effort (transformed to reasoningConfig) @@ -909,7 +907,7 @@ class AmazonConverseConfig(BaseConfig): optional_params["_parallel_tool_use_config"] = { "tool_choice": {"type": "auto", "disable_parallel_tool_use": not value} } - if param == "thinking": + if param == "thinking" and "openai.gpt-5" not in model: if ( isinstance(value, dict) and value.get("type") == "adaptive" diff --git a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py index 66b588168e9..c5ab6027f45 100644 --- a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py +++ b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py @@ -315,6 +315,40 @@ def test_reasoning_effort_maps_to_reasoning_effort_for_openai_gpt5_converse(mode assert "thinking" not in additional_request_params +@pytest.mark.parametrize( + "model", + [ + "us.openai.gpt-5.6-sol", + "bedrock/converse/global.openai.gpt-5.6-luna", + ], +) +def test_openai_gpt5_converse_never_forwards_thinking(model, local_model_cost_map): + """GPT-5.x on Converse must never send Anthropic ``thinking``/``output_config`` (Bedrock rejects them). + + Regression: ``thinking`` is not advertised as supported, and even when supplied alongside + ``reasoning_effort`` in either order it never survives into the request.""" + config = AmazonConverseConfig() + + supported = config.get_supported_openai_params(model=model) + assert "thinking" not in supported + assert "output_config" not in supported + + thinking_block = {"type": "enabled", "budget_tokens": 2048} + for non_default_params in ( + {"reasoning_effort": "high", "thinking": thinking_block}, + {"thinking": thinking_block, "reasoning_effort": "high"}, + ): + optional_params = config.map_openai_params( + non_default_params=dict(non_default_params), + optional_params={}, + model=model, + drop_params=False, + ) + _, additional_request_params, _, _ = config._prepare_request_params(optional_params, model) + assert additional_request_params["reasoning"] == {"effort": "high"} + assert "thinking" not in additional_request_params + + @pytest.mark.parametrize( "model", [