Stream and run cancellation semantics tracker

Author: dsfacciniCreated Jun 9, 2026Updated Sep 18, 2026
Labelsfeatureneeds-discussionstreamingtrackingneeds-maintainer-action

Purpose

This is the canonical tracker for the cancellation / interrupted-stream / interrupted-history work that used to be bundled under #1524.

#1524 started as a concrete stream-cancellation report, but over time it collected several different questions:

  • stopping provider streams after early exit
  • deterministic cleanup for run_stream_events()
  • interrupted response/request capture in message history
  • whole-agent cancellation semantics
  • tool-execution cancellation semantics
  • replay/resume semantics for interrupted histories

Several pieces are now fixed or tracked elsewhere. This issue exists to keep the map current and make it possible to close #1524 as split into narrower work.

Playground

Acceptance-test sketch:

https://play.pydantic.work/p/64IbU2vI/v/1/s/stream_break?version=1.106.0

Notes:

  • The concrete snippets are useful as runnable playground checks via Run.
  • The future-design snippets are intentionally written as contract sketches until the public APIs are decided.
  • Pytest all in the playground wraps snippets differently than repo pytest, so async snippets should be treated as playground snippets first and later copied into real repo tests once the API is implemented.

Open Child Issues

  • #5835 - Define whole-agent-run cancellation semantics.
  • #5836 - Define replay semantics for interrupted message histories.
  • #5837 - Define tool-execution cancellation semantics.
  • #5507 - Graceful result with cancelling stream in tool arguments.
  • #5756 - Streaming: make stream_* methods sync-flip is_complete on early break.
  • #5619 - PR (awaiting review): clean early break from stream_* records interrupted response after run_stream context exit. The originating issue #5615 was closed as not planned (not-a-bug-as-filed); the remaining sync-flip design question is tracked in #5756.

Fixed / Closed Reference Work

  • #5132 - run_stream_events() cancellation cleanup returned before internal tasks finished.
  • #5313 - Fixed deterministic stream cleanup on cancellation and documented provider limitations.
  • #3219 - User report: frontend cancellation produced streamed output but captured messages were empty.
  • #5364 - Captures interrupted model request/response in capture_run_messages() / all_messages() for exception and external-cancellation paths.
  • #5769 / #5771 - Fixed incomplete streamed response when event_stream_handler does not consume the stream.
  • #3960 / #3961 - Operational cancellation of tool calls when the run coroutine is cancelled.
  • #5341 - Drains spawned tasks during agent cancellation.
  • #5390 - Follow-up docs movement for provider stream-cancellation warning.
  • #5782 / #5795 - Fixed defensive await result.cancel() after fully consumed stream flipping response.state.
  • #6162 / #6234 - run_stream_events() now lazy-starts the background run task on first event iteration, so entering/exiting the context manager without consuming events never calls the model (also fixes the 3.10/3.11 contextvar-token teardown flake).
  • #5975 / #6198 - Cleans up the pending task and streams on KeyboardInterrupt in synchronous run_until_complete wrappers.
  • #3714 / #6199 - Runs the sync streaming wrappers on an anyio portal thread (fixing cross-task cancel-scope errors and dropped OTel spans; supersedes #3716), and fixes the async stream_text() early-break teardown crash.
  • #6146 / #6149 - Suppresses ClosedResourceError when cancelling a graph run mid-send.

Closed / Superseded PR Attempts

  • #2901 - Earlier broad stream-cancellation implementation attempt.
  • #4053 - Earlier streaming cancellation support PR.
  • #5031 - Earlier run_stream_events() context-manager/cancellation PR.
  • #5291 - Narrow replacement attempt that explicitly left run-level cancellation, tool execution semantics, RunCancelled, and cancel(end_run=...) out of scope.

Closed Umbrella / Stale Issues

  • #1516 - Old early-break report; closed 2026-06-09, covered by later stream-cleanup work and the #5619 history-completeness path.
  • #1524 - Original umbrella issue; closed 2026-06-09 as split into this tracker and the child issues.

Closure Criteria For This Tracker

This tracker can be closed when:

  • #1524 is closed with a comment linking this tracker and the child issues. Done: closed 2026-06-09.
  • Each open child issue either has a settled design and implementation plan, or is explicitly closed as not planned.
  • The playground constraints have been translated into real repo tests where they describe implemented behavior.