Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions controller/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var completionRatioMetaOptionKeys = []string{
"CacheRatio",
"CreateCacheRatio",
"ImageRatio",
"ImageCompletionRatio",
"AudioRatio",
"AudioCompletionRatio",
}
Expand Down Expand Up @@ -224,6 +225,15 @@ func UpdateOption(c *gin.Context) {
})
return
}
case "ImageCompletionRatio":
err = ratio_setting.UpdateImageCompletionRatioByJSONString(option.Value.(string))
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "图片补全倍率设置失败: " + err.Error(),
})
return
}
case "CreateCacheRatio":
err = ratio_setting.UpdateCreateCacheRatioByJSONString(option.Value.(string))
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions model/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func InitOptionMap() {
common.OptionMap["ImageRatio"] = ratio_setting.ImageRatio2JSONString()
common.OptionMap["AudioRatio"] = ratio_setting.AudioRatio2JSONString()
common.OptionMap["AudioCompletionRatio"] = ratio_setting.AudioCompletionRatio2JSONString()
common.OptionMap["ImageCompletionRatio"] = ratio_setting.ImageCompletionRatio2JSONString()
common.OptionMap["TopUpLink"] = common.TopUpLink
//common.OptionMap["ChatLink"] = common.ChatLink
//common.OptionMap["ChatLink2"] = common.ChatLink2
Expand Down
5 changes: 5 additions & 0 deletions model/pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Pricing struct {
CacheRatio *float64 `json:"cache_ratio,omitempty"`
CreateCacheRatio *float64 `json:"create_cache_ratio,omitempty"`
ImageRatio *float64 `json:"image_ratio,omitempty"`
ImageCompletionRatio *float64 `json:"image_completion_ratio,omitempty"`
AudioRatio *float64 `json:"audio_ratio,omitempty"`
AudioCompletionRatio *float64 `json:"audio_completion_ratio,omitempty"`
EnableGroup []string `json:"enable_groups"`
Expand Down Expand Up @@ -322,6 +323,10 @@ func updatePricing() {
audioCompletionRatio := ratio_setting.GetAudioCompletionRatio(model)
pricing.AudioCompletionRatio = &audioCompletionRatio
}
if ratio_setting.ContainsImageCompletionRatio(model) {
imageCompletionRatio := ratio_setting.GetImageCompletionRatio(model)
pricing.ImageCompletionRatio = &imageCompletionRatio
}
if billingMode := billing_setting.GetBillingMode(model); billingMode == "tiered_expr" {
pricing.BillingMode = billingMode
if expr, ok := billing_setting.GetBillingExpr(model); ok {
Expand Down
9 changes: 9 additions & 0 deletions relay/compatible_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage
imageTokens := usage.PromptTokensDetails.ImageTokens
audioTokens := usage.PromptTokensDetails.AudioTokens
completionTokens := usage.CompletionTokens
completionImageTokens := usage.CompletionTokenDetails.ImageTokens
cachedCreationTokens := usage.PromptTokensDetails.CachedCreationTokens

modelName := relayInfo.OriginModelName
Expand All @@ -265,6 +266,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage
completionRatio := relayInfo.PriceData.CompletionRatio
cacheRatio := relayInfo.PriceData.CacheRatio
imageRatio := relayInfo.PriceData.ImageRatio
imageCompletionRatio := relayInfo.PriceData.ImageCompletionRatio
modelRatio := relayInfo.PriceData.ModelRatio
groupRatio := relayInfo.PriceData.GroupRatioInfo.GroupRatio
modelPrice := relayInfo.PriceData.ModelPrice
Expand All @@ -276,6 +278,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage
dImageTokens := decimal.NewFromInt(int64(imageTokens))
dAudioTokens := decimal.NewFromInt(int64(audioTokens))
dCompletionTokens := decimal.NewFromInt(int64(completionTokens))
dCompletionImageTokens := decimal.NewFromInt(int64(completionImageTokens))
dCachedCreationTokens := decimal.NewFromInt(int64(cachedCreationTokens))
dCompletionRatio := decimal.NewFromFloat(completionRatio)
dCacheRatio := decimal.NewFromFloat(cacheRatio)
Expand Down Expand Up @@ -361,6 +364,12 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage
Add(imageTokensWithRatio).
Add(dCachedCreationTokensWithRatio)

if !dCompletionImageTokens.IsZero() {
dImageCompletionRatio := decimal.NewFromFloat(imageCompletionRatio)
dCompletionTokens = dCompletionTokens.Sub(dCompletionImageTokens)
dCompletionTokens = dCompletionTokens.Add(dCompletionImageTokens.Mul(dImageCompletionRatio))
}

completionQuota := dCompletionTokens.Mul(dCompletionRatio)

quotaCalculateDecimal = promptQuota.Add(completionQuota).Mul(ratio)
Expand Down
3 changes: 3 additions & 0 deletions relay/helper/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
var completionRatio float64
var cacheRatio float64
var imageRatio float64
var imageCompletionRatio float64
var cacheCreationRatio float64
var cacheCreationRatio5m float64
var cacheCreationRatio1h float64
Expand Down Expand Up @@ -92,6 +93,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
// 固定1h和5min缓存写入价格的比例
cacheCreationRatio1h = cacheCreationRatio * claudeCacheCreation1hMultiplier
imageRatio, _ = ratio_setting.GetImageRatio(info.OriginModelName)
imageCompletionRatio = ratio_setting.GetImageCompletionRatio(info.OriginModelName)
audioRatio = ratio_setting.GetAudioRatio(info.OriginModelName)
audioCompletionRatio = ratio_setting.GetAudioCompletionRatio(info.OriginModelName)
ratio := modelRatio * groupRatioInfo.GroupRatio
Expand Down Expand Up @@ -131,6 +133,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
UsePrice: usePrice,
CacheRatio: cacheRatio,
ImageRatio: imageRatio,
ImageCompletionRatio: imageCompletionRatio,
AudioRatio: audioRatio,
AudioCompletionRatio: audioCompletionRatio,
CacheCreationRatio: cacheCreationRatio,
Expand Down
36 changes: 33 additions & 3 deletions setting/ratio_setting/model_ratio.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ var defaultModelRatio = map[string]float64{
"gemini-2.5-flash-lite-preview-thinking-*": 0.05,
"gemini-2.5-flash-lite-preview-06-17": 0.05,
"gemini-2.5-flash": 0.15,
"gemini-3.1-flash-image-preview": 0.25,
"gemini-3-pro-image-preview": 1.0,
"gemini-robotics-er-1.5-preview": 0.15,
"gemini-embedding-001": 0.075,
"text-embedding-004": 0.001,
Expand Down Expand Up @@ -322,9 +324,15 @@ var defaultAudioCompletionRatio = map[string]float64{
"tts-1-hd-1106": 0,
}

var defaultImageCompletionRatio = map[string]float64{
"gemini-3.1-flash-image-preview": 20,
"gemini-3-pro-image-preview": 10,
}

var modelPriceMap = types.NewRWMap[string, float64]()
var modelRatioMap = types.NewRWMap[string, float64]()
var completionRatioMap = types.NewRWMap[string, float64]()
var imageCompletionRatioMap = types.NewRWMap[string, float64]()

var defaultCompletionRatio = map[string]float64{
"gpt-4-gizmo-*": 2,
Expand All @@ -338,6 +346,7 @@ func InitRatioSettings() {
modelPriceMap.AddAll(defaultModelPrice)
modelRatioMap.AddAll(defaultModelRatio)
completionRatioMap.AddAll(defaultCompletionRatio)
imageCompletionRatioMap.AddAll(defaultImageCompletionRatio)
cacheRatioMap.AddAll(defaultCacheRatio)
createCacheRatioMap.AddAll(defaultCreateCacheRatio)
imageRatioMap.AddAll(defaultImageRatio)
Expand Down Expand Up @@ -572,9 +581,8 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
} else if strings.HasPrefix(name, "gemini-robotics-er-1.5") {
return 2.5 / 0.3, false
} else if strings.HasPrefix(name, "gemini-3-pro") {
if strings.HasPrefix(name, "gemini-3-pro-image") {
return 60, false
}
return 6, false
} else if strings.HasPrefix(name, "gemini-3.1-flash") {
return 6, false
}
return 4, false
Expand Down Expand Up @@ -697,6 +705,28 @@ func GetCompletionRatioCopy() map[string]float64 {
return completionRatioMap.ReadAll()
}

func ImageCompletionRatio2JSONString() string {
return imageCompletionRatioMap.MarshalJSONString()
}

func UpdateImageCompletionRatioByJSONString(jsonStr string) error {
return types.LoadFromJsonStringWithCallback(imageCompletionRatioMap, jsonStr, InvalidateExposedDataCache)
}

func GetImageCompletionRatio(name string) float64 {
name = FormatMatchingModelName(name)
if ratio, ok := imageCompletionRatioMap.Get(name); ok {
return ratio
}
return 1
}

func ContainsImageCompletionRatio(name string) bool {
name = FormatMatchingModelName(name)
_, ok := imageCompletionRatioMap.Get(name)
return ok
}

// 转换模型名,减少渠道必须配置各种带参数模型
func FormatMatchingModelName(name string) string {

Expand Down
3 changes: 2 additions & 1 deletion types/price_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type PriceData struct {
CacheCreation5mRatio float64
CacheCreation1hRatio float64
ImageRatio float64
ImageCompletionRatio float64
AudioRatio float64
AudioCompletionRatio float64
OtherRatios map[string]float64
Expand All @@ -38,5 +39,5 @@ func (p *PriceData) AddOtherRatio(key string, ratio float64) {
}

func (p *PriceData) ToSetting() string {
return fmt.Sprintf("ModelPrice: %f, ModelRatio: %f, CompletionRatio: %f, CacheRatio: %f, GroupRatio: %f, UsePrice: %t, CacheCreationRatio: %f, CacheCreation5mRatio: %f, CacheCreation1hRatio: %f, QuotaToPreConsume: %d, ImageRatio: %f, AudioRatio: %f, AudioCompletionRatio: %f", p.ModelPrice, p.ModelRatio, p.CompletionRatio, p.CacheRatio, p.GroupRatioInfo.GroupRatio, p.UsePrice, p.CacheCreationRatio, p.CacheCreation5mRatio, p.CacheCreation1hRatio, p.QuotaToPreConsume, p.ImageRatio, p.AudioRatio, p.AudioCompletionRatio)
return fmt.Sprintf("ModelPrice: %f, ModelRatio: %f, CompletionRatio: %f, CacheRatio: %f, GroupRatio: %f, UsePrice: %t, CacheCreationRatio: %f, CacheCreation5mRatio: %f, CacheCreation1hRatio: %f, QuotaToPreConsume: %d, ImageRatio: %f, ImageCompletionRatio: %f, AudioRatio: %f, AudioCompletionRatio: %f", p.ModelPrice, p.ModelRatio, p.CompletionRatio, p.CacheRatio, p.GroupRatioInfo.GroupRatio, p.UsePrice, p.CacheCreationRatio, p.CacheCreation5mRatio, p.CacheCreation1hRatio, p.QuotaToPreConsume, p.ImageRatio, p.ImageCompletionRatio, p.AudioRatio, p.AudioCompletionRatio)
}