From 4a7cb9e0f0d5330a2e45e90a83e8a73de8becfef Mon Sep 17 00:00:00 2001 From: xiezhouwei Date: Tue, 23 Jun 2026 10:51:46 +0800 Subject: [PATCH] feat: extend ModelHasConfiguredPricing to include channel-level pricing (ChannelModelRatio/ChannelModelPrice) via prebuilt index set --- setting/ratio_setting/group_ratio.go | 12 +++++++++-- setting/ratio_setting/model_ratio.go | 32 ++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/setting/ratio_setting/group_ratio.go b/setting/ratio_setting/group_ratio.go index 55e2566..635404c 100644 --- a/setting/ratio_setting/group_ratio.go +++ b/setting/ratio_setting/group_ratio.go @@ -198,7 +198,11 @@ func ChannelModelPrice2JSONString() string { } func UpdateChannelModelPriceByJSONString(jsonStr string) error { - return types.LoadFromJsonString(channelModelPriceMap, jsonStr) + err := types.LoadFromJsonString(channelModelPriceMap, jsonStr) + if err == nil { + rebuildChannelPricedModelSet() + } + return err } func GetChannelModelPriceCopy() map[string]map[string]float64 { @@ -227,7 +231,11 @@ func ChannelModelRatio2JSONString() string { } func UpdateChannelModelRatioByJSONString(jsonStr string) error { - return types.LoadFromJsonString(channelModelRatioMap, jsonStr) + err := types.LoadFromJsonString(channelModelRatioMap, jsonStr) + if err == nil { + rebuildChannelPricedModelSet() + } + return err } func GetChannelModelRatioCopy() map[string]map[string]float64 { diff --git a/setting/ratio_setting/model_ratio.go b/setting/ratio_setting/model_ratio.go index 94be765..7b4455d 100644 --- a/setting/ratio_setting/model_ratio.go +++ b/setting/ratio_setting/model_ratio.go @@ -2,6 +2,7 @@ package ratio_setting import ( "strings" + "sync" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/setting/operation_setting" @@ -342,6 +343,11 @@ var modelPriceMap = types.NewRWMap[string, float64]() var modelRatioMap = types.NewRWMap[string, float64]() var completionRatioMap = types.NewRWMap[string, float64]() +// channelPricedModelSet 缓存所有在渠道级定价(ChannelModelRatio / ChannelModelPrice)中配置了价格的模型名(已 FormatMatchingModelName)。 +// 用于 ModelHasConfiguredPricing 快速判断,避免每次遍历 channelModelRatioMap / channelModelPriceMap。 +var channelPricedModelSetMu sync.RWMutex +var channelPricedModelSet = make(map[string]bool) + var defaultCompletionRatio = map[string]float64{ "gpt-4-gizmo-*": 2, "gpt-4o-gizmo-*": 3, @@ -365,6 +371,25 @@ func InitRatioSettings() { imagePriceMap.AddAll(defaultImagePrice) } +// rebuildChannelPricedModelSet 从 channelModelRatioMap 和 channelModelPriceMap 重建 channelPricedModelSet。 +// 在渠道级定价数据变更(DB Option 同步 / 管理后台更新)后调用,确保 ModelHasConfiguredPricing 能感知渠道级定价。 +func rebuildChannelPricedModelSet() { + set := make(map[string]bool) + for _, ratios := range channelModelRatioMap.ReadAll() { + for model := range ratios { + set[FormatMatchingModelName(model)] = true + } + } + for _, prices := range channelModelPriceMap.ReadAll() { + for model := range prices { + set[FormatMatchingModelName(model)] = true + } + } + channelPricedModelSetMu.Lock() + channelPricedModelSet = set + channelPricedModelSetMu.Unlock() +} + func GetModelPriceMap() map[string]float64 { return modelPriceMap.ReadAll() } @@ -433,7 +458,7 @@ func GetModelRatio(name string) (float64, bool, string) { return ratio, true, name } -// ModelHasConfiguredPricing 表示模型在价格表或倍率表中存在显式配置(含 compact 通配)。 +// ModelHasConfiguredPricing 表示模型在价格表或倍率表中存在显式配置(含 compact 通配、渠道级定价)。 // 未命中表键时 GetModelRatio 不再提供可用倍率(非自用为 success=false;自用为占位倍率),此类模型不应出现在定价接口。 func ModelHasConfiguredPricing(model string) bool { if _, ok := GetModelPrice(model, false); ok { @@ -448,7 +473,10 @@ func ModelHasConfiguredPricing(model string) bool { return true } } - return false + channelPricedModelSetMu.RLock() + ok := channelPricedModelSet[name] + channelPricedModelSetMu.RUnlock() + return ok } func DefaultModelRatio2JSONString() string {