Commit Graph

1489 Commits

Author SHA1 Message Date
erio
345f853b5d chore: bump version to 0.1.77.1 2026-02-09 22:27:47 +08:00
erio
100a70f87c Merge remote-tracking branch 'upstream/main' into develop 2026-02-09 22:27:07 +08:00
shaw
aa4b102108 fix: 移除Antigravity的apikey账户额外的表单 v0.1.77 2026-02-09 22:15:14 +08:00
erio
18b591bc3b feat: Antigravity extra failover retries after default retries exhausted
When default failover retries are exhausted, continue retrying with
Antigravity accounts only (up to 10 times, configurable via
GATEWAY_ANTIGRAVITY_EXTRA_RETRIES). Each extra retry uses a fixed
500ms delay. Non-Antigravity accounts are skipped during the extra
retry phase. Applied to all three endpoints: Gemini compat, Claude,
and Gemini native API paths.
2026-02-09 22:13:44 +08:00
Rose Ding
e4bc35151f test: 添加单账号 503 退避重试机制的单元测试
覆盖 Service 层和 Handler 层的所有新增逻辑:
- isSingleAccountRetry context 标记检查
- handleSmartRetry 中 503 + SingleAccountRetry 分支
- handleSingleAccountRetryInPlace 原地重试逻辑
- antigravityRetryLoop 预检查跳过限流
- sleepAntigravitySingleAccountBackoff 固定延迟退避
- 端到端集成场景验证

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 22:06:06 +08:00
Wesley Liddick
56da498b7e Merge pull request #532 from touwaeriol/fix/clear-model-rate-limits
fix: support clearing model-level rate limits from action menu and temp-unsched reset
2026-02-09 20:52:44 +08:00
Wesley Liddick
1bba1a62b1 Merge pull request #531 from touwaeriol/fix/gemini-error-policy-before-retry
fix: Gemini error policy check should precede retry logic
2026-02-09 20:52:32 +08:00
erio
4a84ca9a02 fix: support clearing model-level rate limits from action menu and temp-unsched reset 2026-02-09 20:37:30 +08:00
erio
6a52b24369 Merge branch 'develop'
# Conflicts:
#	backend/cmd/server/VERSION
2026-02-09 20:13:54 +08:00
erio
228aca9523 Merge branch 'fix/gemini-error-policy-before-retry' into develop
# Conflicts:
#	backend/cmd/server/VERSION
2026-02-09 20:08:31 +08:00
erio
7e4637cd70 fix: support clearing model-level rate limits from action menu and temp-unsched reset 2026-02-09 20:08:00 +08:00
erio
a70d37a676 fix: Gemini error policy check should precede retry logic 2026-02-09 19:55:17 +08:00
erio
6892e84ad2 fix: skip rate limiting when custom error codes don't match upstream status
Add ShouldHandleErrorCode guard at the entry of handleGeminiUpstreamError
and AntigravityGatewayService.handleUpstreamError so that accounts with
custom error codes (e.g. [599]) are not rate-limited when the upstream
returns a non-matching status (e.g. 429).
2026-02-09 19:55:05 +08:00
erio
73f455745c feat: ErrorPolicySkipped returns 500 instead of upstream status code
When custom error codes are enabled and the upstream error code is NOT
in the configured list, return HTTP 500 to the client instead of
transparently forwarding the original status code.

Also adds integration test TestCustomErrorCode599 verifying that 429,
500, 503, 401, 403 all return 500 without triggering SetRateLimited
or SetError.
2026-02-09 19:54:54 +08:00
erio
3e3c015efa fix: Gemini error policy check should precede retry logic 2026-02-09 19:22:32 +08:00
erio
30c30b1712 fix: skip rate limiting when custom error codes don't match upstream status
Add ShouldHandleErrorCode guard at the entry of handleGeminiUpstreamError
and AntigravityGatewayService.handleUpstreamError so that accounts with
custom error codes (e.g. [599]) are not rate-limited when the upstream
returns a non-matching status (e.g. 429).
2026-02-09 18:53:52 +08:00
erio
e666356483 fix: resolve merge conflict in OpsConcurrencyCard.vue 2026-02-09 18:12:39 +08:00
erio
3710bc883b feat: ErrorPolicySkipped returns 500 instead of upstream status code
When custom error codes are enabled and the upstream error code is NOT
in the configured list, return HTTP 500 to the client instead of
transparently forwarding the original status code. This matches the
frontend description: "other errors will return 500".

