@@ -2584,3 +2584,95 @@ def test_request_metadata_not_provided():
25842584
25852585 # requestMetadata should not be in the request
25862586 assert "requestMetadata" not in request_data
2587+
2588+
2589+ def test_empty_assistant_message_handling ():
2590+ """
2591+ Test that empty assistant messages are handled correctly by replacing
2592+ empty or whitespace-only content with a placeholder to prevent AWS Bedrock
2593+ Converse API 400 Bad Request errors.
2594+ """
2595+ from litellm .litellm_core_utils .prompt_templates .factory import _bedrock_converse_messages_pt
2596+
2597+ # Test case 1: Empty string content - test with modify_params=True to prevent merging
2598+ messages = [
2599+ {"role" : "user" , "content" : "Hello" },
2600+ {"role" : "assistant" , "content" : "" }, # Empty content
2601+ {"role" : "user" , "content" : "How are you?" }
2602+ ]
2603+
2604+ # Enable modify_params to prevent consecutive user message merging
2605+ original_modify_params = litellm .modify_params
2606+ litellm .modify_params = True
2607+
2608+ try :
2609+ result = _bedrock_converse_messages_pt (
2610+ messages = messages ,
2611+ model = "anthropic.claude-3-5-sonnet-20240620-v1:0" ,
2612+ llm_provider = "bedrock_converse"
2613+ )
2614+
2615+ # Should have 3 messages: user, assistant (with placeholder), user
2616+ assert len (result ) == 3
2617+ assert result [0 ]["role" ] == "user"
2618+ assert result [1 ]["role" ] == "assistant"
2619+ assert result [2 ]["role" ] == "user"
2620+
2621+ # Assistant message should have placeholder text instead of empty content
2622+ assert len (result [1 ]["content" ]) == 1
2623+ assert result [1 ]["content" ][0 ]["text" ] == "Please continue."
2624+
2625+ # Test case 2: Whitespace-only content
2626+ messages = [
2627+ {"role" : "user" , "content" : "Hello" },
2628+ {"role" : "assistant" , "content" : " " }, # Whitespace-only content
2629+ {"role" : "user" , "content" : "How are you?" }
2630+ ]
2631+
2632+ result = _bedrock_converse_messages_pt (
2633+ messages = messages ,
2634+ model = "anthropic.claude-3-5-sonnet-20240620-v1:0" ,
2635+ llm_provider = "bedrock_converse"
2636+ )
2637+
2638+ # Assistant message should have placeholder text instead of whitespace
2639+ assert len (result [1 ]["content" ]) == 1
2640+ assert result [1 ]["content" ][0 ]["text" ] == "Please continue."
2641+
2642+ # Test case 3: Empty list content
2643+ messages = [
2644+ {"role" : "user" , "content" : "Hello" },
2645+ {"role" : "assistant" , "content" : [{"type" : "text" , "text" : "" }]}, # Empty text in list
2646+ {"role" : "user" , "content" : "How are you?" }
2647+ ]
2648+
2649+ result = _bedrock_converse_messages_pt (
2650+ messages = messages ,
2651+ model = "anthropic.claude-3-5-sonnet-20240620-v1:0" ,
2652+ llm_provider = "bedrock_converse"
2653+ )
2654+
2655+ # Assistant message should have placeholder text instead of empty text
2656+ assert len (result [1 ]["content" ]) == 1
2657+ assert result [1 ]["content" ][0 ]["text" ] == "Please continue."
2658+
2659+ # Test case 4: Normal content should not be affected
2660+ messages = [
2661+ {"role" : "user" , "content" : "Hello" },
2662+ {"role" : "assistant" , "content" : "I'm doing well, thank you!" }, # Normal content
2663+ {"role" : "user" , "content" : "How are you?" }
2664+ ]
2665+
2666+ result = _bedrock_converse_messages_pt (
2667+ messages = messages ,
2668+ model = "anthropic.claude-3-5-sonnet-20240620-v1:0" ,
2669+ llm_provider = "bedrock_converse"
2670+ )
2671+
2672+ # Assistant message should keep original content
2673+ assert len (result [1 ]["content" ]) == 1
2674+ assert result [1 ]["content" ][0 ]["text" ] == "I'm doing well, thank you!"
2675+
2676+ finally :
2677+ # Restore original modify_params setting
2678+ litellm .modify_params = original_modify_params
0 commit comments