From 81d896bf78da72fa46f8af68958a30dd0e1e99c7 Mon Sep 17 00:00:00 2001 From: erio Date: Fri, 27 Feb 2026 20:42:53 +0800 Subject: [PATCH] fix: sync Antigravity ForwardResult.Usage with client response simulation Apply Claude Max cache billing to usage before returning ForwardResult in Antigravity Forward, ensuring RecordUsage gets the same simulated usage that clients see. Restore apply+fallback in RecordUsage for consistency across GatewayService and Antigravity paths. --- backend/internal/service/antigravity_gateway_service.go | 3 +++ .../service/gateway_record_usage_claude_max_test.go | 8 ++++---- backend/internal/service/gateway_service.go | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/backend/internal/service/antigravity_gateway_service.go b/backend/internal/service/antigravity_gateway_service.go index 4922de3c..fa5b477b 100644 --- a/backend/internal/service/antigravity_gateway_service.go +++ b/backend/internal/service/antigravity_gateway_service.go @@ -1619,6 +1619,9 @@ func (s *AntigravityGatewayService) Forward(ctx context.Context, c *gin.Context, firstTokenMs = streamRes.firstTokenMs } + // Claude Max cache billing: 同步 ForwardResult.Usage 与客户端响应体一致 + applyClaudeMaxCacheBillingPolicyToUsage(usage, parsedRequestFromGinContext(c), claudeMaxGroupFromGinContext(c), originalModel, account.ID) + return &ForwardResult{ RequestID: requestID, Usage: *usage, diff --git a/backend/internal/service/gateway_record_usage_claude_max_test.go b/backend/internal/service/gateway_record_usage_claude_max_test.go index 2e1b5ae7..3cd86938 100644 --- a/backend/internal/service/gateway_record_usage_claude_max_test.go +++ b/backend/internal/service/gateway_record_usage_claude_max_test.go @@ -92,10 +92,10 @@ func TestRecordUsage_SimulateClaudeMaxEnabled_ProjectsUsageAndSkipsTTLOverride(t require.NotNil(t, repo.last) log := repo.last - require.Equal(t, 160, log.InputTokens) - require.Equal(t, 0, log.CacheCreationTokens) + require.Equal(t, 80, log.InputTokens) + require.Equal(t, 80, log.CacheCreationTokens) require.Equal(t, 0, log.CacheCreation5mTokens) - require.Equal(t, 0, log.CacheCreation1hTokens) + require.Equal(t, 80, log.CacheCreation1hTokens) require.False(t, log.CacheTTLOverridden, "simulate outcome should skip account ttl override") } @@ -195,5 +195,5 @@ func TestRecordUsage_SimulateClaudeMaxEnabled_ExistingCacheCreationBypassesSimul require.Equal(t, 120, log.CacheCreation5mTokens) require.Equal(t, 0, log.CacheCreation1hTokens) require.Equal(t, 120, log.CacheCreationTokens) - require.True(t, log.CacheTTLOverridden, "existing cache_creation with SimulateClaudeMax enabled should apply account ttl override") + require.False(t, log.CacheTTLOverridden, "existing cache_creation with SimulateClaudeMax enabled should skip account ttl override") } diff --git a/backend/internal/service/gateway_service.go b/backend/internal/service/gateway_service.go index 2b47509e..af34d472 100644 --- a/backend/internal/service/gateway_service.go +++ b/backend/internal/service/gateway_service.go @@ -5630,8 +5630,9 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu if apiKey != nil { apiKeyGroup = apiKey.Group } - claudeMaxOutcome := detectClaudeMaxCacheBillingOutcomeForUsage(result.Usage, input.ParsedRequest, apiKeyGroup, result.Model) - simulatedClaudeMax := claudeMaxOutcome.Simulated + claudeMaxOutcome := applyClaudeMaxCacheBillingPolicyToUsage(&result.Usage, input.ParsedRequest, apiKeyGroup, result.Model, account.ID) + simulatedClaudeMax := claudeMaxOutcome.Simulated || + (shouldApplyClaudeMaxBillingRulesForUsage(apiKeyGroup, result.Model, input.ParsedRequest) && hasCacheCreationTokens(result.Usage)) // Cache TTL Override: 确保计费时 token 分类与账号设置一致 cacheTTLOverridden := false if account.IsCacheTTLOverrideEnabled() && !simulatedClaudeMax {