mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-19 00:01:29 +00:00
fix(bedrock_mantle): gate reasoning.summary on the OpenAI Responses path
Mantle's /openai/v1/responses rejects reasoning.summary values other than "auto" with 400 unsupported_parameter. Drop it with a warning under drop_params, otherwise raise UnsupportedParamsError naming the remedy. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
22c60ef9e7
commit
bf9e8ea9ef
2 changed files with 113 additions and 4 deletions
|
|
@ -56,6 +56,7 @@ _BEDROCK_MANTLE_SUPPORTED_RESPONSE_TOOL_TYPES: Final = frozenset(
|
|||
)
|
||||
|
||||
_BEDROCK_MANTLE_SUPPORTED_SERVICE_TIERS: Final = frozenset({"auto", "default"})
|
||||
_BEDROCK_MANTLE_OPENAI_PATH_SUPPORTED_REASONING_SUMMARIES: Final = frozenset({"auto"})
|
||||
|
||||
_CODEX_ADDITIONAL_TOOLS_INPUT_ITEM_TYPE: Final = "additional_tools"
|
||||
|
||||
|
|
@ -187,6 +188,35 @@ class BedrockMantleResponsesAPIConfig(BedrockMantleAuthMixin, OpenAIResponsesAPI
|
|||
)
|
||||
return {key: value for key, value in params.items() if key != "service_tier"}
|
||||
|
||||
def _handle_unsupported_reasoning_summary(self, params: dict, model: str, drop_params: bool) -> dict:
|
||||
reasoning: Final = params.get("reasoning")
|
||||
if not self.use_openai_path or not isinstance(reasoning, dict):
|
||||
return params
|
||||
summary: Final = reasoning.get("summary")
|
||||
if summary is None or summary in _BEDROCK_MANTLE_OPENAI_PATH_SUPPORTED_REASONING_SUMMARIES:
|
||||
return params
|
||||
if not drop_params:
|
||||
raise litellm.utils.UnsupportedParamsError(
|
||||
status_code=400,
|
||||
message=(
|
||||
f"bedrock_mantle does not support reasoning.summary={summary!r} for {model!r}; the Bedrock Mantle "
|
||||
"OpenAI Responses path only accepts 'auto'. Set `drop_params: true` (litellm_settings or this "
|
||||
'deployment\'s litellm_params) to have LiteLLM drop it, or set `model_reasoning_summary = "auto"` '
|
||||
"in the client (Codex CLI: ~/.codex/config.toml)."
|
||||
),
|
||||
)
|
||||
verbose_logger.warning(
|
||||
"Bedrock Mantle Responses API: dropping unsupported reasoning.summary %r (supported: %s).",
|
||||
summary,
|
||||
sorted(_BEDROCK_MANTLE_OPENAI_PATH_SUPPORTED_REASONING_SUMMARIES),
|
||||
)
|
||||
stripped: Final = {key: value for key, value in reasoning.items() if key != "summary"}
|
||||
return (
|
||||
{**params, "reasoning": stripped}
|
||||
if stripped
|
||||
else {key: value for key, value in params.items() if key != "reasoning"}
|
||||
)
|
||||
|
||||
def transform_responses_api_request(
|
||||
self,
|
||||
model: str,
|
||||
|
|
@ -343,12 +373,16 @@ class BedrockMantleResponsesAPIConfig(BedrockMantleAuthMixin, OpenAIResponsesAPI
|
|||
model: str,
|
||||
drop_params: bool,
|
||||
) -> dict:
|
||||
params: Final = self._handle_unsupported_service_tier(
|
||||
super().map_openai_params(
|
||||
response_api_optional_params=response_api_optional_params,
|
||||
model=model,
|
||||
params: Final = self._handle_unsupported_reasoning_summary(
|
||||
self._handle_unsupported_service_tier(
|
||||
super().map_openai_params(
|
||||
response_api_optional_params=response_api_optional_params,
|
||||
model=model,
|
||||
drop_params=drop_params,
|
||||
),
|
||||
drop_params=drop_params,
|
||||
),
|
||||
model=model,
|
||||
drop_params=drop_params,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -539,6 +539,81 @@ class TestBedrockMantleServiceTier:
|
|||
assert "priority" in str(mock_warning.call_args)
|
||||
|
||||
|
||||
class TestBedrockMantleReasoningSummary:
|
||||
@pytest.mark.parametrize("summary", ["concise", "detailed"])
|
||||
def test_unsupported_reasoning_summary_dropped_when_drop_params_true(self, summary):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
params = cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium", "summary": summary}},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=True,
|
||||
)
|
||||
assert params["reasoning"] == {"effort": "medium"}
|
||||
|
||||
def test_reasoning_summary_only_field_drops_reasoning(self):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
params = cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"summary": "detailed"}},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=True,
|
||||
)
|
||||
assert "reasoning" not in params
|
||||
|
||||
@pytest.mark.parametrize("summary", ["concise", "detailed"])
|
||||
def test_unsupported_reasoning_summary_raises_when_drop_params_false(self, summary):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
with pytest.raises(litellm.UnsupportedParamsError) as excinfo:
|
||||
cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium", "summary": summary}},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=False,
|
||||
)
|
||||
assert summary in str(excinfo.value)
|
||||
assert "reasoning.summary" in str(excinfo.value)
|
||||
assert "drop_params" in str(excinfo.value)
|
||||
|
||||
@pytest.mark.parametrize("drop_params", [True, False])
|
||||
def test_supported_reasoning_summary_kept(self, drop_params):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
params = cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium", "summary": "auto"}},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=drop_params,
|
||||
)
|
||||
assert params["reasoning"] == {"effort": "medium", "summary": "auto"}
|
||||
|
||||
def test_reasoning_summary_kept_on_standard_path(self):
|
||||
cfg = BedrockMantleResponsesAPIConfig(use_openai_path=False)
|
||||
params = cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium", "summary": "detailed"}},
|
||||
model="openai.gpt-oss-120b",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params["reasoning"] == {"effort": "medium", "summary": "detailed"}
|
||||
|
||||
def test_absent_reasoning_untouched(self):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
params = cfg.map_openai_params(
|
||||
response_api_optional_params={"stream": True},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=False,
|
||||
)
|
||||
assert params == {"stream": True}
|
||||
|
||||
def test_drop_logged_at_warning_level(self):
|
||||
from unittest.mock import patch
|
||||
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
with patch("litellm.llms.bedrock_mantle.responses.transformation.verbose_logger.warning") as mock_warning:
|
||||
cfg.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium", "summary": "detailed"}},
|
||||
model="openai.gpt-5.6-sol",
|
||||
drop_params=True,
|
||||
)
|
||||
assert mock_warning.call_count == 1
|
||||
assert "detailed" in str(mock_warning.call_args)
|
||||
|
||||
|
||||
class TestBedrockMantleCodexRequestEndToEnd:
|
||||
def test_codex_priority_tier_request_becomes_mantle_acceptable(self):
|
||||
cfg = BedrockMantleResponsesAPIConfig()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue