up
This commit is contained in:
@@ -59,9 +59,12 @@ func main() {
|
|||||||
// 初始化用户
|
// 初始化用户
|
||||||
r.POST("/1/users/init", router.Handleinit)
|
r.POST("/1/users/init", router.Handleinit)
|
||||||
|
|
||||||
r.POST("/v1/chat/completions", router.HandleProy)
|
r.Any("/v1/*proxypath", router.HandleProy)
|
||||||
r.GET("/v1/models", router.HandleProy)
|
|
||||||
r.GET("/v1/dashboard/billing/subscription", router.HandleProy)
|
// r.POST("/v1/chat/completions", router.HandleProy)
|
||||||
|
// r.GET("/v1/models", router.HandleProy)
|
||||||
|
// r.GET("/v1/dashboard/billing/subscription", router.HandleProy)
|
||||||
|
|
||||||
r.GET("/", func(c *gin.Context) {
|
r.GET("/", func(c *gin.Context) {
|
||||||
c.Writer.WriteHeader(http.StatusOK)
|
c.Writer.WriteHeader(http.StatusOK)
|
||||||
c.Writer.WriteString(`<h1><a href="https://github.com/mirrors2/opencatd-open" >opencatd-open</a> available</h1>Api-Keys:<a href=https://platform.openai.com/account/api-keys >https://platform.openai.com/account/api-keys</a>`)
|
c.Writer.WriteString(`<h1><a href="https://github.com/mirrors2/opencatd-open" >opencatd-open</a> available</h1>Api-Keys:<a href=https://platform.openai.com/account/api-keys >https://platform.openai.com/account/api-keys</a>`)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"opencatd-open/store"
|
"opencatd-open/store"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sakurasan/to"
|
"github.com/Sakurasan/to"
|
||||||
@@ -20,8 +21,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rootToken string
|
rootToken string
|
||||||
baseUrl = "https://api.openai.com"
|
baseUrl = "https://api.openai.com"
|
||||||
|
GPT3Dot5Turbo = "gpt-3.5-turbo"
|
||||||
|
GPT4 = "gpt-4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
@@ -44,12 +47,7 @@ type Key struct {
|
|||||||
type ChatCompletionMessage struct {
|
type ChatCompletionMessage struct {
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
// This property isn't in the official documentation, but it's in
|
|
||||||
// the documentation for the official library for python:
|
|
||||||
// - https://github.com/openai/openai-python/blob/main/chatml.md
|
|
||||||
// - https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatCompletionRequest struct {
|
type ChatCompletionRequest struct {
|
||||||
@@ -296,6 +294,7 @@ func GenerateToken() string {
|
|||||||
|
|
||||||
func HandleProy(c *gin.Context) {
|
func HandleProy(c *gin.Context) {
|
||||||
var localuser bool
|
var localuser bool
|
||||||
|
var isStream bool
|
||||||
auth := c.Request.Header.Get("Authorization")
|
auth := c.Request.Header.Get("Authorization")
|
||||||
if len(auth) > 7 && auth[:7] == "Bearer " {
|
if len(auth) > 7 && auth[:7] == "Bearer " {
|
||||||
localuser = store.IsExistAuthCache(auth[7:])
|
localuser = store.IsExistAuthCache(auth[7:])
|
||||||
@@ -316,8 +315,18 @@ func HandleProy(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
client.Transport = tr
|
client.Transport = tr
|
||||||
|
|
||||||
|
if c.Request.URL.Path == "/v1/chat/completions" {
|
||||||
|
var chatreq = ChatCompletionRequest{}
|
||||||
|
if err := c.BindJSON(&chatreq); err != nil {
|
||||||
|
return
|
||||||
|
// c.AbortWithError(http.StatusBadRequest,)
|
||||||
|
}
|
||||||
|
isStream = chatreq.Stream
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 创建 API 请求
|
// 创建 API 请求
|
||||||
req, err := http.NewRequest(c.Request.Method, baseUrl+c.Request.URL.Path, c.Request.Body)
|
req, err := http.NewRequest(c.Request.Method, baseUrl+c.Request.RequestURI, c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
|
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
|
||||||
@@ -360,17 +369,18 @@ func HandleProy(c *gin.Context) {
|
|||||||
resp.Header.Del("content-security-policy-report-only")
|
resp.Header.Del("content-security-policy-report-only")
|
||||||
resp.Header.Del("clear-site-data")
|
resp.Header.Del("clear-site-data")
|
||||||
|
|
||||||
bodyRes, err := io.ReadAll(resp.Body)
|
// bodyRes, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Println(err)
|
// log.Println(err)
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
// c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||||
return
|
// return
|
||||||
|
// }
|
||||||
|
reader := bufio.NewReader(resp.Body)
|
||||||
|
|
||||||
|
if resp.StatusCode == 200 && isStream {
|
||||||
|
//todo
|
||||||
}
|
}
|
||||||
if resp.StatusCode == 200 {
|
resbody := io.NopCloser(reader)
|
||||||
// todo
|
|
||||||
log.Println(string(bodyRes))
|
|
||||||
}
|
|
||||||
resbody := io.NopCloser(bytes.NewReader(bodyRes))
|
|
||||||
// 返回 API 响应主体
|
// 返回 API 响应主体
|
||||||
c.Writer.WriteHeader(resp.StatusCode)
|
c.Writer.WriteHeader(resp.StatusCode)
|
||||||
if _, err := io.Copy(c.Writer, resbody); err != nil {
|
if _, err := io.Copy(c.Writer, resbody); err != nil {
|
||||||
@@ -452,3 +462,40 @@ func HandleUsage(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(200, usage)
|
c.JSON(200, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
func streamEvent(reader *bufio.Reader) error {
|
||||||
|
|
||||||
|
lineChan := make(chan string, 1)
|
||||||
|
|
||||||
|
timeout := time.AfterFunc(60*time.Second, func() {
|
||||||
|
lineChan <- ""
|
||||||
|
})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
line, err := reader.ReadString('\n')
|
||||||
|
if err == nil {
|
||||||
|
lineChan <- line
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
line := <-lineChan
|
||||||
|
|
||||||
|
timeout.Stop()
|
||||||
|
if line == "" {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "data:") {
|
||||||
|
line = strings.TrimSpace(strings.TrimPrefix(line, "data:"))
|
||||||
|
//log.Println("Received data:", line)
|
||||||
|
|
||||||
|
if line == "[DONE]" {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user