Also adds integration test TestCustomErrorCode599 verifying that 429,
500, 503, 401, 403 all return 500 without triggering SetRateLimited
or SetError.
2026-02-09 18:10:39 +08:00
Rose Ding
021abfca18 fix: 单账号分组首次 503 不设模型限流标记,避免后续请求雪崩
单账号 antigravity 分组收到 503 (MODEL_CAPACITY_EXHAUSTED) 时,
原逻辑会设置 ~29s 模型限流标记。由于只有一个账号无法切换,
后续所有新请求在预检查时命中限流 → 几毫秒内直接返回 503,
导致约 30 秒的雪崩窗口。

修复:在 Handler 入口处检查分组是否只有单个 antigravity 账号,
如果是则提前设置 SingleAccountRetry context 标记,让 Service 层
首次 503 就走原地重试逻辑(不设限流标记),避免污染后续请求。
2026-02-09 17:25:36 +08:00
Wesley Liddick
7d66f7ff0d Merge pull request #527 from touwaeriol/fix/group-badge-platform-color
fix: pass platform prop to GroupBadge in GroupSelector
2026-02-09 14:39:51 +08:00
erio
470b37be7e fix: pass platform prop to GroupBadge in GroupSelector
GroupBadge in GroupSelector was missing the platform prop, causing all
group badges in account edit/detail pages to use fallback colors instead
of platform-specific colors (e.g. Claude=orange, Gemini=blue).
2026-02-09 14:33:05 +08:00
Rose Ding
f6cfab9901 feat: 添加 Antigravity 单账号 503 退避重试机制
当分组内只有一个可用账号且上游返回 503 (MODEL_CAPACITY_EXHAUSTED) 时,
不再设置模型限流+切换账号(因为切换回来还是同一个账号),而是在 Service 层
原地等待+重试,避免双重等待问题。

主要变更:
- Handler 层:检测单账号 503 场景,清除排除列表并设置 SingleAccountRetry 标记
- Service 层:新增 handleSingleAccountRetryInPlace 原地重试逻辑
- Service 层:预检查跳过单账号模式下的限流检查
- 新增 ctxkey.SingleAccountRetry 上下文标记
2026-02-09 14:26:01 +08:00
erio
64f60d15b0 fix: pass platform prop to GroupBadge in GroupSelector for consistent colors
chore: bump version to 0.1.76.2
2026-02-09 14:11:41 +08:00
erio
bc4a044337 Merge release/custom-0.1.76 into main 2026-02-09 13:44:17 +08:00
erio
cb233bfa66 fix: resolve merge conflict marker in OpsConcurrencyCard.vue 2026-02-09 13:20:14 +08:00
erio
d46059a735 chore: bump version to 0.1.76.1 2026-02-09 13:13:14 +08:00
erio
da2fbd9924 Merge tag 'v0.1.76' into develop
重构速率限制从 scope 级别到 model 级别,新增分组拖拽排序功能,优化 Antigravity 智能重试和错误处理策略。

- 分组拖拽排序:管理后台支持拖拽调整分组顺序
- 账号调度防雷群:相同优先级的账号在调度时随机打乱,防止并发请求集中到同一账号
- 上游账号路由:AccountTypeUpstream 正确路由到 ForwardUpstream 流程
- 客户端断开检测:流式响应时检测客户端断开,继续消费上游响应以确保计费准确
- Antigravity 失败切换延迟:账号切换时增加线性延迟,避免瞬时切换造成雪崩
- Gemini 错误策略集成:统一 Antigravity 错误策略,支持 Gemini 账号自定义错误码

