From 34ef211bdfea510aee52c046f7152e365f204bd7 Mon Sep 17 00:00:00 2001 From: zeke Date: Mon, 25 Nov 2024 17:27:16 +0800 Subject: [PATCH] gogo --- cmd/server/main.go | 25 +++++++++++++++++++++++++ go.mod | 33 +-------------------------------- internal/api/handlers.go | 33 +++++++++++++++++++++++++++++++++ internal/api/routes.go | 15 +++++++++++++++ internal/models/types.go | 14 ++++++++++++++ internal/service/chat.go | 15 +++++++++++++++ internal/utils/hex.go | 5 +++++ internal/utils/process.go | 5 +++++ main.go | 27 +++++++++++++++++++++++++++ 9 files changed, 140 insertions(+), 32 deletions(-) create mode 100644 cmd/server/main.go create mode 100644 internal/api/handlers.go create mode 100644 internal/api/routes.go create mode 100644 internal/models/types.go create mode 100644 internal/service/chat.go create mode 100644 internal/utils/hex.go create mode 100644 internal/utils/process.go diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 0000000..d4332a5 --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "log" + "os" + + "github.com/joho/godotenv" + "cursor-api-proxy/internal/api" +) + +func main() { + if err := godotenv.Load(); err != nil { + log.Println("Warning: Error loading .env file") + } + + server := api.NewServer() + + port := os.Getenv("PORT") + if port == "" { + port = "3000" + } + + log.Printf("服务器运行在端口 %s\n", port) + server.Run(":" + port) +} \ No newline at end of file diff --git a/go.mod b/go.mod index 4c82cdf..35f2184 100644 --- a/go.mod +++ b/go.mod @@ -2,35 +2,4 @@ module cursor-api-proxy go 1.21 -require ( - github.com/gin-gonic/gin v1.9.1 - github.com/google/uuid v1.6.0 - github.com/joho/godotenv v1.5.1 -) - -require ( - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) +// ... 其他依赖 ... diff --git a/internal/api/handlers.go b/internal/api/handlers.go new file mode 100644 index 0000000..7ad70e6 --- /dev/null +++ b/internal/api/handlers.go @@ -0,0 +1,33 @@ +package api + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "cursor-api-proxy/internal/models" + "cursor-api-proxy/internal/service" +) + +func handleChat(c *gin.Context) { + var req models.ChatRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + // 检查是否为 o1 开头的模型且请求流式输出 + if strings.HasPrefix(req.Model, "o1-") && req.Stream { + c.JSON(http.StatusBadRequest, gin.H{"error": "Model not supported stream"}) + return + } + + // ... 其他处理逻辑 ... + + if req.Stream { + service.HandleStreamResponse(c, req) + return + } + + service.HandleNormalResponse(c, req) +} \ No newline at end of file diff --git a/internal/api/routes.go b/internal/api/routes.go new file mode 100644 index 0000000..20046b1 --- /dev/null +++ b/internal/api/routes.go @@ -0,0 +1,15 @@ +package api + +import ( + "github.com/gin-gonic/gin" +) + +func NewServer() *gin.Engine { + r := gin.Default() + setupRoutes(r) + return r +} + +func setupRoutes(r *gin.Engine) { + r.POST("/v1/chat/completions", handleChat) +} \ No newline at end of file diff --git a/internal/models/types.go b/internal/models/types.go new file mode 100644 index 0000000..f6f6c3f --- /dev/null +++ b/internal/models/types.go @@ -0,0 +1,14 @@ +package models + +type Message struct { + Role string `json:"role"` + Content string `json:"content"` +} + +type ChatRequest struct { + Model string `json:"model"` + Messages []Message `json:"messages"` + Stream bool `json:"stream"` +} + +// ... 其他类型定义 ... \ No newline at end of file diff --git a/internal/service/chat.go b/internal/service/chat.go new file mode 100644 index 0000000..0ad206b --- /dev/null +++ b/internal/service/chat.go @@ -0,0 +1,15 @@ +package service + +import ( + "github.com/gin-gonic/gin" + "cursor-api-proxy/internal/models" + "cursor-api-proxy/internal/utils" +) + +func HandleStreamResponse(c *gin.Context, req models.ChatRequest) { + // 从 handlers.go 移动流式响应处理逻辑到这里 +} + +func HandleNormalResponse(c *gin.Context, req models.ChatRequest) { + // 从 handlers.go 移动普通响应处理逻辑到这里 +} \ No newline at end of file diff --git a/internal/utils/hex.go b/internal/utils/hex.go new file mode 100644 index 0000000..f66bf29 --- /dev/null +++ b/internal/utils/hex.go @@ -0,0 +1,5 @@ +package utils + +func StringToHex(str, modelName string) []byte { + // 从 utils.go 移动转换逻辑到这里 +} \ No newline at end of file diff --git a/internal/utils/process.go b/internal/utils/process.go new file mode 100644 index 0000000..6c8df2d --- /dev/null +++ b/internal/utils/process.go @@ -0,0 +1,5 @@ +package utils + +func ProcessChunk(chunk []byte) string { + // 从 process.go 移动处理逻辑到这里 +} \ No newline at end of file diff --git a/main.go b/main.go index 85caa2f..830ca0c 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,18 @@ import ( "github.com/joho/godotenv" ) +// 在 main() 函数之前添加以下结构体定义 +type ChatRequest struct { + Model string `json:"model"` + Messages []Message `json:"messages"` + Stream bool `json:"stream"` +} + +type Message struct { + Role string `json:"role"` + Content string `json:"content"` +} + func main() { if err := godotenv.Load(); err != nil { log.Println("Warning: Error loading .env file") @@ -67,4 +79,19 @@ func handleChat(c *gin.Context) { // 处理非流式请求 handleNormalResponse(c, req) +} + +// 在文件末尾添加这两个新函数 +func handleStreamResponse(c *gin.Context, req ChatRequest) { + // TODO: 实现流式响应的逻辑 + c.JSON(http.StatusNotImplemented, gin.H{ + "error": "Stream response not implemented yet", + }) +} + +func handleNormalResponse(c *gin.Context, req ChatRequest) { + // TODO: 实现普通响应的逻辑 + c.JSON(http.StatusNotImplemented, gin.H{ + "error": "Normal response not implemented yet", + }) } \ No newline at end of file