Files
CLIProxyAPI/sdk/cliproxy/auth/antigravity_credits.go
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

91 lines
2.4 KiB
Go

package auth
import (
"context"
"strings"
"sync"
"time"
)
type antigravityUseCreditsContextKey struct{}
// WithAntigravityCredits returns a child context that signals the executor to
// inject enabledCreditTypes into the request payload.
func WithAntigravityCredits(ctx context.Context) context.Context {
return context.WithValue(ctx, antigravityUseCreditsContextKey{}, true)
}
// AntigravityCreditsRequested reports whether the context carries the credits flag.
func AntigravityCreditsRequested(ctx context.Context) bool {
if ctx == nil {
return false
}
v, _ := ctx.Value(antigravityUseCreditsContextKey{}).(bool)
return v
}
// AntigravityCreditsHint stores the latest known AI credits state for one auth.
type AntigravityCreditsHint struct {
Known bool
Available bool
CreditAmount float64
MinCreditAmount float64
PaidTierID string
UpdatedAt time.Time
}
var antigravityCreditsHintByAuth sync.Map
// SetAntigravityCreditsHint updates the latest known AI credits state for an auth.
func SetAntigravityCreditsHint(authID string, hint AntigravityCreditsHint) {
authID = strings.TrimSpace(authID)
if authID == "" {
return
}
if hint.UpdatedAt.IsZero() {
hint.UpdatedAt = time.Now()
}
antigravityCreditsHintByAuth.Store(authID, hint)
}
// GetAntigravityCreditsHint returns the latest known AI credits state for an auth.
func GetAntigravityCreditsHint(authID string) (AntigravityCreditsHint, bool) {
authID = strings.TrimSpace(authID)
if authID == "" {
return AntigravityCreditsHint{}, false
}
value, ok := antigravityCreditsHintByAuth.Load(authID)
if !ok {
return AntigravityCreditsHint{}, false
}
hint, ok := value.(AntigravityCreditsHint)
if !ok {
antigravityCreditsHintByAuth.Delete(authID)
return AntigravityCreditsHint{}, false
}
return hint, true
}
// HasKnownAntigravityCreditsHint reports whether credits state has been discovered for an auth.
func HasKnownAntigravityCreditsHint(authID string) bool {
hint, ok := GetAntigravityCreditsHint(authID)
return ok && hint.Known
}
func antigravityCreditsAvailableForModel(auth *Auth, model string) bool {
if auth == nil {
return false
}
if !strings.EqualFold(strings.TrimSpace(auth.Provider), "antigravity") {
return false
}
if !strings.Contains(strings.ToLower(strings.TrimSpace(model)), "claude") {
return false
}
hint, ok := GetAntigravityCreditsHint(auth.ID)
if !ok || !hint.Known {
return false
}
return hint.Available
}