Fix: AttributeError: 'Stream' object has no attribute 'choices' and Real-Time Streaming#2145
Open
ramikhafagi96 wants to merge 4 commits into567-labs:mainfrom
Open
Fix: AttributeError: 'Stream' object has no attribute 'choices' and Real-Time Streaming#2145ramikhafagi96 wants to merge 4 commits into567-labs:mainfrom
ramikhafagi96 wants to merge 4 commits into567-labs:mainfrom
Conversation
Collaborator
|
I don’t have time to take this one over right now. I’m not going to merge it as-is, but I’ll revisit the streaming design later when I can review the retry/reask semantics and add the missing coverage. |
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.
Fix streaming behavior in
create()andcreate_partial()Summary
This PR fixes two issues in the streaming path:
create(stream=True)crashes withAttributeError: 'Stream' object has no attribute 'choices'.create_partial()buffers the entire stream into a list, preventingreal-time streaming of partial models.
The changes enable true streaming for partial models and ensure
create(stream=True)works correctly.Problems
1.
create(stream=True)crashWhen
stream=Trueis used withoutPartial, the OpenAIStreamobjectis passed directly to
process_response().Execution falls through to
from_response(), which expects aChatCompletionobject and accessescompletion.choices. SinceStreamis an iterator, this results in:2.
create_partial()disables streamingcreate_partial()wraps the model withPartialand setsstream=True, butprocess_response()consumes the generator:Because
list()eagerly consumes the generator, the entire stream isbuffered before returning. As a result, partial models are not yielded
in real time.
Fix
Generator passthrough for partial streaming
Return the generator directly instead of wrapping it in
list().Before:
After:
This allows callers to iterate over partial models as they arrive.
Fallback for
create(stream=True)Added
_accumulate_stream()to consume a rawStreamand construct asynthetic
ChatCompletionbefore passing it tofrom_response().This prevents the
Stream→choicescrash.Retry behavior with streaming
Retry logic is fundamentally incompatible with streaming partial
responses.
When
create_partial()streams results, partial models may already beyielded to the caller. If validation fails later in the stream, retrying
the request would require retracting previously yielded results, which
is not possible.
For this reason, when
process_response()returns a generator(streaming
Partialcase),retry_syncnow returns it directly insteadof attempting retry logic.
This preserves existing retry behavior for non-streaming calls,
while allowing streaming generators to pass through unchanged.
Changes
response.py - Return generator for
PartialBase + stream- Add_accumulate_stream()helper - Add fallback handling forcreate(stream=True)retry.py - Add
Generatorimport - Return generators directly inretry_syncImpact
create_partial()now streams partial models in real timecreate(stream=True)no longer crashesTested with
instructor==1.14.1.