mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-21 14:19:18 +08:00
fix(openai): preserve explicit GPT-5.6 cache write prices
This commit is contained in:
@@ -97,6 +97,7 @@ type ModelPricing struct {
|
||||
OutputPricePerTokenPriority float64 // priority service tier 下每token输出价格 (USD)
|
||||
CacheCreationPricePerToken float64 // 缓存创建每token价格 (USD)
|
||||
CacheCreationPricePerTokenPriority float64 // priority service tier 下缓存创建每token价格 (USD)
|
||||
CacheCreationPriceExplicit bool // 是否由渠道/区间定价显式设定(为 true 时即使 == 0 也不回退)
|
||||
CacheReadPricePerToken float64 // 缓存读取每token价格 (USD)
|
||||
CacheReadPricePerTokenPriority float64 // priority service tier 下缓存读取每token价格 (USD)
|
||||
CacheCreation5mPrice float64 // 5分钟缓存创建每token价格 (USD)
|
||||
@@ -825,6 +826,7 @@ func (s *BillingService) GetModelPricingWithChannel(model string, channelPricing
|
||||
if channelPricing.CacheWritePrice != nil {
|
||||
pricing.CacheCreationPricePerToken = *channelPricing.CacheWritePrice
|
||||
pricing.CacheCreationPricePerTokenPriority = *channelPricing.CacheWritePrice
|
||||
pricing.CacheCreationPriceExplicit = true
|
||||
pricing.CacheCreation5mPrice = *channelPricing.CacheWritePrice
|
||||
pricing.CacheCreation1hPrice = *channelPricing.CacheWritePrice
|
||||
}
|
||||
@@ -1100,7 +1102,7 @@ func (s *BillingService) applyModelSpecificPricingPolicy(model string, pricing *
|
||||
}
|
||||
needsLongContextPolicy := usesLegacyLongContextPricing &&
|
||||
(pricing.LongContextInputThreshold <= 0 || pricing.LongContextInputMultiplier <= 0 || pricing.LongContextOutputMultiplier <= 0)
|
||||
needsCacheCreationPolicy := isGPT56 && (pricing.CacheCreationPricePerToken <= 0 ||
|
||||
needsCacheCreationPolicy := isGPT56 && !pricing.CacheCreationPriceExplicit && (pricing.CacheCreationPricePerToken <= 0 ||
|
||||
(pricing.InputPricePerTokenPriority > 0 && pricing.CacheCreationPricePerTokenPriority <= 0))
|
||||
if !needsLongContextPolicy && !needsCacheCreationPolicy {
|
||||
return pricing
|
||||
|
||||
@@ -184,6 +184,7 @@ func (r *ModelPricingResolver) applyTokenOverrides(chPricing *ChannelModelPricin
|
||||
if chPricing.CacheWritePrice != nil {
|
||||
resolved.BasePricing.CacheCreationPricePerToken = *chPricing.CacheWritePrice
|
||||
resolved.BasePricing.CacheCreationPricePerTokenPriority = *chPricing.CacheWritePrice
|
||||
resolved.BasePricing.CacheCreationPriceExplicit = true
|
||||
resolved.BasePricing.CacheCreation5mPrice = *chPricing.CacheWritePrice
|
||||
resolved.BasePricing.CacheCreation1hPrice = *chPricing.CacheWritePrice
|
||||
}
|
||||
@@ -253,6 +254,7 @@ func intervalToModelPricing(iv *PricingInterval, supportsCacheBreakdown bool, ch
|
||||
if iv.CacheWritePrice != nil {
|
||||
pricing.CacheCreationPricePerToken = *iv.CacheWritePrice
|
||||
pricing.CacheCreationPricePerTokenPriority = *iv.CacheWritePrice
|
||||
pricing.CacheCreationPriceExplicit = true
|
||||
pricing.CacheCreation5mPrice = *iv.CacheWritePrice
|
||||
pricing.CacheCreation1hPrice = *iv.CacheWritePrice
|
||||
}
|
||||
|
||||
@@ -114,6 +114,52 @@ func TestGetIntervalPricing_NoMatch_FallsBackToBase(t *testing.T) {
|
||||
require.Equal(t, basePricing, result)
|
||||
}
|
||||
|
||||
func TestGPT56ExplicitZeroCacheWritePriceIsPreserved(t *testing.T) {
|
||||
bs := &BillingService{}
|
||||
resolver := NewModelPricingResolver(nil, bs)
|
||||
zero := 0.0
|
||||
|
||||
t.Run("flat channel price", func(t *testing.T) {
|
||||
resolved := &ResolvedPricing{
|
||||
Mode: BillingModeToken,
|
||||
BasePricing: &ModelPricing{
|
||||
InputPricePerToken: 5e-6,
|
||||
OutputPricePerToken: 30e-6,
|
||||
},
|
||||
}
|
||||
resolver.applyTokenOverrides(&ChannelModelPricing{CacheWritePrice: &zero}, resolved)
|
||||
|
||||
require.True(t, resolved.BasePricing.CacheCreationPriceExplicit)
|
||||
cost, err := bs.CalculateCostUnified(CostInput{
|
||||
Model: "gpt-5.6-sol",
|
||||
Tokens: UsageTokens{CacheCreationTokens: 100},
|
||||
RateMultiplier: 1,
|
||||
Resolver: resolver,
|
||||
Resolved: resolved,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, cost.CacheCreationCost)
|
||||
})
|
||||
|
||||
t.Run("interval price", func(t *testing.T) {
|
||||
pricing := intervalToModelPricing(&PricingInterval{CacheWritePrice: &zero}, false, nil)
|
||||
require.True(t, pricing.CacheCreationPriceExplicit)
|
||||
|
||||
cost, err := bs.CalculateCostUnified(CostInput{
|
||||
Model: "gpt-5.6-sol",
|
||||
Tokens: UsageTokens{CacheCreationTokens: 100},
|
||||
RateMultiplier: 1,
|
||||
Resolver: resolver,
|
||||
Resolved: &ResolvedPricing{
|
||||
Mode: BillingModeToken,
|
||||
BasePricing: pricing,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, cost.CacheCreationCost)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetRequestTierPrice(t *testing.T) {
|
||||
bs := newTestBillingServiceForResolver()
|
||||
r := NewModelPricingResolver(&ChannelService{}, bs)
|
||||
|
||||
Reference in New Issue
Block a user