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 allin 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-flipis_completeon early break. - #5619 - PR (awaiting review): clean early break from
stream_*records interrupted response afterrun_streamcontext 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_handlerdoes 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 flippingresponse.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
KeyboardInterruptin synchronousrun_until_completewrappers. - #3714 / #6199 - Runs the sync streaming wrappers on an
anyioportal thread (fixing cross-task cancel-scope errors and dropped OTel spans; supersedes #3716), and fixes the asyncstream_text()early-break teardown crash. - #6146 / #6149 - Suppresses
ClosedResourceErrorwhen 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, andcancel(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.
Source: pydantic/pydantic-ai