Skip to content

fix(execution): cancel agent streams during teardown - #1253

Open
weibit wants to merge 1 commit into
usestrix:mainfrom
weibit:fix/1106-cancel-agent-streams
Open

weibit wants to merge 1 commit into
usestrix:mainfrom
weibit:fix/1106-cancel-agent-streams

Conversation

@weibit

@weibit weibit commented Sep 3, 2026

Copy link
Copy Markdown

Summary

  • cover the cancellation window between starting an SDK run and registering its stream with the coordinator
  • immediately cancel unfinished streams and give the SDK run-loop task a bounded opportunity to settle before detaching
  • deterministically close wrapped provider streams on timeout, cancellation, generator close, and normal completion
  • consolidate async and synchronous provider-stream cleanup in one helper

Problem

Runner.run_streamed() starts its background task before AgentCoordinator.attach_stream() completes. If the owning agent task is cancelled while attachment is pending, the old cleanup boundary is never entered and the detached SDK task can continue model or sandbox work during teardown.

The model idle-timeout wrapper also closes its inner stream only on timeout. Closing the outer guarded model generator does not synchronously close that wrapper, leaving provider cleanup to async-generator finalization.

Changes

  • move stream attachment inside the run-cycle cleanup boundary
  • cancel incomplete streams with mode="immediate"
  • wait up to one second for run_loop_task to unwind before detachment
  • preserve SDK self-cancellation without issuing a duplicate cancel
  • use contextlib.aclosing() around the idle-timeout wrapper
  • use a shared best-effort stream closer with aclose() and close() support
  • add regressions for the attach race, SDK self-cancel behavior, settlement ordering, and nested provider-stream closure

Testing

  • uv run pytest tests/test_execution.py tests/test_stream_idle_timeout.py — 70 passed
  • uv run pytest — 1685 passed
  • pre-commit hooks: Ruff lint/format, Mypy, Bandit, Pyupgrade, and repository hygiene checks passed

Fixes #1106

@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR strengthens agent and provider-stream teardown so cancellation covers the stream-attachment race and provider resources close deterministically.

  • Moves stream attachment into the run-cycle cleanup boundary.
  • Immediately cancels unfinished SDK streams, briefly waits for their run-loop tasks, and detaches afterward.
  • Consolidates synchronous and asynchronous provider-stream cleanup and applies it across timeout, cancellation, generator close, and normal completion.
  • Adds regression coverage for attachment cancellation, SDK self-cancellation, settlement ordering, and nested stream closure.

Confidence Score: 5/5

The PR appears safe to merge; no concrete changed-code defect remains after reviewing the cancellation, settlement, detachment, and provider-stream closure paths.

The new cleanup boundaries are bounded and exception-safe, preserve SDK self-cancellation, and deterministically release wrapped streams across all tested termination modes.

Important Files Changed

Filename Overview
strix/core/execution.py Extends the run-cycle cleanup boundary across attachment, immediately cancels unfinished streams, performs a bounded settlement wait, and guarantees detachment afterward.
strix/config/models.py Introduces shared best-effort stream closure and ensures the idle-timeout and turn-guard wrappers close nested provider streams on every exit path.
tests/test_execution.py Adds focused regressions for cancellation during attachment, SDK self-cancellation, single cancellation, and settlement-before-detachment ordering.
tests/test_stream_idle_timeout.py Expands provider-stream lifecycle coverage across timeout, cancellation, explicit generator closure, normal completion, disabled timeout, and synchronous close implementations.

Reviews (1): Last reviewed commit: "fix(execution): cancel agent streams dur..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cancelled agent turns detach the model stream without cancelling it

1 participant