@@ -702,6 +702,84 @@ async def start_executor(messages: list[ChatMessage], ctx: WorkflowContext) -> N
702702 assert unique_text_count == 1 , f"Response should appear exactly once, but appeared { unique_text_count } times"
703703
704704
705+ class TestWorkflowAgentAuthorName :
706+ """Test cases for author_name enrichment in WorkflowAgent (GitHub issue #1331)."""
707+
708+ async def test_agent_run_update_event_gets_executor_id_as_author_name (self ):
709+ """Test that AgentRunUpdateEvent gets executor_id as author_name when not already set.
710+
711+ This validates the fix for GitHub issue #1331: agent responses should include
712+ identification of which agent produced them in multi-agent workflows.
713+ """
714+ # Create workflow with executor that emits AgentRunUpdateEvent without author_name
715+ executor1 = SimpleExecutor (id = "my_executor_id" , response_text = "Response" , emit_streaming = False )
716+ workflow = WorkflowBuilder ().set_start_executor (executor1 ).build ()
717+ agent = WorkflowAgent (workflow = workflow , name = "Test Agent" )
718+
719+ # Collect streaming updates
720+ updates : list [AgentRunResponseUpdate ] = []
721+ async for update in agent .run_stream ("Hello" ):
722+ updates .append (update )
723+
724+ # Verify at least one update was received
725+ assert len (updates ) >= 1
726+
727+ # Verify author_name is set to executor_id
728+ assert updates [0 ].author_name == "my_executor_id"
729+
730+ async def test_agent_run_update_event_preserves_existing_author_name (self ):
731+ """Test that existing author_name is preserved and not overwritten."""
732+
733+ class AuthorNameExecutor (Executor ):
734+ """Executor that sets author_name explicitly."""
735+
736+ @handler
737+ async def handle_message (self , message : list [ChatMessage ], ctx : WorkflowContext [list [ChatMessage ]]) -> None :
738+ # Emit update with explicit author_name
739+ update = AgentRunResponseUpdate (
740+ contents = [TextContent (text = "Response with author" )],
741+ role = Role .ASSISTANT ,
742+ author_name = "custom_author_name" , # Explicitly set
743+ message_id = str (uuid .uuid4 ()),
744+ )
745+ await ctx .add_event (AgentRunUpdateEvent (executor_id = self .id , data = update ))
746+
747+ executor = AuthorNameExecutor (id = "executor_id" )
748+ workflow = WorkflowBuilder ().set_start_executor (executor ).build ()
749+ agent = WorkflowAgent (workflow = workflow , name = "Test Agent" )
750+
751+ # Collect streaming updates
752+ updates : list [AgentRunResponseUpdate ] = []
753+ async for update in agent .run_stream ("Hello" ):
754+ updates .append (update )
755+
756+ # Verify author_name is preserved (not overwritten with executor_id)
757+ assert len (updates ) >= 1
758+ assert updates [0 ].author_name == "custom_author_name"
759+
760+ async def test_multiple_executors_have_distinct_author_names (self ):
761+ """Test that multiple executors in a workflow have their own author_name."""
762+ # Create workflow with two executors
763+ executor1 = SimpleExecutor (id = "first_executor" , response_text = "First" , emit_streaming = False )
764+ executor2 = SimpleExecutor (id = "second_executor" , response_text = "Second" , emit_streaming = False )
765+
766+ workflow = WorkflowBuilder ().set_start_executor (executor1 ).add_edge (executor1 , executor2 ).build ()
767+ agent = WorkflowAgent (workflow = workflow , name = "Multi-Executor Agent" )
768+
769+ # Collect streaming updates
770+ updates : list [AgentRunResponseUpdate ] = []
771+ async for update in agent .run_stream ("Hello" ):
772+ updates .append (update )
773+
774+ # Should have updates from both executors
775+ assert len (updates ) >= 2
776+
777+ # Verify each update has the correct author_name matching its executor
778+ author_names = [u .author_name for u in updates ]
779+ assert "first_executor" in author_names
780+ assert "second_executor" in author_names
781+
782+
705783class TestWorkflowAgentMergeUpdates :
706784 """Test cases specifically for the WorkflowAgent.merge_updates static method."""
707785
0 commit comments