diff --git a/backend/internal/handler/dto/mappers.go b/backend/internal/handler/dto/mappers.go index 886a5535..5663e299 100644 --- a/backend/internal/handler/dto/mappers.go +++ b/backend/internal/handler/dto/mappers.go @@ -204,6 +204,17 @@ func AccountFromServiceShallow(a *service.Account) *Account { } } + if scopeLimits := a.GetAntigravityScopeRateLimits(); len(scopeLimits) > 0 { + out.ScopeRateLimits = make(map[string]ScopeRateLimitInfo, len(scopeLimits)) + now := time.Now() + for scope, remainingSec := range scopeLimits { + out.ScopeRateLimits[scope] = ScopeRateLimitInfo{ + ResetAt: now.Add(time.Duration(remainingSec) * time.Second), + RemainingSec: remainingSec, + } + } + } + return out } diff --git a/backend/internal/handler/dto/types.go b/backend/internal/handler/dto/types.go index 4cfaef5f..0a58391c 100644 --- a/backend/internal/handler/dto/types.go +++ b/backend/internal/handler/dto/types.go @@ -2,6 +2,11 @@ package dto import "time" +type ScopeRateLimitInfo struct { + ResetAt time.Time `json:"reset_at"` + RemainingSec int64 `json:"remaining_sec"` +} + type User struct { ID int64 `json:"id"` Email string `json:"email"` @@ -108,6 +113,9 @@ type Account struct { RateLimitResetAt *time.Time `json:"rate_limit_reset_at"` OverloadUntil *time.Time `json:"overload_until"` + // Antigravity scope 级限流状态(从 extra 提取) + ScopeRateLimits map[string]ScopeRateLimitInfo `json:"scope_rate_limits,omitempty"` + TempUnschedulableUntil *time.Time `json:"temp_unschedulable_until"` TempUnschedulableReason string `json:"temp_unschedulable_reason"` diff --git a/frontend/src/components/account/AccountStatusIndicator.vue b/frontend/src/components/account/AccountStatusIndicator.vue index 02c962f1..6bb19b87 100644 --- a/frontend/src/components/account/AccountStatusIndicator.vue +++ b/frontend/src/components/account/AccountStatusIndicator.vue @@ -56,6 +56,65 @@ > + + +