From 21b6f2d593a3dce45abdfe491974634842698f08 Mon Sep 17 00:00:00 2001 From: erio Date: Fri, 20 Mar 2026 00:04:01 +0800 Subject: [PATCH] fix(antigravity): correctly mark credits exhausted on "Resource has been exhausted" 429 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shouldMarkCreditsExhausted was blocked by isURLLevelRateLimit check when credit overages retry returned "Resource has been exhausted (e.g. check quota).", causing credits to never be marked as exhausted. This led to an infinite loop where each request injected credits, bypassed model rate limits, and failed again. - Remove isURLLevelRateLimit guard from shouldMarkCreditsExhausted (only called for credit retry responses — if credits retry fails, mark exhausted) - Add "resource has been exhausted" to creditsExhaustedKeywords - Update tests to match corrected behavior --- .../internal/service/antigravity_credits_overages.go | 7 ++++--- .../service/antigravity_credits_overages_test.go | 10 ++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backend/internal/service/antigravity_credits_overages.go b/backend/internal/service/antigravity_credits_overages.go index 1521dfcd20..ec3650859c 100644 --- a/backend/internal/service/antigravity_credits_overages.go +++ b/backend/internal/service/antigravity_credits_overages.go @@ -45,6 +45,7 @@ var ( "minimumcreditamountforusage", "minimum credit amount for usage", "minimum credit", + "resource has been exhausted", } ) @@ -147,9 +148,9 @@ func shouldMarkCreditsExhausted(resp *http.Response, respBody []byte, reqErr err if resp.StatusCode >= 500 || resp.StatusCode == http.StatusRequestTimeout { return false } - if isURLLevelRateLimit(respBody) { - return false - } + // 注意:不再检查 isURLLevelRateLimit。此函数仅在积分重试失败后调用, + // 如果注入 enabledCreditTypes 后仍返回 "Resource has been exhausted", + // 说明积分也已耗尽,应该标记。clearCreditsExhausted 会在后续成功时自动清除。 if info := parseAntigravitySmartRetryInfo(respBody); info != nil { return false } diff --git a/backend/internal/service/antigravity_credits_overages_test.go b/backend/internal/service/antigravity_credits_overages_test.go index bc679494b5..7a5224daf3 100644 --- a/backend/internal/service/antigravity_credits_overages_test.go +++ b/backend/internal/service/antigravity_credits_overages_test.go @@ -406,10 +406,16 @@ func TestShouldMarkCreditsExhausted(t *testing.T) { require.False(t, shouldMarkCreditsExhausted(resp, []byte(`{"error":"Insufficient credits"}`), nil)) }) - t.Run("URL 级限流不标记", func(t *testing.T) { + t.Run("Resource has been exhausted 应标记为积分耗尽", func(t *testing.T) { resp := &http.Response{StatusCode: http.StatusTooManyRequests} body := []byte(`{"error":{"message":"Resource has been exhausted"}}`) - require.False(t, shouldMarkCreditsExhausted(resp, body, nil)) + require.True(t, shouldMarkCreditsExhausted(resp, body, nil)) + }) + + t.Run("Resource has been exhausted (check quota) 完整格式应标记", func(t *testing.T) { + resp := &http.Response{StatusCode: http.StatusTooManyRequests} + body := []byte(`{"error":{"code":429,"message":"Resource has been exhausted (e.g. check quota).","status":"RESOURCE_EXHAUSTED"}}`) + require.True(t, shouldMarkCreditsExhausted(resp, body, nil)) }) t.Run("结构化限流不标记", func(t *testing.T) {