mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(bedrock): omit empty additionalModelRequestFields and system from Converse API payload (#29565)
Amazon Nova Pro (and other strict Bedrock models) return 400 Malformed input
request when additionalModelRequestFields: {} or system: [] are present in the
payload. Both fields are optional in CommonRequestObject (total=False) and must
be omitted rather than sent as empty structures.
Co-authored-by: shin-berri <shin-laptop@berri.ai>
Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b93656f132
commit
1d6402a89a
4 changed files with 71 additions and 8 deletions
|
|
@ -1649,12 +1649,14 @@ class AmazonConverseConfig(BaseConfig):
|
|||
bedrock_tool_config["toolChoice"] = tool_choice_values
|
||||
|
||||
data: CommonRequestObject = {
|
||||
"additionalModelRequestFields": additional_request_params,
|
||||
"system": system_content_blocks,
|
||||
"inferenceConfig": self._transform_inference_params(
|
||||
inference_params=inference_params
|
||||
),
|
||||
}
|
||||
if additional_request_params:
|
||||
data["additionalModelRequestFields"] = additional_request_params
|
||||
if system_content_blocks:
|
||||
data["system"] = system_content_blocks
|
||||
|
||||
# Handle all config blocks
|
||||
for config_name, config_class in self.get_config_blocks().items():
|
||||
|
|
|
|||
|
|
@ -3059,8 +3059,6 @@ async def test_bedrock_max_completion_tokens(model: str):
|
|||
|
||||
assert request_body == {
|
||||
"messages": [{"role": "user", "content": [{"text": "Hello!"}]}],
|
||||
"additionalModelRequestFields": {},
|
||||
"system": [],
|
||||
"inferenceConfig": {"maxTokens": 10},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1467,11 +1467,10 @@ def test_transform_request_with_function_tool():
|
|||
)
|
||||
|
||||
# Verify the structure
|
||||
assert "additionalModelRequestFields" in request_data
|
||||
additional_fields = request_data["additionalModelRequestFields"]
|
||||
# Function tools are not computer use tools, so they don't get anthropic_beta —
|
||||
# additionalModelRequestFields should be absent (not serialized as empty {})
|
||||
assert "additionalModelRequestFields" not in request_data
|
||||
|
||||
# Function tools are not computer use tools, so they don't get anthropic_beta
|
||||
# They are processed through the regular tool config
|
||||
assert "toolConfig" in request_data
|
||||
assert "tools" in request_data["toolConfig"]
|
||||
assert len(request_data["toolConfig"]["tools"]) == 1
|
||||
|
|
|
|||
|
|
@ -128,6 +128,70 @@ class TestBedrockFilesTransformation:
|
|||
# Must have messages
|
||||
assert "messages" in model_input
|
||||
|
||||
# Nova Pro rejects empty additionalModelRequestFields / system — they must be absent
|
||||
assert (
|
||||
"additionalModelRequestFields" not in model_input
|
||||
), "Nova: empty additionalModelRequestFields must be omitted, not serialized as {}"
|
||||
assert (
|
||||
"system" not in model_input
|
||||
), "Nova: empty system must be omitted, not serialized as []"
|
||||
|
||||
def test_nova_batch_jsonl_omits_empty_converse_fields(self):
|
||||
"""
|
||||
Regression test: Amazon Nova Pro returns 400 Malformed input request when
|
||||
additionalModelRequestFields or system are present but empty in the Converse
|
||||
API payload. The proxy must strip these keys when they carry no data.
|
||||
"""
|
||||
from litellm.llms.bedrock.files.transformation import BedrockFilesConfig
|
||||
|
||||
config = BedrockFilesConfig()
|
||||
|
||||
openai_jsonl_content = [
|
||||
{
|
||||
"custom_id": "req-0",
|
||||
"method": "POST",
|
||||
"url": "/v1/chat/completions",
|
||||
"body": {
|
||||
"model": "us.amazon.nova-pro-v1:0",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is 1 + 1? Answer with just the number.",
|
||||
}
|
||||
],
|
||||
"max_tokens": 16,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
result = config._transform_openai_jsonl_content_to_bedrock_jsonl_content(
|
||||
openai_jsonl_content
|
||||
)
|
||||
|
||||
assert len(result) == 1
|
||||
model_input = result[0]["modelInput"]
|
||||
|
||||
assert (
|
||||
"additionalModelRequestFields" not in model_input
|
||||
or model_input["additionalModelRequestFields"]
|
||||
), "additionalModelRequestFields must be absent or non-empty — Nova rejects {}"
|
||||
assert (
|
||||
"system" not in model_input or model_input["system"]
|
||||
), "system must be absent or non-empty — Nova rejects []"
|
||||
|
||||
# Validate the exact shape AWS accepts
|
||||
assert model_input == {
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"text": "What is 1 + 1? Answer with just the number."}
|
||||
],
|
||||
}
|
||||
],
|
||||
"inferenceConfig": {"maxTokens": 16},
|
||||
}
|
||||
|
||||
def test_nova_image_content_uses_converse_image_blocks(self):
|
||||
"""
|
||||
Test that image_url content blocks are converted to Bedrock Converse
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue