| | package handler
|
| |
|
| | import (
|
| | "crypto/rand"
|
| | "encoding/hex"
|
| | "encoding/json"
|
| | "errors"
|
| | "fmt"
|
| | "io"
|
| | "net/http"
|
| |
|
| | "github.com/gin-gonic/gin"
|
| | "zencoder-2api/internal/model"
|
| | "zencoder-2api/internal/service"
|
| | )
|
| |
|
| | type OpenAIHandler struct {
|
| | svc *service.OpenAIService
|
| | grokSvc *service.GrokService
|
| | }
|
| |
|
| | func NewOpenAIHandler() *OpenAIHandler {
|
| | return &OpenAIHandler{
|
| | svc: service.NewOpenAIService(),
|
| | grokSvc: service.NewGrokService(),
|
| | }
|
| | }
|
| |
|
| |
|
| | func generateTraceID() string {
|
| | b := make([]byte, 16)
|
| | rand.Read(b)
|
| | return hex.EncodeToString(b)
|
| | }
|
| |
|
| |
|
| | func (h *OpenAIHandler) ChatCompletions(c *gin.Context) {
|
| | body, err := io.ReadAll(c.Request.Body)
|
| | if err != nil {
|
| | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
| | return
|
| | }
|
| |
|
| |
|
| | var req struct {
|
| | Model string `json:"model"`
|
| | }
|
| | if err := json.Unmarshal(body, &req); err != nil {
|
| | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
| | return
|
| | }
|
| |
|
| |
|
| | zenModel, exists := model.GetZenModel(req.Model)
|
| | if !exists {
|
| |
|
| | h.handleError(c, service.ErrNoAvailableAccount)
|
| | return
|
| | }
|
| | if zenModel.ProviderID == "xai" {
|
| |
|
| | if err := h.grokSvc.ChatCompletionsProxy(c.Request.Context(), c.Writer, body); err != nil {
|
| | h.handleError(c, err)
|
| | }
|
| | return
|
| | }
|
| |
|
| |
|
| | if err := h.svc.ChatCompletionsProxy(c.Request.Context(), c.Writer, body); err != nil {
|
| | h.handleError(c, err)
|
| | }
|
| | }
|
| |
|
| |
|
| | func (h *OpenAIHandler) Responses(c *gin.Context) {
|
| | body, err := io.ReadAll(c.Request.Body)
|
| | if err != nil {
|
| | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
| | return
|
| | }
|
| |
|
| | if err := h.svc.ResponsesProxy(c.Request.Context(), c.Writer, body); err != nil {
|
| | h.handleError(c, err)
|
| | }
|
| | }
|
| |
|
| |
|
| | func (h *OpenAIHandler) handleError(c *gin.Context, err error) {
|
| | if errors.Is(err, service.ErrNoAvailableAccount) || errors.Is(err, service.ErrNoPermission) {
|
| | traceID := generateTraceID()
|
| | errMsg := fmt.Sprintf("没有可用token(traceid: %s)", traceID)
|
| | c.JSON(http.StatusServiceUnavailable, gin.H{"error": errMsg})
|
| | return
|
| | }
|
| | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
| | }
|
| |
|