From 6451158680ac671e65f7691f1197b0f9f51c4637 Mon Sep 17 00:00:00 2001 From: CaIon Date: Sat, 13 Sep 2025 12:53:28 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"feat:=20gemini-2.5-flash-image-previe?= =?UTF-8?q?w=20=E6=96=87=E6=9C=AC=E5=92=8C=E5=9B=BE=E7=89=87=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E8=AE=A1=E8=B4=B9"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e732c5842675d2aeeb3faa2af633341fb9d9c1ac. --- dto/gemini.go | 16 ++++---- relay/channel/gemini/relay-gemini-native.go | 36 ------------------ relay/compatible_handler.go | 15 -------- service/token_counter.go | 2 +- setting/model_setting/gemini.go | 1 - setting/operation_setting/tools.go | 11 ------ setting/ratio_setting/model_ratio.go | 10 ++--- web/src/helpers/render.jsx | 38 ++++--------------- web/src/hooks/usage-logs/useUsageLogsData.jsx | 2 - 9 files changed, 20 insertions(+), 111 deletions(-) diff --git a/dto/gemini.go b/dto/gemini.go index cd5d74cdd..5df67ba0b 100644 --- a/dto/gemini.go +++ b/dto/gemini.go @@ -2,12 +2,11 @@ package dto import ( "encoding/json" + "github.com/gin-gonic/gin" "one-api/common" "one-api/logger" "one-api/types" "strings" - - "github.com/gin-gonic/gin" ) type GeminiChatRequest struct { @@ -269,15 +268,14 @@ type GeminiChatResponse struct { } type GeminiUsageMetadata struct { - PromptTokenCount int `json:"promptTokenCount"` - CandidatesTokenCount int `json:"candidatesTokenCount"` - TotalTokenCount int `json:"totalTokenCount"` - ThoughtsTokenCount int `json:"thoughtsTokenCount"` - PromptTokensDetails []GeminiModalityTokenCount `json:"promptTokensDetails"` - CandidatesTokensDetails []GeminiModalityTokenCount `json:"candidatesTokensDetails"` + PromptTokenCount int `json:"promptTokenCount"` + CandidatesTokenCount int `json:"candidatesTokenCount"` + TotalTokenCount int `json:"totalTokenCount"` + ThoughtsTokenCount int `json:"thoughtsTokenCount"` + PromptTokensDetails []GeminiPromptTokensDetails `json:"promptTokensDetails"` } -type GeminiModalityTokenCount struct { +type GeminiPromptTokensDetails struct { Modality string `json:"modality"` TokenCount int `json:"tokenCount"` } diff --git a/relay/channel/gemini/relay-gemini-native.go b/relay/channel/gemini/relay-gemini-native.go index 564b86908..974a22f50 100644 --- a/relay/channel/gemini/relay-gemini-native.go +++ b/relay/channel/gemini/relay-gemini-native.go @@ -46,32 +46,6 @@ func GeminiTextGenerationHandler(c *gin.Context, info *relaycommon.RelayInfo, re usage.CompletionTokenDetails.ReasoningTokens = geminiResponse.UsageMetadata.ThoughtsTokenCount - if strings.HasPrefix(info.UpstreamModelName, "gemini-2.5-flash-image-preview") { - imageOutputCounts := 0 - for _, candidate := range geminiResponse.Candidates { - for _, part := range candidate.Content.Parts { - if part.InlineData != nil && strings.HasPrefix(part.InlineData.MimeType, "image/") { - imageOutputCounts++ - } - } - } - if imageOutputCounts != 0 { - usage.CompletionTokens = usage.CompletionTokens - imageOutputCounts*1290 - usage.TotalTokens = usage.TotalTokens - imageOutputCounts*1290 - c.Set("gemini_image_tokens", imageOutputCounts*1290) - } - } - - // if strings.HasPrefix(info.UpstreamModelName, "gemini-2.5-flash-image-preview") { - // for _, detail := range geminiResponse.UsageMetadata.CandidatesTokensDetails { - // if detail.Modality == "IMAGE" { - // usage.CompletionTokens = usage.CompletionTokens - detail.TokenCount - // usage.TotalTokens = usage.TotalTokens - detail.TokenCount - // c.Set("gemini_image_tokens", detail.TokenCount) - // } - // } - // } - for _, detail := range geminiResponse.UsageMetadata.PromptTokensDetails { if detail.Modality == "AUDIO" { usage.PromptTokensDetails.AudioTokens = detail.TokenCount @@ -162,16 +136,6 @@ func GeminiTextGenerationStreamHandler(c *gin.Context, info *relaycommon.RelayIn usage.PromptTokensDetails.TextTokens = detail.TokenCount } } - - if strings.HasPrefix(info.UpstreamModelName, "gemini-2.5-flash-image-preview") { - for _, detail := range geminiResponse.UsageMetadata.CandidatesTokensDetails { - if detail.Modality == "IMAGE" { - usage.CompletionTokens = usage.CompletionTokens - detail.TokenCount - usage.TotalTokens = usage.TotalTokens - detail.TokenCount - c.Set("gemini_image_tokens", detail.TokenCount) - } - } - } } // 直接发送 GeminiChatResponse 响应 diff --git a/relay/compatible_handler.go b/relay/compatible_handler.go index 8f27fd60b..01ab1fff4 100644 --- a/relay/compatible_handler.go +++ b/relay/compatible_handler.go @@ -326,22 +326,11 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage } else { quotaCalculateDecimal = dModelPrice.Mul(dQuotaPerUnit).Mul(dGroupRatio) } - var dGeminiImageOutputQuota decimal.Decimal - var imageOutputPrice float64 - if strings.HasPrefix(modelName, "gemini-2.5-flash-image-preview") { - imageOutputPrice = operation_setting.GetGeminiImageOutputPricePerMillionTokens(modelName) - if imageOutputPrice > 0 { - dImageOutputTokens := decimal.NewFromInt(int64(ctx.GetInt("gemini_image_tokens"))) - dGeminiImageOutputQuota = decimal.NewFromFloat(imageOutputPrice).Div(decimal.NewFromInt(1000000)).Mul(dImageOutputTokens).Mul(dGroupRatio).Mul(dQuotaPerUnit) - } - } // 添加 responses tools call 调用的配额 quotaCalculateDecimal = quotaCalculateDecimal.Add(dWebSearchQuota) quotaCalculateDecimal = quotaCalculateDecimal.Add(dFileSearchQuota) // 添加 audio input 独立计费 quotaCalculateDecimal = quotaCalculateDecimal.Add(audioInputQuota) - // 添加 Gemini image output 计费 - quotaCalculateDecimal = quotaCalculateDecimal.Add(dGeminiImageOutputQuota) quota := int(quotaCalculateDecimal.Round(0).IntPart()) totalTokens := promptTokens + completionTokens @@ -440,10 +429,6 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage other["audio_input_token_count"] = audioTokens other["audio_input_price"] = audioInputPrice } - if !dGeminiImageOutputQuota.IsZero() { - other["image_output_token_count"] = ctx.GetInt("gemini_image_tokens") - other["image_output_price"] = imageOutputPrice - } model.RecordConsumeLog(ctx, relayInfo.UserId, model.RecordConsumeLogParams{ ChannelId: relayInfo.ChannelId, PromptTokens: promptTokens, diff --git a/service/token_counter.go b/service/token_counter.go index da56523fe..be5c2e80c 100644 --- a/service/token_counter.go +++ b/service/token_counter.go @@ -336,7 +336,7 @@ func CountRequestToken(c *gin.Context, meta *types.TokenCountMeta, info *relayco for i, file := range meta.Files { switch file.FileType { case types.FileTypeImage: - if info.RelayFormat == types.RelayFormatGemini && !strings.HasPrefix(model, "gemini-2.5-flash-image-preview") { + if info.RelayFormat == types.RelayFormatGemini { tkm += 256 } else { token, err := getImageToken(file, model, info.IsStream) diff --git a/setting/model_setting/gemini.go b/setting/model_setting/gemini.go index 5412155f1..f132fec88 100644 --- a/setting/model_setting/gemini.go +++ b/setting/model_setting/gemini.go @@ -26,7 +26,6 @@ var defaultGeminiSettings = GeminiSettings{ SupportedImagineModels: []string{ "gemini-2.0-flash-exp-image-generation", "gemini-2.0-flash-exp", - "gemini-2.5-flash-image-preview", }, ThinkingAdapterEnabled: false, ThinkingAdapterBudgetTokensPercentage: 0.6, diff --git a/setting/operation_setting/tools.go b/setting/operation_setting/tools.go index b87265ee1..549a1862e 100644 --- a/setting/operation_setting/tools.go +++ b/setting/operation_setting/tools.go @@ -24,10 +24,6 @@ const ( ClaudeWebSearchPrice = 10.00 ) -const ( - Gemini25FlashImagePreviewImageOutputPrice = 30.00 -) - func GetClaudeWebSearchPricePerThousand() float64 { return ClaudeWebSearchPrice } @@ -69,10 +65,3 @@ func GetGeminiInputAudioPricePerMillionTokens(modelName string) float64 { } return 0 } - -func GetGeminiImageOutputPricePerMillionTokens(modelName string) float64 { - if strings.HasPrefix(modelName, "gemini-2.5-flash-image-preview") { - return Gemini25FlashImagePreviewImageOutputPrice - } - return 0 -} diff --git a/setting/ratio_setting/model_ratio.go b/setting/ratio_setting/model_ratio.go index 1a1b0afa8..f06cd71ef 100644 --- a/setting/ratio_setting/model_ratio.go +++ b/setting/ratio_setting/model_ratio.go @@ -178,7 +178,6 @@ 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-2.5-flash-image-preview": 0.15, // $0.30(text/image) / 1M tokens "text-embedding-004": 0.001, "chatglm_turbo": 0.3572, // ¥0.005 / 1k tokens "chatglm_pro": 0.7143, // ¥0.01 / 1k tokens @@ -294,11 +293,10 @@ var ( ) var defaultCompletionRatio = map[string]float64{ - "gpt-4-gizmo-*": 2, - "gpt-4o-gizmo-*": 3, - "gpt-4-all": 2, - "gpt-image-1": 8, - "gemini-2.5-flash-image-preview": 8.3333333333, + "gpt-4-gizmo-*": 2, + "gpt-4o-gizmo-*": 3, + "gpt-4-all": 2, + "gpt-image-1": 8, } // InitRatioSettings initializes all model related settings maps diff --git a/web/src/helpers/render.jsx b/web/src/helpers/render.jsx index 3d9d8d710..65332701b 100644 --- a/web/src/helpers/render.jsx +++ b/web/src/helpers/render.jsx @@ -1017,7 +1017,7 @@ export function renderModelPrice( cacheRatio = 1.0, image = false, imageRatio = 1.0, - imageInputTokens = 0, + imageOutputTokens = 0, webSearch = false, webSearchCallCount = 0, webSearchPrice = 0, @@ -1027,8 +1027,6 @@ export function renderModelPrice( audioInputSeperatePrice = false, audioInputTokens = 0, audioInputPrice = 0, - imageOutputTokens = 0, - imageOutputPrice = 0, ) { const { ratio: effectiveGroupRatio, label: ratioLabel } = getEffectiveRatio( groupRatio, @@ -1059,9 +1057,9 @@ export function renderModelPrice( let effectiveInputTokens = inputTokens - cacheTokens + cacheTokens * cacheRatio; // Handle image tokens if present - if (image && imageInputTokens > 0) { + if (image && imageOutputTokens > 0) { effectiveInputTokens = - inputTokens - imageInputTokens + imageInputTokens * imageRatio; + inputTokens - imageOutputTokens + imageOutputTokens * imageRatio; } if (audioInputTokens > 0) { effectiveInputTokens -= audioInputTokens; @@ -1071,8 +1069,7 @@ export function renderModelPrice( (audioInputTokens / 1000000) * audioInputPrice * groupRatio + (completionTokens / 1000000) * completionRatioPrice * groupRatio + (webSearchCallCount / 1000) * webSearchPrice * groupRatio + - (fileSearchCallCount / 1000) * fileSearchPrice * groupRatio + - (imageOutputTokens / 1000000) * imageOutputPrice * groupRatio; + (fileSearchCallCount / 1000) * fileSearchPrice * groupRatio; return ( <> @@ -1107,7 +1104,7 @@ export function renderModelPrice( )}
)} - {image && imageInputTokens > 0 && ( + {image && imageOutputTokens > 0 && ({i18next.t( '图片输入价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (图片倍率: {{imageRatio}})', @@ -1134,26 +1131,17 @@ export function renderModelPrice( })}
)} - {imageOutputPrice > 0 && imageOutputTokens > 0 && ( -- {i18next.t('图片输出价格:${{price}} * 分组倍率{{ratio}} = ${{total}} / 1M tokens', { - price: imageOutputPrice, - ratio: groupRatio, - total: imageOutputPrice * groupRatio, - })} -
- )}{(() => { // 构建输入部分描述 let inputDesc = ''; - if (image && imageInputTokens > 0) { + if (image && imageOutputTokens > 0) { inputDesc = i18next.t( '(输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}}', { - nonImageInput: inputTokens - imageInputTokens, - imageInput: imageInputTokens, + nonImageInput: inputTokens - imageOutputTokens, + imageInput: imageOutputTokens, imageRatio: imageRatio, price: inputRatioPrice, }, @@ -1223,16 +1211,6 @@ export function renderModelPrice( }, ) : '', - imageOutputPrice > 0 && imageOutputTokens > 0 - ? i18next.t( - ' + 图片输出 {{tokenCounts}} tokens * ${{price}} / 1M tokens * 分组倍率{{ratio}}', - { - tokenCounts: imageOutputTokens, - price: imageOutputPrice, - ratio: groupRatio, - }, - ) - : '', ].join(''); return i18next.t( diff --git a/web/src/hooks/usage-logs/useUsageLogsData.jsx b/web/src/hooks/usage-logs/useUsageLogsData.jsx index 3584f1d9b..81f3f539a 100644 --- a/web/src/hooks/usage-logs/useUsageLogsData.jsx +++ b/web/src/hooks/usage-logs/useUsageLogsData.jsx @@ -447,8 +447,6 @@ export const useLogsData = () => { other?.audio_input_seperate_price || false, other?.audio_input_token_count || 0, other?.audio_input_price || 0, - other?.image_output_token_count || 0, - other?.image_output_price || 0, ); } expandDataLocal.push({