@@ -120,10 +120,6 @@ def _run_patch_behaviour_tests(self):
120120 self ._test_unpatched_botocore_propagator ()
121121 self ._test_unpatched_gevent_instrumentation ()
122122 self ._test_unpatched_starlette_instrumentation ()
123- # TODO: remove these tests once we bump botocore instrumentation version to 0.56b0
124- # Bedrock Runtime tests
125- self ._test_unpatched_converse_stream_wrapper ()
126- self ._test_unpatched_extract_tool_calls ()
127123
128124 # Apply patches
129125 apply_instrumentation_patches ()
@@ -222,6 +218,17 @@ def _test_unpatched_botocore_instrumentation(self):
222218 # DynamoDB
223219 self .assertTrue ("dynamodb" in _KNOWN_EXTENSIONS , "Upstream has removed a DynamoDB extension" )
224220
221+ # Bedrock Runtime tests
222+ # TODO: remove these tests once we bump botocore instrumentation version to 0.56b0
223+ self ._test_unpatched_converse_stream_wrapper ()
224+ self ._test_unpatched_extract_tool_calls ()
225+
226+ # TODO: remove these tests once we bump botocore instrumentation version to 0.60b0
227+ self ._test_unpatched_process_anthropic_claude_chunk ({"location" : "Seattle" }, {"location" : "Seattle" })
228+ self ._test_unpatched_process_anthropic_claude_chunk (None , None )
229+ self ._test_unpatched_process_anthropic_claude_chunk ({}, {})
230+
231+
225232 def _test_unpatched_gevent_instrumentation (self ):
226233 self .assertFalse (gevent .monkey .is_module_patched ("os" ), "gevent os module has been patched" )
227234 self .assertFalse (gevent .monkey .is_module_patched ("thread" ), "gevent thread module has been patched" )
@@ -267,10 +274,14 @@ def _test_patched_botocore_instrumentation(self):
267274 # Bedrock Agent Operation
268275 self ._test_patched_bedrock_agent_instrumentation ()
269276
270- # TODO: remove these tests once we bump botocore instrumentation version to 0.56b0
271277 # Bedrock Runtime
278+ # TODO: remove these tests once we bump botocore instrumentation version to 0.56b0
272279 self ._test_patched_converse_stream_wrapper ()
273280 self ._test_patched_extract_tool_calls ()
281+ # TODO: remove these tests once we bump botocore instrumentation version to 0.60b0
282+ self ._test_patched_process_anthropic_claude_chunk ({"location" : "Seattle" }, {"location" : "Seattle" })
283+ self ._test_patched_process_anthropic_claude_chunk (None , None )
284+ self ._test_patched_process_anthropic_claude_chunk ({}, {})
274285
275286 # Bedrock Agent Runtime
276287 self .assertTrue ("bedrock-agent-runtime" in _KNOWN_EXTENSIONS )
@@ -679,6 +690,73 @@ def _test_patched_extract_tool_calls(self):
679690 result = bedrock_utils .extract_tool_calls (message_with_string_content , True )
680691 self .assertIsNone (result )
681692
693+ def _test_patched_process_anthropic_claude_chunk (self , input_value : Dict [str , str ], expected_output : Dict [str , str ]):
694+ self ._test_process_anthropic_claude_chunk (input_value , expected_output , False )
695+
696+ def _test_unpatched_process_anthropic_claude_chunk (self , input_value : Dict [str , str ], expected_output : Dict [str , str ]):
697+ self ._test_process_anthropic_claude_chunk (input_value , expected_output , True )
698+
699+ def _test_process_anthropic_claude_chunk (self , input_value : Dict [str , str ], expected_output : Dict [str , str ], expect_exception : bool ):
700+ """Test that _process_anthropic_claude_chunk handles various tool_use input formats."""
701+ wrapper = bedrock_utils .InvokeModelWithResponseStreamWrapper (
702+ stream = MagicMock (),
703+ stream_done_callback = MagicMock ,
704+ stream_error_callback = MagicMock ,
705+ model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0" ,
706+ )
707+
708+ # Simulate message_start
709+ wrapper ._process_anthropic_claude_chunk (
710+ {
711+ "type" : "message_start" ,
712+ "message" : {
713+ "role" : "assistant" ,
714+ "content" : [],
715+ },
716+ }
717+ )
718+
719+ # Simulate content_block_start with specified input
720+ content_block = {
721+ "type" : "tool_use" ,
722+ "id" : "test_id" ,
723+ "name" : "test_tool" ,
724+ }
725+ if input_value is not None :
726+ content_block ["input" ] = input_value
727+
728+ wrapper ._process_anthropic_claude_chunk (
729+ {
730+ "type" : "content_block_start" ,
731+ "index" : 0 ,
732+ "content_block" : content_block ,
733+ }
734+ )
735+
736+ # Simulate content_block_stop
737+ try :
738+ wrapper ._process_anthropic_claude_chunk (
739+ {"type" : "content_block_stop" , "index" : 0 }
740+ )
741+ except TypeError :
742+ if expect_exception :
743+ return
744+ else :
745+ raise
746+
747+ # Verify the message content
748+ self .assertEqual (len (wrapper ._message ["content" ]), 1 )
749+ tool_block = wrapper ._message ["content" ][0 ]
750+ self .assertEqual (tool_block ["type" ], "tool_use" )
751+ self .assertEqual (tool_block ["id" ], "test_id" )
752+ self .assertEqual (tool_block ["name" ], "test_tool" )
753+
754+ if expected_output is not None :
755+ self .assertEqual (tool_block ["input" ], expected_output )
756+ self .assertIsInstance (tool_block ["input" ], dict )
757+ else :
758+ self .assertNotIn ("input" , tool_block )
759+
682760 def _test_patched_bedrock_agent_instrumentation (self ):
683761 """For bedrock-agent service, both extract_attributes and on_success provides attributes,
684762 the attributes depend on the API being invoked."""
0 commit comments