Commit Graph
2177 Commits
Author SHA1 Message Date
erioandClaude Opus 4.6 6a7bcabb6f feat(frontend): add GDrive storage test button in profile drawer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 22:56:23 +08:00
erio 298f5c1baf feat(sora): add GDrive full-cycle test endpoint (upload/download/delete) 2026-03-06 22:33:37 +08:00
erio 3f1ca43514 debug: add OAuth exchange logging 2026-03-06 21:21:29 +08:00
erioandClaude Opus 4.6 e3f9774eda fix(sora): add GDrive OAuth callback page for postMessage flow
The OAuth flow opens a popup window that redirects to /admin/gdrive-oauth-callback,
but this route and page were missing. Add the callback view that extracts the
authorization code from the URL and sends it back to the opener window via
postMessage, completing the OAuth authorization flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:10:02 +08:00
erio e0a9c34067 Merge branch 'release/custom-0.1.92' into worktree-feature/sora 2026-03-06 20:47:06 +08:00
erioandClaude Opus 4.6 ad54040c07 feat(sora): add Google Drive storage backend with unified storage abstraction
- Define SoraObjectStorage interface abstracting S3 and GDrive backends
- Implement SoraGDriveStorage with OAuth2 and Service Account auth
- Add SoraStorageRouter to route requests based on active profile provider
- Add GDrive OAuth handler for authorization flow (start + callback)
- Extend profile model with provider, auth_type, and GDrive-specific fields
- Update frontend UI with provider selection, dynamic form fields, and i18n
- Migrate API paths from /sora-s3 to /sora-storage (old paths preserved)
- All existing S3 functionality remains backward compatible

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:45:51 +08:00
erioandClaude Opus 4.6 d7a3c7f8a8 chore: bump version to 0.1.92.10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:07:02 +08:00
erioandClaude Opus 4.6 465a58a1c9 fix: replace CTE with inline UPDATE to prevent lost update on period reset
CTE snapshot in READ COMMITTED can cause concurrent requests during
period reset to lose one increment. Inline CASE in single UPDATE
ensures PostgreSQL re-evaluates all expressions with latest row data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:07:02 +08:00
erioandClaude Opus 4.6 9430776393 chore: bump version to 0.1.92.9
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:03:29 +08:00
erioandClaude Opus 4.6 c087e94413 fix: use UTC timezone in quota period SQL and reset period_start on quota reset
- Use NOW() AT TIME ZONE 'UTC' to ensure consistent timestamps
  regardless of database timezone setting
- Clear quota_period_start when manually resetting quota so a
  fresh period starts from next usage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:03:16 +08:00
erioandClaude Opus 4.6 a4ee71d796 chore: bump version to 0.1.92.8
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:51:52 +08:00
erioandClaude Opus 4.6 e976409ba1 feat: add periodic quota reset for API Key accounts
Support daily/weekly automatic quota reset using a rolling period
anchored to first usage. Implements lazy reset via atomic CTE SQL
in IncrementQuotaUsed - no cron job needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:51:41 +08:00
erioandClaude Opus 4.6 da99de82e9 chore: bump version to 0.1.92.7
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:55:38 +08:00
erioandClaude Opus 4.6 e8e5acb9e7 revert: remove client affinity count display infrastructure
Remove frontend badge/tooltip and backend counting/query infrastructure
for client affinity. Core client affinity scheduling logic is preserved.

Removed:
- GatewayCache injection in AccountHandler
- GetAccountAffinityCount/Batch/Clients methods and interface
- AffinityClientInfo struct and ClientAffinityTTL function
- /affinity-clients API endpoint and route
- Reverse index (account_affinity:*) Lua scripts
- Frontend blue badge, tooltip, and lazy-load logic
- affinity_client_count field from types and response

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:47:52 +08:00
erioandClaude Opus 4.6 77ae2bcccb fix: exclude Antigravity from OAuth 401 temp-unschedulable and escalation logic
PR #723 changed all OAuth 401 to use SetTempUnschedulable instead of SetError,
and PR #761 added 401 escalation logic in tryTempUnschedulable. Both caused
non-OpenAI accounts to frequently become temporarily unschedulable.

- HandleUpstreamError case 401: limit temp-unschedulable to OpenAI OAuth only,
  other platforms (Anthropic/Gemini/Antigravity) revert to original SetError
- tryTempUnschedulable: skip 401 escalation for Antigravity, let its
  applyErrorPolicy temp_unschedulable_rules handle 401 naturally

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:32:57 +08:00
erioandClaude Opus 4.6 6315dea094 fix: prevent reverse affinity index from premature expiration
The reverse index account_affinity:{accountID} was using the same 1h
EXPIRE as the forward index. But the forward key EXPIRE refreshes on
every client request, while the reverse key only refreshes when a
request is routed to that specific account. This caused reverse keys
to expire prematurely.

