2025-08-05 03:56:23 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
2025-08-11 01:21:05 +02:00
|
|
|
|
|
|
|
"github.com/revrost/go-openrouter"
|
2025-08-05 03:56:23 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type Chunk struct {
|
|
|
|
Type string `json:"type"`
|
|
|
|
Text string `json:"text"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Stream struct {
|
|
|
|
wr http.ResponseWriter
|
|
|
|
fl http.Flusher
|
|
|
|
en *json.Encoder
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewStream(w http.ResponseWriter) (*Stream, error) {
|
|
|
|
flusher, ok := w.(http.Flusher)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("failed to create flusher")
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/event-stream")
|
|
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
|
|
w.Header().Set("Connection", "keep-alive")
|
|
|
|
|
|
|
|
return &Stream{
|
|
|
|
wr: w,
|
|
|
|
fl: flusher,
|
|
|
|
en: json.NewEncoder(w),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Stream) Send(ch Chunk) error {
|
|
|
|
if err := s.en.Encode(ch); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := s.wr.Write([]byte("\n\n")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
s.fl.Flush()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReasoningChunk(text string) Chunk {
|
|
|
|
return Chunk{
|
|
|
|
Type: "reason",
|
|
|
|
Text: text,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TextChunk(text string) Chunk {
|
|
|
|
return Chunk{
|
|
|
|
Type: "text",
|
|
|
|
Text: text,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-08-11 15:43:00 +02:00
|
|
|
func IDChunk(id string) Chunk {
|
|
|
|
return Chunk{
|
|
|
|
Type: "id",
|
|
|
|
Text: id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-08-05 03:56:23 +02:00
|
|
|
func ErrorChunk(err error) Chunk {
|
|
|
|
return Chunk{
|
|
|
|
Type: "error",
|
2025-08-11 01:21:05 +02:00
|
|
|
Text: GetErrorMessage(err),
|
2025-08-05 03:56:23 +02:00
|
|
|
}
|
|
|
|
}
|
2025-08-11 01:21:05 +02:00
|
|
|
|
|
|
|
func GetErrorMessage(err error) string {
|
|
|
|
if apiErr, ok := err.(*openrouter.APIError); ok {
|
|
|
|
return apiErr.Error()
|
|
|
|
}
|
|
|
|
|
|
|
|
return err.Error()
|
|
|
|
}
|