mirror of
https://github.com/linux-do/new-api.git
synced 2025-09-17 16:06:38 +08:00
merge upstream
Signed-off-by: wozulong <>
This commit is contained in:
commit
9932962320
@ -70,9 +70,17 @@ var DefaultModelRatio = map[string]float64{
|
|||||||
"claude-3-haiku-20240307": 0.125, // $0.25 / 1M tokens
|
"claude-3-haiku-20240307": 0.125, // $0.25 / 1M tokens
|
||||||
"claude-3-sonnet-20240229": 1.5, // $3 / 1M tokens
|
"claude-3-sonnet-20240229": 1.5, // $3 / 1M tokens
|
||||||
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
|
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
|
||||||
"ERNIE-Bot": 0.8572, // ¥0.012 / 1k tokens
|
"ERNIE-Bot": 0.8572, // ¥0.012 / 1k tokens //renamed to ERNIE-3.5-8K
|
||||||
"ERNIE-Bot-turbo": 0.5715, // ¥0.008 / 1k tokens
|
"ERNIE-Bot-turbo": 0.5715, // ¥0.008 / 1k tokens //renamed to ERNIE-Lite-8K
|
||||||
"ERNIE-Bot-4": 8.572, // ¥0.12 / 1k tokens
|
"ERNIE-Bot-4": 8.572, // ¥0.12 / 1k tokens //renamed to ERNIE-4.0-8K
|
||||||
|
"ERNIE-4.0-8K": 8.572, // ¥0.12 / 1k tokens
|
||||||
|
"ERNIE-3.5-8K": 0.8572, // ¥0.012 / 1k tokens
|
||||||
|
"ERNIE-Speed-8K": 0.2858, // ¥0.004 / 1k tokens
|
||||||
|
"ERNIE-Speed-128K": 0.2858, // ¥0.004 / 1k tokens
|
||||||
|
"ERNIE-Lite-8K": 0.2143, // ¥0.003 / 1k tokens
|
||||||
|
"ERNIE-Tiny-8K": 0.0715, // ¥0.001 / 1k tokens
|
||||||
|
"ERNIE-Character-8K": 0.2858, // ¥0.004 / 1k tokens
|
||||||
|
"ERNIE-Functions-8K": 0.2858, // ¥0.004 / 1k tokens
|
||||||
"Embedding-V1": 0.1429, // ¥0.002 / 1k tokens
|
"Embedding-V1": 0.1429, // ¥0.002 / 1k tokens
|
||||||
"PaLM-2": 1,
|
"PaLM-2": 1,
|
||||||
"gemini-pro": 1, // $0.00025 / 1k characters -> $0.001 / 1k tokens
|
"gemini-pro": 1, // $0.00025 / 1k characters -> $0.001 / 1k tokens
|
||||||
@ -80,6 +88,7 @@ var DefaultModelRatio = map[string]float64{
|
|||||||
"gemini-1.0-pro-vision-001": 1,
|
"gemini-1.0-pro-vision-001": 1,
|
||||||
"gemini-1.0-pro-001": 1,
|
"gemini-1.0-pro-001": 1,
|
||||||
"gemini-1.5-pro-latest": 1,
|
"gemini-1.5-pro-latest": 1,
|
||||||
|
"gemini-1.5-flash-latest": 1,
|
||||||
"gemini-1.0-pro-latest": 1,
|
"gemini-1.0-pro-latest": 1,
|
||||||
"gemini-1.0-pro-vision-latest": 1,
|
"gemini-1.0-pro-vision-latest": 1,
|
||||||
"gemini-ultra": 1,
|
"gemini-ultra": 1,
|
||||||
@ -98,6 +107,9 @@ var DefaultModelRatio = map[string]float64{
|
|||||||
"SparkDesk-v3.1": 1.2858, // ¥0.018 / 1k tokens
|
"SparkDesk-v3.1": 1.2858, // ¥0.018 / 1k tokens
|
||||||
"SparkDesk-v3.5": 1.2858, // ¥0.018 / 1k tokens
|
"SparkDesk-v3.5": 1.2858, // ¥0.018 / 1k tokens
|
||||||
"360GPT_S2_V9": 0.8572, // ¥0.012 / 1k tokens
|
"360GPT_S2_V9": 0.8572, // ¥0.012 / 1k tokens
|
||||||
|
"360gpt-turbo": 0.0858, // ¥0.0012 / 1k tokens
|
||||||
|
"360gpt-turbo-responsibility-8k": 0.8572, // ¥0.012 / 1k tokens
|
||||||
|
"360gpt-pro": 0.8572, // ¥0.012 / 1k tokens
|
||||||
"embedding-bert-512-v1": 0.0715, // ¥0.001 / 1k tokens
|
"embedding-bert-512-v1": 0.0715, // ¥0.001 / 1k tokens
|
||||||
"embedding_s1_v1": 0.0715, // ¥0.001 / 1k tokens
|
"embedding_s1_v1": 0.0715, // ¥0.001 / 1k tokens
|
||||||
"semantic_similarity_s1_v1": 0.0715, // ¥0.001 / 1k tokens
|
"semantic_similarity_s1_v1": 0.0715, // ¥0.001 / 1k tokens
|
||||||
@ -299,6 +311,15 @@ func GetCompletionRatio(name string) float64 {
|
|||||||
if strings.HasPrefix(name, "deepseek") {
|
if strings.HasPrefix(name, "deepseek") {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(name, "ERNIE-Speed-") {
|
||||||
|
return 2
|
||||||
|
} else if strings.HasPrefix(name, "ERNIE-Lite-") {
|
||||||
|
return 2
|
||||||
|
} else if strings.HasPrefix(name, "ERNIE-Character") {
|
||||||
|
return 2
|
||||||
|
} else if strings.HasPrefix(name, "ERNIE-Functions") {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
switch name {
|
switch name {
|
||||||
case "llama2-70b-4096":
|
case "llama2-70b-4096":
|
||||||
return 0.8 / 0.64
|
return 0.8 / 0.64
|
||||||
|
@ -258,3 +258,12 @@ func MapToJsonStrFloat(m map[string]float64) string {
|
|||||||
}
|
}
|
||||||
return string(bytes)
|
return string(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StrToMap(str string) map[string]interface{} {
|
||||||
|
m := make(map[string]interface{})
|
||||||
|
err := json.Unmarshal([]byte(str), &m)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
@ -64,7 +64,21 @@ func testChannel(channel *model.Channel, testModel string) (err error, openaiErr
|
|||||||
} else {
|
} else {
|
||||||
testModel = adaptor.GetModelList()[0]
|
testModel = adaptor.GetModelList()[0]
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
modelMapping := *channel.ModelMapping
|
||||||
|
if modelMapping != "" && modelMapping != "{}" {
|
||||||
|
modelMap := make(map[string]string)
|
||||||
|
err := json.Unmarshal([]byte(modelMapping), &modelMap)
|
||||||
|
if err != nil {
|
||||||
|
openaiErr := service.OpenAIErrorWrapperLocal(err, "unmarshal_model_mapping_failed", http.StatusInternalServerError).Error
|
||||||
|
return err, &openaiErr
|
||||||
}
|
}
|
||||||
|
if modelMap[testModel] != "" {
|
||||||
|
testModel = modelMap[testModel]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
request := buildTestRequest()
|
request := buildTestRequest()
|
||||||
request.Model = testModel
|
request.Model = testModel
|
||||||
meta.UpstreamModelName = testModel
|
meta.UpstreamModelName = testModel
|
||||||
|
@ -108,8 +108,8 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
openAIModelsMap = make(map[string]dto.OpenAIModels)
|
openAIModelsMap = make(map[string]dto.OpenAIModels)
|
||||||
for _, model := range openAIModels {
|
for _, aiModel := range openAIModels {
|
||||||
openAIModelsMap[model.Id] = model
|
openAIModelsMap[aiModel.Id] = aiModel
|
||||||
}
|
}
|
||||||
channelId2Models = make(map[int][]string)
|
channelId2Models = make(map[int][]string)
|
||||||
for i := 1; i <= common.ChannelTypeDummy; i++ {
|
for i := 1; i <= common.ChannelTypeDummy; i++ {
|
||||||
@ -174,8 +174,8 @@ func DashboardListModels(c *gin.Context) {
|
|||||||
|
|
||||||
func RetrieveModel(c *gin.Context) {
|
func RetrieveModel(c *gin.Context) {
|
||||||
modelId := c.Param("model")
|
modelId := c.Param("model")
|
||||||
if model, ok := openAIModelsMap[modelId]; ok {
|
if aiModel, ok := openAIModelsMap[modelId]; ok {
|
||||||
c.JSON(200, model)
|
c.JSON(200, aiModel)
|
||||||
} else {
|
} else {
|
||||||
openAIError := dto.OpenAIError{
|
openAIError := dto.OpenAIError{
|
||||||
Message: fmt.Sprintf("The model '%s' does not exist", modelId),
|
Message: fmt.Sprintf("The model '%s' does not exist", modelId),
|
||||||
@ -191,12 +191,12 @@ func RetrieveModel(c *gin.Context) {
|
|||||||
|
|
||||||
func GetPricing(c *gin.Context) {
|
func GetPricing(c *gin.Context) {
|
||||||
userId := c.GetInt("id")
|
userId := c.GetInt("id")
|
||||||
user, _ := model.GetUserById(userId, true)
|
group, err := model.CacheGetUserGroup(userId)
|
||||||
groupRatio := common.GetGroupRatio("default")
|
groupRatio := common.GetGroupRatio("default")
|
||||||
if user != nil {
|
if err != nil {
|
||||||
groupRatio = common.GetGroupRatio(user.Group)
|
groupRatio = common.GetGroupRatio(group)
|
||||||
}
|
}
|
||||||
pricing := model.GetPricing(user, openAIModels)
|
pricing := model.GetPricing(group)
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"data": pricing,
|
"data": pricing,
|
||||||
|
@ -43,7 +43,7 @@ func Relay(c *gin.Context) {
|
|||||||
group := c.GetString("group")
|
group := c.GetString("group")
|
||||||
originalModel := c.GetString("original_model")
|
originalModel := c.GetString("original_model")
|
||||||
openaiErr := relayHandler(c, relayMode)
|
openaiErr := relayHandler(c, relayMode)
|
||||||
useChannel := []int{channelId}
|
c.Set("use_channel", []string{fmt.Sprintf("%d", channelId)})
|
||||||
if openaiErr != nil {
|
if openaiErr != nil {
|
||||||
go processChannelError(c, channelId, openaiErr)
|
go processChannelError(c, channelId, openaiErr)
|
||||||
} else {
|
} else {
|
||||||
@ -56,7 +56,9 @@ func Relay(c *gin.Context) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
channelId = channel.Id
|
channelId = channel.Id
|
||||||
useChannel = append(useChannel, channelId)
|
useChannel := c.GetStringSlice("use_channel")
|
||||||
|
useChannel = append(useChannel, fmt.Sprintf("%d", channelId))
|
||||||
|
c.Set("use_channel", useChannel)
|
||||||
common.LogInfo(c.Request.Context(), fmt.Sprintf("using channel #%d to retry (remain times %d)", channel.Id, i))
|
common.LogInfo(c.Request.Context(), fmt.Sprintf("using channel #%d to retry (remain times %d)", channel.Id, i))
|
||||||
middleware.SetupContextForSelectedChannel(c, channel, originalModel)
|
middleware.SetupContextForSelectedChannel(c, channel, originalModel)
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ func Relay(c *gin.Context) {
|
|||||||
go processChannelError(c, channelId, openaiErr)
|
go processChannelError(c, channelId, openaiErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
useChannel := c.GetStringSlice("use_channel")
|
||||||
if len(useChannel) > 1 {
|
if len(useChannel) > 1 {
|
||||||
retryLogStr := fmt.Sprintf("重试:%s", strings.Trim(strings.Join(strings.Fields(fmt.Sprint(useChannel)), "->"), "[]"))
|
retryLogStr := fmt.Sprintf("重试:%s", strings.Trim(strings.Join(strings.Fields(fmt.Sprint(useChannel)), "->"), "[]"))
|
||||||
common.LogInfo(c.Request.Context(), retryLogStr)
|
common.LogInfo(c.Request.Context(), retryLogStr)
|
||||||
|
10
model/log.go
10
model/log.go
@ -155,6 +155,16 @@ func GetUserLogs(userId int, logType int, startTimestamp int64, endTimestamp int
|
|||||||
|
|
||||||
err = tx.Order("id desc").Limit(num).Offset(startIdx).Omit("id").Find(&logs).Error
|
err = tx.Order("id desc").Limit(num).Offset(startIdx).Omit("id").Find(&logs).Error
|
||||||
return logs, total, err
|
return logs, total, err
|
||||||
|
for i := range logs {
|
||||||
|
var otherMap map[string]interface{}
|
||||||
|
otherMap = common.StrToMap(logs[i].Other)
|
||||||
|
if otherMap != nil {
|
||||||
|
// delete admin
|
||||||
|
delete(otherMap, "admin_info")
|
||||||
|
}
|
||||||
|
logs[i].Other = common.MapToJsonStr(otherMap)
|
||||||
|
}
|
||||||
|
return logs, total, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchAllLogs(keyword string) (logs []*Log, err error) {
|
func SearchAllLogs(keyword string) (logs []*Log, err error) {
|
||||||
|
@ -93,12 +93,12 @@ func InitDB() (err error) {
|
|||||||
if !common.IsMasterNode {
|
if !common.IsMasterNode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if common.UsingMySQL {
|
//if common.UsingMySQL {
|
||||||
_, _ = sqlDB.Exec("DROP INDEX idx_channels_key ON channels;") // TODO: delete this line when most users have upgraded
|
// _, _ = sqlDB.Exec("DROP INDEX idx_channels_key ON channels;") // TODO: delete this line when most users have upgraded
|
||||||
_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY action VARCHAR(40);") // TODO: delete this line when most users have upgraded
|
// _, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY action VARCHAR(40);") // TODO: delete this line when most users have upgraded
|
||||||
_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY progress VARCHAR(30);") // TODO: delete this line when most users have upgraded
|
// _, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY progress VARCHAR(30);") // TODO: delete this line when most users have upgraded
|
||||||
_, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY status VARCHAR(20);") // TODO: delete this line when most users have upgraded
|
// _, _ = sqlDB.Exec("ALTER TABLE midjourneys MODIFY status VARCHAR(20);") // TODO: delete this line when most users have upgraded
|
||||||
}
|
//}
|
||||||
common.SysLog("database migration started")
|
common.SysLog("database migration started")
|
||||||
err = db.AutoMigrate(&Channel{})
|
err = db.AutoMigrate(&Channel{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -13,16 +13,16 @@ var (
|
|||||||
updatePricingLock sync.Mutex
|
updatePricingLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetPricing(user *User, openAIModels []dto.OpenAIModels) []dto.ModelPricing {
|
func GetPricing(group string) []dto.ModelPricing {
|
||||||
updatePricingLock.Lock()
|
updatePricingLock.Lock()
|
||||||
defer updatePricingLock.Unlock()
|
defer updatePricingLock.Unlock()
|
||||||
|
|
||||||
if time.Since(lastGetPricingTime) > time.Minute*1 || len(pricingMap) == 0 {
|
if time.Since(lastGetPricingTime) > time.Minute*1 || len(pricingMap) == 0 {
|
||||||
updatePricing(openAIModels)
|
updatePricing()
|
||||||
}
|
}
|
||||||
if user != nil {
|
if group != "" {
|
||||||
userPricingMap := make([]dto.ModelPricing, 0)
|
userPricingMap := make([]dto.ModelPricing, 0)
|
||||||
models := GetGroupModels(user.Group)
|
models := GetGroupModels(group)
|
||||||
for _, pricing := range pricingMap {
|
for _, pricing := range pricingMap {
|
||||||
if !common.StringsContains(models, pricing.ModelName) {
|
if !common.StringsContains(models, pricing.ModelName) {
|
||||||
pricing.Available = false
|
pricing.Available = false
|
||||||
@ -34,28 +34,19 @@ func GetPricing(user *User, openAIModels []dto.OpenAIModels) []dto.ModelPricing
|
|||||||
return pricingMap
|
return pricingMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePricing(openAIModels []dto.OpenAIModels) {
|
func updatePricing() {
|
||||||
modelRatios := common.GetModelRatios()
|
//modelRatios := common.GetModelRatios()
|
||||||
enabledModels := GetEnabledModels()
|
enabledModels := GetEnabledModels()
|
||||||
allModels := make(map[string]string)
|
allModels := make(map[string]int)
|
||||||
for _, openAIModel := range openAIModels {
|
for i, model := range enabledModels {
|
||||||
if common.StringsContains(enabledModels, openAIModel.Id) {
|
allModels[model] = i
|
||||||
allModels[openAIModel.Id] = openAIModel.OwnedBy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for model, _ := range modelRatios {
|
|
||||||
if common.StringsContains(enabledModels, model) {
|
|
||||||
if _, ok := allModels[model]; !ok {
|
|
||||||
allModels[model] = "custom"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pricingMap = make([]dto.ModelPricing, 0)
|
pricingMap = make([]dto.ModelPricing, 0)
|
||||||
for model, ownerBy := range allModels {
|
for model, _ := range allModels {
|
||||||
pricing := dto.ModelPricing{
|
pricing := dto.ModelPricing{
|
||||||
Available: true,
|
Available: true,
|
||||||
ModelName: model,
|
ModelName: model,
|
||||||
OwnerBy: ownerBy,
|
|
||||||
}
|
}
|
||||||
modelPrice, findPrice := common.GetModelPrice(model, false)
|
modelPrice, findPrice := common.GetModelPrice(model, false)
|
||||||
if findPrice {
|
if findPrice {
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
type Token struct {
|
type Token struct {
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
UserId int `json:"user_id"`
|
UserId int `json:"user_id" gorm:"index"`
|
||||||
Key string `json:"key" gorm:"type:char(48);uniqueIndex"`
|
Key string `json:"key" gorm:"type:char(48);uniqueIndex"`
|
||||||
Status int `json:"status" gorm:"default:1"`
|
Status int `json:"status" gorm:"default:1"`
|
||||||
Name string `json:"name" gorm:"index" `
|
Name string `json:"name" gorm:"index" `
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package ai360
|
package ai360
|
||||||
|
|
||||||
var ModelList = []string{
|
var ModelList = []string{
|
||||||
|
"360gpt-turbo",
|
||||||
|
"360gpt-turbo-responsibility-8k",
|
||||||
|
"360gpt-pro",
|
||||||
"360GPT_S2_V9",
|
"360GPT_S2_V9",
|
||||||
"embedding-bert-512-v1",
|
"embedding-bert-512-v1",
|
||||||
"embedding_s1_v1",
|
"embedding_s1_v1",
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"one-api/relay/channel"
|
"one-api/relay/channel"
|
||||||
relaycommon "one-api/relay/common"
|
relaycommon "one-api/relay/common"
|
||||||
"one-api/relay/constant"
|
"one-api/relay/constant"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Adaptor struct {
|
type Adaptor struct {
|
||||||
@ -33,8 +34,24 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
|
|||||||
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant"
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant"
|
||||||
case "BLOOMZ-7B":
|
case "BLOOMZ-7B":
|
||||||
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/bloomz_7b1"
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/bloomz_7b1"
|
||||||
|
case "ERNIE-4.0-8K":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro"
|
||||||
|
case "ERNIE-3.5-8K":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions"
|
||||||
|
case "ERNIE-Speed-8K":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie_speed"
|
||||||
|
case "ERNIE-Character-8K":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-char-8k"
|
||||||
|
case "ERNIE-Functions-8K":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-func-8k"
|
||||||
|
case "ERNIE-Lite-8K-0922":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant"
|
||||||
|
case "Yi-34B-Chat":
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/yi_34b_chat"
|
||||||
case "Embedding-V1":
|
case "Embedding-V1":
|
||||||
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1"
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1"
|
||||||
|
default:
|
||||||
|
fullRequestURL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/" + strings.ToLower(info.UpstreamModelName)
|
||||||
}
|
}
|
||||||
var accessToken string
|
var accessToken string
|
||||||
var err error
|
var err error
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
package baidu
|
package baidu
|
||||||
|
|
||||||
var ModelList = []string{
|
var ModelList = []string{
|
||||||
"ERNIE-Bot-4",
|
"ERNIE-3.5-8K",
|
||||||
"ERNIE-Bot-8K",
|
"ERNIE-4.0-8K",
|
||||||
"ERNIE-Bot",
|
"ERNIE-Speed-8K",
|
||||||
"ERNIE-Speed",
|
"ERNIE-Speed-128K",
|
||||||
"ERNIE-Bot-turbo",
|
"ERNIE-Lite-8K",
|
||||||
|
"ERNIE-Tiny-8K",
|
||||||
|
"ERNIE-Character-8K",
|
||||||
|
"ERNIE-Functions-8K",
|
||||||
|
//"ERNIE-Bot-4",
|
||||||
|
//"ERNIE-Bot-8K",
|
||||||
|
//"ERNIE-Bot",
|
||||||
|
//"ERNIE-Speed",
|
||||||
|
//"ERNIE-Bot-turbo",
|
||||||
"Embedding-V1",
|
"Embedding-V1",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ func (a *Adaptor) Init(info *relaycommon.RelayInfo, request dto.GeneralOpenAIReq
|
|||||||
// 定义一个映射,存储模型名称和对应的版本
|
// 定义一个映射,存储模型名称和对应的版本
|
||||||
var modelVersionMap = map[string]string{
|
var modelVersionMap = map[string]string{
|
||||||
"gemini-1.5-pro-latest": "v1beta",
|
"gemini-1.5-pro-latest": "v1beta",
|
||||||
|
"gemini-1.5-flash-latest": "v1beta",
|
||||||
"gemini-ultra": "v1beta",
|
"gemini-ultra": "v1beta",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var ModelList = []string{
|
var ModelList = []string{
|
||||||
"gemini-1.0-pro-latest", "gemini-1.0-pro-001", "gemini-1.5-pro-latest", "gemini-ultra",
|
"gemini-1.0-pro-latest", "gemini-1.0-pro-001", "gemini-1.5-pro-latest", "gemini-1.5-flash-latest", "gemini-ultra",
|
||||||
"gemini-1.0-pro-vision-latest", "gemini-1.0-pro-vision-001",
|
"gemini-1.0-pro-vision-latest", "gemini-1.0-pro-vision-001",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ const (
|
|||||||
APITypeAIProxyLibrary
|
APITypeAIProxyLibrary
|
||||||
APITypeTencent
|
APITypeTencent
|
||||||
APITypeGemini
|
APITypeGemini
|
||||||
APITypeZhipu_v4
|
APITypeZhipuV4
|
||||||
APITypeOllama
|
APITypeOllama
|
||||||
APITypePerplexity
|
APITypePerplexity
|
||||||
APITypeAws
|
APITypeAws
|
||||||
@ -48,7 +48,7 @@ func ChannelType2APIType(channelType int) (int, bool) {
|
|||||||
case common.ChannelTypeGemini:
|
case common.ChannelTypeGemini:
|
||||||
apiType = APITypeGemini
|
apiType = APITypeGemini
|
||||||
case common.ChannelTypeZhipu_v4:
|
case common.ChannelTypeZhipu_v4:
|
||||||
apiType = APITypeZhipu_v4
|
apiType = APITypeZhipuV4
|
||||||
case common.ChannelTypeOllama:
|
case common.ChannelTypeOllama:
|
||||||
apiType = APITypeOllama
|
apiType = APITypeOllama
|
||||||
case common.ChannelTypePerplexity:
|
case common.ChannelTypePerplexity:
|
||||||
|
@ -323,6 +323,9 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
|
|||||||
other["group_ratio"] = groupRatio
|
other["group_ratio"] = groupRatio
|
||||||
other["completion_ratio"] = completionRatio
|
other["completion_ratio"] = completionRatio
|
||||||
other["model_price"] = modelPrice
|
other["model_price"] = modelPrice
|
||||||
|
adminInfo := make(map[string]interface{})
|
||||||
|
adminInfo["use_channel"] = ctx.GetStringSlice("use_channel")
|
||||||
|
other["admin_info"] = adminInfo
|
||||||
model.RecordConsumeLog(ctx, relayInfo.UserId, relayInfo.ChannelId, promptTokens, completionTokens, logModel, tokenName, quota, logContent, relayInfo.TokenId, userQuota, int(useTimeSeconds), relayInfo.IsStream, other)
|
model.RecordConsumeLog(ctx, relayInfo.UserId, relayInfo.ChannelId, promptTokens, completionTokens, logModel, tokenName, quota, logContent, relayInfo.TokenId, userQuota, int(useTimeSeconds), relayInfo.IsStream, other)
|
||||||
|
|
||||||
//if quota != 0 {
|
//if quota != 0 {
|
||||||
|
@ -41,7 +41,7 @@ func GetAdaptor(apiType int) channel.Adaptor {
|
|||||||
return &xunfei.Adaptor{}
|
return &xunfei.Adaptor{}
|
||||||
case constant.APITypeZhipu:
|
case constant.APITypeZhipu:
|
||||||
return &zhipu.Adaptor{}
|
return &zhipu.Adaptor{}
|
||||||
case constant.APITypeZhipu_v4:
|
case constant.APITypeZhipuV4:
|
||||||
return &zhipu_4v.Adaptor{}
|
return &zhipu_4v.Adaptor{}
|
||||||
case constant.APITypeOllama:
|
case constant.APITypeOllama:
|
||||||
return &ollama.Adaptor{}
|
return &ollama.Adaptor{}
|
||||||
|
@ -20,7 +20,7 @@ func SetApiRouter(router *gin.Engine) {
|
|||||||
apiRouter.GET("/about", controller.GetAbout)
|
apiRouter.GET("/about", controller.GetAbout)
|
||||||
apiRouter.GET("/midjourney", controller.GetMidjourney)
|
apiRouter.GET("/midjourney", controller.GetMidjourney)
|
||||||
apiRouter.GET("/home_page_content", controller.GetHomePageContent)
|
apiRouter.GET("/home_page_content", controller.GetHomePageContent)
|
||||||
apiRouter.GET("/pricing", middleware.CriticalRateLimit(), middleware.TryUserAuth(), controller.GetPricing)
|
apiRouter.GET("/pricing", middleware.TryUserAuth(), controller.GetPricing)
|
||||||
apiRouter.GET("/verification", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.SendEmailVerification)
|
apiRouter.GET("/verification", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.SendEmailVerification)
|
||||||
apiRouter.GET("/reset_password", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.SendPasswordResetEmail)
|
apiRouter.GET("/reset_password", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.SendPasswordResetEmail)
|
||||||
apiRouter.POST("/user/reset", middleware.CriticalRateLimit(), controller.ResetPassword)
|
apiRouter.POST("/user/reset", middleware.CriticalRateLimit(), controller.ResetPassword)
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
showError,
|
showError,
|
||||||
showInfo,
|
showInfo,
|
||||||
showSuccess,
|
showSuccess,
|
||||||
|
showWarning,
|
||||||
timestamp2string,
|
timestamp2string,
|
||||||
} from '../helpers';
|
} from '../helpers';
|
||||||
|
|
||||||
@ -309,6 +310,12 @@ const ChannelsTable = () => {
|
|||||||
|
|
||||||
const setChannelFormat = (channels) => {
|
const setChannelFormat = (channels) => {
|
||||||
for (let i = 0; i < channels.length; i++) {
|
for (let i = 0; i < channels.length; i++) {
|
||||||
|
if (channels[i].type === 8) {
|
||||||
|
showWarning(
|
||||||
|
'检测到您使用了“自定义渠道”类型,请更换为“OpenAI”渠道类型!',
|
||||||
|
);
|
||||||
|
showWarning('下个版本将不再支持“自定义渠道”类型!');
|
||||||
|
}
|
||||||
channels[i].key = '' + channels[i].id;
|
channels[i].key = '' + channels[i].id;
|
||||||
let test_models = [];
|
let test_models = [];
|
||||||
channels[i].models.split(',').forEach((item, index) => {
|
channels[i].models.split(',').forEach((item, index) => {
|
||||||
|
@ -294,6 +294,30 @@ const LogsTable = () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '重试',
|
||||||
|
dataIndex: 'retry',
|
||||||
|
className: isAdmin() ? 'tableShow' : 'tableHiddle',
|
||||||
|
render: (text, record, index) => {
|
||||||
|
let content = '渠道:' + record.channel;
|
||||||
|
if (record.other !== '') {
|
||||||
|
let other = JSON.parse(record.other);
|
||||||
|
if (other.admin_info !== undefined) {
|
||||||
|
if (
|
||||||
|
other.admin_info.use_channel !== null &&
|
||||||
|
other.admin_info.use_channel !== undefined &&
|
||||||
|
other.admin_info.use_channel !== ''
|
||||||
|
) {
|
||||||
|
// channel id array
|
||||||
|
let useChannel = other.admin_info.use_channel;
|
||||||
|
let useChannelStr = useChannel.join('->');
|
||||||
|
content = `渠道:${useChannelStr}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isAdminUser ? <div>{content}</div> : <></>;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '详情',
|
title: '详情',
|
||||||
dataIndex: 'content',
|
dataIndex: 'content',
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { API, copy, showError, showSuccess } from '../helpers';
|
import { API, copy, showError, showSuccess } from '../helpers';
|
||||||
|
|
||||||
import { Banner, Layout, Modal, Table, Tag, Tooltip } from '@douyinfe/semi-ui';
|
import {
|
||||||
|
Banner,
|
||||||
|
Input,
|
||||||
|
Layout,
|
||||||
|
Modal,
|
||||||
|
Space,
|
||||||
|
Table,
|
||||||
|
Tag,
|
||||||
|
Tooltip,
|
||||||
|
} from '@douyinfe/semi-ui';
|
||||||
import { stringToColor } from '../helpers/render.js';
|
import { stringToColor } from '../helpers/render.js';
|
||||||
import { UserContext } from '../context/User/index.js';
|
import { UserContext } from '../context/User/index.js';
|
||||||
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
import Text from '@douyinfe/semi-ui/lib/es/typography/text';
|
||||||
@ -45,6 +54,27 @@ function renderAvailable(available) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ModelPricing = () => {
|
const ModelPricing = () => {
|
||||||
|
const [filteredValue, setFilteredValue] = useState([]);
|
||||||
|
const compositionRef = useRef({ isComposition: false });
|
||||||
|
|
||||||
|
const handleChange = (value) => {
|
||||||
|
if (compositionRef.current.isComposition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newFilteredValue = value ? [value] : [];
|
||||||
|
setFilteredValue(newFilteredValue);
|
||||||
|
};
|
||||||
|
const handleCompositionStart = () => {
|
||||||
|
compositionRef.current.isComposition = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCompositionEnd = (event) => {
|
||||||
|
compositionRef.current.isComposition = false;
|
||||||
|
const value = event.target.value;
|
||||||
|
const newFilteredValue = value ? [value] : [];
|
||||||
|
setFilteredValue(newFilteredValue);
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '可用性',
|
title: '可用性',
|
||||||
@ -52,28 +82,28 @@ const ModelPricing = () => {
|
|||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return renderAvailable(text);
|
return renderAvailable(text);
|
||||||
},
|
},
|
||||||
|
sorter: (a, b) => a.available - b.available,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '提供者',
|
title: (
|
||||||
dataIndex: 'owner_by',
|
<Space>
|
||||||
render: (text, record, index) => {
|
<span>模型名称</span>
|
||||||
return (
|
<Input
|
||||||
<>
|
placeholder='模糊搜索'
|
||||||
<Tag color={stringToColor(text)} size='large'>
|
style={{ width: 200 }}
|
||||||
{text}
|
onCompositionStart={handleCompositionStart}
|
||||||
</Tag>
|
onCompositionEnd={handleCompositionEnd}
|
||||||
</>
|
onChange={handleChange}
|
||||||
);
|
showClear
|
||||||
},
|
/>
|
||||||
},
|
</Space>
|
||||||
{
|
),
|
||||||
title: '模型名称',
|
|
||||||
dataIndex: 'model_name', // 以finish_time作为dataIndex
|
dataIndex: 'model_name', // 以finish_time作为dataIndex
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tag
|
<Tag
|
||||||
color={stringToColor(record.owner_by)}
|
color={stringToColor(text)}
|
||||||
size='large'
|
size='large'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
copyText(text);
|
copyText(text);
|
||||||
@ -84,6 +114,8 @@ const ModelPricing = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onFilter: (value, record) => record.model_name.includes(value),
|
||||||
|
filteredValue,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '计费类型',
|
title: '计费类型',
|
||||||
@ -91,6 +123,7 @@ const ModelPricing = () => {
|
|||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return renderQuotaType(parseInt(text));
|
return renderQuotaType(parseInt(text));
|
||||||
},
|
},
|
||||||
|
sorter: (a, b) => a.quota_type - b.quota_type,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '模型倍率',
|
title: '模型倍率',
|
||||||
@ -150,14 +183,17 @@ const ModelPricing = () => {
|
|||||||
return a.quota_type - b.quota_type;
|
return a.quota_type - b.quota_type;
|
||||||
});
|
});
|
||||||
|
|
||||||
// sort by owner_by, openai is max, other use localeCompare
|
// sort by model_name, start with gpt is max, other use localeCompare
|
||||||
models.sort((a, b) => {
|
models.sort((a, b) => {
|
||||||
if (a.owner_by === 'openai') {
|
if (a.model_name.startsWith('gpt') && !b.model_name.startsWith('gpt')) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (b.owner_by === 'openai') {
|
} else if (
|
||||||
|
!a.model_name.startsWith('gpt') &&
|
||||||
|
b.model_name.startsWith('gpt')
|
||||||
|
) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return a.owner_by.localeCompare(b.owner_by);
|
return a.model_name.localeCompare(b.model_name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user