Skip to content

Python: Preserve concurrent steps across workflow pause - #9291

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 10 commits into
microsoft:mainfrom
eavanvalkenburg:fix-functional-workflow-pause
Oct 14, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 10 commits into
microsoft:mainfrom
eavanvalkenburg:fix-functional-workflow-pause

Conversation

@eavanvalkenburg

Copy link
Copy Markdown
Member

Motivation & Context

Functional workflows could capture HITL replay and checkpoint state while a concurrent @step was still running. The step then completed after the paused run returned, so resume executed it again and could duplicate model, tool, or write side effects. asyncio.TaskGroup also exposed the internal interruption as a BaseExceptionGroup.

This change settles active concurrent steps before pause state is captured, while cancelling detached workflow tasks so a pause cannot leave background work running.

Description & Review Guide

  • What are the major changes? Track nested active @step executions, await those tasks before HITL replay/checkpoint capture, cancel and drain remaining detached tasks, and separate internal interruption leaves from real exception-group failures.
  • What is the impact of these changes? Completed concurrent steps are replayed from cache instead of executing twice, cancellations do not orphan tasks, and TaskGroup-based workflows pause and resume through the normal HITL path.
  • What do you want reviewers to focus on? The task-settlement lifecycle around interruption, cancellation, nested steps, and mixed exception groups.

Related Issue

Closes #9268

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: Implementation, tests, design review, and 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 balanced review requested due to automatic review settings October 12, 2026 09:33
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Oct 12, 2026

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.

🟡 Changes recommended

Task settlement can incorrectly re-raise previously handled task failures.

1 open finding
What changed in this PR

Preserves concurrent functional-workflow steps across HITL pauses to prevent duplicate side effects.

Changes:

  • Tracks and settles active nested steps before snapshots.
  • Cancels detached workflow tasks.
  • Handles interruption-only and mixed exception groups.
File Description
_functional.py Implements task settlement and interruption-group handling.
test_functional_workflow.py Adds concurrency, cancellation, and TaskGroup regressions.

🧠 Review effort: Balanced


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

Comment thread python/packages/core/agent_framework/_workflows/_functional.py Outdated

@github-actions github-actions Bot 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.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (2 commit(s)): 1009056cffa8, 6db8e3b491a0
Model: gpt-5.6-sol

Overview

The change adds active-step tracking, task draining, and exception-group normalization, with focused tests for gather, cancellation, nested steps, and TaskGroup interruption. Those guards cover cooperative gather-based pauses well, but TaskGroup sibling cancellation still permits duplicate side effects, and the settlement path mistakes concurrently handled failures for unhandled ones. Both residual defects affect whether a workflow can pause and resume without repeating work or replacing the pause with an error.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (1 high, 1 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: python/packages/core/agent_framework/_workflows/_functional.py

Comment thread python/packages/core/agent_framework/_workflows/_functional.py Outdated
Comment thread python/packages/core/agent_framework/_workflows/_functional.py
Comment thread python/packages/core/agent_framework/_workflows/_functional.py Outdated
Comment thread python/packages/core/agent_framework/_workflows/_functional.py Outdated

This branch was successfully deployed

1 active deployment
github-app-auth — ee613898 Deployed Oct 14, 2026 by eavanvalkenburg via add_label #25319
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]: Functional workflow re-executes a @step that was still running when a sibling asyncio.gather branch paused for request_info

4 participants