velo / controller /gemini.go
Jack698's picture
Upload folder using huggingface_hub
adc1e1c verified
package controller
import (
"bytes"
"encoding/json"
"io"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"veloera/common"
"veloera/dto"
"veloera/model"
relaycommon "veloera/relay/common"
"veloera/service"
)
func RelayGemini(c *gin.Context) {
modelParam := c.Param("model")
action := "generateContent"
modelName := modelParam
if idx := strings.Index(modelParam, ":"); idx >= 0 {
action = modelParam[idx+1:]
modelName = modelParam[:idx]
}
stream := false
switch action {
case "generateContent":
stream = false
case "streamGenerateContent":
stream = true
default:
respondGeminiError(c, http.StatusNotFound, "unsupported action")
return
}
if modelName == "" {
respondGeminiError(c, http.StatusBadRequest, "model is required")
return
}
bodyBytes, err := common.GetRequestBody(c)
if err != nil {
respondGeminiError(c, http.StatusBadRequest, "failed to read request body")
return
}
var geminiReq dto.GeminiCompatGenerateContentRequest
if len(bodyBytes) > 0 {
if err := json.Unmarshal(bodyBytes, &geminiReq); err != nil {
respondGeminiError(c, http.StatusBadRequest, "invalid JSON body")
return
}
}
openaiReq, err := service.ConvertGeminiCompatRequestToOpenAI(&geminiReq, modelName, stream)
if err != nil {
respondGeminiError(c, http.StatusBadRequest, err.Error())
return
}
convertedBody, err := json.Marshal(openaiReq)
if err != nil {
respondGeminiError(c, http.StatusInternalServerError, "failed to encode internal request")
return
}
c.Set(common.KeyRequestBody, convertedBody)
c.Request.Body = io.NopCloser(bytes.NewBuffer(convertedBody))
c.Request.ContentLength = int64(len(convertedBody))
c.Request.Header.Set("Content-Type", "application/json")
c.Set("relay_format", relaycommon.RelayFormatGemini)
Relay(c)
}
func ListGeminiModels(c *gin.Context) {
userID := c.GetInt("id")
group, err := model.GetUserGroup(userID, true)
if err != nil {
respondGeminiError(c, http.StatusInternalServerError, "failed to load user group")
return
}
tokenGroup := c.GetString("token_group")
if tokenGroup != "" {
group = tokenGroup
}
models := model.GetGroupModels(group)
response := dto.GeminiModelListResponse{Models: make([]dto.GeminiModel, 0, len(models))}
for _, name := range models {
response.Models = append(response.Models, dto.GeminiModel{
Name: "models/" + name,
BaseModelID: name,
Version: "v1beta",
DisplayName: name,
Description: "",
InputTokenLimit: 32768,
OutputTokenLimit: 8192,
SupportedGenerationMethods: []string{"generateContent", "streamGenerateContent"},
})
}
c.JSON(http.StatusOK, response)
}
func RetrieveGeminiModel(c *gin.Context) {
modelName := c.Param("model")
if modelName == "" {
respondGeminiError(c, http.StatusNotFound, "model not found")
return
}
userID := c.GetInt("id")
group, err := model.GetUserGroup(userID, true)
if err != nil {
respondGeminiError(c, http.StatusInternalServerError, "failed to load user group")
return
}
tokenGroup := c.GetString("token_group")
if tokenGroup != "" {
group = tokenGroup
}
models := model.GetGroupModels(group)
found := false
for _, name := range models {
if name == modelName {
found = true
break
}
}
if !found {
respondGeminiError(c, http.StatusNotFound, "model not found")
return
}
c.JSON(http.StatusOK, dto.GeminiModel{
Name: "models/" + modelName,
BaseModelID: modelName,
Version: "v1beta",
DisplayName: modelName,
Description: "",
InputTokenLimit: 32768,
OutputTokenLimit: 8192,
SupportedGenerationMethods: []string{"generateContent", "streamGenerateContent"},
})
}
func respondGeminiError(c *gin.Context, status int, message string) {
resp := service.BuildGeminiErrorResponse(status, message)
c.JSON(status, resp)
}