- 16 Mar, 2026 24 commits
-
-
erio authored
Click on a group name, model name, or endpoint name in the distribution tables to expand and show per-user usage breakdown (requests, tokens, actual cost, standard cost). Backend: new GET /admin/dashboard/user-breakdown API with group_id, model, endpoint, endpoint_type filters. Frontend: clickable rows with expand/collapse sub-table in all three distribution charts.
-
Wesley Liddick authored
fix(antigravity): add stream keepalive to prevent connection drops
-
shaw authored
Docker named volumes and host bind-mounts may be owned by root, causing "open data/model_pricing.sha256: permission denied" when the container runs as the non-root sub2api user. Add an entrypoint script that fixes /app/data ownership before dropping to sub2api via su-exec. Replace USER directive with the entrypoint approach across all three Dockerfiles and update both GoReleaser configs to include the script in Docker build contexts.
-
Wesley Liddick authored
fix(i18n): correct usage label from "Total" to "Last 30d"
-
erio authored
The usage stats query defaults to a 30-day rolling window, but the UI label said "Total"/"累计" implying lifetime aggregation. Rename to "Last 30d"/"近30天" so the label matches the actual query semantics. Closes #1060
-
kunish authored
Antigravity streaming handlers were missing the keepalive mechanism that exists in the standard gateway, causing proxy/CDN idle timeouts to break connections during long thinking phases (e.g. claude-opus-4-6). This resulted in truncated responses with missing tool calls. Add StreamKeepaliveInterval support to all three Antigravity streaming paths: Claude SSE, Gemini SSE, and upstream passthrough.
-
Wesley Liddick authored
fix(admin/accounts): make usage window refresh deterministic and restore missing stats
-
Wesley Liddick authored
chore(antigravity): bump default User-Agent version to 1.20.5
-
shaw authored
-
Ethan0x0000 authored
- Simplify OpenAI rendering: always fetch /usage, prefer fetched data over codex snapshot (snapshot serves as loading placeholder only) - Remove dead code: preferFetchedOpenAIUsage, isOpenAICodexSnapshotStale, and unreachable template branch - Add today-stats support for key accounts (req/tokens/A/U badges) - Use formatCompactNumber for consistent number formatting - Add A/U badge titles for clarity - Filter zero-value window stats in UsageProgressBar to avoid empty badges - Update tests to match new fetched-data-first behavior
-
Ethan0x0000 authored
- Pass todayStats/todayStatsLoading to AccountUsageCell for key accounts - Propagate usageManualRefreshToken to force usage reload on explicit refresh - Refresh today stats when toggling usage/today_stats columns visible
-
Ethan0x0000 authored
- Add formatCompactNumber() for consistent large-number formatting (K/M/B) - Include last_used_at in OpenAI usage refresh key for better change detection - Add .gitattributes eol=lf rules for frontend source files
-
Ethan0x0000 authored
Removes hasMeaningfulWindowStats guard so the /usage endpoint consistently returns WindowStats for both time windows. The frontend now controls zero-value display filtering at the component level.
-
Ethan0x0000 authored
UpdateAccount previously required len(input.Extra) > 0, causing explicit empty payloads (extra:{}) to be silently skipped. Change condition to input.Extra != nil so clearing quota keys actually persists. -
erio authored
-
Wesley Liddick authored
fix(billing): add window expiration check to Redis rate limit Lua script
-
erio authored
The updateRateLimitUsageScript Lua script previously performed unconditional HINCRBYFLOAT on all usage counters without checking whether the rate limit window had expired. This caused usage to accumulate across window boundaries in Redis while the DB correctly reset on expiration, leading to incorrect 429 rate limiting that could persist for up to 24 hours. The Lua script now checks each window timestamp before incrementing: - If the window has expired, usage is reset to the current cost and the window timestamp is updated (matching DB-side semantics) - If the window is still valid, usage is accumulated normally This also resolves the async race condition where stale HINCRBYFLOAT tasks from the worker queue could pollute a freshly rebuilt cache after invalidation, since the script now self-corrects expired windows. Closes #1049
-
Wesley Liddick authored
fix(gateway): 防止 OpenAI Codex 跨用户串流 + WS 连接池条件式 MarkBroken
-
QTom authored
正常终端事件(response.completed 等)退出后连接归还复用, 仅异常路径(读写错误、error 事件、客户端断连)MarkBroken 销毁。 Generate 模式: - 引入 cleanExit 标记,仅在 isTerminalEvent break 时设置 true - defer 中根据 cleanExit 决定是否 MarkBroken - 所有异常路径已在各自分支中提前调用 MarkBroken Ingress 模式: - 引入 lastTurnClean 标记,sendAndRelay 正常完成时设为 true - releaseSessionLease 根据 lastTurnClean 决定是否 MarkBroken - 错误路径重置 lastTurnClean = false - 客户端断连后 drain 仍保守 MarkBroken(L2916)
-
QTom authored
根因:多个用户共享同一 OAuth 账号时,conversation_id/session_id 头 未做用户隔离,导致上游 chatgpt.com 将不同用户的请求关联到同一会话。 HTTP SSE 修复: - 新增 isolateOpenAISessionID(apiKeyID, raw),将 API Key ID 混入 session 标识符(xxhash),确保不同 Key 的用户产生不同上游会话 - buildUpstreamRequest: OAuth 分支先 Del 客户端透传的 session 头, 再用隔离值覆盖 - buildUpstreamRequestOpenAIPassthrough: 透传路径同样隔离 - ForwardAsAnthropic: Anthropic Messages 兼容路径同步修复 - buildOpenAIWSHeaders: WS 路径的 OAuth session 头同步隔离
-
Wesley Liddick authored
feat: Antigravity AI Credits overages handling & balance display
-
Wesley Liddick authored
fix(admin): polish spending ranking and usage defaults
-
Wesley Liddick authored
fix: record endpoint info for all API surfaces & unify normalization via middleware
-
Wesley Liddick authored
feat: unified OAuth token refresh API with distributed locking
-
- 15 Mar, 2026 16 commits
-
-
erio authored
- Fix gofmt alignment in admin_service.go and trailing newline in antigravity_credits_overages.go - Suppress errcheck for fmt.Sscanf in client.go GetMinimumAmount
-
erio authored
Remove SimulateClaudeMaxEnabled field and related logic from admin_service.go, and remove applyClaudeMaxCacheBillingPolicyToUsage, applyClaudeMaxNonStreamingRewrite, setupClaudeMaxStreamingHook calls from antigravity_gateway_service.go. These symbols are not yet available in upstream/main.
-
erio authored
Replace process-memory sync.Map + per-model runtime state with a single "AICredits" key in model_rate_limits, making credits exhaustion fully isomorphic with model-level rate limiting. Scheduler: rate-limited accounts with overages enabled + credits available are now scheduled instead of excluded. Forwarding: when model is rate-limited + credits available, inject credits proactively without waiting for a 429 round trip. Storage: credits exhaustion stored as model_rate_limits["AICredits"] with 5h duration, reusing SetModelRateLimit/isRateLimitActiveForKey. Frontend: show credits_active (yellow
⚡ ) when model rate-limited but credits available, credits_exhausted (red) when AICredits key active. Tests: add unit tests for shouldMarkCreditsExhausted, injectEnabledCreditTypes, clearCreditsExhausted, and update existing overages tests. -
SilentFlower authored
-
SilentFlower authored
-
SilentFlower authored
-
SilentFlower authored
feat: implement resolveCreditsOveragesModelKey function to stabilize model key resolution for credit overages
-
erio authored
-
erio authored
Introduce OAuthRefreshAPI as the single entry point for all OAuth token refresh operations, eliminating the race condition where background refresh and inline refresh could simultaneously use the same refresh_token (fixes #1035). Key changes: - Add OAuthRefreshExecutor interface extending TokenRefresher with CacheKey - Add OAuthRefreshAPI.RefreshIfNeeded with lock → DB re-read → double-check flow - Add ProviderRefreshPolicy / BackgroundRefreshPolicy strategy types - Simplify all 4 TokenProviders to delegate to OAuthRefreshAPI - Rewrite TokenRefreshService.refreshWithRetry to use unified API path - Add MergeCredentials and BuildClaudeAccountCredentials helpers - Add 40 unit tests covering all new and modified code paths
-
Peter authored
-
Ethan0x0000 authored
- Apply InboundEndpointMiddleware to all gateway route groups - Replace normalizedOpenAIInboundEndpoint/normalizedOpenAIUpstreamEndpoint and normalizedGatewayInboundEndpoint/normalizedGatewayUpstreamEndpoint with GetInboundEndpoint/GetUpstreamEndpoint - Remove 4 old constants and 4 old normalization functions (-70 lines) - Migrate existing endpoint normalization test to new API Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode ) Co-authored-by:
Sisyphus <clio-agent@sisyphuslabs.ai>
-
Ethan0x0000 authored
Introduce endpoint.go with shared constants, NormalizeInboundEndpoint, DeriveUpstreamEndpoint, InboundEndpointMiddleware, and context helpers. This replaces the two separate normalization implementations (OpenAI and Gateway) with a single source of truth. Includes comprehensive test coverage. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode ) Co-authored-by:
Sisyphus <clio-agent@sisyphuslabs.ai>
-
Ethan0x0000 authored
Extend RecordUsageInput and RecordUsageLongContextInput structs with InboundEndpoint and UpstreamEndpoint so that Claude, Gemini, and Sora handlers can record endpoint info alongside OpenAI handlers. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode ) Co-authored-by:
Sisyphus <clio-agent@sisyphuslabs.ai>
-
Ethan0x0000 authored
Replace t.Add(24*time.Hour - time.Nanosecond) with t.AddDate(0, 0, 1) and use SQL < instead of <= for end-of-day boundaries. This avoids edge-case misses around DST transitions. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode ) Co-authored-by:
Sisyphus <clio-agent@sisyphuslabs.ai>
-
Wesley Liddick authored
feat(ops): add ignore insufficient balance errors toggle and extract error constants
-
Wesley Liddick authored
fix: 修复多个issues - Gemini schema 兼容性、批量编辑白名单、Docker 工具支持和限额字段处理Fix/open issues cleanup
-