- 16 Mar, 2026 6 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.
-
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.
-
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. -
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 头同步隔离
-
- 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
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
-
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>
-
shaw authored
-
IanShaw027 authored
-
erio authored
- Add 5th error filter switch IgnoreInsufficientBalanceErrors to suppress upstream insufficient balance / insufficient_quota errors from ops log - Extract hardcoded error strings into package-level constants for shouldSkipOpsErrorLog, normalizeOpsErrorType, classifyOpsPhase, and classifyOpsIsBusinessLimited - Define ErrNoAvailableAccounts sentinel error and replace all errors.New("no available accounts") call sites - Update tests to use require.ErrorIs with the sentinel error -
erio authored
Previously, v-model.number produced "" when input was cleared, causing JSON decode errors on the backend. Also, normalizeLimit treated 0 as "unlimited" which prevented setting a zero quota. Now "" is converted to null (unlimited) in frontend, and 0 is preserved as a valid limit. Closes Wei-Shaw/sub2api#1021
-
erio authored
When Redis cache is populated from DB with a NULL window_1d_start, the Lua increment script only updates usage counters without setting window timestamps. IsWindowExpired(nil) previously returned false, so the accumulated usage was never reset across time windows, effectively turning usage_1d into a lifetime counter. Once this exceeded rate_limit_1d the key was incorrectly blocked with "日限额已用完". Fixes Wei-Shaw/sub2api#1022
-
YanzheL authored
Claude's output_config.effort parameter (low/medium/high/max) was not being extracted from requests or logged in the reasoning_effort column of usage logs. Only the OpenAI path populated this field. Changes: - Extract output_config.effort in ParseGatewayRequest - Add ReasoningEffort field to ForwardResult - Populate reasoning_effort in both RecordUsage and RecordUsageWithLongContext - Guard against overwriting service-set effort values in handler - Update stale comments that described reasoning_effort as OpenAI-only - Add unit tests for extraction, normalization, and persistence
-
Ethan0x0000 authored
将入站、上游与路径三类端点分布统一到使用记录页的一致化卡片交互中,并补齐端点元数据与统计链路,提升排障与流量分析效率。
-
- 14 Mar, 2026 10 commits
-
-
shaw authored
-
erio authored
Increase MAX(bucket_start) query timeout from 3s to 5s to reduce timeout-induced fallbacks. Shrink backfill window from 30 days to 1 hour so that fallback recomputation stays lightweight instead of scanning the entire retention range.
-
Rose Ding authored
1. S3 凭证加密存储:使用 SecretEncryptor (AES-256-GCM) 加密 SecretAccessKey, 防止备份文件中泄露 S3 凭证,兼容旧的未加密数据 2. 修复 saveRecord 竞态条件:添加 recordsMu 互斥锁保护 records 的 load/save 3. 恢复操作增加服务端验证:handler 层要求重新输入管理员密码,通过 bcrypt 校验,前端弹出密码输入框 4. pg_dump/psql/S3 操作抽象为接口:定义 DBDumper 和 BackupObjectStore 接口, 实现放入 repository 层,遵循项目依赖注入架构规范 5. 改为流式处理避免大数据库 OOM:备份时 pg_dump stdout -> gzip -> io.Pipe -> S3 upload;恢复时 S3 download -> gzip reader -> psql stdin,不再全量加载 6. loadRecords 区分"无数据"和"数据损坏"场景:JSON 解析失败返回明确错误 7. 添加 18 个核心逻辑单元测试:覆盖加密、并发、流式备份/恢复、错误处理等 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
wucm667 authored
-
SsageParuders authored
-
SsageParuders authored
Consolidate two separate channel types (bedrock + bedrock-apikey) into a single "AWS Bedrock" channel. Authentication mode is now distinguished by credentials.auth_mode ("sigv4" | "apikey") instead of separate types. Backend: - Remove AccountTypeBedrockAPIKey constant - IsBedrock() simplified; IsBedrockAPIKey() checks auth_mode - Add IsAPIKeyOrBedrock() helper to eliminate repeated type checks - Extend pool mode, quota scheduling, and billing to bedrock - Add RetryableOnSameAccount to handleBedrockUpstreamErrors - Add "bedrock" scope to Beta Policy for independent control Frontend: - Merge two buttons into one "AWS Bedrock" with auth mode radio - Badge displays "Anthropic | AWS" - Pool mode and quota limit UI available for bedrock - Quota display in account list (usage bars, capacity badges, reset) - Remove all bedrock-apikey type references -
ius authored
-
Wang Lvyuan authored
-
InCerry authored
-
Wang Lvyuan authored
-
- 13 Mar, 2026 8 commits
-
-
erio authored
The 403 detection PR changed the 401 handler condition from `account.Type == AccountTypeOAuth` to `account.Type == AccountTypeOAuth && account.Platform == PlatformOpenAI`, which accidentally excluded Gemini OAuth from the temp-unschedulable path. Fix: use `!= PlatformAntigravity` instead, preserving Gemini behavior while correctly excluding Antigravity (whose 401 is handled by applyErrorPolicy's temp_unschedulable_rules). Update tests to reflect Antigravity's new 401 semantics: - HandleUpstreamError: Antigravity OAuth 401 now uses SetError - CheckErrorPolicy: Antigravity 401 second hit stays TempUnscheduled - DB fallback: split into Gemini (escalates) and Antigravity (stays temp)
-
Ylarod authored
-
erio authored
Backend: - Detect and classify 403 responses into three types: validation (account needs Google verification), violation (terms of service / banned), forbidden (generic 403) - Extract verification/appeal URLs from 403 response body (structured JSON parsing with regex fallback) - Add needs_verify, is_banned, needs_reauth, error_code fields to UsageInfo (omitempty for zero impact on other platforms) - Handle 403 in request path: classify and permanently set account error - Save validation_url in error_message for degraded path recovery - Enrich usage with account error on both success and degraded paths - Add singleflight dedup for usage requests with independent context - Differentiate cache TTL: success/403 → 3min, errors → 1min - Return degraded UsageInfo instead of HTTP 500 on quota fetch errors Frontend: - Display forbidden status badges with color coding (red for banned, amber for needs verification, gray for generic) - Show clickable verification/appeal URL links - Display needs_reauth and degraded error states in usage cell - Add Antigravity tier label badge next to platform type Tests: - Comprehensive unit tests for classifyForbiddenType (7 cases) - Unit tests for extractValidationURL (8 cases including unicode escapes) - Integration test for FetchQuota forbidden path
-
Peter authored
-
Ylarod authored
-
Rose Ding authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
wucm667 authored
refactor: 将 ComputeQuotaResetAt 和 ValidateQuotaResetConfig 函数中的 map 类型从 map[string]interface{} 修改为 map[string]any -
wucm667 authored
- 后端新增 rolling/fixed 两种配额重置模式,支持日配额和周配额 - fixed 模式下可配置重置时刻(小时)、重置星期几(周配额)及时区(IANA) - 在 account_repo.go 中使用 SQL 表达式适配两种模式的过期判断与重置时间推进 - 新增 ComputeQuotaResetAt / ValidateQuotaResetConfig 等辅助函数 - DTO 层新增相关字段并在 mappers 中完整映射 - 前端 QuotaLimitCard 新增 rolling/fixed 切换 UI、时区选择器 - CreateAccountModal / EditAccountModal 透传新配置字段 - i18n(zh/en)同步新增相关翻译词条
-