@@ -361,14 +361,21 @@ def tool_names(self) -> list[str]:
361361 all_tools = self .tool_registry .get_all_tools_config ()
362362 return list (all_tools .keys ())
363363
364- def __call__ (self , prompt : Union [ str , list [ContentBlock ]] , ** kwargs : Any ) -> AgentResult :
364+ def __call__ (self , prompt : str | list [ContentBlock ] | Messages | None = None , ** kwargs : Any ) -> AgentResult :
365365 """Process a natural language prompt through the agent's event loop.
366366
367- This method implements the conversational interface (e.g., `agent("hello!")`). It adds the user's prompt to
368- the conversation history, processes it through the model, executes any tool calls, and returns the final result.
367+ This method implements the conversational interface with multiple input patterns:
368+ - String input: `agent("hello!")`
369+ - ContentBlock list: `agent([{"text": "hello"}, {"image": {...}}])`
370+ - Message list: `agent([{"role": "user", "content": [{"text": "hello"}]}])`
371+ - No input: `agent()` - uses existing conversation history
369372
370373 Args:
371- prompt: User input as text or list of ContentBlock objects for multi-modal content.
374+ prompt: User input in various formats:
375+ - str: Simple text input
376+ - list[ContentBlock]: Multi-modal content blocks
377+ - list[Message]: Complete messages with roles
378+ - None: Use existing conversation history
372379 **kwargs: Additional parameters to pass through the event loop.
373380
374381 Returns:
@@ -387,14 +394,23 @@ def execute() -> AgentResult:
387394 future = executor .submit (execute )
388395 return future .result ()
389396
390- async def invoke_async (self , prompt : Union [str , list [ContentBlock ]], ** kwargs : Any ) -> AgentResult :
397+ async def invoke_async (
398+ self , prompt : str | list [ContentBlock ] | Messages | None = None , ** kwargs : Any
399+ ) -> AgentResult :
391400 """Process a natural language prompt through the agent's event loop.
392401
393- This method implements the conversational interface (e.g., `agent("hello!")`). It adds the user's prompt to
394- the conversation history, processes it through the model, executes any tool calls, and returns the final result.
402+ This method implements the conversational interface with multiple input patterns:
403+ - String input: Simple text input
404+ - ContentBlock list: Multi-modal content blocks
405+ - Message list: Complete messages with roles
406+ - No input: Use existing conversation history
395407
396408 Args:
397- prompt: User input as text or list of ContentBlock objects for multi-modal content.
409+ prompt: User input in various formats:
410+ - str: Simple text input
411+ - list[ContentBlock]: Multi-modal content blocks
412+ - list[Message]: Complete messages with roles
413+ - None: Use existing conversation history
398414 **kwargs: Additional parameters to pass through the event loop.
399415
400416 Returns:
@@ -411,7 +427,7 @@ async def invoke_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
411427
412428 return cast (AgentResult , event ["result" ])
413429
414- def structured_output (self , output_model : Type [T ], prompt : Optional [ Union [ str , list [ContentBlock ]]] = None ) -> T :
430+ def structured_output (self , output_model : Type [T ], prompt : str | list [ContentBlock ] | Messages | None = None ) -> T :
415431 """This method allows you to get structured output from the agent.
416432
417433 If you pass in a prompt, it will be used temporarily without adding it to the conversation history.
@@ -423,7 +439,11 @@ def structured_output(self, output_model: Type[T], prompt: Optional[Union[str, l
423439 Args:
424440 output_model: The output model (a JSON schema written as a Pydantic BaseModel)
425441 that the agent will use when responding.
426- prompt: The prompt to use for the agent (will not be added to conversation history).
442+ prompt: The prompt to use for the agent in various formats:
443+ - str: Simple text input
444+ - list[ContentBlock]: Multi-modal content blocks
445+ - list[Message]: Complete messages with roles
446+ - None: Use existing conversation history
427447
428448 Raises:
429449 ValueError: If no conversation history or prompt is provided.
@@ -437,7 +457,7 @@ def execute() -> T:
437457 return future .result ()
438458
439459 async def structured_output_async (
440- self , output_model : Type [T ], prompt : Optional [ Union [ str , list [ContentBlock ]]] = None
460+ self , output_model : Type [T ], prompt : str | list [ContentBlock ] | Messages | None = None
441461 ) -> T :
442462 """This method allows you to get structured output from the agent.
443463
@@ -462,12 +482,8 @@ async def structured_output_async(
462482 try :
463483 if not self .messages and not prompt :
464484 raise ValueError ("No conversation history or prompt provided" )
465- # Create temporary messages array if prompt is provided
466- if prompt :
467- content : list [ContentBlock ] = [{"text" : prompt }] if isinstance (prompt , str ) else prompt
468- temp_messages = self .messages + [{"role" : "user" , "content" : content }]
469- else :
470- temp_messages = self .messages
485+
486+ temp_messages : Messages = self .messages + self ._convert_prompt_to_messages (prompt )
471487
472488 structured_output_span .set_attributes (
473489 {
@@ -499,16 +515,25 @@ async def structured_output_async(
499515 finally :
500516 self .hooks .invoke_callbacks (AfterInvocationEvent (agent = self ))
501517
502- async def stream_async (self , prompt : Union [str , list [ContentBlock ]], ** kwargs : Any ) -> AsyncIterator [Any ]:
518+ async def stream_async (
519+ self ,
520+ prompt : str | list [ContentBlock ] | Messages | None = None ,
521+ ** kwargs : Any ,
522+ ) -> AsyncIterator [Any ]:
503523 """Process a natural language prompt and yield events as an async iterator.
504524
505- This method provides an asynchronous interface for streaming agent events, allowing
506- consumers to process stream events programmatically through an async iterator pattern
507- rather than callback functions. This is particularly useful for web servers and other
508- async environments.
525+ This method provides an asynchronous interface for streaming agent events with multiple input patterns:
526+ - String input: Simple text input
527+ - ContentBlock list: Multi-modal content blocks
528+ - Message list: Complete messages with roles
529+ - No input: Use existing conversation history
509530
510531 Args:
511- prompt: User input as text or list of ContentBlock objects for multi-modal content.
532+ prompt: User input in various formats:
533+ - str: Simple text input
534+ - list[ContentBlock]: Multi-modal content blocks
535+ - list[Message]: Complete messages with roles
536+ - None: Use existing conversation history
512537 **kwargs: Additional parameters to pass to the event loop.
513538
514539 Yields:
@@ -532,13 +557,15 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
532557 """
533558 callback_handler = kwargs .get ("callback_handler" , self .callback_handler )
534559
535- content : list [ContentBlock ] = [{"text" : prompt }] if isinstance (prompt , str ) else prompt
536- message : Message = {"role" : "user" , "content" : content }
560+ # Process input and get message to add (if any)
561+ messages = self ._convert_prompt_to_messages (prompt )
562+
563+ self .trace_span = self ._start_agent_trace_span (messages )
537564
538- self .trace_span = self ._start_agent_trace_span (message )
539565 with trace_api .use_span (self .trace_span ):
540566 try :
541- events = self ._run_loop (message , invocation_state = kwargs )
567+ events = self ._run_loop (messages , invocation_state = kwargs )
568+
542569 async for event in events :
543570 if "callback" in event :
544571 callback_handler (** event ["callback" ])
@@ -555,12 +582,12 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
555582 raise
556583
557584 async def _run_loop (
558- self , message : Message , invocation_state : dict [str , Any ]
585+ self , messages : Messages , invocation_state : dict [str , Any ]
559586 ) -> AsyncGenerator [dict [str , Any ], None ]:
560587 """Execute the agent's event loop with the given message and parameters.
561588
562589 Args:
563- message : The user message to add to the conversation.
590+ messages : The input messages to add to the conversation.
564591 invocation_state: Additional parameters to pass to the event loop.
565592
566593 Yields:
@@ -571,7 +598,8 @@ async def _run_loop(
571598 try :
572599 yield {"callback" : {"init_event_loop" : True , ** invocation_state }}
573600
574- self ._append_message (message )
601+ for message in messages :
602+ self ._append_message (message )
575603
576604 # Execute the event loop cycle with retry logic for context limits
577605 events = self ._execute_event_loop_cycle (invocation_state )
@@ -629,6 +657,34 @@ async def _execute_event_loop_cycle(self, invocation_state: dict[str, Any]) -> A
629657 async for event in events :
630658 yield event
631659
660+ def _convert_prompt_to_messages (self , prompt : str | list [ContentBlock ] | Messages | None ) -> Messages :
661+ messages : Messages | None = None
662+ if prompt is not None :
663+ if isinstance (prompt , str ):
664+ # String input - convert to user message
665+ messages = [{"role" : "user" , "content" : [{"text" : prompt }]}]
666+ elif isinstance (prompt , list ):
667+ if len (prompt ) == 0 :
668+ # Empty list
669+ messages = []
670+ # Check if all item in input list are dictionaries
671+ elif all (isinstance (item , dict ) for item in prompt ):
672+ # Check if all items are messages
673+ if all (all (key in item for key in Message .__annotations__ .keys ()) for item in prompt ):
674+ # Messages input - add all messages to conversation
675+ messages = cast (Messages , prompt )
676+
677+ # Check if all items are content blocks
678+ elif all (any (key in ContentBlock .__annotations__ .keys () for key in item ) for item in prompt ):
679+ # Treat as List[ContentBlock] input - convert to user message
680+ # This allows invalid structures to be passed through to the model
681+ messages = [{"role" : "user" , "content" : cast (list [ContentBlock ], prompt )}]
682+ else :
683+ messages = []
684+ if messages is None :
685+ raise ValueError ("Input prompt must be of type: `str | list[Contentblock] | Messages | None`." )
686+ return messages
687+
632688 def _record_tool_execution (
633689 self ,
634690 tool : ToolUse ,
@@ -694,15 +750,15 @@ def _record_tool_execution(
694750 self ._append_message (tool_result_msg )
695751 self ._append_message (assistant_msg )
696752
697- def _start_agent_trace_span (self , message : Message ) -> trace_api .Span :
753+ def _start_agent_trace_span (self , messages : Messages ) -> trace_api .Span :
698754 """Starts a trace span for the agent.
699755
700756 Args:
701- message : The user message .
757+ messages : The input messages .
702758 """
703759 model_id = self .model .config .get ("model_id" ) if hasattr (self .model , "config" ) else None
704760 return self .tracer .start_agent_span (
705- message = message ,
761+ messages = messages ,
706762 agent_name = self .name ,
707763 model_id = model_id ,
708764 tools = self .tool_names ,
0 commit comments