Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions litellm/llms/bedrock/chat/converse_transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,16 @@ def _handle_reasoning_effort_parameter(self, model: str, reasoning_effort: str,
Handle the reasoning_effort parameter based on the model type.

- GPT-OSS models: passed through unchanged via additionalModelRequestFields.
- OpenAI GPT-5.x models: mapped to ``reasoning.effort`` via additionalModelRequestFields.
- Nova 2 models: transformed to reasoningConfig.
- Anthropic models: mapped to ``thinking`` (and ``output_config.effort`` on
adaptive Claude 4.6 / 4.7).
"""
if "gpt-oss" in model:
optional_params["reasoning_effort"] = reasoning_effort
elif "openai.gpt-5" in model:
Comment thread
6matt marked this conversation as resolved.
reasoning: Final[BedrockConverseGptReasoningEffortBlock] = {"effort": reasoning_effort}
optional_params["reasoning"] = reasoning
Comment on lines +428 to +430

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Aliases use Anthropic reasoning

When a Bedrock Converse deployment uses an alias without openai.gpt-5 while its resolved base_model identifies GPT-5, parameter detection accepts reasoning_effort but this branch classifies only the alias and falls through to the Anthropic thinking mapping, causing Bedrock to reject the request with a 400.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing: opaque profile ARNs map to thinking identically at merge base, for gpt-oss and Nova 2 too. Plumbing base_model through map_openai_params is out of scope.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Since opaque profile ARNs already have this behavior at merge base for GPT-OSS and Nova 2, and threading base_model through map_openai_params would expand the scope, I’m withdrawing this as a PR-blocking finding.

elif self._is_nova_2_model(model):
reasoning_config: Final = self._transform_reasoning_effort_to_reasoning_config(reasoning_effort)
optional_params.update(reasoning_config)
Expand Down Expand Up @@ -555,7 +559,7 @@ def get_supported_openai_params(self, model: str) -> list[str]:
# 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)
Expand Down Expand Up @@ -903,7 +907,7 @@ def map_openai_params(
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"
Expand Down
6 changes: 6 additions & 0 deletions litellm/model_prices_and_context_window_backup.json
Original file line number Diff line number Diff line change
Expand Up @@ -49473,6 +49473,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-sol": {
Expand All @@ -49498,6 +49499,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"us.openai.gpt-5.6-terra": {
Expand All @@ -49523,6 +49525,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-terra": {
Expand All @@ -49548,6 +49551,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"us.openai.gpt-5.6-luna": {
Expand All @@ -49573,6 +49577,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-luna": {
Expand All @@ -49598,6 +49603,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"bedrock_mantle/openai.gpt-5.5": {
Expand Down
6 changes: 5 additions & 1 deletion litellm/types/llms/bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from enum import Enum
from typing import TYPE_CHECKING, Any, Final, Literal

from typing_extensions import Required, TypedDict, override
from typing_extensions import ReadOnly, Required, TypedDict, override

from .openai import ChatCompletionToolCallChunk

Expand Down Expand Up @@ -97,6 +97,10 @@ class BedrockConverseReasoningContentBlockDelta(TypedDict, total=False):
text: str


class BedrockConverseGptReasoningEffortBlock(TypedDict):
effort: ReadOnly[str]


class GuardrailConverseTextBlock(TypedDict, total=False):
text: str

Expand Down
6 changes: 6 additions & 0 deletions model_prices_and_context_window.json
Original file line number Diff line number Diff line change
Expand Up @@ -49473,6 +49473,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-sol": {
Expand All @@ -49498,6 +49499,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"us.openai.gpt-5.6-terra": {
Expand All @@ -49523,6 +49525,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-terra": {
Expand All @@ -49548,6 +49551,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"us.openai.gpt-5.6-luna": {
Expand All @@ -49573,6 +49577,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"global.openai.gpt-5.6-luna": {
Expand All @@ -49598,6 +49603,7 @@
],
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_vision": true
},
"bedrock_mantle/openai.gpt-5.5": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,71 @@ def test_reasoning_with_forced_tool_choice_switches_to_auto():
assert optional_params["tool_choice"] == {"auto": {}}


@pytest.mark.parametrize(
"model",
[
"us.openai.gpt-5.6-sol",
"global.openai.gpt-5.6-terra",
"bedrock/converse/us.openai.gpt-5.6-luna",
],
)
def test_reasoning_effort_maps_to_reasoning_effort_for_openai_gpt5_converse(model, local_model_cost_map):
"""OpenAI GPT-5.x on Bedrock Converse routes reasoning_effort to
``additionalModelRequestFields.reasoning.effort`` rather than Anthropic ``thinking``."""
config = AmazonConverseConfig()

assert "reasoning_effort" in config.get_supported_openai_params(model=model)

optional_params = config.map_openai_params(
non_default_params={"reasoning_effort": "high"},
optional_params={},
model=model,
drop_params=False,
)

assert optional_params["reasoning"] == {"effort": "high"}
assert "thinking" not in optional_params
assert "reasoning_effort" not in optional_params

_, 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",
[
"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",
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,16 @@ def test_bedrock_gpt_5_6_advertises_only_converse_supported_features(


@pytest.mark.parametrize("profile", GPT_5_6_PROFILES, ids=lambda p: p.model_id)
def test_bedrock_gpt_5_6_offers_tools_but_not_reasoning(profile, local_model_cost_map):
"""Converse rejects the Anthropic-shaped thinking block LiteLLM emits for
reasoning_effort, so neither reasoning param may be offered yet, while the tool
params these models do accept must be."""
def test_bedrock_gpt_5_6_offers_tools_and_reasoning_effort_but_not_thinking(profile, local_model_cost_map):
"""GPT-5.x on Converse maps reasoning_effort to reasoning.effort, so reasoning_effort
is offered while the Anthropic-only thinking/output_config are not, alongside the tool
params these models accept."""
supported = AmazonConverseConfig().get_supported_openai_params(
model=f"bedrock/{profile.model_id}"
)

assert "tools" in supported
assert "tool_choice" in supported
assert "reasoning_effort" not in supported
assert "reasoning_effort" in supported
assert "thinking" not in supported
assert "output_config" not in supported
Loading