Skip to content

[BREAKING] Python: Fix workflow as agent streaming output#3649

Merged
TaoChenOSU merged 17 commits intomicrosoft:mainfrom
TaoChenOSU:taochen/python-fix-workflow-as-agent-streaming-output
Feb 5, 2026
Merged

[BREAKING] Python: Fix workflow as agent streaming output#3649
TaoChenOSU merged 17 commits intomicrosoft:mainfrom
TaoChenOSU:taochen/python-fix-workflow-as-agent-streaming-output

Conversation

@TaoChenOSU
Copy link
Contributor

@TaoChenOSU TaoChenOSU commented Feb 3, 2026

Motivation and Context

Closes #3126

Description

  1. [BREAKING] Remove AgentRunEvent and AgentRunUpdateEvent. Replace with WorkflowOutputEvent.
  2. [BREAKING] The built-in AgentExecutor will always emit WorkflowOutputEvent carrying either AgentReponse or AgentResponseUpdate when they become available. The output_response flag is removed.
  3. Add with_output_from to allow developers to configure which executors in the workflow can surface WorkflowOutputEvents.
  4. [BREAKING] The built-in WorkflowAgent for using workflow as an agent now runs the workflow in non-streaming mode if it's invoked via run. Previously, the underlying workflow would run in streaming mode regardless of if it's invoked via run or run_stream.
  5. Sample clean up.

With the changes above, the workflow as an agent will have the following pattern:

  1. A workflow can emit any number of WorkflowOutputEvents. WorkflowOutputEvents are considered as the outputs of a workflow.
  2. When a workflow is used as an agent, outputs of the workflow will be considered as the outputs of the agent. Thus, data in WorkflowOutputEvents will be converted to AgentResponse or AgentResponseUpdate.
  3. Developers can control which executors/agents can emit WorkflowOutputEvents. It's implemented as a simple filter.
  4. If the agent is invoked in streaming mode, the following will happen depending on the data carried in the WorkflowOutputEvent:
    a. AgentResponseUpdate will be directly yielded without modification.
    b. AgentResponse will be converted to an AgentResponseUpdate by extracting contents from messages, dropping message IDs. The original response is preserved in raw_representation.
    c. ChatMessage will be converted to an AgentResponseUpdate by extracting contents. The original message is preserved in raw_representation.
    d. A list of ChatMessage will be converted to multiple AgentResponseUpdate, one per message.
    c. Any other data type will be converted to Content of type text and put into an AgentResponseUpdate.
  5. If the agent is invoked in non-streaming mode, the following will happen depending on the data carried in the WorkflowOutputEvent:
    a. AgentResponseUpdate will result in an exception.
    b. AgentResponse will be directly returned without modification.
    c. A single ChatMessage or a list of ChatMessages will be returned in an AgentResponse. The original messages are preserved in raw_representation.
    d. Any other data type will be converted to Content of type text and placed in a ChatMessage.
  6. RequestInfoEvents stay unchanged in this PR.

