Skip to content

feat: add auth health status tracking and Kiro quota query#24

Merged
rensumo merged 2 commits intoVe-ria:devfrom
hpylsy:feat/auth-recent-requests-health
May 9, 2026
Merged

feat: add auth health status tracking and Kiro quota query#24
rensumo merged 2 commits intoVe-ria:devfrom
hpylsy:feat/auth-recent-requests-health

Conversation

@hpylsy
Copy link
Copy Markdown

@hpylsy hpylsy commented May 9, 2026

Summary

This PR adds two features to the management API:

1. Auth Health Status Tracking (recent_requests)

Resolves #23

Per-auth request success/failure tracking via a 20-bucket ring buffer (10-minute intervals, 200-minute sliding window). The /v0/management/auth-files endpoint now returns success, failed, and recent_requests fields for each auth entry, enabling the management panel to render health status indicators (red/green/yellow bars).

Before: Kiro and other auth entries had no health status data in the API response.
After: Each auth entry includes real-time request tracking that the panel can use to display health bars.

2. Kiro Quota Query

  • GET /v0/management/kiro-quota?auth_index=<INDEX>: Returns usage breakdown, remaining quota, usage percentage, subscription info, and next reset time.
  • kiro_quota field in /v0/management/auth-files: Each Kiro auth entry now includes cached quota info (plan, used, limit, remaining, percentage).
  • Background refresher: Quota data is refreshed every 5 minutes for all active Kiro credentials.

Files Changed

File Change
sdk/cliproxy/auth/types.go Add Success/Failed counters, ring buffer, RecentRequestsSnapshot()
sdk/cliproxy/auth/conductor.go Record requests in MarkResult(), preserve state on reload
internal/api/handlers/management/auth_files.go Expose success, failed, recent_requests, kiro_quota
internal/api/handlers/management/kiro_quota.go New: GetKiroQuota handler
internal/api/handlers/management/kiro_quota_cache.go New: Background quota cache + refresher
internal/api/server.go Register route + start refresher

Testing

  • All existing tests pass (go test ./...)
  • Verified on live server: health bars populate after requests, Kiro quota returns correct plan/usage data
  • Round-robin distributes across all Kiro accounts, each shows independent health tracking

rensumo and others added 2 commits May 7, 2026 20:09
Resolves router-for-me#23

## Health Status Tracking (recent_requests)

Add per-auth request success/failure tracking via a 20-bucket ring buffer
(10-minute intervals, 200-minute sliding window). The /v0/management/auth-files
endpoint now returns 'success', 'failed', and 'recent_requests' fields for each
auth entry, enabling the management panel to render health status indicators
(red/green/yellow bars).

Changes:
- sdk/cliproxy/auth/types.go: Add Success/Failed counters, recentRequestRing
  type, RecentRequestBucket export type, recordRecentRequest() and
  RecentRequestsSnapshot() methods to Auth struct.
- sdk/cliproxy/auth/conductor.go: Call recordRecentRequest() and increment
  counters in MarkResult(); preserve counters across auth reloads.
- internal/api/handlers/management/auth_files.go: Expose success, failed,
  and recent_requests in buildAuthFileEntry() response.

## Kiro Quota Query

Add a management API endpoint and background cache for querying Kiro (AWS
CodeWhisperer) usage quota per auth entry.

- GET /v0/management/kiro-quota?auth_index=<INDEX>: Returns usage breakdown,
  remaining quota, usage percentage, subscription info, and next reset time.
- kiro_quota field in /v0/management/auth-files: Each Kiro auth entry now
  includes cached quota info (plan, used, limit, remaining, percentage).
- Background refresher: Quota data is refreshed every 5 minutes for all
  active Kiro credentials.

Changes:
- internal/api/handlers/management/kiro_quota.go: GetKiroQuota handler,
  findKiroAuth, extractKiroTokenData, buildKiroQuotaStatus helpers.
- internal/api/handlers/management/kiro_quota_cache.go: Background quota
  cache with StartKiroQuotaRefresher goroutine.
- internal/api/server.go: Register /kiro-quota route and start refresher.
Copilot AI review requested due to automatic review settings May 9, 2026 06:03
@github-actions github-actions Bot changed the base branch from main to dev May 9, 2026 06:03
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

This pull request targeted main.

The base branch has been automatically changed to dev.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the management API with (1) per-auth request health tracking (success/failed totals + 20-bucket recent history) and (2) Kiro (AWS CodeWhisperer) quota visibility via a new endpoint and cached quota info embedded in /v0/management/auth-files.

Changes:

  • Add in-memory success/failed counters and a 20×10-minute ring buffer snapshot API to sdk/cliproxy/auth.Auth.
  • Record request outcomes in Manager.MarkResult() and preserve counters/history across auth updates/reloads.
  • Add /v0/management/kiro-quota, a background quota refresher, and expose success, failed, recent_requests, and kiro_quota in /v0/management/auth-files.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
