| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package service
- import (
- "bufio"
- "bytes"
- "encoding/json"
- "io"
- "strings"
- )
- const (
- maxOpenAIConcatenatedJSONDocuments = 16
- maxOpenAIConcatenatedJSONBytes = 16 * 1024 * 1024
- )
- // splitOpenAIConcatenatedJSONDocuments recognizes the narrow corruption shape
- // produced when multiple complete Responses events arrive in one transport
- // message. Other malformed payloads are left untouched for normal error paths.
- func splitOpenAIConcatenatedJSONDocuments(payload []byte) ([][]byte, bool) {
- payload = bytes.TrimSpace(payload)
- if len(payload) == 0 || len(payload) > maxOpenAIConcatenatedJSONBytes || json.Valid(payload) {
- return nil, false
- }
- decoder := json.NewDecoder(bytes.NewReader(payload))
- documents := make([][]byte, 0, 2)
- for {
- var raw json.RawMessage
- err := decoder.Decode(&raw)
- if err != nil {
- if err == io.EOF && len(documents) > 1 {
- return documents, true
- }
- return nil, false
- }
- raw = bytes.TrimSpace(raw)
- var envelope struct {
- Type string `json:"type"`
- }
- if err := json.Unmarshal(raw, &envelope); err != nil {
- return nil, false
- }
- eventType := strings.TrimSpace(envelope.Type)
- if eventType == "" || strings.ContainsAny(eventType, "\r\n") {
- return nil, false
- }
- if len(documents) == maxOpenAIConcatenatedJSONDocuments {
- return nil, false
- }
- documents = append(documents, raw)
- }
- }
- type openAISSEJSONDocumentScanner struct {
- scanner *bufio.Scanner
- pending []string
- current string
- }
- func newOpenAISSEJSONDocumentScanner(scanner *bufio.Scanner) *openAISSEJSONDocumentScanner {
- return &openAISSEJSONDocumentScanner{scanner: scanner}
- }
- func (s *openAISSEJSONDocumentScanner) Scan() bool {
- if len(s.pending) > 0 {
- s.current = s.pending[0]
- s.pending = s.pending[1:]
- return true
- }
- if s.scanner == nil || !s.scanner.Scan() {
- return false
- }
- line := s.scanner.Text()
- data, ok := extractOpenAISSEDataLine(line)
- if !ok {
- s.current = line
- return true
- }
- if len(data) > maxOpenAIConcatenatedJSONBytes {
- s.current = line
- return true
- }
- documents, repaired := splitOpenAIConcatenatedJSONDocuments([]byte(data))
- if !repaired {
- s.current = line
- return true
- }
- expanded := make([]string, 0, len(documents)*3)
- for i, document := range documents {
- if i > 0 {
- var envelope struct {
- Type string `json:"type"`
- }
- _ = json.Unmarshal(document, &envelope)
- expanded = append(expanded, "event: "+strings.TrimSpace(envelope.Type))
- }
- expanded = append(expanded, "data: "+string(document), "")
- }
- s.current = expanded[0]
- s.pending = expanded[1:]
- return true
- }
- func (s *openAISSEJSONDocumentScanner) Text() string {
- return s.current
- }
- func (s *openAISSEJSONDocumentScanner) Err() error {
- if s.scanner == nil {
- return nil
- }
- return s.scanner.Err()
- }
|