Skip to content

Unknown Stream Events Classified as a ResponseErrorEvent #287

Description

@hirparap1

Intermittently, when using OpenAI::Client.new(...).responses.stream(...) we will receive a keepalive event: e.g.,{"sequence_number":3,"type":"keepalive"}. We are using Azure OpenAI, so my guess is that these keepalive events are sent to keep the connection open when there's a gap between received events or a larger time-to-first-token (although there is no mention of these events in the Azure documentation of this).

In our code, we have a case statement branching on different types of ResponseStreamEvent:

      # Translates events from the OpenAI::Models::Responses::ResponseStreamEvent to StreamResponseEvent
      def parse_stream_event(event:)
        case event
        when OpenAI::Models::Responses::ResponseCreatedEvent
          parse_created_event(event:)
        when OpenAI::Models::Responses::ResponseTextDeltaEvent
          parse_output_text_delta_event(event:)
        when OpenAI::Models::Responses::ResponseCompletedEvent
          parse_completed_event(event:)
        when OpenAI::Models::Responses::ResponseFailedEvent
          parse_failed_event(event:)
        when OpenAI::Models::Responses::ResponseIncompleteEvent
          report_token_usage(response: event.response)
          parse_incomplete_event(event:)
        when OpenAI::Models::Responses::ResponseErrorEvent
          parse_error(event:)
        end
      end

We are seeing these keepalive events being classified as a ResponseErrorEvent, resulting in our code treating these keepalive events as errors. Looking at the OpenAI::Internal::Type::Union#coerce method, it seems as though it tries to match the best-fit variant but does not enforce type matching the expected value for the variant.

We've since added logic to skip these events if type == 'keepalive' but I wanted to share this in case this is not expected behavior and the logic for Union#coerce should be altered to be more strict

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions