package model import ( "aiChat/internal/consts" "bufio" "context" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/gclient" "github.com/gogf/gf/v2/util/gconv" "io" "net/http" "strings" ) type GPTReq struct { *BaseQuestion Identity string `json:"identity"` } // SimpleRes 语义服务,响应常用问题 type SimpleRes struct { Status int `json:"status"` Result struct { Prompt string `json:"prompt"` Answer string `json:"answer"` } `json:"result"` } // GPTRes 业务及扩展聊天响应 type GPTRes struct { Status int `json:"status"` Response string `json:"response"` History [][]string `json:"history"` Time string `json:"time"` } var ( ChatGpt = &cChatGpt{} ) type cChatGpt struct { } func (c *cChatGpt) SimpleDo(ctx context.Context, qReq *QuestionReq) (res *SimpleRes, err error) { gReq := GPTReq{ BaseQuestion: qReq.BaseQuestion, Identity: g.Config().MustGet(ctx, "chat.api.identity", "剑鱼chat").String(), } var gRes *gclient.Response gRes, err = g.Client().Header(consts.RequestJsonHeader).Post(ctx, g.Config().MustGet(ctx, "chat.api.addr_simple", "").String(), gReq) if err != nil { return nil, err } res = &SimpleRes{} defer gRes.Close() err = gconv.Struct(gRes.ReadAll(), res) //g.Dump("SimpleDo", gReq, res) if err != nil { return nil, err } return } func (c *cChatGpt) GPTDo(ctx context.Context, qReq *QuestionReq) (res io.ReadCloser, err error) { gReq := GPTReq{ BaseQuestion: qReq.BaseQuestion, Identity: g.Config().MustGet(ctx, "chat.api.identity", "剑鱼chat").String(), } if gReq.History == nil { gReq.History = [][]string{} } req, err := http.NewRequest("POST", g.Config().MustGet(ctx, "chat.api.addr_answer", "").String(), strings.NewReader(gconv.String(gReq))) if err != nil { return nil, err } client := &http.Client{} req.Header.Set("Accept", "text/event-stream") resp, err := client.Do(req) if err != nil { return nil, err } return resp.Body, nil } type BufRes struct { Delta string `json:"delta"` Response string `json:"response"` Finished bool `json:"finished"` } func readEvent(res *bufio.Reader) (string, error) { event := "" buf := make([]byte, 1024) for { n, err := res.Read(buf) if err != nil { return "", err } // 解析Event-Stream消息 for _, b := range buf[:n] { if b == '\n' { return event, nil } event += string(b) } } }