2025-02-20 16:41:46 +08:00
package helper
import (
2025-02-28 19:17:15 +08:00
"fmt"
2025-02-20 16:41:46 +08:00
"one-api/common"
2025-04-03 17:32:48 +08:00
constant2 "one-api/constant"
2025-02-20 16:41:46 +08:00
relaycommon "one-api/relay/common"
2025-06-18 18:00:49 +08:00
"one-api/setting/ratio_setting"
2025-06-11 23:46:59 +08:00
"github.com/gin-gonic/gin"
2025-02-20 16:41:46 +08:00
)
2025-06-17 21:05:35 +08:00
type GroupRatioInfo struct {
GroupRatio float64
GroupSpecialRatio float64
2025-06-22 17:52:48 +08:00
HasSpecialRatio bool
2025-06-17 21:05:35 +08:00
}
2025-02-20 16:41:46 +08:00
type PriceData struct {
ModelPrice float64
ModelRatio float64
2025-03-02 15:47:12 +08:00
CompletionRatio float64
2025-03-08 01:30:50 +08:00
CacheRatio float64
2025-04-24 19:25:08 +08:00
CacheCreationRatio float64
ImageRatio float64
2025-02-20 16:41:46 +08:00
UsePrice bool
ShouldPreConsumedQuota int
2025-06-17 21:05:35 +08:00
GroupRatioInfo GroupRatioInfo
2025-02-20 16:41:46 +08:00
}
2025-03-17 17:52:54 +08:00
func ( p PriceData ) ToSetting ( ) string {
2025-06-17 21:05:35 +08:00
return fmt . Sprintf ( "ModelPrice: %f, ModelRatio: %f, CompletionRatio: %f, CacheRatio: %f, GroupRatio: %f, UsePrice: %t, CacheCreationRatio: %f, ShouldPreConsumedQuota: %d, ImageRatio: %f" , p . ModelPrice , p . ModelRatio , p . CompletionRatio , p . CacheRatio , p . GroupRatioInfo . GroupRatio , p . UsePrice , p . CacheCreationRatio , p . ShouldPreConsumedQuota , p . ImageRatio )
2025-03-17 17:52:54 +08:00
}
2025-06-22 17:52:48 +08:00
// HandleGroupRatio checks for "auto_group" in the context and updates the group ratio and relayInfo.UsingGroup if present
2025-06-17 21:05:35 +08:00
func HandleGroupRatio ( ctx * gin . Context , relayInfo * relaycommon . RelayInfo ) GroupRatioInfo {
groupRatioInfo := GroupRatioInfo {
GroupRatio : 1.0 , // default ratio
2025-06-19 15:36:06 +08:00
GroupSpecialRatio : - 1 ,
2025-06-17 21:05:35 +08:00
}
// check auto group
autoGroup , exists := ctx . Get ( "auto_group" )
2025-06-16 22:15:12 +08:00
if exists {
2025-06-17 21:05:35 +08:00
if common . DebugEnabled {
println ( fmt . Sprintf ( "final group: %s" , autoGroup ) )
}
2025-06-22 17:52:48 +08:00
relayInfo . UsingGroup = autoGroup . ( string )
2025-06-16 22:15:12 +08:00
}
2025-06-17 21:05:35 +08:00
// check user group special ratio
2025-06-22 17:52:48 +08:00
userGroupRatio , ok := ratio_setting . GetGroupGroupRatio ( relayInfo . UserGroup , relayInfo . UsingGroup )
2025-06-11 23:46:59 +08:00
if ok {
2025-06-17 21:05:35 +08:00
// user group special ratio
groupRatioInfo . GroupSpecialRatio = userGroupRatio
groupRatioInfo . GroupRatio = userGroupRatio
2025-06-22 17:52:48 +08:00
groupRatioInfo . HasSpecialRatio = true
2025-06-17 21:05:35 +08:00
} else {
// normal group ratio
2025-06-22 17:52:48 +08:00
groupRatioInfo . GroupRatio = ratio_setting . GetGroupRatio ( relayInfo . UsingGroup )
2025-06-11 23:46:59 +08:00
}
2025-06-17 21:05:35 +08:00
return groupRatioInfo
}
func ModelPriceHelper ( c * gin . Context , info * relaycommon . RelayInfo , promptTokens int , maxTokens int ) ( PriceData , error ) {
2025-06-18 18:00:49 +08:00
modelPrice , usePrice := ratio_setting . GetModelPrice ( info . OriginModelName , false )
2025-06-17 21:05:35 +08:00
groupRatioInfo := HandleGroupRatio ( c , info )
2025-02-20 16:41:46 +08:00
var preConsumedQuota int
var modelRatio float64
2025-03-02 15:47:12 +08:00
var completionRatio float64
2025-03-08 01:30:50 +08:00
var cacheRatio float64
2025-04-24 19:25:08 +08:00
var imageRatio float64
2025-03-12 21:31:46 +08:00
var cacheCreationRatio float64
2025-02-20 16:41:46 +08:00
if ! usePrice {
preConsumedTokens := common . PreConsumedQuota
if maxTokens != 0 {
preConsumedTokens = promptTokens + maxTokens
}
2025-02-28 20:28:44 +08:00
var success bool
2025-06-18 18:00:49 +08:00
modelRatio , success = ratio_setting . GetModelRatio ( info . OriginModelName )
2025-02-28 19:17:15 +08:00
if ! success {
2025-04-03 17:32:48 +08:00
acceptUnsetRatio := false
if accept , ok := info . UserSetting [ constant2 . UserAcceptUnsetRatioModel ] ; ok {
b , ok := accept . ( bool )
if ok {
acceptUnsetRatio = b
}
}
if ! acceptUnsetRatio {
2025-04-18 19:36:18 +08:00
return PriceData { } , fmt . Errorf ( "模型 %s 倍率或价格未配置, 请联系管理员设置或开始自用模式; Model %s ratio or price not set, please set or start self-use mode" , info . OriginModelName , info . OriginModelName )
2025-03-01 21:13:48 +08:00
}
2025-02-28 19:17:15 +08:00
}
2025-06-18 18:00:49 +08:00
completionRatio = ratio_setting . GetCompletionRatio ( info . OriginModelName )
cacheRatio , _ = ratio_setting . GetCacheRatio ( info . OriginModelName )
cacheCreationRatio , _ = ratio_setting . GetCreateCacheRatio ( info . OriginModelName )
imageRatio , _ = ratio_setting . GetImageRatio ( info . OriginModelName )
2025-06-17 21:05:35 +08:00
ratio := modelRatio * groupRatioInfo . GroupRatio
2025-02-20 16:41:46 +08:00
preConsumedQuota = int ( float64 ( preConsumedTokens ) * ratio )
} else {
2025-06-17 21:05:35 +08:00
preConsumedQuota = int ( modelPrice * common . QuotaPerUnit * groupRatioInfo . GroupRatio )
2025-02-20 16:41:46 +08:00
}
2025-03-17 17:52:54 +08:00
priceData := PriceData {
2025-02-20 16:41:46 +08:00
ModelPrice : modelPrice ,
ModelRatio : modelRatio ,
2025-03-02 15:47:12 +08:00
CompletionRatio : completionRatio ,
2025-06-17 21:05:35 +08:00
GroupRatioInfo : groupRatioInfo ,
2025-02-20 16:41:46 +08:00
UsePrice : usePrice ,
2025-03-08 01:30:50 +08:00
CacheRatio : cacheRatio ,
2025-04-24 19:25:08 +08:00
ImageRatio : imageRatio ,
2025-03-12 21:31:46 +08:00
CacheCreationRatio : cacheCreationRatio ,
2025-02-20 16:41:46 +08:00
ShouldPreConsumedQuota : preConsumedQuota ,
2025-03-17 17:52:54 +08:00
}
if common . DebugEnabled {
println ( fmt . Sprintf ( "model_price_helper result: %s" , priceData . ToSetting ( ) ) )
}
return priceData , nil
2025-02-20 16:41:46 +08:00
}
2025-04-18 19:36:18 +08:00
2025-06-22 17:52:48 +08:00
type PerCallPriceData struct {
ModelPrice float64
Quota int
GroupRatioInfo GroupRatioInfo
}
// ModelPriceHelperPerCall 按次计费的 PriceHelper (MJ、Task)
func ModelPriceHelperPerCall ( c * gin . Context , info * relaycommon . RelayInfo ) PerCallPriceData {
groupRatioInfo := HandleGroupRatio ( c , info )
modelPrice , success := ratio_setting . GetModelPrice ( info . OriginModelName , true )
// 如果没有配置价格,则使用默认价格
if ! success {
defaultPrice , ok := ratio_setting . GetDefaultModelRatioMap ( ) [ info . OriginModelName ]
if ! ok {
modelPrice = 0.1
} else {
modelPrice = defaultPrice
}
}
quota := int ( modelPrice * common . QuotaPerUnit * groupRatioInfo . GroupRatio )
priceData := PerCallPriceData {
ModelPrice : modelPrice ,
Quota : quota ,
GroupRatioInfo : groupRatioInfo ,
}
return priceData
}
2025-04-18 19:36:18 +08:00
func ContainPriceOrRatio ( modelName string ) bool {
2025-06-18 18:00:49 +08:00
_ , ok := ratio_setting . GetModelPrice ( modelName , false )
2025-04-18 19:36:18 +08:00
if ok {
return true
}
2025-06-18 18:00:49 +08:00
_ , ok = ratio_setting . GetModelRatio ( modelName )
2025-04-18 19:36:18 +08:00
if ok {
return true
}
return false
}