pref(ChatGPT): advanced streaming and text transformation, support reasoner model

This commit is contained in:
Jacky 2025-01-31 20:51:48 +08:00
parent 4f674ec13e
commit 2af29eb80f
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
4 changed files with 273 additions and 97 deletions

View file

@ -2,15 +2,17 @@ package openai
import (
"context"
"errors"
"fmt"
"github.com/0xJacky/Nginx-UI/internal/chatbot"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"errors"
"github.com/sashabaranov/go-openai"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
"io"
"strings"
"time"
)
const ChatGPTInitPrompt = `You are a assistant who can help users write and optimise the configurations of Nginx,
@ -83,31 +85,69 @@ func MakeChatCompletionRequest(c *gin.Context) {
msgChan := make(chan string)
go func() {
defer close(msgChan)
messageCh := make(chan string)
// 消息接收协程
go func() {
defer close(messageCh)
for {
response, err := stream.Recv()
if errors.Is(err, io.EOF) {
return
}
if err != nil {
messageCh <- fmt.Sprintf("error: %v", err)
logger.Errorf("Stream error: %v\n", err)
return
}
messageCh <- response.Choices[0].Delta.Content
}
}()
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
var buffer strings.Builder
for {
response, err := stream.Recv()
if errors.Is(err, io.EOF) {
return
select {
case msg, ok := <-messageCh:
if !ok {
if buffer.Len() > 0 {
msgChan <- buffer.String()
}
return
}
if strings.HasPrefix(msg, "error: ") {
msgChan <- msg
return
}
buffer.WriteString(msg)
case <-ticker.C:
if buffer.Len() > 0 {
msgChan <- buffer.String()
buffer.Reset()
}
}
if err != nil {
logger.Errorf("Stream error: %v\n", err)
return
}
message := fmt.Sprintf("%s", response.Choices[0].Delta.Content)
msgChan <- message
}
}()
c.Stream(func(w io.Writer) bool {
if m, ok := <-msgChan; ok {
c.SSEvent("message", gin.H{
"type": "message",
"content": m,
})
return true
m, ok := <-msgChan
if !ok {
return false
}
return false
if strings.HasPrefix(m, "error: ") {
c.SSEvent("message", gin.H{
"type": "error",
"content": strings.TrimPrefix(m, "error: "),
})
return false
}
c.SSEvent("message", gin.H{
"type": "message",
"content": m,
})
return true
})
}