Repository navigation
feat(server): bind guarded streams to HTTP - #2436
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
e97105a to
3dd8fea
Compare
3dd8fea to
bd3fade
Compare
|
bd3fade to
5814177
Compare
5814177 to
50a025d
Compare
This comment has been minimized.
This comment has been minimized.
50a025d to
fe7408e
Compare
fe7408e to
9112df3
Compare
9112df3 to
6668113
Compare
6668113 to
aa07f76
Compare
|
@greptileai the stream index doesn't break export: stream export only exists from #2437, and its export commit adds |
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Make the streaming response the owner of the upstream body. It closes the body iterator and the source in a shielded cleanup, so a client disconnect or send failure before the first chunk no longer leaks the provider connection. Reject a non-user input message before dispatch instead of failing after the response starts. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
An inspected stream may withhold events, emit a provider-native error, or drop an unfinished tail, so validators computed over the provider body no longer describe the bytes sent downstream. Remove ETag, Content-MD5, Digest, Content-Digest, and Repr-Digest alongside Content-Length whenever the stream may change. Uninspected relays keep every end-to-end header. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Clients such as the OpenAI SDK send Accept-Encoding: gzip, and inspected streams reject a provider stream that is not identity-encoded. A compressing provider therefore turned every inspected streaming request into a proxy error. When the stream is inspected, replace Accept-Encoding with identity before dispatch, matching buffered output inspection. Uninspected relays forward the client's preference unchanged, and a still-encoded inspected stream remains rejected. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Buffered requests and responses read only the last Content-Encoding header, so "gzip" followed by "identity" passed as unencoded, while streams combined every header but rejected an empty value. Both paths now share one rule: duplicate headers and comma lists form one coding list, empty elements are ignored, and the body is unencoded only when every coding is identity. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Closing the body iterator does not prove the upstream connection is closed. A client disconnect can cancel an async generator's own cleanup part-way, and later aclose() calls cannot resume it. StreamingHttpResponse now carries an optional close callback that releases the upstream resource directly. Iterators that own their resource may keep exposing aclose(); a bare async generator must supply the callback and is otherwise rejected. Dispatch owns resources until it returns the response and must clean up if construction fails. From then on the executor owns cleanup on every path, including rejection and disconnect before iteration. Closing must be idempotent; each attempt is bounded and failures are logged. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
The streaming executor treated any exception from dispatch as an upstream failure, so a bug in a dispatcher or in our own code was reported to the client and operators as a provider outage. It now catches only HttpDispatchFailed, like the buffered path; other exceptions propagate. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Adds cases for invalid StreamingHttpResponse values, non-byte chunks in an uninspected relay, non-positive byte limits, and an unsupported dispatch result. No runtime behavior changes. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
78cd081 to
ef094d6
Compare
Summary
Adds an injected streaming HTTP lifecycle bridge around the provider-neutral runner, including response validation and reliable source closure.
What Changed
identity.closecallback toStreamingHttpResponsethat releases the upstream resource independently of the body iterator. A bare async-generator body must provide it; self-owning iterators may expose an idempotentaclose.Review Notes
Review pre-header validation, framing, transparent relay, and resource ownership. The Content-Encoding and Content-Type rules also change buffered behavior:
gzipfollowed byidentity, and duplicate Content-Type headers, are now rejected. Dispatch remains injected; concrete outbound HTTP and application client lifecycle remain separate work.AI Assistance
Checklist
Stack Position
Part 3 of 4.
Stack Context
Adds OpenAI Chat streaming above the merged buffered implementation on develop in four parts: provider-neutral execution, typed OpenAI stream declarations and handwritten hooks, injected HTTP lifecycle handling, and integration with the buffered request pipeline.
The open chain is develop → #2434 → #2435 → #2436 → #2437. The buffered foundation is merged; #2412 is closed.
Python declarations own field and event policy. Hooks are handwritten and created for each stream by the integration. The final PR exports the bound buffered and streaming policy for inspection; export never constructs runtime components. Concrete outbound HTTP, deployment configuration, and replacement execution land separately.
Review each PR against its listed base branch.
pouyanpi/transparent-proxy-streaming-kernel-1developpouyanpi/openai-chat-streaming-contract-2pouyanpi/transparent-proxy-streaming-kernel-1pouyanpi/transparent-proxy-streaming-http-3pouyanpi/openai-chat-streaming-contract-2pouyanpi/openai-chat-streaming-integration-4pouyanpi/transparent-proxy-streaming-http-3Summary by CodeRabbit