refactor(price): improve handling of other ratios in PriceData
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
relaycommon "github.com/QuantumNous/new-api/relay/common"
|
||||
"github.com/QuantumNous/new-api/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIsResponsesEventStreamContentType(t *testing.T) {
|
||||
@@ -24,3 +28,44 @@ func TestIsResponsesEventStreamContentType(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecalcQuotaFromRatiosIgnoresInvalidMultipliers(t *testing.T) {
|
||||
info := &relaycommon.RelayInfo{
|
||||
PriceData: types.PriceData{
|
||||
Quota: 100,
|
||||
},
|
||||
}
|
||||
info.PriceData.AddOtherRatio("duration", 2)
|
||||
|
||||
quota, ok := recalcQuotaFromRatios(info, map[string]float64{
|
||||
"duration": 3,
|
||||
"zero": 0,
|
||||
"negative": -1,
|
||||
"nan": math.NaN(),
|
||||
"inf": math.Inf(1),
|
||||
})
|
||||
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, 150, quota)
|
||||
assert.True(t, info.PriceData.HasOtherRatio("duration"))
|
||||
}
|
||||
|
||||
func TestRecalcQuotaFromRatiosRejectsAllInvalidAdjustedRatios(t *testing.T) {
|
||||
info := &relaycommon.RelayInfo{
|
||||
PriceData: types.PriceData{
|
||||
Quota: 100,
|
||||
},
|
||||
}
|
||||
info.PriceData.AddOtherRatio("duration", 2)
|
||||
|
||||
quota, ok := recalcQuotaFromRatios(info, map[string]float64{
|
||||
"zero": 0,
|
||||
"negative": -1,
|
||||
"nan": math.NaN(),
|
||||
"inf": math.Inf(1),
|
||||
})
|
||||
|
||||
require.False(t, ok)
|
||||
assert.Equal(t, 0, quota)
|
||||
assert.True(t, info.PriceData.HasOtherRatio("duration"))
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func ImageHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *type
|
||||
// Adaptors may have already set a more accurate count from the
|
||||
// upstream response; only set the default when they haven't.
|
||||
if info.PriceData.UsePrice { // only price model use N ratio
|
||||
if _, hasN := info.PriceData.OtherRatios["n"]; !hasN {
|
||||
if !info.PriceData.HasOtherRatio("n") {
|
||||
info.PriceData.AddOtherRatio("n", float64(imageN))
|
||||
}
|
||||
}
|
||||
|
||||
+15
-25
@@ -196,12 +196,7 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (*TaskSubmitRe
|
||||
|
||||
// 6. 将 OtherRatios 应用到基础额度(饱和转换,防止溢出成负数)
|
||||
if !common.StringsContains(constant.TaskPricePatches, modelName) {
|
||||
quotaWithRatios := float64(info.PriceData.Quota)
|
||||
for _, ra := range info.PriceData.OtherRatios {
|
||||
if ra != 1.0 {
|
||||
quotaWithRatios *= ra
|
||||
}
|
||||
}
|
||||
quotaWithRatios := info.PriceData.ApplyOtherRatiosToFloat(float64(info.PriceData.Quota))
|
||||
quota, clamp := common.QuotaFromFloatChecked(quotaWithRatios)
|
||||
info.PriceData.Quota = quota
|
||||
noteTaskQuotaClamp(info, clamp)
|
||||
@@ -232,7 +227,7 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (*TaskSubmitRe
|
||||
}
|
||||
|
||||
// 10. 返回 OtherRatios 给下游(header 必须在 DoResponse 写 body 之前设置)
|
||||
otherRatios := info.PriceData.OtherRatios
|
||||
otherRatios := info.PriceData.OtherRatios()
|
||||
if otherRatios == nil {
|
||||
otherRatios = map[string]float64{}
|
||||
}
|
||||
@@ -248,10 +243,12 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (*TaskSubmitRe
|
||||
// 11. 提交后计费调整:让适配器根据上游实际返回调整 OtherRatios
|
||||
finalQuota := info.PriceData.Quota
|
||||
if adjustedRatios := adaptor.AdjustBillingOnSubmit(info, taskData); len(adjustedRatios) > 0 {
|
||||
// 基于调整后的 ratios 重新计算 quota
|
||||
finalQuota = recalcQuotaFromRatios(info, adjustedRatios)
|
||||
info.PriceData.OtherRatios = adjustedRatios
|
||||
info.PriceData.Quota = finalQuota
|
||||
if adjustedQuota, ok := recalcQuotaFromRatios(info, adjustedRatios); ok {
|
||||
// 基于调整后的 ratios 重新计算 quota
|
||||
finalQuota = adjustedQuota
|
||||
info.PriceData.ReplaceOtherRatios(adjustedRatios)
|
||||
info.PriceData.Quota = finalQuota
|
||||
}
|
||||
}
|
||||
|
||||
return &TaskSubmitResult{
|
||||
@@ -264,25 +261,18 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (*TaskSubmitRe
|
||||
|
||||
// recalcQuotaFromRatios 根据 adjustedRatios 重新计算 quota。
|
||||
// 公式: baseQuota × ∏(ratio) — 其中 baseQuota 是不含 OtherRatios 的基础额度。
|
||||
func recalcQuotaFromRatios(info *relaycommon.RelayInfo, ratios map[string]float64) int {
|
||||
func recalcQuotaFromRatios(info *relaycommon.RelayInfo, ratios map[string]float64) (int, bool) {
|
||||
// 从 PriceData 获取不含 OtherRatios 的基础价格
|
||||
baseQuota := float64(info.PriceData.Quota)
|
||||
// 先除掉原有的 OtherRatios 恢复基础额度
|
||||
for _, ra := range info.PriceData.OtherRatios {
|
||||
if ra != 1.0 && ra > 0 {
|
||||
baseQuota /= ra
|
||||
}
|
||||
baseQuota := info.PriceData.RemoveOtherRatiosFromFloat(float64(info.PriceData.Quota))
|
||||
priceData := info.PriceData
|
||||
if !priceData.ReplaceOtherRatios(ratios) {
|
||||
return 0, false
|
||||
}
|
||||
// 应用新的 ratios
|
||||
result := baseQuota
|
||||
for _, ra := range ratios {
|
||||
if ra != 1.0 {
|
||||
result *= ra
|
||||
}
|
||||
}
|
||||
result := priceData.ApplyOtherRatiosToFloat(baseQuota)
|
||||
quota, clamp := common.QuotaFromFloatChecked(result)
|
||||
noteTaskQuotaClamp(info, clamp)
|
||||
return quota
|
||||
return quota, true
|
||||
}
|
||||
|
||||
// noteTaskQuotaClamp records the first quota saturation event onto the task's
|
||||
|
||||
Reference in New Issue
Block a user