fix(bedrock_mantle): resolve gpt-5 sampling rules from the OpenAI catalogue entry

This commit is contained in:
mateo-berri 2026-09-17 17:25:59 -07:00
parent 4f585d3931
commit 9ae5bde829
3 changed files with 47 additions and 15 deletions

View file

@ -344,6 +344,10 @@ class BedrockMantleResponsesAPIConfig(BedrockMantleAuthMixin, OpenAIResponsesAPI
kept: Final = [item for item, _ in normalized if item is not None] # mutable-ok: ResponseInputParam is a list
return kept # pyright: ignore[reportReturnType] # Codex passthrough items sit outside the OpenAI input union
@staticmethod
def _model_map_lookup_name(model: str) -> str:
return model.split("/")[-1].removeprefix("openai.")
def map_openai_params(
self,
response_api_optional_params: ResponsesAPIOptionalRequestParams,

View file

@ -125,6 +125,10 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
return False
return is_gpt_reasoning_series_name(model)
@staticmethod
def _model_map_lookup_name(model: str) -> str:
return model
@staticmethod
def _supports_reasoning_effort_none(model: str) -> bool:
"""Return True if the model supports reasoning.effort='none'."""
@ -235,11 +239,12 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
status_code=400,
)
if self._is_gpt_5_model(model=model):
lookup_name: Final = self._model_map_lookup_name(model)
if self._is_gpt_5_model(model=lookup_name):
reasoning: Final = params.get("reasoning") or {}
effort: Final = reasoning.get("effort") if isinstance(reasoning, dict) else None
supports_none: Final = self._supports_reasoning_effort_none(model=model)
effort_is_none: Final = supports_none and self._effort_resolves_to_none(model, effort)
supports_none: Final = self._supports_reasoning_effort_none(model=lookup_name)
effort_is_none: Final = supports_none and self._effort_resolves_to_none(lookup_name, effort)
temperature: Final = params.get("temperature")
if temperature is not None and temperature != 1:

View file

@ -370,26 +370,49 @@ class TestBedrockMantleResponsesTools:
class TestBedrockMantleSamplingParams:
"""Mantle rejects top_p on its gpt-5 reasoning models and non-default temperature
while reasoning is active, the same rule the OpenAI Responses surface applies, so
drop_params must strip both before the request leaves."""
"""Mantle serves OpenAI's gpt-5 models under their OpenAI sampling rule: top_p and a
non-default temperature are accepted only when reasoning.effort resolves to none, so
the `openai.` catalogue name (region-prefixed on GovCloud) must answer from the OpenAI
model's map entry instead of dropping both params on every request."""
@pytest.mark.parametrize(
"model",
"model, effort, survives",
[
"openai.gpt-5.4",
"openai.gpt-5.5",
"openai.gpt-5.6-luna",
("openai.gpt-5.4", None, True),
("openai.gpt-5.5", None, False),
("openai.gpt-5.6-luna", None, False),
("openai.gpt-5.6-luna", "none", True),
("openai.gpt-5.6-luna", "low", False),
("us-gov-west-1/openai.gpt-5.4", None, True),
("us-gov-west-1/openai.gpt-5.6-luna", None, False),
],
)
def test_map_openai_params_drops_top_p_and_temperature(self, local_cost_map, model):
params = BedrockMantleResponsesAPIConfig().map_openai_params(
response_api_optional_params={"top_p": 0.9, "temperature": 0.2},
def test_top_p_and_temperature_follow_the_resolved_effort(self, local_cost_map, model, effort, survives):
params = {"top_p": 0.9, "temperature": 0.2}
if effort is not None:
params["reasoning"] = {"effort": effort}
mapped = BedrockMantleResponsesAPIConfig().map_openai_params(
response_api_optional_params=params,
model=model,
drop_params=True,
)
assert "top_p" not in params
assert "temperature" not in params
assert ("top_p" in mapped) is survives
assert ("temperature" in mapped) is survives
def test_top_p_without_drop_params_raises_only_while_reasoning_is_active(self, local_cost_map):
with pytest.raises(litellm.UnsupportedParamsError):
BedrockMantleResponsesAPIConfig().map_openai_params(
response_api_optional_params={"top_p": 0.9},
model="openai.gpt-5.6-luna",
drop_params=False,
)
mapped = BedrockMantleResponsesAPIConfig().map_openai_params(
response_api_optional_params={"top_p": 0.9},
model="openai.gpt-5.4",
drop_params=False,
)
assert mapped["top_p"] == 0.9
class TestBedrockMantleResponsesWebSearch: