fix(bedrock): keep a Responses batch row's drop_params and keep it out of passthrough rows

This commit is contained in:
mateo-berri 2026-11-06 01:56:11 -08:00
parent ce94d2894d
commit 3705e7bcce
2 changed files with 27 additions and 13 deletions

View file

@ -1021,7 +1021,11 @@ class BedrockFilesConfig(BaseAWSLLM, BaseFilesConfig):
model), so `input`, `instructions`, `max_output_tokens` and the tool
params translate identically in batch and real time.
"""
return responses_batch_body_to_chat_body(openai_request_body)
chat_body: Final = responses_batch_body_to_chat_body(openai_request_body)
drop_params: Final = openai_request_body.get("drop_params")
if drop_params is None:
return chat_body
return _frozen_mapping(chain(chat_body.items(), (("drop_params", drop_params),)))
@staticmethod
def _transform_batch_body_to_chat_body(
@ -1119,7 +1123,7 @@ class BedrockFilesConfig(BaseAWSLLM, BaseFilesConfig):
# like openai.gpt-oss-*, qwen, deepseek, etc.) ---
return {
"messages": messages,
**optional_params,
**{k: v for k, v in optional_params.items() if k != "drop_params"},
}
def _resolve_batch_record_model_and_provider(

View file

@ -100,16 +100,15 @@ class TestBedrockFilesTransformation:
assert result[0]["modelInput"]["max_tokens"] == 10
@staticmethod
def _nova_row(**body_params: object) -> dict[str, object]:
def _nova_row(
url: str = "/v1/chat/completions", model: str = "us.amazon.nova-pro-v1:0", **body_params: object
) -> dict[str, object]:
prompt: Final = {"input": "hi"} if url == "/v1/responses" else {"messages": [{"role": "user", "content": "hi"}]}
return {
"custom_id": "nova-tier-1",
"method": "POST",
"url": "/v1/chat/completions",
"body": {
"model": "us.amazon.nova-pro-v1:0",
"messages": [{"role": "user", "content": "hi"}],
**body_params,
},
"url": url,
"body": {"model": model, **prompt, **body_params},
}
def test_nova_row_with_null_service_tier_sends_no_tier(self):
@ -119,18 +118,29 @@ class TestBedrockFilesTransformation:
assert "serviceTier" not in result[0]["modelInput"]
def test_nova_row_with_unmapped_service_tier_fails_the_row_like_real_time(self):
@pytest.mark.parametrize("url", ["/v1/chat/completions", "/v1/responses"])
def test_nova_row_with_unmapped_service_tier_fails_the_row_like_real_time(self, url: str):
with pytest.raises(litellm.UnsupportedParamsError, match="ultrafast"):
BedrockFilesConfig().transform_openai_jsonl_content_to_bedrock_jsonl_content(
[self._nova_row(service_tier="ultrafast")]
[self._nova_row(url, service_tier="ultrafast")]
)
def test_nova_row_level_drop_params_drops_the_unmapped_service_tier(self):
@pytest.mark.parametrize("url", ["/v1/chat/completions", "/v1/responses"])
def test_nova_row_level_drop_params_drops_the_unmapped_service_tier(self, url: str):
result: Final = BedrockFilesConfig().transform_openai_jsonl_content_to_bedrock_jsonl_content(
[self._nova_row(service_tier="ultrafast", drop_params=True)]
[self._nova_row(url, service_tier="ultrafast", drop_params=True)]
)
assert "serviceTier" not in result[0]["modelInput"]
assert "drop_params" not in json.dumps(result[0]["modelInput"])
@pytest.mark.parametrize("url", ["/v1/chat/completions", "/v1/responses"])
def test_passthrough_row_keeps_row_level_drop_params_out_of_the_model_input(self, url: str):
result: Final = BedrockFilesConfig().transform_openai_jsonl_content_to_bedrock_jsonl_content(
[self._nova_row(url, "openai.gpt-oss-120b-1:0", drop_params=True)]
)
assert "drop_params" not in result[0]["modelInput"]
def test_nova_text_only_uses_converse_format(self):
"""