pig_protocol/sse

Parsers for OpenAI Server-Sent Events (SSE) streams.

Handles two streams:

The framing decoder is pure and operates on byte chunks. It does not convert a network chunk to a string until a complete event is available.

Types

The pure state carried between raw network chunks.

The buffer is kept as bytes so a UTF-8 code point split across chunks is not decoded prematurely.

pub opaque type Decoder

The framing decoder could not decode a complete event as UTF-8.

pub type DecoderError {
  InvalidUtf8
}

Constructors

  • InvalidUtf8

A decoded event from an OpenAI Responses API (Codex) SSE stream.

pub type ResponsesEvent {
  ResponseCreated(id: String)
  OutputTextDelta(delta: String)
  FunctionCallArgumentsDelta(delta: String)
  FunctionCallArgumentsDone(arguments: String)
  ResponseCompleted(metadata: inference.InferenceMetadata)
  ResponseIncomplete(metadata: inference.InferenceMetadata)
  ResponseFailed(message: String)
  ResponseError(message: String)
  OtherResponseEvent
}

Constructors

  • ResponseCreated(id: String)
  • OutputTextDelta(delta: String)
  • FunctionCallArgumentsDelta(delta: String)
  • FunctionCallArgumentsDone(arguments: String)
  • ResponseCompleted(metadata: inference.InferenceMetadata)
  • ResponseIncomplete(metadata: inference.InferenceMetadata)
  • ResponseFailed(message: String)
  • ResponseError(message: String)
  • OtherResponseEvent

A decoded delta from a Chat Completions SSE stream.

pub type StreamDelta {
  ContentChunk(String)
  UsageChunk(input: Int, output: Int)
  StreamDone
}

Constructors

  • ContentChunk(String)
  • UsageChunk(input: Int, output: Int)
  • StreamDone

Values

pub fn finish(
  decoder: Decoder,
) -> Result(List(String), DecoderError)

Finish a stream and emit one event if bytes remain without a final blank line. A trailing partial line is valid at end of an SSE response.

pub fn frame_data(frame: String) -> String

Extract the concatenated data: payload from an SSE frame.

Ignores comments and unknown fields. Multiple data: lines are joined with a newline, as required by the SSE event stream format. The single optional space after data: is removed, but all other payload whitespace is preserved.

pub fn new() -> Decoder

Create an empty SSE frame decoder.

pub fn parse_chat_line(data: String) -> Result(StreamDelta, Nil)

Parse a single data: payload from a Chat Completions stream.

Returns StreamDone for [DONE], UsageChunk for a final usage frame, and ContentChunk for a token delta.

pub fn parse_responses_event(data: String) -> ResponsesEvent

Parse a single data: payload from a Responses API stream.

pub fn push(
  decoder: Decoder,
  chunk: BitArray,
) -> Result(#(Decoder, List(String)), DecoderError)

Add one byte chunk and return complete SSE frames plus the new decoder.

Frames do not include their blank-line delimiter. The returned strings are only decoded after the delimiter is found, so chunks may split delimiters and multibyte UTF-8 code points safely.

pub fn split_frames(buffer: String) -> #(List(String), String)

Split a buffer into complete SSE frames and any trailing partial frame.

This string-based helper is retained for callers that already have a decoded response. New streaming callers should use new, push, and finish so decoding is deferred until a complete frame is available.

Search Document