|
33 | 33 | from ..models.model import Model
|
34 | 34 | from ..session.session_manager import SessionManager
|
35 | 35 | from ..telemetry.metrics import EventLoopMetrics
|
36 |
| -from ..telemetry.tracer import get_tracer |
| 36 | +from ..telemetry.tracer import get_tracer, serialize |
37 | 37 | from ..tools.registry import ToolRegistry
|
38 | 38 | from ..tools.watcher import ToolWatcher
|
39 | 39 | from ..types.content import ContentBlock, Message, Messages
|
@@ -445,27 +445,48 @@ async def structured_output_async(
|
445 | 445 | ValueError: If no conversation history or prompt is provided.
|
446 | 446 | """
|
447 | 447 | self.hooks.invoke_callbacks(BeforeInvocationEvent(agent=self))
|
448 |
| - |
449 |
| - try: |
450 |
| - if not self.messages and not prompt: |
451 |
| - raise ValueError("No conversation history or prompt provided") |
452 |
| - |
453 |
| - # Create temporary messages array if prompt is provided |
454 |
| - if prompt: |
455 |
| - content: list[ContentBlock] = [{"text": prompt}] if isinstance(prompt, str) else prompt |
456 |
| - temp_messages = self.messages + [{"role": "user", "content": content}] |
457 |
| - else: |
458 |
| - temp_messages = self.messages |
459 |
| - |
460 |
| - events = self.model.structured_output(output_model, temp_messages, system_prompt=self.system_prompt) |
461 |
| - async for event in events: |
462 |
| - if "callback" in event: |
463 |
| - self.callback_handler(**cast(dict, event["callback"])) |
464 |
| - |
465 |
| - return event["output"] |
466 |
| - |
467 |
| - finally: |
468 |
| - self.hooks.invoke_callbacks(AfterInvocationEvent(agent=self)) |
| 448 | + with self.tracer.tracer.start_as_current_span( |
| 449 | + "execute_structured_output", kind=trace_api.SpanKind.CLIENT |
| 450 | + ) as structured_output_span: |
| 451 | + try: |
| 452 | + if not self.messages and not prompt: |
| 453 | + raise ValueError("No conversation history or prompt provided") |
| 454 | + # Create temporary messages array if prompt is provided |
| 455 | + if prompt: |
| 456 | + content: list[ContentBlock] = [{"text": prompt}] if isinstance(prompt, str) else prompt |
| 457 | + temp_messages = self.messages + [{"role": "user", "content": content}] |
| 458 | + else: |
| 459 | + temp_messages = self.messages |
| 460 | + |
| 461 | + structured_output_span.set_attributes( |
| 462 | + { |
| 463 | + "gen_ai.system": "strands-agents", |
| 464 | + "gen_ai.agent.name": self.name, |
| 465 | + "gen_ai.agent.id": self.agent_id, |
| 466 | + "gen_ai.operation.name": "execute_structured_output", |
| 467 | + } |
| 468 | + ) |
| 469 | + for message in temp_messages: |
| 470 | + structured_output_span.add_event( |
| 471 | + f"gen_ai.{message['role']}.message", |
| 472 | + attributes={"role": message["role"], "content": serialize(message["content"])}, |
| 473 | + ) |
| 474 | + if self.system_prompt: |
| 475 | + structured_output_span.add_event( |
| 476 | + "gen_ai.system.message", |
| 477 | + attributes={"role": "system", "content": serialize([{"text": self.system_prompt}])}, |
| 478 | + ) |
| 479 | + events = self.model.structured_output(output_model, temp_messages, system_prompt=self.system_prompt) |
| 480 | + async for event in events: |
| 481 | + if "callback" in event: |
| 482 | + self.callback_handler(**cast(dict, event["callback"])) |
| 483 | + structured_output_span.add_event( |
| 484 | + "gen_ai.choice", attributes={"message": serialize(event["output"].model_dump())} |
| 485 | + ) |
| 486 | + return event["output"] |
| 487 | + |
| 488 | + finally: |
| 489 | + self.hooks.invoke_callbacks(AfterInvocationEvent(agent=self)) |
469 | 490 |
|
470 | 491 | async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: Any) -> AsyncIterator[Any]:
|
471 | 492 | """Process a natural language prompt and yield events as an async iterator.
|
|
0 commit comments