Fix: set reverse key EXPIRE to 24h as safety net, rely on
ZREMRANGEBYSCORE for member-level expiration. Also clean up empty
keys after member cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:04:52 +08:00
erioandClaude Opus 4.6 c7e88ffcf1 feat: extend client affinity to all Anthropic account types
- Backend: expand IsClientAffinityEnabled() to support all Anthropic
  accounts (OAuth/SetupToken/APIKey), not just OAuth/SetupToken
- Frontend: show client affinity toggle for all Anthropic accounts
- Frontend: fix save logic to properly chain extra field updates
- Antigravity accounts explicitly excluded from client affinity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:46:00 +08:00
erioandClaude Opus 4.6 fb5f471fe1 feat: extend client affinity to all Anthropic account types
- Backend: expand IsClientAffinityEnabled() to support all Anthropic
  accounts (OAuth/SetupToken/APIKey), not just OAuth/SetupToken
- Frontend: show client affinity toggle for all Anthropic accounts
- Frontend: fix save logic to properly chain extra field updates
- Antigravity accounts explicitly excluded from client affinity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:44:27 +08:00
erio 5f4561306f chore: bump version to 0.1.92.5
Made-with: Cursor
2026-03-06 17:31:27 +08:00
erio 6b31b34672 feat: extend client affinity support to Antigravity and Anthropic APIKey accounts
Made-with: Cursor
2026-03-06 17:31:18 +08:00
erioandClaude Opus 4.6 af5d5dbcbc chore: bump version to 0.1.92.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:01:10 +08:00
erioandClaude Opus 4.6 7fe246b784 fix: show affinity badge for enabled accounts even with 0 clients
- Backend: remove count > 0 filter in GetAccountAffinityCountBatch so
  accounts with 0 bound clients are included in the response
- Frontend: change badge condition from affinityClientCount > 0 to
  account.client_affinity_enabled so the badge always shows for accounts
  with affinity enabled

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:00:46 +08:00
erio 064a70db29 fix: update wire_gen.go to pass gatewayCache to NewAccountHandler 2026-03-06 15:55:23 +08:00
erio c616284890 chore: bump version to 0.1.92.3 2026-03-06 15:49:11 +08:00
erio 60f050d184 feat: add account affinity client count indicator
Add reverse Redis index (account_affinity:{accountID}) to track which
clients are bound to each account via affinity scheduling. Display a
blue badge with client count in the admin account list, with a hover
tooltip showing client details (groupID:clientID + TTL).

Backend: reverse index in Lua scripts, batch query methods, new
GET /accounts/:id/affinity-clients endpoint.
Frontend: blue badge + lazy-loaded tooltip in AccountStatusIndicator.
2026-03-06 15:48:58 +08:00
erio 63dff62673 fix: restrict client affinity to Anthropic OAuth/SetupToken accounts only
客户端亲和仅对 Claude Code 账号(Anthropic OAuth/SetupToken)生效,
移除 Antigravity 平台支持。UI toggle 移动到拦截预热请求下方。
2026-03-06 14:46:47 +08:00
erio c1816f39f2 revert: remove passthrough check from isModelSupportedByAccount
该函数不被 OpenAI 调度路径调用,透传短路应只加在
openai_account_scheduler.go 中。
2026-03-06 14:30:44 +08:00
erio 69abdff732 chore: bump version to 0.1.92.2 2026-03-06 14:24:58 +08:00
erio 489a6d4839 fix: OpenAI scheduler also bypass model check for passthrough accounts
之前只在 gateway_service.isModelSupportedByAccount 中添加了透传短路,
但 OpenAI 调度器 (openai_account_scheduler.go) 直接调用
account.IsModelSupported(),未经过该函数,导致 gpt-5.4 仍然 503。
2026-03-06 14:20:08 +08:00
erio 312f2ecb8d fix: OpenAI passthrough accounts bypass model mapping check
透传模式账号仅替换认证,应允许所有模型通过。之前调度阶段的
isModelSupportedByAccount 不感知透传模式,导致 model_mapping
中未配置的新模型(如 gpt-5.4)被拒绝返回 503。
2026-03-06 13:54:25 +08:00
erio 75f1faea14 chore: bump version to 0.1.92.1 2026-03-06 13:08:32 +08:00
erio b4005aa7b2 Merge branch 'release/custom-0.1.91' into release/custom-0.1.92 2026-03-06 13:06:17 +08:00
erio 180c515f9a fix: race condition in TestOpsSystemLogSink_StartStopAndFlushSuccess
done 信号在 BatchInsertSystemLogsFn 内发出,但 writtenCount 在函数返回后
才原子递增,导致测试主 goroutine 收到信号后立即检查 WrittenCount 时可能为 0。
改用短轮询等待 WrittenCount > 0,消除竞态。
2026-03-06 13:02:04 +08:00
erio 896fb2b0b4 feat: add client affinity scheduling for Anthropic/Antigravity accounts
新增客户端亲和调度功能,新会话优先调度到客户端之前使用过的账号,减少账号频繁切换。

