Repository navigation
feat(server): add OpenAI Chat stream projections and hooks - #2435
Merged
Merged
Conversation
This was referenced Oct 5, 2026
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 6, 2026 11:05
73f46d5 to
625e4cb
Compare
Pouyanpi
marked this pull request as ready for review
October 6, 2026 11:06
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 6, 2026 15:22
625e4cb to
80703c1
Compare
Contributor
|
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 7, 2026 09:00
c312770 to
d5510f4
Compare
This was referenced Oct 8, 2026
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 8, 2026 17:52
d5510f4 to
969832f
Compare
This was referenced Oct 8, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Pouyanpi
added this pull request to stack #2445
October 9, 2026 13:16
Contributor
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
3 times, most recently
from
October 12, 2026 13:21
2c347bb to
021670c
Compare
tgasser-nv
approved these changes
Oct 13, 2026
tgasser-nv
left a comment
Collaborator
There was a problem hiding this comment.
Looks good! Can you add some more test coverage for the missing lines before merging?
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 13, 2026 09:33
021670c to
3a89b42
Compare
Base automatically changed from
pouyanpi/transparent-proxy-streaming-kernel-1
to
develop
October 13, 2026 10:02
Add provider-neutral helpers that derive stream event metadata from the typed projection declarations instead of a second authored policy. stream_text_path follows guarded fields directly, without schema generation, so unrelated field types cannot affect the binding. It follows guarded models, nullable model containers, and lists bounded to at most one item. Unlike buffered extraction, empty arrays, null containers, and null text are valid and become missing text for the event rule to classify. Union containers, unbounded arrays, non-string subjects, recursion, and ambiguous subjects are rejected. stream_shape_coverage collects event shapes by role from the declared rules, missing-text fallbacks, sentinels, and non-data shapes. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Declare the Chat single_text_delta.v1 stream boundary with typed projections and ObjectPolicy. The root, choice, and delta reject unreviewed members; reviewed root metadata passes through unchanged. A chunk carries zero or one choice whose index is exactly the integer 0 and whose logprobs are null, as in buffered responses. Missing or null content is metadata, empty string content is guarded text, and provider error messages are constrained, not guarded output. The error envelope is closed, and its error object is configurable but closed by default. Bind the projections to explicit stream event rules for content, provider errors, and the [DONE] sentinel, with field and shape coverage derived from the declarations. The OpenAI pin comes from providers/openai/source.py. Keep lifecycle checks in handwritten hooks: require an actual [DONE] for successful completion, distinguish it from keepalives, reject payloads after termination or a provider error, and frame native errors. Tests cover classification, unchecked sibling content, completion and termination, raw preservation, isolated hook state, rejected log probabilities and unreviewed members, and member-policy agreement between the export and the projections. JSON Schema accepts index 0.0 where the runtime does not, a known value-level gap. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
The pinned OpenAI schema types ChatCompletionStreamResponseDelta.tool_calls as an array with no minimum length, so an empty list is a valid value that carries no tool content. The stream delta declared it null-only and rejected such chunks, unlike buffered responses. Constrain delta tool_calls to null or an empty list, matching the buffered message. Any tool call chunk is still rejected. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Stream subjects now share the buffered check that a replacement blocker names a declared or reviewed opaque sibling. Streaming replacement stays unsupported, but a misspelled blocker is still a policy error. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
…bulary Field helpers rejected any Pydantic constraint the guard contract could not express, which pushed runtime declarations toward custom validators: the stream choice index used a BeforeValidator to require the integer zero. Helpers now accept the constraints declarations use (length, pattern, ge, le and strict), so the index is declared as a strict integer bounded to zero. Whether the export format can carry a constraint is checked at export time. Strictness has no JSON Schema keyword and is enforced at runtime only. The Chat stream classifier also drops unused aliases kept for an older compiler, derives field coverage directly, and names data-less keepalives "keepalive" instead of reusing the "[DONE]" sentinel's name. Runtime behavior is unchanged. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Adds cases for annotated array items, containers that do not lead to a model, untyped event models, text events without one assistant subject, and non-canonical or repeated sentinels. No runtime behavior changes. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Pouyanpi
force-pushed
the
pouyanpi/openai-chat-streaming-contract-2
branch
from
October 13, 2026 10:02
3a89b42 to
21cc830
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Declares OpenAI Chat stream policy in typed Python models, derives classification metadata, and supplies handwritten completion hooks and native error framing.
What Changed
tool_calls, and requires the choice index to be exactly the integer 0.ge,le, andstrictalongside length and pattern, so exact integers need no custom validator. Export checks separately whether the contract can carry a constraint.keepaliveshape and drops unused classifier aliases.[DONE]for successful completion and rejects duplicate termination or later payloads. Data-less keepalives and provider-error endings remain supported.Review Notes
Review the typed policy, derived coverage and text paths, event inventory, strict JSON, and handwritten completion/error hooks. Endpoint/HTTP integration lands in the final PR.
With output inspection enabled, missing completion produces a native stream error and withholds pending text. Previously approved bytes already sent cannot be retracted. Provider errors can end the stream without
[DONE]; the proxy preserves that failure without adding a missing-completion error.AI Assistance
Checklist
Stack Position
Part 2 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