Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions litellm/llms/bedrock/chat/converse_transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1521,12 +1521,14 @@ def _transform_request_helper(
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():
Expand Down
2 changes: 0 additions & 2 deletions tests/llm_translation/test_bedrock_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1340,11 +1340,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,70 @@ def test_nova_text_only_uses_converse_format(self):
# 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 == {
Comment on lines +174 to +183

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The two intermediate assertions check a weaker invariant ("absent or non-empty") but are immediately followed by an exact equality check that already implies both fields must be absent. They add noise without catching anything the final assertion doesn't already cover, and could mislead a future reader into thinking a non-empty additionalModelRequestFields would also be acceptable here.

Suggested change
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 == {
# Validate the exact shape AWS accepts — both empty fields must be absent
assert model_input == {

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

"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
Expand Down
Loading