- 重构速率限制:从 scope 级别(claude/gemini_text/gemini_image)改为 model 级别限速,简化账号选择算法
- 重构会话存储:使用扁平缓存替代 Trie 结构,简化 digest session 存储
- 速率限制延迟:使用上游返回的 retryDelay 而非固定 30s 默认值

- 修复 Gemini 原生请求格式解析,确保 session hash 正确生成
- 修复不同用户发送相同消息时 sessionHash 冲突问题
- 修复 thoughtSignature 清理逻辑,现在适用于所有客户端而非仅 CLI
- 修复粘性会话失败切换时的缓存计费豁免问题

# Conflicts:
#	backend/cmd/server/VERSION
#	backend/internal/service/gateway_multiplatform_test.go
#	backend/internal/service/gemini_multiplatform_test.go
#	frontend/src/components/account/AccountStatusIndicator.vue
#	frontend/src/views/admin/ops/components/OpsConcurrencyCard.vue
2026-02-09 12:40:26 +08:00
erio
084e0adb34 feat: squash merge all changes from develop-0.1.75
Squash of 124 commits from the legacy develop branch (develop-0.1.75)
onto a clean v0.1.75 upstream base, to simplify future upstream merges.

Key changes included:
- Refactor scope-level rate limiting to model-level rate limiting
- Antigravity gateway service improvements (smart retry, error policy)
- Digest session store (flat cache replacing Trie-based store)
- Client disconnect detection during streaming
- Gemini messages compatibility service enhancements
- Scheduler shuffle for thundering herd prevention
- Session hash generation improvements
- Frontend customizations (WeChat service, HomeView, etc.)
- Ops monitoring scope cleanup
2026-02-09 12:32:35 +08:00
shaw
51572b5da0 chore: update version 2026-02-09 12:00:03 +08:00
Wesley Liddick
91ca28b7e3 Merge pull request #525 from DaydreamCoding/feat/crs_sync_preview_with_select
feat(admin): 新增 CRS 同步预览和账号选择功能
2026-02-09 11:58:51 +08:00
QTom
04cedce9a1 test: 为 stubAccountRepo 添加 ListCRSAccountIDs 方法实现 2026-02-09 11:40:37 +08:00
QTom
5e0d789440 feat(admin): 新增 CRS 同步预览和账号选择功能
- 后端新增 PreviewFromCRS 接口,允许用户先预览 CRS 中的账号
- 后端支持在同步时选择特定账号,不选中的账号将被跳过
- 前端重构 SyncFromCrsModal 为三步向导:输入凭据 → 预览账号 → 执行同步
- 改进表单无障碍性:添加 for/id 关联和 required 属性
- 修复 Back 按钮返回时的状态清理
- 新增 buildSelectedSet 和 shouldCreateAccount 的单元测试
- 完整的向后兼容性:旧客户端不发送 selected_account_ids 时行为不变
2026-02-09 10:39:09 +08:00
shaw
3bddbb6afe chore: update version v0.1.76 2026-02-09 09:42:29 +08:00
Wesley Liddick
149e4267cd Merge pull request #523 from touwaeriol/feat/antigravity-improvements
feat: Antigravity improvements and scope-to-model rate limiting refactor
2026-02-09 09:38:55 +08:00
erio
9a479d1b55 fix: resolve CI failures from scope removal refactor
- Fix gofmt alignment in ops_realtime_models.go
- Remove SetAntigravityQuotaScopeLimit mock from api_contract_test.go
- Add UpdateSortOrders mock to mockGroupRepoForGateway
2026-02-09 08:27:14 +08:00
erio
fc095bf054 refactor: replace scope-level rate limiting with model-level rate limiting
Merge functional changes from develop branch:
- Remove AntigravityQuotaScope system (claude/gemini_text/gemini_image)
- Replace with per-model rate limiting using resolveAntigravityModelKey
- Remove model load statistics (IncrModelCallCount/GetModelLoadBatch)
- Simplify account selection to unified priority→load→LRU algorithm
- Remove SetAntigravityQuotaScopeLimit from AccountRepository
- Clean up scope-related UI indicators and API fields
2026-02-09 08:19:01 +08:00
erio
1af06aed96 feat: shuffle accounts within same sort group to prevent thundering herd
Add post-sort shuffle for accounts with identical (priority, loadRate,
lastUsedAt) to break deterministic ordering when concurrent requests
read the same scheduler snapshot. Applies to both Antigravity and
OpenAI scheduling paths, plus the sortAccountsByPriorityAndLastUsed
helper.

