mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-30 06:43:27 +00:00
fix: stay silent when reasoning is turned off on /v1/responses and warn on the Bedrock Responses fallback drop
This commit is contained in:
parent
d32087cd8e
commit
9eaba58c73
4 changed files with 36 additions and 7 deletions
|
|
@ -56,6 +56,7 @@ from litellm.llms.bedrock.common_utils import (
|
|||
bedrock_reasoning_effort_disabled,
|
||||
bedrock_supports_openai_responses,
|
||||
)
|
||||
from litellm.llms.openai.chat.gpt_reasoning_transformation import DROP_REFUSED_REASONING_EFFORT_WARNING
|
||||
from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
from litellm.types.llms.openai import ResponseInputParam, ResponsesAPIOptionalRequestParams
|
||||
|
|
@ -173,7 +174,7 @@ def _without_disabled_reasoning_effort(
|
|||
),
|
||||
status_code=400,
|
||||
)
|
||||
verbose_logger.debug("Dropping unsupported `reasoning.effort=%s` for Bedrock model=%s.", effort, model)
|
||||
verbose_logger.warning(DROP_REFUSED_REASONING_EFFORT_WARNING, "reasoning.effort", effort, model, model)
|
||||
rest: Final = {key: value for key, value in reasoning.items() if key != "effort"}
|
||||
without_reasoning: Final = {key: value for key, value in params.items() if key != "reasoning"}
|
||||
return {**without_reasoning, "reasoning": rest} if rest else without_reasoning
|
||||
|
|
|
|||
|
|
@ -330,10 +330,11 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
|
|||
|
||||
@staticmethod
|
||||
def _requests_reasoning_effort(reasoning: object) -> bool:
|
||||
effort: Final = (
|
||||
reasoning.get("effort") if isinstance(reasoning, Mapping) else getattr(reasoning, "effort", None)
|
||||
)
|
||||
return effort is not None
|
||||
return OpenAIResponsesAPIConfig._requested_effort(reasoning) is not None
|
||||
|
||||
@staticmethod
|
||||
def _requested_effort(reasoning: object) -> object:
|
||||
return reasoning.get("effort") if isinstance(reasoning, Mapping) else getattr(reasoning, "effort", None)
|
||||
|
||||
@staticmethod
|
||||
def _enforce_min_max_output_tokens(max_output_tokens: "int | None") -> "int | None":
|
||||
|
|
@ -406,7 +407,8 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
|
|||
):
|
||||
if drop_params or litellm.drop_params:
|
||||
dropped_reasoning: Final = params.pop("reasoning", None)
|
||||
verbose_logger.warning(DROP_UNSUPPORTED_REASONING_WARNING, dropped_reasoning, model)
|
||||
if self._requested_effort(dropped_reasoning) != "none":
|
||||
verbose_logger.warning(DROP_UNSUPPORTED_REASONING_WARNING, dropped_reasoning, model)
|
||||
else:
|
||||
raise litellm.UnsupportedParamsError(
|
||||
message=(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import pytest
|
|||
|
||||
import litellm
|
||||
from litellm.llms.bedrock.common_utils import bedrock_supports_openai_responses
|
||||
from litellm.llms.bedrock.responses.transformation import BedrockOpenAIResponsesConfig
|
||||
from litellm.llms.bedrock.responses.transformation import BedrockOpenAIResponsesConfig, _without_disabled_reasoning_effort
|
||||
from litellm.responses.file_search.emulated_handler import should_use_emulated_file_search
|
||||
from litellm.responses.utils import ResponsesAPIRequestUtils
|
||||
from litellm.types.router import GenericLiteLLMParams
|
||||
|
|
@ -357,6 +357,19 @@ class TestDisabledReasoningEffort:
|
|||
]
|
||||
assert len(dropped) == 1 and model in dropped[0]
|
||||
|
||||
def test_bedrock_disabled_effort_drop_warns_on_its_own(
|
||||
self, local_model_cost_map: None, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
with caplog.at_level(logging.WARNING, logger="LiteLLM"):
|
||||
params: Final = _without_disabled_reasoning_effort(
|
||||
{"reasoning": {"effort": "minimal"}, "max_output_tokens": 64}, MODEL, True, ()
|
||||
)
|
||||
assert params == {"max_output_tokens": 64}
|
||||
dropped: Final = [
|
||||
r.getMessage() for r in caplog.records if "Dropping reasoning.effort='minimal'" in r.getMessage()
|
||||
]
|
||||
assert len(dropped) == 1 and MODEL in dropped[0]
|
||||
|
||||
def test_effort_only_reasoning_is_removed_when_dropped(self, local_model_cost_map):
|
||||
params = _cfg().map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "minimal"}}, model=MODEL, drop_params=True
|
||||
|
|
|
|||
|
|
@ -2426,6 +2426,19 @@ class TestResponsesSurfaceSharesTheEffortRule:
|
|||
assert len(drop_warnings) == 1
|
||||
assert all(fragment in drop_warnings[0] for fragment in ("'medium'", "gpt-4o", "supports_reasoning"))
|
||||
|
||||
def test_turning_reasoning_off_for_a_model_without_supports_reasoning_drops_it_silently(
|
||||
self, local_model_cost_map: None, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
with caplog.at_level(logging.WARNING, logger="LiteLLM"):
|
||||
mapped: Final = OpenAIResponsesAPIConfig().map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "none", "summary": "auto"}},
|
||||
model="gpt-4o",
|
||||
drop_params=True,
|
||||
)
|
||||
|
||||
assert "reasoning" not in mapped
|
||||
assert not [record for record in caplog.records if "Dropping" in record.getMessage()]
|
||||
|
||||
def test_a_forwarded_effort_logs_no_drop_warning(
|
||||
self, local_model_cost_map: None, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue