SSEDecoder can legitimately yield an event with empty data for control-only blocks such as id: or retry:. Stream.__stream__() and AsyncStream.__stream__() currently pass every yielded event to sse.json(), so a control-only block terminates an otherwise valid stream with a JSON decoding error before the next API data event is processed.
Example wire sequence:
Expected behavior: OpenAI JSON stream processing should ignore control-only SSE records with empty data and continue to the next data event. Decoder state such as event ID and retry may still be preserved at the SSE layer.
Actual behavior: the stream attempts to parse the empty control record as JSON and fails.
SSEDecodercan legitimately yield an event with emptydatafor control-only blocks such asid:orretry:.Stream.__stream__()andAsyncStream.__stream__()currently pass every yielded event tosse.json(), so a control-only block terminates an otherwise valid stream with a JSON decoding error before the next API data event is processed.Example wire sequence:
Expected behavior: OpenAI JSON stream processing should ignore control-only SSE records with empty data and continue to the next data event. Decoder state such as event ID and retry may still be preserved at the SSE layer.
Actual behavior: the stream attempts to parse the empty control record as JSON and fails.