feat(backend): add kiro account support

This commit is contained in:
nianzs
2026-04-30 14:02:05 +08:00
parent 9d801595c9
commit 05bc424c9a
60 changed files with 11916 additions and 38 deletions
@@ -103,10 +103,17 @@ type antigravityUsageCache struct {
timestamp time.Time
}
// kiroUsageCache 缓存 Kiro 额度快照
type kiroUsageCache struct {
usageInfo *UsageInfo
timestamp time.Time
}
const (
apiCacheTTL = 3 * time.Minute
apiErrorCacheTTL = 1 * time.Minute // 负缓存 TTL:429 等错误缓存 1 分钟
antigravityErrorTTL = 1 * time.Minute // Antigravity 错误缓存 TTL(可恢复错误)
kiroUsageErrorTTL = 1 * time.Minute // Kiro 错误缓存 TTL(可恢复错误)
apiQueryMaxJitter = 800 * time.Millisecond // 用量查询最大随机延迟
windowStatsCacheTTL = 1 * time.Minute
openAIProbeCacheTTL = 10 * time.Minute
@@ -118,8 +125,10 @@ type UsageCache struct {
apiCache sync.Map // accountID -> *apiUsageCache
windowStatsCache sync.Map // accountID -> *windowStatsCache
antigravityCache sync.Map // accountID -> *antigravityUsageCache
kiroUsageCache sync.Map // accountID -> *kiroUsageCache
apiFlight singleflight.Group // 防止同一账号的并发请求击穿缓存(Anthropic)
antigravityFlight singleflight.Group // 防止同一 Antigravity 账号的并发请求击穿缓存
kiroUsageFlight singleflight.Group // 防止同一 Kiro 账号的并发请求击穿缓存
openAIProbeCache sync.Map // accountID -> time.Time
}
@@ -176,6 +185,23 @@ type AICredit struct {
MinimumBalance float64 `json:"minimum_balance,omitempty"`
}
// KiroCreditProgress 表示 Kiro 主额度或 Bonus 的用量进度。
type KiroCreditProgress struct {
CurrentUsage float64 `json:"current_usage"`
UsageLimit float64 `json:"usage_limit"`
PercentageUsed float64 `json:"percentage_used"`
DaysRemaining int `json:"days_remaining,omitempty"`
ExpiryDate *time.Time `json:"expiry_date,omitempty"`
}
// KiroOverageInfo 表示 Kiro 账号的 overage 状态。
type KiroOverageInfo struct {
CurrentOverages float64 `json:"current_overages"`
OverageCharges float64 `json:"overage_charges"`
CurrencyCode string `json:"currency_code,omitempty"`
CurrencySymbol string `json:"currency_symbol,omitempty"`
}
// UsageInfo 账号使用量信息
type UsageInfo struct {
Source string `json:"source,omitempty"` // "passive" or "active"
@@ -203,6 +229,21 @@ type UsageInfo struct {
// Antigravity AI Credits 余额
AICredits []AICredit `json:"ai_credits,omitempty"`
// Kiro Credits 额度与 overage 信息
KiroSubscriptionName string `json:"kiro_subscription_name,omitempty"`
KiroSubscriptionType string `json:"kiro_subscription_type,omitempty"`
KiroResetAt *time.Time `json:"kiro_reset_at,omitempty"`
KiroOveragesEnabled bool `json:"kiro_overages_enabled,omitempty"`
KiroCredit *KiroCreditProgress `json:"kiro_credit,omitempty"`
KiroBonus *KiroCreditProgress `json:"kiro_bonus,omitempty"`
KiroOverage *KiroOverageInfo `json:"kiro_overage,omitempty"`
KiroQuotaState string `json:"kiro_quota_state,omitempty"`
KiroQuotaReason string `json:"kiro_quota_reason,omitempty"`
KiroQuotaResetAt *time.Time `json:"kiro_quota_reset_at,omitempty"`
KiroRuntimeState string `json:"kiro_runtime_state,omitempty"`
KiroRuntimeReason string `json:"kiro_runtime_reason,omitempty"`
KiroRuntimeResetAt *time.Time `json:"kiro_runtime_reset_at,omitempty"`
// Antigravity 废弃模型转发规则 (old_model_id -> new_model_id)
ModelForwardingRules map[string]string `json:"model_forwarding_rules,omitempty"`
@@ -266,6 +307,7 @@ type AccountUsageService struct {
cache *UsageCache
identityCache IdentityCache
tlsFPProfileService *TLSFingerprintProfileService
kiroCooldownStore KiroCooldownStore
}
// NewAccountUsageService 创建AccountUsageService实例
@@ -291,6 +333,13 @@ func NewAccountUsageService(
}
}
func (s *AccountUsageService) SetKiroCooldownStore(store KiroCooldownStore) *AccountUsageService {
if s != nil {
s.kiroCooldownStore = store
}
return s
}
// GetUsage 获取账号使用量
// OAuth账号: 调用Anthropic API获取真实数据(需要profile scope),API响应缓存10分钟,窗口统计缓存1分钟
// Setup Token账号: 根据session_window推算5h窗口,7d数据不可用(没有profile scope
@@ -317,6 +366,10 @@ func (s *AccountUsageService) GetUsage(ctx context.Context, accountID int64) (*U
return usage, err
}
if account.Platform == PlatformKiro && account.Type == AccountTypeOAuth {
return s.getKiroUsage(ctx, account, "active", false)
}
// Antigravity 平台:使用 AntigravityQuotaFetcher 获取额度
if account.Platform == PlatformAntigravity {
usage, err := s.getAntigravityUsage(ctx, account)
@@ -425,6 +478,13 @@ func (s *AccountUsageService) GetPassiveUsage(ctx context.Context, accountID int
return nil, fmt.Errorf("get account failed: %w", err)
}
if account.Platform == PlatformKiro {
if account.Type != AccountTypeOAuth {
return nil, fmt.Errorf("passive usage only supported for Kiro OAuth accounts")
}
return s.getKiroUsage(ctx, account, "passive", false)
}
if !account.IsAnthropicOAuthOrSetupToken() {
return nil, fmt.Errorf("passive usage only supported for Anthropic OAuth/SetupToken accounts")
}