.NET: Refactor Workflows MessageMerger to preserve message order and structure#6826
.NET: Refactor Workflows MessageMerger to preserve message order and structure#6826marcominerva wants to merge 9 commits into
Conversation
Refactored MessageMerger to delegate update grouping and merging to M.E.AI, preserving the correct order and structure of assistant messages, especially for reasoning content without message IDs. Removed per-message bucketing and CreatedAt-based sorting. Added tests to verify message order and correct merging of reasoning and text updates.
There was a problem hiding this comment.
Pull request overview
This PR refactors the .NET MessageMerger in Microsoft.Agents.AI.Workflows to preserve assistant message order/structure by delegating update grouping and coalescing to Microsoft.Extensions.AI’s ToAgentResponse, addressing the reasoning-vs-text ordering/structure discrepancy reported in #6329.
Changes:
- Refactored
MessageMergerto maintain a single ordered update list per response and rely onToAgentResponsefor message reconstruction (removing per-message bucketing and CreatedAt-based sorting). - Simplified response merging logic and handling of id-less (“dangling”) updates.
- Added unit tests to validate ordering when reasoning lacks
CreatedAt, and merging reasoning + text into a single assistant message when reasoning updates lackMessageId.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| dotnet/src/Microsoft.Agents.AI.Workflows/MessageMerger.cs | Refactors merge state to preserve streaming/arrival order and delegate message grouping to ToAgentResponse. |
| dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/MessageMergerTests.cs | Adds tests covering ordering and reasoning/text merge behavior for id-less reasoning updates. |
…timestamps during merging.
Removed logic for tracking unique creation times and now always assign DateTimeOffset.UtcNow to the merged response's CreatedAt property. This simplifies timestamp handling during message merging.
|
Hi @rogerbarreto! I'm just asking to understand the situation, I definitely don't want to rush you. Is there anything I need to do on the branch so you can continue with the review? I noticed there's one failing test, but it seems to be related to an |
|
@marcominerva could you please resolve the conflict with main? We recently made changes to |
Refactored MessageMerger to fold identifierless reasoning segments into the following id'd message at the flattened-message level, ensuring correct merging across response buckets (fixes microsoft#6329). Updated ComputeMerged to merge id-less messages with the next message of the same role. Removed redundant per-bucket folding logic. Added unit tests to verify correct folding behavior and role matching.
|
@peibekwe |
|
@marcominerva - Thanks for the quick update to the PR branch! Please take a look at the few comments and we can get the review finalized. |
Removed the unused Role property from MessageMergeState for code cleanliness.
Changed MessageMerger to iterate messages in reverse order, ensuring all consecutive messages without IDs preceding a message with an ID are merged correctly. Updated merging logic, index handling, and comments to reflect this new approach.
|
@peibekwe done 😉 |
Summary
Refactored MessageMerger to delegate update grouping and merging to M.E.AI, preserving the correct order and structure of assistant messages, especially for reasoning content without message IDs. Removed per-message bucketing and CreatedAt-based sorting. Added tests to verify message order and correct merging of reasoning and text updates.
Refactoring and Simplification:
ResponseMergeStateclass now maintains a single ordered list of updates (_updates) instead of bucketing updates by message ID and separately tracking dangling updates. Grouping and coalescing of updates into messages is now handled by M.E.AI'sToAgentResponsemethod, ensuring correct merging of reasoning and text, as well as preserving message order.CreatedAttimestamp have been removed, eliminating previous issues where reasoning content without a timestamp could be reordered incorrectly. [1] [2] [3]Bug Fixes and Behavioral Improvements:
CreatedAttimestamp, and correctly merges id-less reasoning updates with subsequent text into a single message when appropriate.Testing:
CreatedAttimestamp, and (2) reasoning and text are merged into a single message when reasoning updates lack a message ID, matching the behavior of directly-invoked agents.Closes #6329