pig_protocol/sse
Parsers for OpenAI Server-Sent Events (SSE) streams.
Handles two streams:
- Chat Completions:
parse_chat_linedecodes per-token deltas. - Responses API (Codex):
parse_responses_eventdecodes typed events keyed off the event’stypefield.
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 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.