Skip to content
Open
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
28 changes: 27 additions & 1 deletion litellm/llms/bedrock/chat/chat_completions/transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from litellm.llms.bedrock.common_utils import (
BedrockError,
bedrock_model_is_openai_gpt,
bedrock_reasoning_effort_disabled,
split_bedrock_region_path,
)
from litellm.llms.openai.chat.gpt_transformation import OpenAIChatCompletionStreamingHandler
Expand Down Expand Up @@ -130,6 +131,20 @@ def non_string_reasoning_effort(params: Mapping[str, object]) -> frozenset[str]:
return frozenset(("reasoning_effort",))


def disabled_reasoning_effort(model: str, params: Mapping[str, object]) -> frozenset[str]:
"""``reasoning_effort`` when the model map sets ``supports_<effort>_reasoning_effort`` to false for this GPT model.

AWS answers such an effort (``"minimal"`` on GPT 5.4 and newer) with a 400, so the native config refuses it before
the call, or drops it under ``drop_params``, the same way Converse does.
"""
effort: Final = params.get("reasoning_effort")
if not isinstance(effort, str) or not bedrock_model_is_openai_gpt(model):
return frozenset()
if not bedrock_reasoning_effort_disabled(model=model, effort=effort):
return frozenset()
return frozenset(("reasoning_effort",))


def _held_close_tag_prefix(text: str) -> int:
return next(
(
Expand Down Expand Up @@ -378,6 +393,7 @@ def map_openai_params(
)
raw_params: Final = _PARAMS_DICT_ADAPTER.validate_python(non_default_params)
malformed_effort: Final = non_string_reasoning_effort(raw_params)
disabled_effort: Final = disabled_reasoning_effort(model, raw_params)
refused_while_reasoning: Final = chat_completions_params_refused_while_reasoning(model, raw_params)
if malformed_effort and not (litellm.drop_params or drop_params):
raise litellm.utils.UnsupportedParamsError(
Expand All @@ -388,6 +404,14 @@ def map_openai_params(
),
status_code=400,
)
if disabled_effort and not (litellm.drop_params or drop_params):
raise litellm.utils.UnsupportedParamsError(
message=(
f"{model} does not support reasoning_effort={raw_params['reasoning_effort']}. "
"To drop unsupported params, set `litellm.drop_params = True`."
),
status_code=400,
)
if refused_while_reasoning and not (litellm.drop_params or drop_params):
raise litellm.utils.UnsupportedParamsError(
message=(
Expand All @@ -400,7 +424,9 @@ def map_openai_params(
return dict(
without_refused_reasoning_effort(
model,
with_max_completion_tokens(_without_params(mapped, refused_while_reasoning | malformed_effort)),
with_max_completion_tokens(
_without_params(mapped, refused_while_reasoning | malformed_effort | disabled_effort)
),
)
)

Expand Down
12 changes: 6 additions & 6 deletions litellm/model_prices_and_context_window_backup.json
Original file line number Diff line number Diff line change
Expand Up @@ -58781,7 +58781,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58819,7 +58819,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58894,7 +58894,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58928,7 +58928,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58965,7 +58965,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58999,7 +58999,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down
12 changes: 6 additions & 6 deletions model_prices_and_context_window.json
Original file line number Diff line number Diff line change
Expand Up @@ -58781,7 +58781,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58819,7 +58819,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58894,7 +58894,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58928,7 +58928,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58965,7 +58965,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down Expand Up @@ -58999,7 +58999,7 @@
"supports_function_calling": true,
"supports_max_reasoning_effort": true,
"supports_minimal_reasoning_effort": false,
"supports_none_reasoning_effort": false,
"supports_none_reasoning_effort": true,
"supports_tool_choice": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
bedrock_route_for_request,
bedrock_runtime_chat_completions_is_default,
get_bedrock_chat_config,
split_bedrock_region_path,
)
from litellm.llms.custom_httpx.http_handler import HTTPHandler

Expand Down Expand Up @@ -710,6 +711,59 @@ def test_map_openai_params_keeps_reasoning_effort_none_for_gpt56():
assert mapped["reasoning_effort"] == "none"


@pytest.mark.parametrize(
"model, effort",
[
("global.openai.gpt-5.6-sol", "minimal"),
("bedrock/us-east-1/us.openai.gpt-5.6-luna", "minimal"),
("us.openai.gpt-6.1-sol", "none"),
],
)
def test_map_openai_params_refuses_an_effort_the_model_map_disables_without_drop_params(local_cost_map, model, effort):
assert litellm.model_cost[split_bedrock_region_path(model)[1]][f"supports_{effort}_reasoning_effort"] is False
with pytest.raises(litellm.UnsupportedParamsError, match="drop_params") as refused:
AmazonBedrockRuntimeChatCompletionsConfig().map_openai_params(
non_default_params={"reasoning_effort": effort, "max_tokens": 64},
optional_params={},
model=model,
drop_params=False,
)
assert refused.value.status_code == 400
assert f"reasoning_effort={effort}" in str(refused.value)


@pytest.mark.parametrize("drop_params_via", ["request", "litellm.drop_params"])
def test_map_openai_params_drops_an_effort_the_model_map_disables_under_drop_params(
local_cost_map, monkeypatch, drop_params_via
):
monkeypatch.setattr(litellm, "drop_params", drop_params_via == "litellm.drop_params")
mapped = AmazonBedrockRuntimeChatCompletionsConfig().map_openai_params(
non_default_params={"reasoning_effort": "minimal", "max_tokens": 64},
optional_params={},
model="global.openai.gpt-5.6-sol",
drop_params=drop_params_via == "request",
)
assert "reasoning_effort" not in mapped
assert mapped["max_completion_tokens"] == 64


@pytest.mark.parametrize("effort, sent", [("minimal", None), ("low", "low")])
def test_completion_on_the_default_route_leaves_out_an_effort_the_model_map_disables(
local_cost_map, fake_aws_env, effort, sent
):
requests, client = _recording_client(json=_chat_completion_json("ok", "us.openai.gpt-5.6-luna"))
litellm.completion(
model="bedrock/us.openai.gpt-5.6-luna",
messages=[{"role": "user", "content": "hello"}],
reasoning_effort=effort,
drop_params=True,
client=client,
)

assert [request.url.raw_path for request in requests] == [b"/openai/v1/chat/completions"]
assert json.loads(requests[0].content).get("reasoning_effort") == sent


def test_reasoning_efforts_refused_for_is_empty_outside_xai():
assert chat_completions_reasoning_efforts_refused_for("openai.gpt-oss-20b-1:0") == frozenset()

Expand Down
Loading