- 调度层 Layer 1.6:粘性会话未命中时,从 Redis Sorted Set 按最近使用时间降序
  查找亲和账号,通过全部可调度检查后尝试获取槽位
- 账号级 opt-in:通过 Extra 字段 client_affinity_enabled 控制,未启用的账号
  既不写入亲和关系也不被亲和选中
- Redis 数据结构:ZSET client_affinity:{groupID}:{clientID},Lua 脚本原子清理
  过期成员 + 查询/更新,per-member TTL 通过 score 实现
- 仅 Claude Code/Console 客户端生效(通过 metadata.user_id 格式识别)
- DTO/前端:新增开关 UI,支持 Anthropic OAuth/SetupToken 和 Antigravity 平台
2026-03-06 12:43:22 +08:00
shaw 0cce0a8877 chore: gpt-5.4示例配置修改model_reasoning_effort为xhigh 2026-03-06 11:29:43 +08:00
shaw 225fd035ae chore: 更新codex配置部分支持gpt-5.4的长上下文 2026-03-06 10:55:09 +08:00
Wesley Liddick fb7d1346b5 Merge pull request #800 from mt21625457/pr/gpt54-support-upstream
feat(openai): 增加 GPT-5.4 支持并修复长上下文计费与白名单回归
2026-03-06 10:42:01 +08:00
shaw 491a744481 fix: 修复账号列表首次加载窗口费用显示 $0.00
lite 模式下从快照缓存读取窗口费用,非 lite 模式查询后写入缓存
2026-03-06 10:23:22 +08:00
yangjianbo f366026435 fix(openai): 修复 gpt-5.4 长上下文计费与快照白名单
补齐 gpt-5.4 fallback 的长上下文计费元信息,\n确保超过 272000 输入 token 时对整次会话应用\n2x 输入与 1.5x 输出计费规则。\n\n同时将官方快照 gpt-5.4-2026-03-05 加入前端\n白名单候选与回归测试,避免 whitelist 模式误拦截。\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

(cherry picked from commit d95497af87f608c6dadcbe7d6e851de9413ae147)
2026-03-06 10:16:23 +08:00
yangjianbo 1a0d4ed668 feat(openai): 增加 gpt-5.4 模型支持与定价配置
- 接入 gpt-5.4 模型识别与规范化,补充默认模型列表
- 增加 gpt-5.4 输入/缓存命中/输出价格与计费兜底逻辑
- 同步前端模型白名单与 OpenCode 上下文窗口(1050000/128000)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
(cherry picked from commit 924476dcac6181cd0f3ee731ec7b73672ff03793)
2026-03-06 10:16:23 +08:00
Wesley Liddick 63a8c76946 Merge pull request #798 from touwaeriol/feature/account-load-factor
feat: add account load_factor for scheduling load calculation
2026-03-06 09:42:10 +08:00
Wesley Liddick f355a68bc9 Merge pull request #796 from touwaeriol/feature/apikey-quota-limit
feat: add configurable spending limit for API Key accounts
2026-03-06 09:37:52 +08:00
erio 95fcb02fe2 fix: restore SimulateClaudeMaxEnabled and ResetAccountQuota lost during merge 2026-03-06 05:34:03 +08:00
erio e74270f8eb chore: bump version to 0.1.91.4 2026-03-06 05:29:07 +08:00
erio 3c204c1862 Merge branch 'feature/account-load-factor' into release/custom-0.1.91 2026-03-06 05:25:32 +08:00
erio c87e6526c1 fix: use real Concurrency instead of LoadFactor for metrics and monitoring
LoadFactor should only affect scheduling weight, not load rate reporting.
2026-03-06 05:18:45 +08:00
erio af3a5076d6 fix: add load_factor upper bound validation to BulkUpdateAccounts 2026-03-06 05:17:52 +08:00
erio 18f2e21414 fix: use HTML-safe expressions for @input handlers in Vue templates
Replace `<` comparisons with Math.max/ternary+>= to avoid Vue template
parser treating `<` as HTML tag start in attribute values.
2026-03-06 05:07:52 +08:00
erio 8a8cdeebb4 fix: prevent negative values for concurrency and load_factor inputs 2026-03-06 05:07:52 +08:00
erio 12b33f4ea4 fix: address load_factor code review findings
- Fix bulk edit: send 0 instead of null/NaN to clear load_factor
- Fix edit modal: explicit NaN check instead of implicit falsy
- Fix create modal: use ?? instead of || for load_factor
- Add load_factor upper limit validation (max 10000)
- Add //go:build unit tag and self-contained intPtrHelper in test
- Add design intent comments on WaitPlan.MaxConcurrency
2026-03-06 05:07:52 +08:00