85 lines
2.7 KiB
Go
85 lines
2.7 KiB
Go
package httpapi
|
|
|
|
import "net/http"
|
|
|
|
func prepareCompatibleStream(w http.ResponseWriter) http.Flusher {
|
|
w.Header().Set("Content-Type", "text/event-stream")
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
w.Header().Set("Connection", "keep-alive")
|
|
flusher, _ := w.(http.Flusher)
|
|
return flusher
|
|
}
|
|
|
|
func writeCompatibleDelta(w http.ResponseWriter, kind string, model string, content string) {
|
|
if kind == "responses" {
|
|
sendSSE(w, "response.output_text.delta", map[string]any{"type": "response.output_text.delta", "delta": content})
|
|
return
|
|
}
|
|
sendSSE(w, "message", map[string]any{
|
|
"id": "chatcmpl-stream",
|
|
"object": "chat.completion.chunk",
|
|
"model": model,
|
|
"choices": []any{map[string]any{"index": 0, "delta": map[string]any{"content": content}, "finish_reason": nil}},
|
|
})
|
|
}
|
|
|
|
func writeCompatibleDone(w http.ResponseWriter, kind string, model string, output map[string]any) {
|
|
if kind == "responses" {
|
|
sendSSE(w, "response.completed", map[string]any{"type": "response.completed", "response": output})
|
|
return
|
|
}
|
|
sendSSE(w, "message", map[string]any{
|
|
"id": firstString(output["id"], "chatcmpl-stream"),
|
|
"object": "chat.completion.chunk",
|
|
"model": model,
|
|
"choices": []any{map[string]any{"index": 0, "delta": map[string]any{}, "finish_reason": "stop"}},
|
|
})
|
|
}
|
|
|
|
func writeCompatibleStream(w http.ResponseWriter, kind string, model string, output map[string]any) {
|
|
prepareCompatibleStream(w)
|
|
content := extractOutputText(output)
|
|
if content == "" {
|
|
content = "done"
|
|
}
|
|
if kind == "responses" {
|
|
sendSSE(w, "response.output_text.delta", map[string]any{"type": "response.output_text.delta", "delta": content})
|
|
sendSSE(w, "response.completed", map[string]any{"type": "response.completed", "response": output})
|
|
return
|
|
}
|
|
sendSSE(w, "message", map[string]any{
|
|
"id": output["id"],
|
|
"object": "chat.completion.chunk",
|
|
"model": model,
|
|
"choices": []any{map[string]any{"index": 0, "delta": map[string]any{"content": content}, "finish_reason": nil}},
|
|
})
|
|
sendSSE(w, "message", map[string]any{
|
|
"id": output["id"],
|
|
"object": "chat.completion.chunk",
|
|
"model": model,
|
|
"choices": []any{map[string]any{"index": 0, "delta": map[string]any{}, "finish_reason": "stop"}},
|
|
})
|
|
}
|
|
|
|
func firstString(value any, fallback string) string {
|
|
if text, ok := value.(string); ok && text != "" {
|
|
return text
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func extractOutputText(output map[string]any) string {
|
|
if text, ok := output["output_text"].(string); ok {
|
|
return text
|
|
}
|
|
choices, _ := output["choices"].([]any)
|
|
for _, rawChoice := range choices {
|
|
choice, _ := rawChoice.(map[string]any)
|
|
message, _ := choice["message"].(map[string]any)
|
|
if content, ok := message["content"].(string); ok {
|
|
return content
|
|
}
|
|
}
|
|
return ""
|
|
}
|