Note: WorkflowOutputEvents don't signal the end state of a workflow. A workflow run can emit any number of WorkflowOutputEvents (including zero). Any data the workflow generates should be considered outputs of the workflow.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@TaoChenOSU TaoChenOSU self-assigned this Feb 3, 2026
@TaoChenOSU TaoChenOSU added python workflows Related to Workflows in agent-framework labels Feb 3, 2026
@github-actions github-actions bot changed the title Fix workflow as agent streaming output Python: Fix workflow as agent streaming output Feb 3, 2026
@TaoChenOSU TaoChenOSU changed the title Python: Fix workflow as agent streaming output [BREAKING] Python: Fix workflow as agent streaming output Feb 3, 2026
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 3, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _agent.py3285483%59, 67–73, 107–108, 314–315, 324–325, 331, 333, 339–340, 425–426, 435, 442, 468, 519, 548, 607–610, 616, 622, 626–627, 630–636, 640–641, 647, 721–722, 733, 772, 793, 802, 806, 808–810, 817
   _agent_executor.py1602286%98, 146, 164–165, 216–217, 219–220, 252–254, 262–264, 274–276, 278, 282, 286, 290–291
   _concurrent.py1933084%53, 62–63, 71–72, 91–92, 97, 124, 129, 134–135, 141, 163, 173, 180, 348, 351, 379, 435, 447, 486, 488–489, 491, 503–504, 509, 531, 535
   _events.py1171289%57–58, 76, 84, 88, 178–179, 230, 255, 292, 310, 335
   _group_chat.py2913986%172, 333, 340, 367, 378–379, 385, 390, 406, 433–438, 440, 473–476, 478, 483–487, 651, 656, 670, 751, 757, 802, 822, 896–897, 931, 950, 969, 979
   _handoff.py3825785%110–111, 113, 142–143, 163–173, 175, 177, 179, 184, 284, 338, 363, 391, 399–400, 414, 463–464, 496, 543–545, 731, 738, 743, 830, 833, 842–845, 855, 860, 867, 873–876, 911, 916, 1113, 1116, 1124, 1142, 1149, 1224
   _magentic.py6209185%68–77, 82, 86–97, 262, 273, 277, 297, 358, 367, 369, 411, 428, 437–438, 440–442, 444, 455, 597, 599, 639, 689, 725–727, 729, 737–740, 744–747, 790, 817–820, 911, 917, 923, 962, 1000, 1029, 1046, 1057, 1111–1112, 1116–1118, 1142, 1163–1164, 1177, 1193, 1215, 1263–1264, 1302–1303, 1462, 1471, 1474, 1479, 1875, 1930, 1945, 1974
   _runner_context.py168696%84, 87, 383, 403, 491, 495
   _sequential.py1141487%74, 167, 185, 196, 202, 239, 241–242, 244, 256–257, 262, 284, 288
   _typing_utils.py1262877%153, 177, 256, 258–259, 268, 270, 277, 279, 299, 301, 303, 308–315, 318–319, 321–325, 327
   _validation.py151596%128, 149, 244, 325, 328
   _workflow.py2671992%89, 267–269, 271–272, 290, 294, 322, 423, 704, 746, 751, 754, 773–775, 788, 856
   _workflow_builder.py2763786%246, 522, 621, 628–629, 730, 733, 738, 740, 747, 750–754, 756, 818, 893, 896, 956–957, 1116, 1129, 1143–1150, 1152, 1155, 1157–1159, 1167
TOTAL16334193288% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3953 221 💤 0 ❌ 0 🔥 1m 7s ⏱️

@TaoChenOSU TaoChenOSU moved this to In Review in Agent Framework Feb 4, 2026
@TaoChenOSU TaoChenOSU marked this pull request as ready for review February 4, 2026 23:09
Copilot AI review requested due to automatic review settings February 4, 2026 23:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements breaking changes to fix workflow-as-agent streaming output (closes #3126). The changes consolidate output event handling by removing AgentRunEvent and AgentRunUpdateEvent in favor of WorkflowOutputEvent, introduce output executor filtering via with_output_from, and fix workflow-as-agent to properly stream agent responses.

Changes:

  • Removes AgentRunEvent and AgentRunUpdateEvent classes, consolidating on WorkflowOutputEvent for all executor outputs
  • Adds with_output_from builder method to filter which executors emit workflow outputs, with validation
  • Changes WorkflowAgent to run workflows in non-streaming mode when invoked via run() (previously always streamed)

Reviewed changes

Copilot reviewed 66 out of 68 changed files in this pull request and generated no comments.

Show a summary per file
File Description
_events.py Removes deprecated event classes
_agent_executor.py Removes output_response parameter, always yields outputs via WorkflowOutputEvent
_workflow.py Adds output executor filtering support
_workflow_builder.py Adds with_output_from method, removes deprecated add_agent
_agent.py Implements proper streaming/non-streaming mode handling for workflow-as-agent
_validation.py Adds output executor validation
Builder files Add with_intermediate_outputs to control output filtering
Sample files Updated to handle new event patterns
Test files Comprehensive updates for new behavior

@moonbox3 moonbox3 added the breaking change Introduces changes that are not backward compatible and may require updates to dependent code. label Feb 4, 2026
@TaoChenOSU TaoChenOSU enabled auto-merge February 5, 2026 00:08
@TaoChenOSU TaoChenOSU added this pull request to the merge queue Feb 5, 2026
Merged via the queue into microsoft:main with commit a971d24 Feb 5, 2026
23 checks passed
@github-project-automation github-project-automation bot moved this from In Review to Done in Agent Framework Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Introduces changes that are not backward compatible and may require updates to dependent code. python workflows Related to Workflows in agent-framework

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Workflows as agents don't stream agent responses

4 participants