Skip to content

Python: fix(core): start a new message when the author changes in streamed updates - #9353

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
shanto462:fix-streaming-author-message-boundary
Oct 14, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
shanto462:fix-streaming-author-message-boundary

Conversation

@shanto462

@shanto462 Md. Shalah Uddin (shanto462) commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Motivation & Context

_process_update, which combines streamed updates into messages for ChatResponse.from_updates, AgentResponse.from_updates and get_final_response(), started a new message only when the role or a non-empty message_id changed. Most chat clients do not set message_id on streaming updates, so updates from different authors were merged into one message attributed to the last author. A streamed sequential workflow agent returned one "reviewer" message with the writer's text in it, while the same non-streamed run returned two messages.

Description & Review Guide

  • What are the major changes? _process_update also starts a new message when both the update and the last message have a non-empty author_name and they differ, the same pattern as the message_id check next to it. Regression tests: two authors give two messages (for ChatResponse and AgentResponse), a chunk without an author stays in the current message, a message without an author takes the author of a later chunk instead of splitting, interleaved authors keep each run of updates with its author, and two authors that share a message_id give two messages. An orchestrations test streams SequentialBuilder(..., output_from="all").build().as_agent() and checks that get_final_response() returns one message per agent, the same as the non-streaming run.
  • What is the impact of these changes? Streamed multi-agent output keeps one message per author, matching non-streamed runs. Single-author streams, and streams where only some chunks carry author_name, do not change. All package tests pass (poe test -A).
  • What do you want reviewers to focus on? The rule only splits when both names are non-empty, so a client that sets author_name on the first chunk only, or a message that gets its author from a later chunk, still forms one message. Two intended behavior changes: interleaved updates from parallel agents (for example a streamed concurrent workflow) now give one message per run of updates from the same author instead of one merged message attributed to the last author, and two authors that share a message_id now give two messages with that id instead of one.

Related Issue

Fixes #9352

No other open PR covers this issue.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: issue analysis, implementation, tests, and this PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused implementation matches the documented behavior and includes comprehensive regression coverage.

0 open findings

What changed in this PR

Fixes streamed multi-agent updates being merged across author changes.

Changes:

  • Splits messages when non-empty author names differ.
  • Adds regression coverage for author transitions and shared message IDs.
File Description
python/​packages/​core/​agent_framework/​_types.py Detects author changes during update aggregation.
python/​packages/​core/​tests/​core/​test_types.py Tests author-based message boundaries and edge cases.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed head 76f3dcb21543302a5727f766b56e7df43f11e0d0 against base 1b9879c58ac950ef235471209b4c5cb402972bab.

I checked the existing review and exercised the public workflow path with two deterministic agents through SequentialBuilder(..., output_from="all").build().as_agent(). On the base, get_final_response() combines both replies into one message attributed to the reviewer; on this head it matches the non-streaming writer/reviewer messages, including a continuation chunk without an author.

I also checked function-call fragments: an authorless continuation still completes the first author's arguments, while a second author using the same call ID starts a separate call. The base concatenates the two argument objects into invalid JSON; this head keeps {"a":1} and {"b":2} in their respective messages. Usage-only updates from the current author retain the aggregated token counts and response ID without adding a message. This supports placing the boundary check before content merging.

Please consider adding the public sequential-workflow case as a regression test alongside the direct aggregation tests: it also covers the workflow adapter's author propagation and stream finalizer.

Offline validation on macOS arm64/Python 3.14.7: test_types.py, test_sequential.py, test_workflow_agent.py, and test_workflow_agent_intermediate.py passed (528 tests; one experimental-feature warning). Ruff 0.16.10 lint and format checks passed on both changed files. The full workspace, provider integrations, and type-checker suites were not run. I found no correctness blocker in the behavior exercised here.

@shanto462

Copy link
Copy Markdown
Contributor Author

Bicheng (Kenneth) (@BichengWang) Thanks for the thorough check. Added the public sequential-workflow streaming case as a regression test in 877a792 (test_sequential_as_agent_streaming_keeps_one_message_per_agent); it fails on the base and passes here.

Merged via the queue into microsoft:main with commit ea6aa0a Oct 14, 2026
46 checks passed
@shanto462
Md. Shalah Uddin (shanto462) deleted the fix-streaming-author-message-boundary branch October 19, 2026 09:42

This branch was previously deployed

1 inactive deployment
github-app-auth — 877a792d Deployed Oct 14, 2026 by shanto462 via add_label #25269
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Streamed updates from different authors are merged into one message

4 participants