Keeps upstream CallCount/ModelLoadInfo scheduling intact; shuffle is
additive and only randomises within equivalent-rank groups.
2026-02-09 07:33:17 +08:00
erio
9236936a55 feat: route AccountTypeUpstream to ForwardUpstream in Forward() entry
Without this routing guard, ForwardUpstream is never called because
Forward() always proceeds with the standard OAuth/cookie flow.
2026-02-09 07:27:10 +08:00
erio
125152460f fix: use upstream retryDelay for rate limit duration instead of fixed default
- In handleSmartRetry, use the actual upstream retryDelay to set model
  rate limit duration instead of always using the 30s default
- Return info.RetryDelay from shouldTriggerAntigravitySmartRetry when
  shouldRateLimitModel=true, so callers know the actual delay
- Extract getDefaultRateLimitDuration() and resolveResetTime() helpers
  to reduce duplication in handleUpstreamError 429 handling
- Improve debug logging with upstream_retry_delay and response body
2026-02-09 07:11:29 +08:00
erio
6d90fb0bc3 feat: detect client disconnect during streaming and continue draining upstream for billing 2026-02-09 07:06:26 +08:00
erio
b889d5017b refactor: replace Trie-based digest session store with flat cache 2026-02-09 07:02:12 +08:00
erio
72b08f9cc5 fix: ensure sticky session failover triggers cache billing exemption 2026-02-09 06:57:07 +08:00
erio
681950dadd feat: add linear delay between Antigravity account failover switches 2026-02-09 06:56:29 +08:00
erio
a67d9337b8 feat: integrate CheckErrorPolicy into Gemini error handling paths 2026-02-09 06:55:45 +08:00
erio
2f1182e8a9 feat: unified error policy for Antigravity + enable custom error codes for Gemini accounts 2026-02-09 06:54:42 +08:00
erio
cbb4d854ab fix: check type assertion in test to satisfy errcheck linter 2026-02-09 06:47:50 +08:00
erio
35598d5648 fix: parse Gemini native request format in ParseGatewayRequest for correct session hash generation
ParseGatewayRequest only parsed Anthropic format (system/messages),
ignoring Gemini native format (systemInstruction/contents). This caused
GenerateSessionHash to produce identical hashes for all Gemini sessions.

Add protocol parameter to ParseGatewayRequest to branch between
Anthropic and Gemini parsing. Update GenerateSessionHash message
traversal to extract text from both formats.
2026-02-09 06:47:22 +08:00
erio
5c76b9e45a fix: prevent sessionHash collision for different users with same messages
Mix SessionContext (ClientIP, UserAgent, APIKeyID) into
GenerateSessionHash 3rd-level fallback to differentiate requests
from different users sending identical content.

Also switch hashContent from SHA256-truncated to XXHash64 for
better performance, and optimize Trie Lua script to match from
longest prefix first.
2026-02-09 06:46:32 +08:00
erio
0b8fea4cb4 fix: clean thoughtSignature for all clients, not just CLI
Previously, thoughtSignature cleanup only applied to Gemini CLI
requests (detected via x-gemini-api-privileged-user-id header or
tmp dir pattern). This caused 400 errors for non-CLI clients when
session cache expired and they sent stale signatures.

Remove the isGeminiCLIRequest guard so all clients benefit from
proactive thoughtSignature cleanup on session binding miss.
2026-02-09 06:45:01 +08:00
Wesley Liddick
5fa93ebdc7 Merge pull request #519 from bayma888/feature/group-sort-order
feat(admin): 新增-分组管理自由拖拽排序功能
2026-02-08 18:00:22 +08:00