sdk/cliproxy/auth/types.go Adds success/failed counters and recent-request ring buffer snapshot helpers.
sdk/cliproxy/auth/conductor.go Records outcomes into the new counters/ring; preserves state on auth update.
internal/api/handlers/management/auth_files.go Exposes health tracking fields and cached kiro_quota on auth listing.
internal/api/handlers/management/kiro_quota.go Adds GET /v0/management/kiro-quota handler and response shaping.
internal/api/handlers/management/kiro_quota_cache.go Implements a global in-process quota cache and background refresher.
internal/api/server.go Registers the new route and starts the quota refresher.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +449 to +451
if kiroQuota := h.getKiroQuotaCached(auth); kiroQuota != nil {
entry["kiro_quota"] = kiroQuota
}
Comment on lines +24 to +44
// getKiroQuotaCached returns cached quota info for a Kiro auth entry.
func (h *Handler) getKiroQuotaCached(auth *coreauth.Auth) gin.H {
if auth == nil {
return nil
}
provider := strings.ToLower(strings.TrimSpace(auth.Provider))
if provider != "kiro" {
return nil
}

kiroQuotaMu.RLock()
result, ok := kiroQuotaStore[auth.ID]
kiroQuotaMu.RUnlock()

if ok {
return result
}

// If not cached, try to fetch synchronously (first time only)
return h.fetchAndCacheKiroQuota(auth)
}
Comment on lines +61 to +67
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()

usage, err := checker.CheckUsage(ctx, tokenData)
if err != nil {
log.WithError(err).Debugf("kiro quota fetch failed for %s", auth.ID)
return nil
"resource_type": bd.ResourceType,
"used": bd.CurrentUsageWithPrecision,
"limit": bd.UsageLimitWithPrecision,
"remaining": bd.UsageLimitWithPrecision - bd.CurrentUsageWithPrecision,
Comment on lines +70 to +75
result := buildKiroQuotaEntry(usage)

kiroQuotaMu.Lock()
kiroQuotaStore[auth.ID] = result
kiroQuotaMu.Unlock()

usage, err := checker.CheckUsage(ctx, tokenData)
if err != nil {
log.WithError(err).Debug("kiro quota request failed")
c.JSON(http.StatusBadGateway, gin.H{"error": "kiro quota request failed: " + err.Error()})
Comment on lines +72 to +78
// Build enriched response
response := gin.H{
"usage": usage,
"quota_status": buildKiroQuotaStatus(usage),
"auth_index": auth.Index,
"auth_name": auth.FileName,
}
Comment on lines +634 to +636
start := time.Unix(bucketID*recentRequestBucketSeconds, 0).In(time.Local)
end := start.Add(time.Duration(recentRequestBucketSeconds) * time.Second)
return start.Format("15:04") + "-" + end.Format("15:04")
Comment on lines 1979 to +1988
m.mu.Lock()
if auth, ok := m.auths[result.AuthID]; ok && auth != nil {
now := time.Now()

auth.recordRecentRequest(now, result.Success)
if result.Success {
auth.Success++
} else {
auth.Failed++
}
Comment on lines +35 to +81
func (h *Handler) GetKiroQuota(c *gin.Context) {
authIndex := strings.TrimSpace(c.Query("auth_index"))
if authIndex == "" {
authIndex = strings.TrimSpace(c.Query("authIndex"))
}
if authIndex == "" {
authIndex = strings.TrimSpace(c.Query("AuthIndex"))
}

auth := h.findKiroAuth(authIndex)
if auth == nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "no kiro credential found"})
return
}

// Extract token data from auth metadata
tokenData := extractKiroTokenData(auth)
if tokenData == nil || tokenData.AccessToken == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "kiro access token not available (token may need refresh)"})
return
}

// Create usage checker with proxy-aware HTTP client
checker := kiro.NewUsageCheckerWithClient(
util.SetProxy(&h.cfg.SDKConfig, &http.Client{Timeout: 30 * time.Second}),
)

ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()

usage, err := checker.CheckUsage(ctx, tokenData)
if err != nil {
log.WithError(err).Debug("kiro quota request failed")
c.JSON(http.StatusBadGateway, gin.H{"error": "kiro quota request failed: " + err.Error()})
return
}

// Build enriched response
response := gin.H{
"usage": usage,
"quota_status": buildKiroQuotaStatus(usage),
"auth_index": auth.Index,
"auth_name": auth.FileName,
}

c.JSON(http.StatusOK, response)
}
@rensumo rensumo merged commit 7d91d63 into Ve-ria:dev May 9, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

加一下kiro额度显示

3 participants