Skip to content

Python: close loop inner stream on early exit - #9331

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 1 commit into
microsoft:mainfrom
CorgiBoyG:fix/agent-loop-inner-stream-close
Oct 15, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 1 commit into
microsoft:mainfrom
CorgiBoyG:fix/agent-loop-inner-stream-close

Conversation

@CorgiBoyG

Copy link
Copy Markdown
Contributor

Summary

  • enter each streaming loop iteration's inner ResponseStream as an async context manager
  • close the active provider stream deterministically when the outer loop stream is closed or cancelled
  • cover full consumption, explicit early close, and cancellation while the inner stream is suspended

Root cause

AgentLoopMiddleware forwarded updates through an async-generator layer with async for, but did not own the inner stream through its async context protocol. Closing the outer stream therefore finalized the loop generator without propagating close() to the active inner ResponseStream, leaving provider cleanup hooks pending until garbage collection.

Using the existing ResponseStream async context protocol keeps normal finalization unchanged and guarantees that early exits release the active inner stream.

Fixes #9328

Validation

  • python -m pytest -m "not integration" -n auto --dist worksteal tests -q
  • python -m pytest tests/core/test_harness_loop.py -q
  • ruff check agent_framework/_harness/_loop.py tests/core/test_harness_loop.py
  • ruff format --check agent_framework/_harness/_loop.py tests/core/test_harness_loop.py
  • Pyright on the source file and regression test file
  • git diff --check

Signed-off-by: CorgiBoyG <111257566+CorgiBoyG@users.noreply.github.com>

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.

🟢 Approval recommended

The context-manager change correctly propagates cleanup and is comprehensively covered by focused regression tests.

0 open findings

What changed in this PR

Ensures streaming agent loops deterministically release active provider streams on completion, early closure, or cancellation.

Changes:

  • Manages each inner ResponseStream with its async context protocol.
  • Adds regression coverage for all relevant termination paths.
File Description
python/​packages/​core/​agent_framework/​_harness/​_loop.py Closes each active inner stream deterministically.
python/​packages/​core/​tests/​core/​test_harness_loop.py Tests full consumption, early close, and cancellation cleanup.

🧠 Review effort: Balanced


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

Merged via the queue into microsoft:main with commit 7809945 Oct 15, 2026
50 checks passed

This branch was previously deployed

1 inactive deployment
github-app-auth — 75fcde63 Deployed Oct 13, 2026 by CorgiBoyG via team_check #6683
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: AgentLoopMiddleware does not close the active inner stream when streaming is stopped early

3 participants