package openai import ( "bufio" "fmt" "net/http" "strings" ) // PipeSSE reads an OpenAI SSE response body and writes each event line to w, // flushing after every chunk. It returns when the upstream sends "data: [DONE]" // or when the response body is exhausted. // // The caller is responsible for setting the SSE response headers before // calling PipeSSE. The function only writes the event payloads. func PipeSSE(body *bufio.Scanner, w http.ResponseWriter) error { flusher, ok := w.(http.Flusher) if !ok { return fmt.Errorf("response writer does not support flushing (SSE not possible)") } for body.Scan() { line := body.Text() // Blank lines are SSE field separators — skip them. if line == "" { continue } // Write the line followed by the SSE double-newline terminator. if _, err := fmt.Fprintf(w, "%s\n\n", line); err != nil { return fmt.Errorf("writing SSE chunk: %w", err) } flusher.Flush() // OpenAI signals end-of-stream with this sentinel. if strings.TrimSpace(line) == "data: [DONE]" { return nil } } if err := body.Err(); err != nil { return fmt.Errorf("reading SSE body: %w", err) } return nil }