1
0
This commit is contained in:
Antonio Cheong 2023-04-03 01:36:34 +08:00
parent bec2d3a9b5
commit a832ca5152
3 changed files with 161 additions and 10 deletions

View File

@ -45,7 +45,6 @@ func SendRequest(message typings.ChatGPTRequest, puid *string, access_token stri
if err != nil {
return &http.Response{}, err
}
println(string(body_json))
response, err := client.Do(request)
return response, err
}

View File

@ -0,0 +1,54 @@
package responses
type Message struct {
ID string `json:"id"`
Author Author `json:"author"`
CreateTime float64 `json:"create_time"`
UpdateTime interface{} `json:"update_time"`
Content Content `json:"content"`
EndTurn interface{} `json:"end_turn"`
Weight float64 `json:"weight"`
Metadata Metadata `json:"metadata"`
Recipient string `json:"recipient"`
}
type Author struct {
Role string `json:"role"`
Name interface{} `json:"name"`
Metadata map[string]interface{} `json:"metadata"`
}
type Content struct {
ContentType string `json:"content_type"`
Parts []string `json:"parts"`
}
type Metadata struct {
Timestamp string `json:"timestamp_"`
MessageType interface{} `json:"message_type"`
FinishDetails interface{} `json:"finish_details"`
}
type Data struct {
Message Message `json:"message"`
ConversationID string `json:"conversation_id"`
Error interface{} `json:"error"`
}
type ChatCompletionChunk struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []Choices `json:"choices"`
}
type Choices struct {
Delta Delta `json:"delta"`
Index int `json:"index"`
FinishReason interface{} `json:"finish_reason"`
}
type Delta struct {
Content string `json:"content"`
Role string `json:"role"`
}

116
main.go
View File

@ -1,14 +1,17 @@
package main
import (
"bufio"
"encoding/json"
"freechatgpt/internal/chatgpt"
"freechatgpt/internal/tokens"
typings "freechatgpt/internal/typings"
"freechatgpt/internal/typings/responses"
"io"
"os"
"strings"
"github.com/gin-gonic/gin"
_ "github.com/r3labs/sse/v2"
)
var HOST string
@ -79,7 +82,9 @@ func main() {
var chat_request typings.APIRequest
err := c.BindJSON(&chat_request)
if err != nil {
c.String(400, "chat request not provided")
c.JSON(400, gin.H{
"error": "invalid request",
})
return
}
// Convert the chat request to a ChatGPT request
@ -87,16 +92,109 @@ func main() {
// c.JSON(200, chatgpt_request)
response, err := chatgpt.SendRequest(chatgpt_request, &PUID, ACCESS_TOKENS.GetToken())
if err != nil {
c.String(500, "error sending request")
c.JSON(500, gin.H{
"error": "error sending request",
})
return
}
defer response.Body.Close()
c.Status(response.StatusCode)
c.Stream(func(w io.Writer) bool {
// Write data to client
io.Copy(w, response.Body)
return false
})
if response.StatusCode != 200 {
c.JSON(response.StatusCode, gin.H{
"error": "error sending request",
})
return
}
// Create a bufio.Reader from the response body
reader := bufio.NewReader(response.Body)
var fulltext string
// Read the response byte by byte until a newline character is encountered
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
break
}
c.JSON(500, gin.H{
"error": "error reading response",
})
return
}
if len(line) < 6 {
continue
}
// Remove "data: " from the beginning of the line
line = line[6:]
// Parse the line as JSON
var chat_response responses.Data
err = json.Unmarshal([]byte(line), &chat_response)
if err != nil {
c.JSON(500, gin.H{
"error": "error parsing response",
})
return
}
if chat_response.Error != nil {
c.JSON(500, gin.H{
"error": chat_response.Error,
})
return
}
if chat_response.Message.Content.Parts[0] == "" || chat_response.Message.Author.Role != "assistant" {
continue
}
tmp_fulltext := chat_response.Message.Content.Parts[0]
chat_response.Message.Content.Parts[0] = strings.ReplaceAll(chat_response.Message.Content.Parts[0], fulltext, "")
var delta responses.Delta = responses.Delta{
Content: chat_response.Message.Content.Parts[0],
Role: "assistant",
}
var finish_reason interface{}
if chat_response.Message.Metadata.FinishDetails != nil {
finish_reason = "stop"
delta.Content = ""
} else {
finish_reason = nil
}
completions_response := responses.ChatCompletionChunk{
ID: "chatcmpl-QXlha2FBbmROaXhpZUFyZUF3ZXNvbWUK",
Object: "chat.completion.chunk",
Created: int64(chat_response.Message.CreateTime),
Model: "gpt-3.5-turbo-0301",
Choices: []responses.Choices{
{
Index: 0,
Delta: delta,
FinishReason: finish_reason,
},
},
}
// Stream the response to the client
response_string, err := json.Marshal(completions_response)
if err != nil {
c.JSON(500, gin.H{
"error": "error parsing response",
})
return
}
_, err = c.Writer.WriteString("data: " + string(response_string) + "\n\n")
if err != nil {
c.JSON(500, gin.H{
"error": "error writing response",
})
return
}
// Flush the response writer buffer to ensure that the client receives each line as it's written
c.Writer.Flush()
fulltext = tmp_fulltext
if finish_reason != nil {
c.String(200, "data: [DONE]")
break
}
}
})
router.Run(HOST + ":" + PORT)