Compare commits
10 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
fcb87b5c92 | 3 years ago |
|
|
ef35077d23 | 3 years ago |
|
|
2d8ffaed9a | 3 years ago |
|
|
ad6c497f36 | 3 years ago |
|
|
f33f5a7dc5 | 3 years ago |
|
|
5ec8752c26 | 3 years ago |
|
|
23158a7185 | 3 years ago |
|
|
2725f4ab00 | 3 years ago |
|
|
671bdb2168 | 3 years ago |
|
|
2277732de9 | 3 years ago |
@ -1,2 +1,4 @@
|
|||||||
gin.log
|
gin.log
|
||||||
/logs
|
/logs
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
@ -1,102 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BalanceInfo struct {
|
|
||||||
ServerAddress string `json:"server_address"`
|
|
||||||
AvailableKey string `json:"available_key"`
|
|
||||||
UserBalance float64 `json:"user_balance"`
|
|
||||||
TokenRatio float64 `json:"token_ratio"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Consumption struct {
|
|
||||||
SecretKey string `json:"secretKey"`
|
|
||||||
Model string `json:"model"`
|
|
||||||
MsgId string `json:"msgId"`
|
|
||||||
PromptTokens int `json:"promptTokens"`
|
|
||||||
CompletionTokens int `json:"completionTokens"`
|
|
||||||
TotalTokens int `json:"totalTokens"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockBalanceInquiry(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"server_address": "https://gptp.any-door.cn",
|
|
||||||
"available_key": "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",
|
|
||||||
"user_balance": 10000,
|
|
||||||
"token_ratio": 1000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockBalanceConsumption(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": "true",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 余额查询api调用
|
|
||||||
func balanceInquiry(key string, model string) (*BalanceInfo, error) {
|
|
||||||
url := "http://localhost:8080/mock1?key=" + key + "&model=" + model
|
|
||||||
req, err := http.NewRequest("POST", url, nil)
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var balanceInfo BalanceInfo
|
|
||||||
if err := json.Unmarshal(body, &balanceInfo); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &balanceInfo, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 余额消费
|
|
||||||
func balanceConsumption(key string, model string, prompt_tokens int, completion_tokens int, total_tokens int, msg_id string) (string, error) {
|
|
||||||
var data = Consumption{
|
|
||||||
SecretKey: key,
|
|
||||||
Model: model,
|
|
||||||
MsgId: msg_id,
|
|
||||||
PromptTokens: prompt_tokens,
|
|
||||||
CompletionTokens: completion_tokens,
|
|
||||||
TotalTokens: total_tokens,
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonData, err := json.Marshal(data)
|
|
||||||
// 构造post请求的body
|
|
||||||
reqBody := bytes.NewBuffer(jsonData)
|
|
||||||
|
|
||||||
url := "http://172.17.0.1:8080/other/usageRecord"
|
|
||||||
req2, err := http.NewRequest("POST", url, reqBody)
|
|
||||||
|
|
||||||
// 设置http请求的header
|
|
||||||
req2.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req2)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(body), nil
|
|
||||||
}
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"api2gpt-mid/model"
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BalanceConsumption 余额消费
|
||||||
|
func BalanceConsumption(key string, modelStr string, prompt_tokens int, completion_tokens int, total_tokens int, msg_id string) (string, error) {
|
||||||
|
var data = model.Consumption{
|
||||||
|
SecretKey: key,
|
||||||
|
Model: modelStr,
|
||||||
|
MsgId: msg_id,
|
||||||
|
PromptTokens: prompt_tokens,
|
||||||
|
CompletionTokens: completion_tokens,
|
||||||
|
TotalTokens: total_tokens,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
// 构造post请求的body
|
||||||
|
reqBody := bytes.NewBuffer(jsonData)
|
||||||
|
|
||||||
|
url := os.Getenv("SERVER_API_USAGE_RECORD_STRING")
|
||||||
|
if url == "" {
|
||||||
|
url = "http://172.17.0.1:8080/other/usageRecord"
|
||||||
|
}
|
||||||
|
req2, err := http.NewRequest("POST", url, reqBody)
|
||||||
|
|
||||||
|
// 设置http请求的header
|
||||||
|
req2.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req2)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer func(Body io.ReadCloser) {
|
||||||
|
err := Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
}(resp.Body)
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(body), nil
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var StartTime = time.Now().Unix()
|
||||||
|
var Version = "v0.0.0"
|
||||||
|
var SystemName = "Api2gpt Mid"
|
||||||
|
|
||||||
|
var DebugEnabled = os.Getenv("DEBUG") == "true"
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Port = flag.Int("port", 8080, "the listening port")
|
||||||
|
PrintVersion = flag.Bool("version", false, "print version and exit")
|
||||||
|
PrintHelp = flag.Bool("help", false, "print help and exit")
|
||||||
|
LogDir = flag.String("log-dir", "", "specify the log directory")
|
||||||
|
)
|
||||||
|
|
||||||
|
func printHelp() {
|
||||||
|
fmt.Println("Api2gpt " + Version + " - Mid Service.")
|
||||||
|
fmt.Println("Copyright (C) 2023 api2gpt. All rights reserved.")
|
||||||
|
fmt.Println("WebSite: https://www.api2gpt.com")
|
||||||
|
fmt.Println("Usage: one-api [--port <port>] [--log-dir <log directory>] [--version] [--help]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *PrintVersion {
|
||||||
|
fmt.Println(Version)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *PrintHelp {
|
||||||
|
printHelp()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *LogDir != "" {
|
||||||
|
var err error
|
||||||
|
*LogDir, err = filepath.Abs(*LogDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(*LogDir); os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(*LogDir, 0777)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupGinLog() {
|
||||||
|
if *LogDir != "" {
|
||||||
|
commonLogPath := filepath.Join(*LogDir, "common.log")
|
||||||
|
errorLogPath := filepath.Join(*LogDir, "error.log")
|
||||||
|
commonFd, err := os.OpenFile(commonLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to open log file")
|
||||||
|
}
|
||||||
|
errorFd, err := os.OpenFile(errorLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to open log file")
|
||||||
|
}
|
||||||
|
gin.DefaultWriter = io.MultiWriter(os.Stdout, commonFd)
|
||||||
|
gin.DefaultErrorWriter = io.MultiWriter(os.Stderr, errorFd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysLog(s string) {
|
||||||
|
t := time.Now()
|
||||||
|
_, _ = fmt.Fprintf(gin.DefaultWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysError(s string) {
|
||||||
|
t := time.Now()
|
||||||
|
_, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FatalLog(v ...any) {
|
||||||
|
t := time.Now()
|
||||||
|
_, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[FATAL] %v | %v \n", t.Format("2006/01/02 - 15:04:05"), v)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var RDB *redis.Client
|
||||||
|
|
||||||
|
// InitRedisClient This function is called after init()
|
||||||
|
func InitRedisClient() (err error) {
|
||||||
|
SysLog("Redis start connection")
|
||||||
|
redisConnStr := os.Getenv("REDIS_CONN_STRING")
|
||||||
|
if redisConnStr == "" {
|
||||||
|
redisConnStr = "redis://@localhost:6379/0?dial_timeout=5s"
|
||||||
|
}
|
||||||
|
opt, err := redis.ParseURL(redisConnStr)
|
||||||
|
//opt, err := redis.ParseURL(os.Getenv("REDIS_CONN_STRING"))
|
||||||
|
if err != nil {
|
||||||
|
FatalLog("failed to parse Redis connection string: " + err.Error())
|
||||||
|
}
|
||||||
|
RDB = redis.NewClient(opt)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
_, err = RDB.Ping(ctx).Result()
|
||||||
|
if err != nil {
|
||||||
|
FatalLog("Redis ping test failed: " + err.Error())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseRedisOption() *redis.Options {
|
||||||
|
opt, err := redis.ParseURL(os.Getenv("REDIS_CONN_STRING"))
|
||||||
|
if err != nil {
|
||||||
|
FatalLog("failed to parse Redis connection string: " + err.Error())
|
||||||
|
}
|
||||||
|
return opt
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisSet(key string, value string, expiration time.Duration) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.Set(ctx, key, value, expiration).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisGet(key string) (string, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.Get(ctx, key).Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisDel(key string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.Del(ctx, key).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisDecrease(key string, value int64) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.DecrBy(ctx, key, value).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisIncrByFloat(key string, value float64) (float64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.IncrByFloat(ctx, key, value).Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisIncr(key string) (int64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.Incr(ctx, key).Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisExpire(key string, timeOut time.Duration) (bool, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
return RDB.Expire(ctx, key, timeOut).Result()
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"api2gpt-mid/model"
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkoukk/tiktoken-go"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NumTokensFromMessages 计算Messages中的token数量
|
||||||
|
func NumTokensFromMessages(messages []model.Message, model string) int {
|
||||||
|
if strings.Contains(model, "gpt-3.5") {
|
||||||
|
model = "gpt-3.5-turbo"
|
||||||
|
}
|
||||||
|
if strings.Contains(model, "gpt-4") {
|
||||||
|
model = "gpt-4"
|
||||||
|
}
|
||||||
|
tkm, err := tiktoken.EncodingForModel(model)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("getEncoding: %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
numTokens := 0
|
||||||
|
for _, message := range messages {
|
||||||
|
numTokens += len(tkm.Encode(message.Content, nil, nil))
|
||||||
|
numTokens += 6
|
||||||
|
}
|
||||||
|
numTokens += 3
|
||||||
|
return numTokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumTokensFromString 计算String中的token数量
|
||||||
|
func NumTokensFromString(msg string, model string) int {
|
||||||
|
if strings.Contains(model, "gpt-3.5") {
|
||||||
|
model = "gpt-3.5-turbo"
|
||||||
|
}
|
||||||
|
if strings.Contains(model, "gpt-4") {
|
||||||
|
model = "gpt-4"
|
||||||
|
}
|
||||||
|
tkm, err := tiktoken.EncodingForModel(model)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("getEncoding: %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if model == "text-davinci-003" {
|
||||||
|
return len(tkm.Encode(msg, nil, nil)) + 1
|
||||||
|
} else {
|
||||||
|
return len(tkm.Encode(msg, nil, nil)) + 9
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"api2gpt-mid/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreditSummary struct {
|
||||||
|
Object string `json:"object"`
|
||||||
|
TotalGranted float64 `json:"total_granted"`
|
||||||
|
TotalUsed float64 `json:"total_used"`
|
||||||
|
TotalRemaining float64 `json:"total_remaining"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Balance 余额查询
|
||||||
|
func Balance(c *gin.Context) {
|
||||||
|
auth := c.Request.Header.Get("Authorization")
|
||||||
|
key := strings.Trim(auth, "Bearer ")
|
||||||
|
balance, err := service.QueryBlance(key)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
}
|
||||||
|
var creditSummary CreditSummary
|
||||||
|
creditSummary.Object = "credit_grant"
|
||||||
|
creditSummary.TotalGranted = 999999
|
||||||
|
creditSummary.TotalUsed = 999999 - balance
|
||||||
|
creditSummary.TotalRemaining = balance
|
||||||
|
c.JSON(200, creditSummary)
|
||||||
|
}
|
||||||
@ -0,0 +1,458 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://platform.openai.com/docs/api-reference/models/list
|
||||||
|
|
||||||
|
type OpenAIModelPermission struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
Created int `json:"created"`
|
||||||
|
AllowCreateEngine bool `json:"allow_create_engine"`
|
||||||
|
AllowSampling bool `json:"allow_sampling"`
|
||||||
|
AllowLogprobs bool `json:"allow_logprobs"`
|
||||||
|
AllowSearchIndices bool `json:"allow_search_indices"`
|
||||||
|
AllowView bool `json:"allow_view"`
|
||||||
|
AllowFineTuning bool `json:"allow_fine_tuning"`
|
||||||
|
Organization string `json:"organization"`
|
||||||
|
Group *string `json:"group"`
|
||||||
|
IsBlocking bool `json:"is_blocking"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenAIModels struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
Created int `json:"created"`
|
||||||
|
OwnedBy string `json:"owned_by"`
|
||||||
|
Permission []OpenAIModelPermission `json:"permission"`
|
||||||
|
Root string `json:"root"`
|
||||||
|
Parent *string `json:"parent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenAIError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Param string `json:"param"`
|
||||||
|
Code any `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenAIErrorWithStatusCode struct {
|
||||||
|
OpenAIError
|
||||||
|
StatusCode int `json:"status_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var openAIModels []OpenAIModels
|
||||||
|
var openAIModelsMap map[string]OpenAIModels
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var permission []OpenAIModelPermission
|
||||||
|
permission = append(permission, OpenAIModelPermission{
|
||||||
|
Id: "modelperm-LwHkVFn8AcMItP432fKKDIKJ",
|
||||||
|
Object: "model_permission",
|
||||||
|
Created: 1626777600,
|
||||||
|
AllowCreateEngine: true,
|
||||||
|
AllowSampling: true,
|
||||||
|
AllowLogprobs: true,
|
||||||
|
AllowSearchIndices: false,
|
||||||
|
AllowView: true,
|
||||||
|
AllowFineTuning: false,
|
||||||
|
Organization: "*",
|
||||||
|
Group: nil,
|
||||||
|
IsBlocking: false,
|
||||||
|
})
|
||||||
|
// https://platform.openai.com/docs/models/model-endpoint-compatibility
|
||||||
|
openAIModels = []OpenAIModels{
|
||||||
|
{
|
||||||
|
Id: "dall-e",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "dall-e",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "whisper-1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "whisper-1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-3.5-turbo",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-3.5-turbo",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-3.5-turbo-0301",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-3.5-turbo-0301",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-3.5-turbo-0613",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-3.5-turbo-0613",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-3.5-turbo-16k",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-3.5-turbo-16k",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-3.5-turbo-16k-0613",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-3.5-turbo-16k-0613",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4-0314",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4-0314",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4-0613",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4-0613",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4-32k",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4-32k",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4-32k-0314",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4-32k-0314",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "gpt-4-32k-0613",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "gpt-4-32k-0613",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-embedding-ada-002",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-embedding-ada-002",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-davinci-003",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-davinci-003",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-davinci-002",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-davinci-002",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-curie-001",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-curie-001",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-babbage-001",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-babbage-001",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-ada-001",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-ada-001",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-moderation-latest",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-moderation-latest",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-moderation-stable",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-moderation-stable",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "text-davinci-edit-001",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "text-davinci-edit-001",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "code-davinci-edit-001",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "openai",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "code-davinci-edit-001",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "claude-instant-1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "anturopic",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "claude-instant-1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "claude-2",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "anturopic",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "claude-2",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "ERNIE-Bot",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "baidu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "ERNIE-Bot",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "ERNIE-Bot-turbo",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "baidu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "ERNIE-Bot-turbo",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "Embedding-V1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "baidu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "Embedding-V1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "PaLM-2",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "google",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "PaLM-2",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "chatglm_pro",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "zhipu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "chatglm_pro",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "chatglm_std",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "zhipu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "chatglm_std",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "chatglm_lite",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "zhipu",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "chatglm_lite",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "qwen-v1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "ali",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "qwen-v1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "qwen-plus-v1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "ali",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "qwen-plus-v1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "SparkDesk",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "xunfei",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "SparkDesk",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "360GPT_S2_V9",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "360",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "360GPT_S2_V9",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "embedding-bert-512-v1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "360",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "embedding-bert-512-v1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "embedding_s1_v1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "360",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "embedding_s1_v1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "semantic_similarity_s1_v1",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "360",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "semantic_similarity_s1_v1",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "360GPT_S2_V9.4",
|
||||||
|
Object: "model",
|
||||||
|
Created: 1677649963,
|
||||||
|
OwnedBy: "360",
|
||||||
|
Permission: permission,
|
||||||
|
Root: "360GPT_S2_V9.4",
|
||||||
|
Parent: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
openAIModelsMap = make(map[string]OpenAIModels)
|
||||||
|
for _, model := range openAIModels {
|
||||||
|
openAIModelsMap[model.Id] = model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListModels(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"object": "list",
|
||||||
|
"data": openAIModels,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func RetrieveModel(c *gin.Context) {
|
||||||
|
modelId := c.Param("model")
|
||||||
|
if model, ok := openAIModelsMap[modelId]; ok {
|
||||||
|
c.JSON(200, model)
|
||||||
|
} else {
|
||||||
|
openAIError := OpenAIError{
|
||||||
|
Message: fmt.Sprintf("The model '%s' does not exist", modelId),
|
||||||
|
Type: "invalid_request_error",
|
||||||
|
Param: "model",
|
||||||
|
Code: "model_not_found",
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"error": openAIError,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,19 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
server:
|
api2gpt-mid:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: api2gpt-mid
|
container_name: api2gpt-mid-dev
|
||||||
environment:
|
environment:
|
||||||
# 时区上海
|
# 时区上海
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
REDIS_ADDRESS: 172.17.0.1:6379
|
REDIS_ADDRESS: 172.17.0.1:6379
|
||||||
|
REDIS_CONN_STRING: redis://@172.17.0.1:6379/0?dial_timeout=5s
|
||||||
|
SERVER_API_USAGE_RECORD_STRING: http://172.17.0.1:8080/other/usageRecord
|
||||||
privileged: true
|
privileged: true
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 8082:8080
|
- 8083:8080
|
||||||
volumes:
|
volumes:
|
||||||
- ./logs:/app/logs
|
- ./logs:/app/logs
|
||||||
@ -1,37 +1,40 @@
|
|||||||
module main
|
module api2gpt-mid
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bytedance/sonic v1.8.0 // indirect
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
github.com/pkoukk/tiktoken-go v0.1.0
|
||||||
|
github.com/redis/go-redis/v9 v9.0.3
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/sonic v1.9.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/dlclark/regexp2 v1.8.1 // indirect
|
github.com/dlclark/regexp2 v1.8.1 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.9.0 // indirect
|
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
github.com/go-redis/redis v6.15.9+incompatible // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/goccy/go-json v0.10.0 // indirect
|
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
github.com/pkoukk/tiktoken-go v0.1.0 // indirect
|
|
||||||
github.com/redis/go-redis/v9 v9.0.3 // indirect
|
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/crypto v0.5.0 // indirect
|
golang.org/x/crypto v0.9.0 // indirect
|
||||||
golang.org/x/net v0.7.0 // indirect
|
golang.org/x/net v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
golang.org/x/text v0.7.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"api2gpt-mid/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TokenAuth() func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
auth := c.Request.Header.Get("Authorization")
|
||||||
|
log.Printf("auth: %v", auth)
|
||||||
|
if auth == "" {
|
||||||
|
c.AbortWithStatusJSON(401, gin.H{"code": 40001})
|
||||||
|
} else {
|
||||||
|
//key := strings.Trim(auth, "Bearer ")
|
||||||
|
key := auth[7:]
|
||||||
|
log.Printf("key: %v", key)
|
||||||
|
msg, err := service.CheckKeyAndTimeCount(key)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("checkKeyMid err: %v", err)
|
||||||
|
c.AbortWithStatusJSON(msg, gin.H{"code": err.Error()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("auth check end")
|
||||||
|
// 执行函数
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CORS() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
method := c.Request.Method
|
||||||
|
origin := c.Request.Header.Get("Origin")
|
||||||
|
if origin != "" {
|
||||||
|
c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
|
||||||
|
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
|
||||||
|
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
|
||||||
|
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
|
||||||
|
c.Header("Access-Control-Allow-Credentials", "true")
|
||||||
|
}
|
||||||
|
if method == "OPTIONS" {
|
||||||
|
c.AbortWithStatus(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Consumption struct {
|
||||||
|
SecretKey string `json:"secretKey"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
MsgId string `json:"msgId"`
|
||||||
|
PromptTokens int `json:"promptTokens"`
|
||||||
|
CompletionTokens int `json:"completionTokens"`
|
||||||
|
TotalTokens int `json:"totalTokens"`
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ModelInfo struct {
|
||||||
|
ModelName string `json:"model_name"`
|
||||||
|
ModelPrice float64 `json:"model_price"`
|
||||||
|
ModelPrice2 float64 `json:"model_price2"`
|
||||||
|
ModelPrepayment int `json:"model_prepayment"`
|
||||||
|
ServerId int `json:"server_id"`
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Role string `json:"role,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatRequest struct {
|
||||||
|
Stream bool `json:"stream,omitempty"`
|
||||||
|
Model string `json:"model,omitempty"`
|
||||||
|
PresencePenalty float64 `json:"presence_penalty,omitempty"`
|
||||||
|
Temperature float64 `json:"temperature,omitempty"`
|
||||||
|
Messages []Message `json:"messages,omitempty"`
|
||||||
|
Prompt string `json:"prompt,omitempty"`
|
||||||
|
Input interface{} `json:"input,omitempty"`
|
||||||
|
Instruction string `json:"instruction,omitempty"`
|
||||||
|
N int `json:"n,omitempty"`
|
||||||
|
Functions interface{} `json:"functions,omitempty"`
|
||||||
|
MaxTokens int `json:"max_tokens,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagesRequest struct {
|
||||||
|
Prompt string `json:"prompt,omitempty"`
|
||||||
|
N int `json:"n,omitempty"`
|
||||||
|
Size string `json:"size,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatResponse struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
Object string `json:"object,omitempty"`
|
||||||
|
Created int64 `json:"created,omitempty"`
|
||||||
|
Model string `json:"model,omitempty"`
|
||||||
|
Usage Usage `json:"usage,omitempty"`
|
||||||
|
Choices []Choice `json:"choices,omitempty"`
|
||||||
|
}
|
||||||
|
type ImagesResponse struct {
|
||||||
|
Created int64 `json:"created,omitempty"`
|
||||||
|
Data []ImagesData `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagesData struct {
|
||||||
|
Url string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Usage struct {
|
||||||
|
PromptTokens int `json:"prompt_tokens,omitempty"`
|
||||||
|
CompletionTokens int `json:"completion_tokens,omitempty"`
|
||||||
|
TotalTokens int `json:"total_tokens,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Choice struct {
|
||||||
|
Message Message `json:"message,omitempty"`
|
||||||
|
Delta Delta `json:"delta,omitempty"`
|
||||||
|
FinishReason string `json:"finish_reason,omitempty"`
|
||||||
|
Index int `json:"index,omitempty"`
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Delta struct {
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreditSummary struct {
|
||||||
|
Object string `json:"object"`
|
||||||
|
TotalGranted float64 `json:"total_granted"`
|
||||||
|
TotalUsed float64 `json:"total_used"`
|
||||||
|
TotalRemaining float64 `json:"total_remaining"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListModelResponse struct {
|
||||||
|
Object string `json:"object"`
|
||||||
|
Data []Model `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
Created int `json:"created"`
|
||||||
|
OwnedBy string `json:"owned_by"`
|
||||||
|
Permission []ModelPermission `json:"permission"`
|
||||||
|
Root string `json:"root"`
|
||||||
|
Parent any `json:"parent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModelPermission struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
Created int `json:"created"`
|
||||||
|
AllowCreateEngine bool `json:"allow_create_engine"`
|
||||||
|
AllowSampling bool `json:"allow_sampling"`
|
||||||
|
AllowLogprobs bool `json:"allow_logprobs"`
|
||||||
|
AllowSearchIndices bool `json:"allow_search_indices"`
|
||||||
|
AllowView bool `json:"allow_view"`
|
||||||
|
AllowFineTuning bool `json:"allow_fine_tuning"`
|
||||||
|
Organization string `json:"organization"`
|
||||||
|
Group any `json:"group"`
|
||||||
|
IsBlocking bool `json:"is_blocking"`
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ServerInfo struct {
|
||||||
|
ServerAddress string `json:"server_address"`
|
||||||
|
AvailableKey string `json:"available_key"`
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type UserInfo struct {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
SID string `json:"sid"`
|
||||||
|
RPM int `json:"rpm"`
|
||||||
|
TPM int `json:"tpm"`
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"api2gpt-mid/controller"
|
||||||
|
"api2gpt-mid/middleware"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetApiRouter(router *gin.Engine) {
|
||||||
|
modelsRouter := router.Group("/v1/models")
|
||||||
|
modelsRouter.Use(middleware.TokenAuth())
|
||||||
|
{
|
||||||
|
modelsRouter.GET("", controller.ListModels)
|
||||||
|
modelsRouter.GET("/:model", controller.RetrieveModel)
|
||||||
|
}
|
||||||
|
relayV1Router := router.Group("/v1")
|
||||||
|
relayV1Router.Use(middleware.TokenAuth())
|
||||||
|
{
|
||||||
|
relayV1Router.POST("/completions", controller.Completions)
|
||||||
|
relayV1Router.POST("/chat/completions", controller.Completions)
|
||||||
|
relayV1Router.POST("/embeddings", controller.Embeddings)
|
||||||
|
relayV1Router.POST("/edits", controller.Edit)
|
||||||
|
relayV1Router.POST("/images/generations", controller.Images)
|
||||||
|
}
|
||||||
|
dashboardRouter := router.Group("/dashboard")
|
||||||
|
dashboardRouter.Use(middleware.TokenAuth())
|
||||||
|
{
|
||||||
|
dashboardRouter.GET("/dashboard/billing/credit_grants", controller.Balance)
|
||||||
|
}
|
||||||
|
router.OPTIONS("/v1/*path", controller.HandleOptions)
|
||||||
|
router.GET("/ping", func(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"message": "pong from api2gpt",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import "github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
func SetRouter(router *gin.Engine) {
|
||||||
|
SetApiRouter(router)
|
||||||
|
}
|
||||||
Loading…
Reference in new issue