47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
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
|
|
}
|