Skip to content

Python: include checkpoint_id on AG-UI interrupt metadata (#8150) - #8163

Open
lsmlhi_25 (FOWEPJF255) wants to merge 6 commits into
microsoft:mainfrom
FOWEPJF255:fix/ag-ui-interrupt-checkpoint-8150
Open

Python: include checkpoint_id on AG-UI interrupt metadata (#8150)#8163
lsmlhi_25 (FOWEPJF255) wants to merge 6 commits into
microsoft:mainfrom
FOWEPJF255:fix/ag-ui-interrupt-checkpoint-8150

Conversation

@FOWEPJF255

@FOWEPJF255 lsmlhi_25 (FOWEPJF255) commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

AG-UI workflow interrupts need a durable pause checkpoint_id so multi-worker clients can resume via forwardedProps.checkpoint_id without a side-channel lookup (Option A from #8150).

Description & Review Guide

  • What are the major changes?
    • Attach the pause checkpoint_id to each interrupt's metadata.agent_framework when AG-UI workflow runs finish with interrupts and checkpoint storage is active.
    • Prefer this runner's last-saved pause checkpoint over shared get_latest(workflow_name=...) (avoids cross-owner races / stale ids).
    • Resolve builder-configured checkpoint storage via the workflow runner when run_workflow_stream does not pass checkpoint_storage.
    • Skip storage work when interrupts is empty; remove the unused checkpoint_id kwarg on _workflow_interrupt_metadata.
  • What is the impact of these changes?
    • Clients can round-trip the pause checkpoint id from interrupt metadata for durable resume across workers.
  • What do you want reviewers to focus on?
    • Correctness of pause-id selection vs shared get_latest, builder-only storage path, and empty-interrupt short-circuit.

Related Issue

Fixes #8150

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 is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • 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.

…8150)

Attach the pause workflow checkpoint id to RUN_FINISHED interrupt
metadata.agent_framework so multi-worker clients can resume via
forwardedProps.checkpoint_id without a side channel.

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

Checkpoint selection can advertise a stale or different request owner’s checkpoint ID.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds checkpoint IDs to AG-UI workflow interrupt metadata for durable multi-worker resume.

Changes:

  • Resolves and attaches pause checkpoint IDs to interrupts.
  • Adds helper and checkpoint-resume coverage.
File summaries
File Description
_workflow_run.py Adds checkpoint lookup and interrupt metadata enrichment.
test_workflow_run.py Tests attachment and checkpoint ID propagation.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 3
  • Review effort level: Balanced

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

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

Addressed review feedback:

  1. Stop using shared get_latest(workflow_name=...) (races across owners / stale ids). Prefer this runner's _previous_checkpoint_id and only advertise it when the checkpoint's pending request set covers the interrupt ids.
  2. Resolve builder-configured storage via the workflow runner when run_workflow_stream does not pass checkpoint_storage.
  3. Skip storage work when interrupts is empty; remove the unused checkpoint_id kwarg on _workflow_interrupt_metadata.
  4. Added regression tests for competing shared latest + builder-only storage.

@moonbox3

Evan Mattson (moonbox3) commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

lsmlhi_25 (@FOWEPJF255):

  1. Please update the PR body to use our approved template: https://github.com/microsoft/agent-framework/blob/main/.github/pull_request_template.md
  2. Per our contributing guidelines, please respond to all open PR comments as to whether they're addressed or not. Then resolve the threads once done.
  3. Please also fix the failing code quality checks.

@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

Evan Mattson (@moonbox3) Thanks 鈥?addressed your checklist:

  1. PR body updated to the approved template.
  2. Replied on each review thread and resolved them.
  3. Pushed a follow-up for the failing code quality checks: ruff I001 (import blank line) and ty ignores on the new yield_output("done") test helpers.

Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Move pause-checkpoint selection into Workflow and require a run-scoped
baseline so leftover runner ids are not advertised across runs.
@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

Evan Mattson (@moonbox3) Follow-up for the run-scoped / core-helper review:

  • Workflow.get_last_checkpoint_id() + Workflow.resolve_pause_checkpoint_id(...) in core (storage precedence, pending-request coverage, run-scoped baseline filter).
  • AG-UI captures the baseline before workflow.run() and no longer digs into Runner private fields for pause-id selection.
  • Regression tests in core test_pause_checkpoint_resolve.py and AG-UI run-scoped coverage.

Commit: 68f5abe.

Comment thread python/packages/core/agent_framework/_workflows/_workflow.py
Comment thread python/packages/core/agent_framework/_workflows/_workflow.py
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py Outdated
Comment thread python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py
Comment thread python/packages/core/tests/workflow/test_pause_checkpoint_resolve.py Outdated
LI (ktz03) added a commit to ktz03/agent-framework that referenced this pull request Sep 11, 2026
- Workflow captures run baseline / restored id inside run(); resolve uses them
  so callers need not thread baseline_checkpoint_id.
- Exclude restored checkpoint from pause candidates after resume.
- Drop issue reference in docstring; emit RUN_FINISHED via existing
  _build_run_finished_event after attaching pause id.
- Move core pause-resolve coverage into test_workflow.py (no new test file).
@ktz03

Copy link
Copy Markdown

Left a follow-up into your branch for the open Eduard van Valkenburg (@eavanvalkenburg) / Evan Mattson (@moonbox3) threads:

Highlights:

  • Workflow owns run baseline + restored id inside
    un(); AG-UI no longer threads �aseline_checkpoint_id / resume known_checkpoint_id`n- Restored checkpoint excluded from pause candidates after resume
  • Docstring no longer cites the issue; RUN_FINISHED goes through existing _build_run_finished_event`n- Core pause-resolve tests moved into est_workflow.py (dedicated test file removed)

Feel free to merge #2 or cherry-pick �58e11f.

…ip (#2)

- Workflow captures run baseline / restored id inside run(); resolve uses them
  so callers need not thread baseline_checkpoint_id.
- Exclude restored checkpoint from pause candidates after resume.
- Drop issue reference in docstring; emit RUN_FINISHED via existing
  _build_run_finished_event after attaching pause id.
- Move core pause-resolve coverage into test_workflow.py (no new test file).
@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

Merged the pause-checkpoint ownership follow-up on the PR branch (FOWEPJF255#2). Ready for another maintainer pass.

@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

All open review threads from Evan Mattson (@moonbox3) / Eduard van Valkenburg (@eavanvalkenburg) are addressed on the PR head (d42a8b3, via FOWEPJF255#2):

  • Workflow owns run baseline + excludes restored checkpoint from pause candidates
  • AG-UI reuses _build_run_finished_event (no extra helper / issue link in docstring)
  • Core tests live in test_workflow.py (no dedicated bug-fix test file)

Ready for another look when you have a moment.

1 similar comment
@FOWEPJF255

Copy link
Copy Markdown
Contributor Author

All open review threads from Evan Mattson (@moonbox3) / Eduard van Valkenburg (@eavanvalkenburg) are addressed on the PR head (d42a8b3, via FOWEPJF255#2):

  • Workflow owns run baseline + excludes restored checkpoint from pause candidates
  • AG-UI reuses _build_run_finished_event (no extra helper / issue link in docstring)
  • Core tests live in test_workflow.py (no dedicated bug-fix test file)

Ready for another look when you have a moment.

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: AG-UI: include checkpoint_id on RUN_FINISHED interrupts for multi-worker resume

6 participants