Skip to content

Python: Preserve merge mode in WorkflowAgent streaming - #10331

Open
WhaleTech (ryo-whaletech) wants to merge 1 commit into
microsoft:mainfrom
ryo-whaletech:codex/fix-workflow-agent-merge-mode
Open

WhaleTech (ryo-whaletech) wants to merge 1 commit into
microsoft:mainfrom
ryo-whaletech:codex/fix-workflow-agent-merge-mode

Conversation

@ryo-whaletech

Copy link
Copy Markdown
Contributor

Motivation & Context

WorkflowAgent reconstructs executor-emitted AgentResponseUpdate objects without copying their merge_mode.
An authoritative replace snapshot therefore becomes an ordinary accumulating update: draft followed by final
with the same message ID produces draftfinal. The stale content also reaches session history, and replacement
snapshots containing URI content retain the earlier URI.

The existing content identity contract
already defines update-level replacement. This change preserves that intent through the workflow wrapper.

Description & Review Guide

  • What are the major changes?
    • Forward data.merge_mode when reconstructing an AgentResponseUpdate in _workflows/_agent.py.
    • Extend the metadata-forwarding test to cover None, append, and replace.
    • Add public streaming regressions that verify replacement in both get_final_response() and
      InMemoryHistoryProvider, with text-only and text-plus-URI updates.
  • What is the impact of these changes?
    • Replacement updates remove the earlier contents of the same logical message instead of leaving stale text or
      URI content in the final response and history.
    • Updates without a merge mode keep their existing accumulation behavior, and explicit append intent is preserved.
    • The change uses an existing field and does not alter public signatures or serialization formats.
    • Outbound A2A, AG-UI, Foundry Hosting, and DevUI converters retain an existing limitation: local before/after
      probes still project draftfinal. This change fixes core forwarding and aggregation, not those converters.
    • If custom code bypasses the typed contract by assigning an invalid merge_mode after construction, forwarding
      now raises the constructor's ValueError instead of silently dropping that invalid value.
  • What do you want reviewers to focus on?
    • Whether forwarding the incoming merge intent implements the logical-message replacement contract through both
      stream finalization and history persistence.

On source commits 30285709c1d60736a9b8b8ad87cd4f94a3719f6a and
6811ef8c7d83cf2949679f733aa15ac1bf290fe6, the focused checks give 6 failures and 3 passing controls before the
fix, then 9 passes after it. The nine checks also pass on Python 3.11 through 3.15.

On the latter commit, using macOS arm64, Python 3.11.14, frozen workspace dependencies, and uv 0.13.7:
poe test -A -n 4 gives 21,401 passed, 580 skipped, and 5 xfailed. Core alone gives 9,731 passed. Individual package
runs for A2A, AG-UI, Foundry Hosting, DevUI, declarative, and orchestrations give 4,949 passed in total. Core strict source Pyright and all
five test type checkers pass, as do changed-file Ruff, format, and pre-commit hooks with poe-check skipped as in CI.
The aggregate run emits 1,498 warnings and shutdown-time OpenTelemetry exporter diagnostics; an unfixed core control
also reproduces the exporter diagnostics. Linux/Windows CI and external-service integration tests were not run locally.

The aggregate command was rerun before publication on main commit
c7e50ccd90370416afc4ab466394b06395f7dccd: 21,401 passed, 580 skipped, 5 xfailed, and 1,491 warnings.
The core source and test trees are unchanged from the earlier validation commit.

Related Issue

Fixes #10330

Maintainer agreement on this maintenance candidate has not yet been recorded.

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: Duplicate research, local reproduction, diagnosis, the implementation, regression tests,
and this pull request 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.

Forward the existing update-level merge_mode when rebuilding executor updates
so replacement snapshots discard stale content from finalized responses and
session history.

Cover merge intent forwarding and text/URI replacement through the public
streaming API and in-memory history provider.

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

No active review issues are reported for the change preserving merge modes in streamed workflow updates.

No open issues 🎉

What changed in this PR

This PR fixes #10330 by preserving merge_mode when WorkflowAgent forwards streamed updates, allowing replacement snapshots to remove stale content from final responses and session history.

Changes:

  • Forward the existing merge_mode field without changing public signatures.
  • Extend metadata-forwarding coverage for None, append, and replace.
  • Add text and URI replacement regressions for stream finalization and history persistence.
File Description
python/​packages/​core/​tests/​workflow/​test_workflow_agent.py Tests merge-mode forwarding and replacement behavior in final responses and history.
python/​packages/​core/​agent_framework/​_workflows/​_agent.py Preserves incoming merge_mode when reconstructing streamed updates.

Review effort: Balanced

This branch was successfully deployed

1 active deployment
github-app-auth — 5261a84a Deployed Nov 13, 2026 by ryo-whaletech via team_check #9417
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]: WorkflowAgent drops merge_mode from streamed updates

2 participants