From 9895c537c93ecd7ee0d2599c68244d3b191f328d Mon Sep 17 00:00:00 2001 From: Benke Qu Date: Tue, 16 Jun 2026 10:03:13 -0700 Subject: [PATCH 1/3] Python: fix: concurrent_agents sample treats output as list[Message] but it is AgentResponse The default ConcurrentBuilder aggregator yields AgentResponse, not list[Message]. The sample incorrectly cast the output to list[Message] and iterated it directly. Fix by checking isinstance(output, AgentResponse) and iterating output.messages instead. --- .../03-workflows/orchestrations/concurrent_agents.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/python/samples/03-workflows/orchestrations/concurrent_agents.py b/python/samples/03-workflows/orchestrations/concurrent_agents.py index 7e90ff1bda..555f162917 100644 --- a/python/samples/03-workflows/orchestrations/concurrent_agents.py +++ b/python/samples/03-workflows/orchestrations/concurrent_agents.py @@ -2,9 +2,8 @@ import asyncio import os -from typing import Any -from agent_framework import Agent, Message +from agent_framework import Agent, AgentResponse, Message from agent_framework.foundry import FoundryChatClient from agent_framework.orchestrations import ConcurrentBuilder from azure.identity import AzureCliCredential @@ -80,8 +79,10 @@ async def main() -> None: if outputs: print("===== Final Aggregated Conversation (messages) =====") for output in outputs: - messages: list[Message] | Any = output - for i, msg in enumerate(messages, start=1): + if not isinstance(output, AgentResponse): + print(f"[WARNING] Unexpected output type: {type(output).__name__}, skipping.") + continue + for i, msg in enumerate(output.messages, start=1): name = msg.author_name if msg.author_name else "user" print(f"{'-' * 60}\n\n{i:02d} [{name}]:\n{msg.text}") From 615a81d38fd5574a54a98c20d77568180c3a4bf1 Mon Sep 17 00:00:00 2001 From: Benke Qu Date: Thu, 9 Jul 2026 10:49:38 -0700 Subject: [PATCH 2/3] fix: remove warning print per review feedback --- python/samples/03-workflows/orchestrations/concurrent_agents.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/samples/03-workflows/orchestrations/concurrent_agents.py b/python/samples/03-workflows/orchestrations/concurrent_agents.py index 555f162917..657cc72327 100644 --- a/python/samples/03-workflows/orchestrations/concurrent_agents.py +++ b/python/samples/03-workflows/orchestrations/concurrent_agents.py @@ -80,7 +80,6 @@ async def main() -> None: print("===== Final Aggregated Conversation (messages) =====") for output in outputs: if not isinstance(output, AgentResponse): - print(f"[WARNING] Unexpected output type: {type(output).__name__}, skipping.") continue for i, msg in enumerate(output.messages, start=1): name = msg.author_name if msg.author_name else "user" From b861dff3026985e45da8e2bda3243e6c7e1159a7 Mon Sep 17 00:00:00 2001 From: Benke Qu Date: Tue, 14 Jul 2026 15:53:48 -0700 Subject: [PATCH 3/3] fix: address review - remove unused Message import, update docs and sample output - Remove unused Message import - Update docstring: default aggregator yields AgentResponse objects, not list[Message] - Fix sample output: remove user prompt entry (aggregator returns only assistant messages) - Renumber sample output entries (researcher=01, marketer=02, legal=03) --- .../orchestrations/concurrent_agents.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/python/samples/03-workflows/orchestrations/concurrent_agents.py b/python/samples/03-workflows/orchestrations/concurrent_agents.py index 657cc72327..24cec1d50a 100644 --- a/python/samples/03-workflows/orchestrations/concurrent_agents.py +++ b/python/samples/03-workflows/orchestrations/concurrent_agents.py @@ -3,7 +3,7 @@ import asyncio import os -from agent_framework import Agent, AgentResponse, Message +from agent_framework import Agent, AgentResponse from agent_framework.foundry import FoundryChatClient from agent_framework.orchestrations import ConcurrentBuilder from azure.identity import AzureCliCredential @@ -17,8 +17,8 @@ Build a high-level concurrent workflow using ConcurrentBuilder and three domain agents. The default dispatcher fans out the same user prompt to all agents in parallel. -The default aggregator fans in their results and yields output containing -a list[Message] representing the concatenated conversations from all agents. +The default aggregator fans in their results and yields AgentResponse objects +containing only the participants' assistant messages. Demonstrates: - Minimal wiring with ConcurrentBuilder(participants=[...]).build() @@ -91,11 +91,7 @@ async def main() -> None: ===== Final Aggregated Conversation (messages) ===== ------------------------------------------------------------ - 01 [user]: - We are launching a new budget-friendly electric bike for urban commuters. - ------------------------------------------------------------ - - 02 [researcher]: + 01 [researcher]: **Insights:** - **Target Demographic:** Urban commuters seeking affordable, eco-friendly transport; @@ -115,7 +111,7 @@ async def main() -> None: ... ------------------------------------------------------------ - 03 [marketer]: + 02 [marketer]: **Value Proposition:** "Empowering your city commute: Our new electric bike combines affordability, reliability, and sustainable design—helping you conquer urban journeys without breaking the bank." @@ -126,7 +122,7 @@ async def main() -> None: ... ------------------------------------------------------------ - 04 [legal]: + 03 [legal]: **Constraints, Disclaimers, & Policy Concerns for Launching a Budget-Friendly Electric Bike for Urban Commuters:** **1. Regulatory Compliance**