From f0f0215b207f689733021713385e9dc8d1c20685 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Mon, 20 Apr 2026 17:01:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(pricing):=20=E4=BF=AE=E5=A4=8D=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=80=8D=E7=8E=87=E5=86=99=E5=85=A5=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC1=E5=92=8C=E7=BC=93=E5=AD=98=E5=88=9B=E5=BB=BAtoken?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. CopyGlobalPricing 检查 ratio 查找的 bool 返回值,未找到时写 0 而非写入 fallback 值 1,避免覆盖全局正确的 0.1 2. Claude 响应使用 GetCacheCreationTotalTokens() 替代直接读 CacheCreationInputTokens,兼容新版本子对象格式 3. 新增 GetAudioRatioV2/GetAudioCompletionRatioV2 带 bool 返回 Co-Authored-By: Claude Opus 4.7 --- controller/channel_pricing.go | 25 ++++++++++++++++++++----- relay/channel/claude/relay-claude.go | 8 ++++---- setting/ratio_setting/model_ratio.go | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/controller/channel_pricing.go b/controller/channel_pricing.go index 9292ff9..3bfdb45 100644 --- a/controller/channel_pricing.go +++ b/controller/channel_pricing.go @@ -212,11 +212,26 @@ func CopyGlobalPricing(c *gin.Context) { } // 获取全局扩展比率 - globalCacheRatio, _ := ratio_setting.GetCacheRatio(ability.Model) - globalCacheCreationRatio, _ := ratio_setting.GetCreateCacheRatio(ability.Model) - globalImageRatio, _ := ratio_setting.GetImageRatio(ability.Model) - globalAudioRatio := ratio_setting.GetAudioRatio(ability.Model) - globalAudioCompletionRatio := ratio_setting.GetAudioCompletionRatio(ability.Model) + globalCacheRatio, hasCacheRatio := ratio_setting.GetCacheRatio(ability.Model) + if !hasCacheRatio { + globalCacheRatio = 0 + } + globalCacheCreationRatio, hasCacheCreationRatio := ratio_setting.GetCreateCacheRatio(ability.Model) + if !hasCacheCreationRatio { + globalCacheCreationRatio = 0 + } + globalImageRatio, hasImageRatio := ratio_setting.GetImageRatio(ability.Model) + if !hasImageRatio { + globalImageRatio = 0 + } + globalAudioRatio, hasAudioRatio := ratio_setting.GetAudioRatioV2(ability.Model) + if !hasAudioRatio { + globalAudioRatio = 0 + } + globalAudioCompletionRatio, hasAudioCompRatio := ratio_setting.GetAudioCompletionRatioV2(ability.Model) + if !hasAudioCompRatio { + globalAudioCompletionRatio = 0 + } // 确定定价类型 var quotaType int diff --git a/relay/channel/claude/relay-claude.go b/relay/channel/claude/relay-claude.go index be2e2a8..8bf7cad 100644 --- a/relay/channel/claude/relay-claude.go +++ b/relay/channel/claude/relay-claude.go @@ -635,7 +635,7 @@ func FormatClaudeResponseInfo(claudeResponse *dto.ClaudeResponse, oaiResponse *d if claudeResponse.Message != nil && claudeResponse.Message.Usage != nil { claudeInfo.Usage.PromptTokens = claudeResponse.Message.Usage.InputTokens claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Message.Usage.CacheReadInputTokens - claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Message.Usage.CacheCreationInputTokens + claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Message.Usage.GetCacheCreationTotalTokens() claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Message.Usage.GetCacheCreation5mTokens() claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Message.Usage.GetCacheCreation1hTokens() claudeInfo.Usage.CompletionTokens = claudeResponse.Message.Usage.OutputTokens @@ -659,8 +659,8 @@ func FormatClaudeResponseInfo(claudeResponse *dto.ClaudeResponse, oaiResponse *d if claudeResponse.Usage.CacheReadInputTokens > 0 { claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Usage.CacheReadInputTokens } - if claudeResponse.Usage.CacheCreationInputTokens > 0 { - claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Usage.CacheCreationInputTokens + if total := claudeResponse.Usage.GetCacheCreationTotalTokens(); total > 0 { + claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = total } if cacheCreation5m := claudeResponse.Usage.GetCacheCreation5mTokens(); cacheCreation5m > 0 { claudeInfo.Usage.ClaudeCacheCreation5mTokens = cacheCreation5m @@ -811,7 +811,7 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud claudeInfo.Usage.CompletionTokens = claudeResponse.Usage.OutputTokens claudeInfo.Usage.TotalTokens = claudeResponse.Usage.InputTokens + claudeResponse.Usage.OutputTokens claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Usage.CacheReadInputTokens - claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Usage.CacheCreationInputTokens + claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Usage.GetCacheCreationTotalTokens() claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Usage.GetCacheCreation5mTokens() claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Usage.GetCacheCreation1hTokens() } diff --git a/setting/ratio_setting/model_ratio.go b/setting/ratio_setting/model_ratio.go index 6014f3f..7e36362 100644 --- a/setting/ratio_setting/model_ratio.go +++ b/setting/ratio_setting/model_ratio.go @@ -604,6 +604,15 @@ func GetAudioRatio(name string) float64 { return 1 } +func GetAudioRatioV2(name string) (float64, bool) { + name = FormatMatchingModelName(name) + ratio, ok := audioRatioMap.Get(name) + if !ok { + return 0, false + } + return ratio, true +} + func GetAudioCompletionRatio(name string) float64 { name = FormatMatchingModelName(name) if ratio, ok := audioCompletionRatioMap.Get(name); ok { @@ -612,6 +621,15 @@ func GetAudioCompletionRatio(name string) float64 { return 1 } +func GetAudioCompletionRatioV2(name string) (float64, bool) { + name = FormatMatchingModelName(name) + ratio, ok := audioCompletionRatioMap.Get(name) + if !ok { + return 0, false + } + return ratio, true +} + func ContainsAudioRatio(name string) bool { name = FormatMatchingModelName(name) _, ok := audioRatioMap.Get(name)