Skip to content

Python: Sramsey/python continuation token fix - #9002

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 8 commits into
mainfrom
sramsey/python-continuation-token-fix
Oct 9, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 8 commits into
mainfrom
sramsey/python-continuation-token-fix

Conversation

@sophia-ramsey

@sophia-ramsey sophia-ramsey commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

Tokenless intermediate streaming updates currently overwrite an active continuation token, incorrectly indicating that the provider operation has completed. This change preserves the token while an operation remains in progress and clears it when the operation reaches a terminal state, including after responses are buffered and converted back into updates.

Description & Review Guide

  • What are the major changes? This PR adds a private operation-state marker to chat and agent responses and updates. The marker distinguishes in-progress and terminal operations while leaving unspecified updates with their existing behavior for provider compatibility. _OperationState is preserved through aggregation, response-to-update conversion, workflow forwarding, and buffered middleware. OpenAI completed, incomplete, and failed events and A2A completed, failed, canceled, and rejected states are marked terminal; intermediate provider updates are marked in_progress.
  • What is the impact of these changes? Streaming responses no longer lose an active continuation token when a provider omits the token from an intermediate update. Terminal operations clear the token reliably, including after buffering or response round-trips. Existing providers that do not set operation state retain their current token-handling behavior, and the private marker does not change the public serialized response shape.
  • What do you want reviewers to focus on? Whether the private compatibility-preserving operation state is straightforward, whether it covers aggregation and buffering without affecting existing provider behavior, and whether the OpenAI and A2A classifications correctly represent in-progress and terminal operations.

Related Issue

Fixes #8826

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.

Copilot AI balanced review requested due to automatic review settings October 3, 2026 02:14
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Oct 3, 2026
@github-actions github-actions Bot changed the title Sramsey/python continuation token fix Python: Sramsey/python continuation token fix Oct 3, 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.

Copilot review overview

🟡 Changes recommended

Completed responses converted with to_updates() can still fail to clear a previously aggregated continuation token.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds explicit terminal-state signaling so streaming aggregation preserves active continuation tokens until completion.

Changes:

  • Adds and propagates is_operation_terminal.
  • Marks terminal OpenAI and A2A events.
  • Adds aggregation and provider regression tests.
File Description
python/​packages/​core/​agent_framework/​_types.py Adds terminal signaling and token aggregation logic.
python/​packages/​core/​agent_framework/​_workflows/​_agent.py Propagates terminal state through workflows.
python/​packages/​core/​tests/​core/​test_types.py Tests aggregation, mapping, and serialization.
python/​packages/​core/​tests/​workflow/​test_workflow_agent.py Tests workflow metadata propagation.
python/​packages/​openai/​agent_framework_openai/​_chat_client.py Marks terminal Responses API events.
python/​packages/​openai/​tests/​openai/​test_openai_chat_client.py Tests OpenAI terminal handling.
python/​packages/​a2a/​agent_framework_a2a/​_agent.py Emits A2A terminal markers.
python/​packages/​a2a/​tests/​test_a2a_agent.py Tests A2A completion and artifact streams.

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

Comment thread python/packages/core/agent_framework/_types.py Outdated
@github-code-quality

github-code-quality Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Python

Python / code-coverage/python

The overall line coverage in commit 46d13cd in the sramsey/python-conti... branch remains at 92%, unchanged from commit 91ab44f in the main branch.

Show a line coverage summary of the most impacted files.
File main 91ab44f sramsey/python-conti... 46d13cd +/-
packages/a2a/ag...k_a2a/_agent.py 95% 94% -1%
packages/openai..._chat_client.py 94% 94% 0%
packages/core/a...ework/_types.py 96% 96% 0%
packages/core/a...flows/_agent.py 91% 91% 0%

Updated October 08, 2026 23:51 UTC

@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)): d298983a1397, 2b67d6b3571d
Model: gpt-5.6-sol

Overview

The PR introduces an explicit terminal-operation signal and applies it consistently in the changed A2A, OpenAI, chat-to-agent, and workflow-update paths, with focused tests for token preservation, terminal clearing, serialization, and artifact deduplication. The remaining risk is in compatibility paths outside those direct producers: response-to-update round-trips discard the new signal, and existing custom providers do not emit it, so both paths can retain stale continuation tokens after completion.

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

Affected areas: python/packages/core/agent_framework/_types.py

Comment thread python/packages/core/agent_framework/_types.py Outdated
Comment thread python/packages/core/agent_framework/_types.py Outdated
Comment thread python/packages/core/agent_framework/_types.py Outdated
@eavanvalkenburg

Copy link
Copy Markdown
Member

sophia-ramsey The response round-trip still drops terminality: ChatResponse.to_updates() / AgentResponse.to_updates() copy tail metadata but not is_operation_terminal, and aggregation has no representation that preserves it. Buffered middleware can therefore turn a terminal update into a nonterminal sequence or retain stale token state; existing providers’ final tokenless updates also default nonterminal. This needs an explicit preserved representation and compatibility coverage before the public flag shape is settled.

@sophia-ramsey
sophia-ramsey force-pushed the sramsey/python-continuation-token-fix branch from 2b67d6b to df1a3e8 Compare October 8, 2026 00:13
Comment thread python/packages/core/agent_framework/_types.py Fixed
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@eavanvalkenburg

Copy link
Copy Markdown
Member

Copilot the last commit broke everything, please fix

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

Copilot AI commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Copilot the last commit broke everything, please fix

Restored the missing Generic import in aea1a64. Syntax and whitespace checks pass; I couldn't run pytest because uv and pytest are unavailable in this environment.

Comment thread python/packages/core/agent_framework/_types.py Dismissed

@jpalvarezl Jose Alvarez (jpalvarezl) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Found two continuation-lifecycle gaps not covered by the existing review threads; details are attached inline.

Comment thread python/packages/core/agent_framework/_types.py
Comment thread python/packages/openai/agent_framework_openai/_chat_client.py

@jpalvarezl Jose Alvarez (jpalvarezl) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The two follow-up commits address the outstanding continuation-lifecycle findings: operation state now survives update serialization round-trips, and OpenAI streaming error/terminal-created events clear resume state and surface errors. The added regressions cover both paths, and the current CI suite is fully green.

Merged via the queue into main with commit 513ec8f Oct 9, 2026
52 checks passed
@eavanvalkenburg
Eduard van Valkenburg (eavanvalkenburg) deleted the sramsey/python-continuation-token-fix branch October 9, 2026 09:43

This branch was previously deployed

1 inactive deployment
github-app-auth — 46d13cdf Deployed Oct 8, 2026 by sophia-ramsey via add_label #24839
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]: Streaming a response that is still in progress drops its continuation_token

5 participants