Files
CLIProxyAPI/sdk/cliproxy/auth/antigravity_credits_test.go
T
sususu98 14d46a0a5d feat(antigravity): conductor-level credits fallback for Claude models
Move credits handling from executor-level retry to conductor-level
orchestration. When all free-tier auths are exhausted (429/503), the
conductor discovers auths with available Google One AI credits and
retries with enabledCreditTypes injected via context flag.

Key changes:
- Add AntigravityCreditsHint system for tracking per-auth credits state
- Conductor tries credits fallback after all auths fail (Execute/Stream/Count)
- Executor injects enabledCreditTypes only when conductor sets context flag
- Credits fallback respects provider scope (requires antigravity in providers)
- Add context cancellation check in credits fallback to avoid wasted requests
- Remove executor-level attemptCreditsFallback and preferCredits machinery
- Restructure 429 decision logic (parse details first, keyword fallback)
- Expand shouldAbort to cover INVALID_ARGUMENT/FAILED_PRECONDITION/500+UNKNOWN
- Support human-readable retry delay parsing (e.g. "1h43m56s")
2026-04-23 13:44:20 +08:00

63 lines
1.6 KiB
Go

package auth
import (
"testing"
"time"
)
func TestIsAuthBlockedForModel_ClaudeWithCreditsStillBlockedDuringCooldown(t *testing.T) {
auth := &Auth{
ID: "ag-1",
Provider: "antigravity",
ModelStates: map[string]*ModelState{
"claude-sonnet-4-6": {
Unavailable: true,
NextRetryAfter: time.Now().Add(10 * time.Minute),
Quota: QuotaState{
Exceeded: true,
NextRecoverAt: time.Now().Add(10 * time.Minute),
},
},
},
}
SetAntigravityCreditsHint(auth.ID, AntigravityCreditsHint{
Known: true,
Available: true,
UpdatedAt: time.Now(),
})
blocked, reason, _ := isAuthBlockedForModel(auth, "claude-sonnet-4-6", time.Now())
if !blocked || reason != blockReasonCooldown {
t.Fatalf("expected auth to be blocked during cooldown even with credits, got blocked=%v reason=%v", blocked, reason)
}
}
func TestIsAuthBlockedForModel_KeepsGeminiBlockedWithoutCreditsBypass(t *testing.T) {
auth := &Auth{
ID: "ag-2",
Provider: "antigravity",
ModelStates: map[string]*ModelState{
"gemini-3-flash": {
Unavailable: true,
NextRetryAfter: time.Now().Add(10 * time.Minute),
Quota: QuotaState{
Exceeded: true,
NextRecoverAt: time.Now().Add(10 * time.Minute),
},
},
},
}
SetAntigravityCreditsHint(auth.ID, AntigravityCreditsHint{
Known: true,
Available: true,
UpdatedAt: time.Now(),
})
blocked, reason, _ := isAuthBlockedForModel(auth, "gemini-3-flash", time.Now())
if !blocked || reason != blockReasonCooldown {
t.Fatalf("expected gemini auth to remain blocked, got blocked=%v reason=%v", blocked, reason)
}
}