65 lines
1.9 KiB
Go
65 lines
1.9 KiB
Go
package openai
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
func writeContentDeltaSSE(w http.ResponseWriter, flusher http.Flusher, id string, created int64, model string, content string) {
|
|
if content == "" {
|
|
return
|
|
}
|
|
writeSSE(w, flusher, chatCompletionChunk{
|
|
ID: id,
|
|
Object: "chat.completion.chunk",
|
|
Created: created,
|
|
Model: model,
|
|
Choices: []chatCompletionChunkChoice{{
|
|
Index: 0,
|
|
Delta: chatDelta{Content: content},
|
|
}},
|
|
})
|
|
}
|
|
|
|
func writeToolCallsDeltaSSE(w http.ResponseWriter, flusher http.Flusher, id string, created int64, model string, toolCalls []any) {
|
|
if len(toolCalls) == 0 {
|
|
return
|
|
}
|
|
writeSSE(w, flusher, chatCompletionChunk{
|
|
ID: id,
|
|
Object: "chat.completion.chunk",
|
|
Created: created,
|
|
Model: model,
|
|
Choices: []chatCompletionChunkChoice{{
|
|
Index: 0,
|
|
Delta: chatDelta{ToolCalls: toolCallsForStreamDelta(toolCalls)},
|
|
}},
|
|
})
|
|
}
|
|
|
|
// streamBufferedChatCompletion collects the full run output, validates tool
|
|
// calls against the request schema before emitting anything, and — when
|
|
// validation fails on a run that has not yet written a user-visible chunk —
|
|
// resubmits the same request as a bounded exact replay. Only a validated (or
|
|
// validation-disabled) result reaches the SSE writer; a malformed tool call
|
|
// that survives the retry budget is surfaced as an SSE error instead of a
|
|
|
|
func writeSSE(w http.ResponseWriter, flusher http.Flusher, v any) {
|
|
b, err := json.Marshal(v)
|
|
if err != nil {
|
|
return
|
|
}
|
|
fmt.Fprintf(w, "data: %s\n\n", b)
|
|
flusher.Flush()
|
|
}
|
|
|
|
func writeSSEError(w http.ResponseWriter, flusher http.Flusher, message string) {
|
|
writeSSEErrorWithType(w, flusher, "run_error", message)
|
|
}
|
|
|
|
func writeSSEErrorWithType(w http.ResponseWriter, flusher http.Flusher, errType, message string) {
|
|
writeSSE(w, flusher, errorResponse{Error: errorBody{Type: errType, Message: message}})
|
|
fmt.Fprint(w, "data: [DONE]\n\n")
|
|
flusher.Flush()
|
|
}
|