diff --git a/src/strands/agent/agent.py b/src/strands/agent/agent.py index acc6a7650..5150060c6 100644 --- a/src/strands/agent/agent.py +++ b/src/strands/agent/agent.py @@ -470,16 +470,16 @@ async def structured_output_async( "gen_ai.operation.name": "execute_structured_output", } ) - for message in temp_messages: - structured_output_span.add_event( - f"gen_ai.{message['role']}.message", - attributes={"role": message["role"], "content": serialize(message["content"])}, - ) if self.system_prompt: structured_output_span.add_event( "gen_ai.system.message", attributes={"role": "system", "content": serialize([{"text": self.system_prompt}])}, ) + for message in temp_messages: + structured_output_span.add_event( + f"gen_ai.{message['role']}.message", + attributes={"role": message["role"], "content": serialize(message["content"])}, + ) events = self.model.structured_output(output_model, temp_messages, system_prompt=self.system_prompt) async for event in events: if "callback" in event: diff --git a/tests/strands/agent/test_agent.py b/tests/strands/agent/test_agent.py index 444232455..7e769c6d7 100644 --- a/tests/strands/agent/test_agent.py +++ b/tests/strands/agent/test_agent.py @@ -18,6 +18,7 @@ from strands.handlers.callback_handler import PrintingCallbackHandler, null_callback_handler from strands.models.bedrock import DEFAULT_BEDROCK_MODEL_ID, BedrockModel from strands.session.repository_session_manager import RepositorySessionManager +from strands.telemetry.tracer import serialize from strands.types.content import Messages from strands.types.exceptions import ContextWindowOverflowException, EventLoopException from strands.types.session import Session, SessionAgent, SessionMessage, SessionType @@ -1028,15 +1029,23 @@ def test_agent_structured_output(agent, system_prompt, user, agenerator): } ) - mock_span.add_event.assert_any_call( - "gen_ai.user.message", - attributes={"role": "user", "content": '[{"text": "Jane Doe is 30 years old and her email is jane@doe.com"}]'}, - ) + # ensure correct otel event messages are emitted + act_event_names = mock_span.add_event.call_args_list + exp_event_names = [ + unittest.mock.call( + "gen_ai.system.message", attributes={"role": "system", "content": serialize([{"text": system_prompt}])} + ), + unittest.mock.call( + "gen_ai.user.message", + attributes={ + "role": "user", + "content": '[{"text": "Jane Doe is 30 years old and her email is jane@doe.com"}]', + }, + ), + unittest.mock.call("gen_ai.choice", attributes={"message": json.dumps(user.model_dump())}), + ] - mock_span.add_event.assert_called_with( - "gen_ai.choice", - attributes={"message": json.dumps(user.model_dump())}, - ) + assert act_event_names == exp_event_names def test_agent_structured_output_multi_modal_input(agent, system_prompt, user, agenerator):