@@ -684,3 +684,174 @@ def test_serialize_vs_json_dumps():
684684 custom_result = serialize ({"text" : japanese_text })
685685 assert japanese_text in custom_result
686686 assert "\\ u" not in custom_result
687+
688+
689+ def test_get_event_name_for_message_user ():
690+ """Test getting event name for regular user message."""
691+ tracer = Tracer ()
692+ message = {"role" : "user" , "content" : [{"text" : "Hello" }]}
693+
694+ event_name = tracer ._get_event_name_for_message (message )
695+
696+ assert event_name == "gen_ai.user.message"
697+
698+
699+ def test_get_event_name_for_message_assistant ():
700+ """Test getting event name for regular assistant message."""
701+ tracer = Tracer ()
702+ message = {"role" : "assistant" , "content" : [{"text" : "Hello" }]}
703+
704+ event_name = tracer ._get_event_name_for_message (message )
705+
706+ assert event_name == "gen_ai.assistant.message"
707+
708+
709+ def test_get_event_name_for_message_with_tool_result ():
710+ """Test getting event name for message containing tool result."""
711+ tracer = Tracer ()
712+ message = {
713+ "role" : "user" ,
714+ "content" : [{"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "Tool response" }]}}],
715+ }
716+
717+ event_name = tracer ._get_event_name_for_message (message )
718+
719+ assert event_name == "gen_ai.tool.message"
720+
721+
722+ def test_get_event_name_for_message_with_mixed_content ():
723+ """Test getting event name for message with both text and tool result."""
724+ tracer = Tracer ()
725+ message = {
726+ "role" : "user" ,
727+ "content" : [
728+ {"text" : "Here are the results:" },
729+ {"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "Tool response" }]}},
730+ ],
731+ }
732+
733+ event_name = tracer ._get_event_name_for_message (message )
734+
735+ # Should be tool message since it contains a tool result
736+ assert event_name == "gen_ai.tool.message"
737+
738+
739+ def test_get_event_name_for_message_empty_content ():
740+ """Test getting event name for message with empty content."""
741+ tracer = Tracer ()
742+ message = {"role" : "user" , "content" : []}
743+
744+ event_name = tracer ._get_event_name_for_message (message )
745+
746+ assert event_name == "gen_ai.user.message"
747+
748+
749+ def test_get_event_name_for_message_no_content ():
750+ """Test getting event name for message with no content key."""
751+ tracer = Tracer ()
752+ message = {"role" : "assistant" }
753+
754+ event_name = tracer ._get_event_name_for_message (message )
755+
756+ assert event_name == "gen_ai.assistant.message"
757+
758+
759+ def test_get_event_name_for_message_multiple_tool_results ():
760+ """Test getting event name for message with multiple tool results."""
761+ tracer = Tracer ()
762+ message = {
763+ "role" : "user" ,
764+ "content" : [
765+ {"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "First tool" }]}},
766+ {"toolResult" : {"toolUseId" : "456" , "status" : "success" , "content" : [{"text" : "Second tool" }]}},
767+ ],
768+ }
769+
770+ event_name = tracer ._get_event_name_for_message (message )
771+
772+ assert event_name == "gen_ai.tool.message"
773+
774+
775+ def test_start_model_invoke_span_with_tool_result_message (mock_tracer ):
776+ """Test that start_model_invoke_span correctly labels tool result messages."""
777+ with mock .patch ("strands.telemetry.tracer.trace_api.get_tracer" , return_value = mock_tracer ):
778+ tracer = Tracer ()
779+ tracer .tracer = mock_tracer
780+
781+ mock_span = mock .MagicMock ()
782+ mock_tracer .start_span .return_value = mock_span
783+
784+ # Message that contains a tool result
785+ messages = [
786+ {
787+ "role" : "user" ,
788+ "content" : [
789+ {"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "Weather is sunny" }]}}
790+ ],
791+ }
792+ ]
793+
794+ span = tracer .start_model_invoke_span (messages = messages , model_id = "test-model" )
795+
796+ # Should use gen_ai.tool.message event name instead of gen_ai.user.message
797+ mock_span .add_event .assert_called_with (
798+ "gen_ai.tool.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])}
799+ )
800+ assert span is not None
801+
802+
803+ def test_start_agent_span_with_tool_result_message (mock_tracer ):
804+ """Test that start_agent_span correctly labels tool result messages."""
805+ with mock .patch ("strands.telemetry.tracer.trace_api.get_tracer" , return_value = mock_tracer ):
806+ tracer = Tracer ()
807+ tracer .tracer = mock_tracer
808+
809+ mock_span = mock .MagicMock ()
810+ mock_tracer .start_span .return_value = mock_span
811+
812+ # Message that contains a tool result
813+ messages = [
814+ {
815+ "role" : "user" ,
816+ "content" : [
817+ {"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "Weather is sunny" }]}}
818+ ],
819+ }
820+ ]
821+
822+ span = tracer .start_agent_span (messages = messages , agent_name = "WeatherAgent" , model_id = "test-model" )
823+
824+ # Should use gen_ai.tool.message event name instead of gen_ai.user.message
825+ mock_span .add_event .assert_called_with (
826+ "gen_ai.tool.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])}
827+ )
828+ assert span is not None
829+
830+
831+ def test_start_event_loop_cycle_span_with_tool_result_message (mock_tracer ):
832+ """Test that start_event_loop_cycle_span correctly labels tool result messages."""
833+ with mock .patch ("strands.telemetry.tracer.trace_api.get_tracer" , return_value = mock_tracer ):
834+ tracer = Tracer ()
835+ tracer .tracer = mock_tracer
836+
837+ mock_span = mock .MagicMock ()
838+ mock_tracer .start_span .return_value = mock_span
839+
840+ # Message that contains a tool result
841+ messages = [
842+ {
843+ "role" : "user" ,
844+ "content" : [
845+ {"toolResult" : {"toolUseId" : "123" , "status" : "success" , "content" : [{"text" : "Weather is sunny" }]}}
846+ ],
847+ }
848+ ]
849+
850+ event_loop_kwargs = {"event_loop_cycle_id" : "cycle-123" }
851+ span = tracer .start_event_loop_cycle_span (event_loop_kwargs , messages = messages )
852+
853+ # Should use gen_ai.tool.message event name instead of gen_ai.user.message
854+ mock_span .add_event .assert_called_with (
855+ "gen_ai.tool.message" , attributes = {"content" : json .dumps (messages [0 ]["content" ])}
856+ )
857+ assert span is not None
0 commit comments