文件历史

1 次代码提交

作者 SHA1 备注 提交日期
Ali Khokhar 5ffa47fbc3 Make response stream lifetimes explicit (#1060)
## Problem

Client disconnects and response-start send failures could abandon a
prefetched provider stream and its generation lease. Re-yielding
iterators and response-proxy middleware left no owner that closed the
complete body chain before runtime release.

## Changes

| Before | After |
| --- | --- |
| Starlette body iteration indirectly owned stream cleanup and lease
release. | One FCC streaming response surrounds the real ASGI send,
closes the body transitively, then releases the lease exactly once. |
| The prefetched first-frame generator could not close its tail before
replay began. | An explicit closeable replay iterator owns the
prefetched tail in every commit state. |
| Tracing, execution, Responses conversion, and native transport
transforms re-yielded inputs without closing them. | Every retained
transform closes its direct input; redundant transport wrappers are
removed while provider construction failures remain deferred. |
| Function-style correlation middleware proxied and canceled streaming
responses. | Pure ASGI correlation spans the complete stream, preserves
request headers and log context, and keeps the catch-all 500 fallback
correlated. |
| Repeated cancellation could interrupt pre-start and post-start
cleanup. | Shielded completion tasks finish body closure before release
and then restore caller cancellation. |
| The package version was 3.5.5. | The package version is 3.5.6; full CI
passes with 2,162 tests and stable live API/provider/disconnect/client
smoke passes 63 scenarios. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR makes streaming response ownership explicit across the API path.
The main changes are:

- Adds a managed streaming response that closes the body chain before
releasing provider resources.
- Adds a prefetched replay iterator for first-frame commit handling.
- Moves request correlation to pure ASGI middleware for full-stream
context.
- Propagates direct-input closure through execution, tracing, Responses
conversion, and provider transports.
- Bumps the package version and updates tests for stream cleanup
behavior.
</details>

<h3>Confidence Score: 5/5</h3>

This looks safe to merge.

No blocking issues found in the changed code.

None.

<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>

**What T-Rex did**
- Validated the execution environment by reviewing the environment proof
log, confirming uv 0.11.28, CPython 3.14.0, a repo-local virtual
environment, and exit code 0.
- Verified that the requested test command was executed, based on the
test proof log.
- Confirmed the test run completed successfully with 91 tests passing in
3.63 seconds, as shown in the test proof log.

<a
href="https://app.greptile.com/trex/runs/14099258/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>

<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>

<details open><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| src/free_claude_code/api/response_streams.py | Adds the managed
response owner, first-frame replay iterator, and shielded cleanup flow.
|
| src/free_claude_code/api/request_ids.py | Adds pure ASGI request
correlation and response-start header injection. |
| src/free_claude_code/core/trace.py | Adds shared stream input closure
tracing and closes traced inputs on exit. |
| src/free_claude_code/application/execution.py | Closes provider stream
iterators from the executor wrapper when streaming ends. |
|
src/free_claude_code/providers/transports/anthropic_messages/transport.py
| Returns provider runner streams directly and closes layered SSE
iterators explicitly. |

</details>

<sub>Reviews (2): Last reviewed commit: ["Make response stream lifetimes
explicit"](https://github.com/alishahryar1/free-claude-code/commit/cb698c62c08924d5f80a1cea7dbd19c0b8af26a2)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=43527620)</sub>

<!-- /greptile_comment -->
2026-07-11 09:33:31 -07:00