Commit Graph

1040 Commits

Author SHA1 Message Date
erio
50a783ff01 feat: add Anthropic sticky session digest chain matching via Trie
The previous fallback (step 3) in GenerateSessionHash hashed system +
all messages together, producing a different hash each round as the
conversation grew ([a] -> [a,b] -> [a,b,c]). This made fallback sticky
sessions ineffective for multi-turn conversations.

Implement per-message Trie digest chain matching (reusing Gemini's Trie
infrastructure) so that the previous round's chain is always a prefix
of the current round's chain, enabling reliable session affinity.
2026-02-07 18:00:56 +08:00
yangjianbo
f6ca701917 fix(oauth): SessionStore.Stop() 添加 sync.Once 防重入保护 (P1-05)
oauth 和 openai 包的 SessionStore.Stop() 直接调用 close(stopCh),
重复调用会导致 panic。使用 sync.Once 包裹确保幂等安全。

新增单元测试覆盖连续调用和 50 goroutine 并发调用场景。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:39:18 +08:00
yangjianbo
a84604dceb fix(config): 禁止 server.frontend_url 携带 query/userinfo 2026-02-07 17:37:08 +08:00
yangjianbo
e75d3e3584 fix(security): 修复密码重置链接 Host Header 注入漏洞 (P0-07)
ForgotPassword 原来从 c.Request.Host 构建重置链接基础 URL,攻击者
可伪造 Host 头将重置链接指向恶意域名窃取 token。

修复方案:
- ServerConfig 新增 frontend_url 配置项
- auth_handler 改为从配置读取前端 URL,未配置时拒绝请求
- Validate() 校验 frontend_url 必须为绝对 HTTP(S) URL
- 新增 TestValidateServerFrontendURL 单元测试
- config.example.yaml 添加配置说明

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:15:26 +08:00
shaw
1439eb39a9 fix(gateway): harden digest logging and align antigravity ops
- avoid panic by using safe UUID prefix truncation in Gemini digest fallback logs\n- remove unconditional Antigravity 429 full-body debug logs and honor log truncation config\n- align Antigravity quick preset mappings to opus 4.6-thinking targets only\n- restore scope rate-limit aggregation/output in ops availability stats
2026-02-07 17:12:15 +08:00
yangjianbo
8226a4ce4d perf(service): 优化 model 替换函数,用 gjson/sjson 替代全量 JSON 序列化
SSE 热路径中 replaceModelInSSELine 和 replaceModelInResponseBody 原来
使用 json.Unmarshal/Marshal 对每个事件做全量反序列化再序列化,现改为
gjson.Get/sjson.Set 精确字段操作,消除 O(n) 中间 map 分配,保持 JSON
字段顺序不变。涉及 OpenAIGatewayService 和 GatewayService 两个服务。

新增 23 个单元测试覆盖:顶层/嵌套 model 替换、不匹配跳过、空行/[DONE]/
非法 JSON 等边界情况。

Fixes: P1-08

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:09:55 +08:00
erio
e1a68497d6 refactor: simplify sticky session rate limit handling — switch immediately on any rate limit
Remove threshold-based waiting in both sticky session and antigravity
pre-check paths. When a model is rate-limited, immediately clear the
sticky session and switch accounts instead of waiting for short durations.
2026-02-07 17:06:49 +08:00
yangjianbo
65c0d8b51f fix(middleware): 管理员JWT增加TokenVersion校验
管理员改密后旧JWT会被拒绝,并补充单元测试覆盖。
2026-02-07 16:34:57 +08:00
yangjianbo
a9e256ce8c fix(openai): 修复 usage 为空导致 panic(P0-02) 2026-02-07 16:15:30 +08:00
erio
fa28dcbf32 fix(test): update test calls to match method receivers on handleSmartRetry and antigravityRetryLoop 2026-02-07 16:05:09 +08:00
erio
2656320d04 fix(antigravity): fetch default mapping from API and sync Redis on rate limit
1. Frontend: replace hardcoded antigravityDefaultMappings with async
   fetch from GET /admin/accounts/antigravity/default-model-mapping,
   eliminating the duplicate data source that caused frontend/backend
   mapping inconsistency.

2. Backend: convert handleSmartRetry and antigravityRetryLoop from
   standalone functions to AntigravityGatewayService methods, enabling
   Redis cache sync (updateAccountModelRateLimitInCache) after both
   rate-limit write paths — long-delay branch and retry-exhausted branch.
2026-02-07 15:59:27 +08:00
yangjianbo
7e1674e43a chore(version): 更新版本号至 0.1.70.2 2026-02-07 14:58:52 +08:00
erio
b4f6c4f9d5 style: fix gofmt formatting in gateway_service.go
Remove extra blank line that caused golangci-lint gofmt check to fail.
2026-02-07 14:51:20 +08:00
yangjianbo
0e514ed80b perf(middleware): 优化订阅模式认证中间件,5次串行调用降至2步同步+1步异步
- 为 GetActiveSubscription 添加 ristretto L1 缓存 + singleflight 防击穿
- 合并 ValidateSubscription + CheckUsageLimits 为纯内存 ValidateAndCheckLimits
- 窗口维护操作(激活/重置)异步化,不再阻塞首字节
- 缓存返回浅拷贝,避免并发 data race 和缓存污染
- 所有管理操作(分配/续期/撤销/扩展/窗口重置)同步失效 L1 缓存
- 新增 SubscriptionCacheConfig 可配置 L1 缓存大小/TTL/抖动

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:43:12 +08:00
erio
14c6c9321a refactor: remove unused IsAntigravityModelSupported function and its tests 2026-02-07 14:42:28 +08:00
erio
386126b1b2 test(antigravity): add missing unit tests for upstream and custom model_mapping
- Add GetAccessToken upstream branch tests (success/failure/empty/nil)
- Add mapAntigravityModel wildcard-target-equals-request edge case tests
- Add upstream account smart retry test case
- Add GeminiMessagesCompatService custom model_mapping and empty model tests
2026-02-07 14:39:25 +08:00
erio
de0927289e fix(antigravity): support upstream accounts and custom model_mapping in scheduling
- GetAccessToken: add upstream branch to read api_key from credentials
- shouldTriggerAntigravitySmartRetry: relax check from IsOAuth to Platform-based
- isModelSupportedByAccount/WithContext: replace IsAntigravityModelSupported
  whitelist with mapAntigravityModel for unified scheduling/forwarding logic
- mapAntigravityModel: fix edge case where wildcard target equals request model
- Update tests for new behavior and add custom model_mapping test cases
2026-02-07 14:32:08 +08:00
erio
edb0937024 fix: restore non-failover error passthrough from 7b156489 2026-02-07 14:24:55 +08:00
erio
43a4840daf fix: restore error passthrough service improvements from 7b156489 2026-02-07 14:16:19 +08:00
erio
5e98445b22 feat(antigravity): comprehensive enhancements - model mapping, rate limiting, scheduling & ops
Key changes:
- Upgrade model mapping: Opus 4.5 → Opus 4.6-thinking with precise matching
- Unified rate limiting: scope-level → model-level with Redis snapshot sync
- Load-balanced scheduling by call count with smart retry mechanism
- Force cache billing support
- Model identity injection in prompts with leak prevention
- Thinking mode auto-handling (max_tokens/budget_tokens fix)
- Frontend: whitelist mode toggle, model mapping validation, status indicators
- Gemini session fallback with Redis Trie O(L) matching
- Ops: enhanced concurrency monitoring, account availability, retry logic
- Migration scripts: 049-051 for model mapping unification
2026-02-07 12:31:10 +08:00
Wesley Liddick
20283bb55b Merge pull request #507 from touwaeriol/pr/fix-429-fallback-default
fix(antigravity): reduce 429 fallback cooldown from 5min to 30s
2026-02-07 12:19:14 +08:00
erio
8917afab2a fix(antigravity): reduce 429 fallback cooldown from 5min to 30s
The default fallback cooldown when rate limit reset time cannot be
parsed was 5 minutes, which is too aggressive and causes accounts
to be unnecessarily locked out. Reduce to 30 seconds for faster
recovery. Config override still works (unit remains minutes).
2026-02-07 11:54:00 +08:00
erio
49233ec26a fix(antigravity): auto-fix max_tokens <= budget_tokens causing 400 error
When extended thinking is enabled, Claude API requires max_tokens >
thinking.budget_tokens. If misconfigured, this auto-adjusts max_tokens
to budget_tokens + 1000 instead of returning a 400 error.

- Add ensureMaxTokensGreaterThanBudget helper function
- Extract Gemini25FlashThinkingBudgetLimit constant (24576)
- Log adjustment for debugging
2026-02-07 11:49:03 +08:00
shaw
39a5b17d31 fix: 账号测试根据类型使用不同的 beta header
- OAuth 账号:使用完整的 DefaultBetaHeader 和 Claude Code 客户端 headers
- API Key 账号:使用 APIKeyBetaHeader(不含 oauth beta)
2026-02-07 11:33:06 +08:00
yangjianbo
782a54a8a1 chore(version): 更新版本号至 0.1.70.1 2026-02-07 11:17:46 +08:00
shaw
5299f3dcf6 fix: ix: antigravity 添加 aude-opus-4-6-thinking 模型支持 2026-02-07 10:38:10 +08:00
shaw
7b1564898b fix: make error passthrough effective for non-failover upstream errors 2026-02-07 10:25:56 +08:00
yangjianbo
4e01126ff2 test(codex): 清理无用的 opencode 缓存测试
移除不再需要的 setupCodexCache 调用与辅助函数(已不再回源/读写缓存)
2026-02-07 09:53:01 +08:00
yangjianbo
55b56328da feat(codex): 移除 opencode 指令回源与缓存
- 不再从 GitHub 拉取 opencode codex_header.txt\n- 删除 ~/.opencode 缓存与异步刷新逻辑\n- 所有 instructions 统一使用内置 codex_cli_instructions.md
2026-02-07 09:28:32 +08:00
yangjianbo
ce764bf2d9 feat(gateway): 支持强制 Codex CLI 模式并伪装 UA
- Codex CLI 请求仅使用内置 instructions,不再读取 opencode 缓存/回源\n- 新增 gateway.force_codex_cli(环境变量 GATEWAY_FORCE_CODEX_CLI)\n- ForceCodexCLI=true 时转发上游强制 User-Agent=codex_cli_rs/0.0.0\n- 更新 deploy 示例配置
2026-02-07 09:21:15 +08:00
yangjianbo
d71537d431 perf(service): SSE Scanner buffer 改用 sync.Pool 复用,减少高并发 GC 压力
将流式响应中 bufio.Scanner 的 64KB buffer 从每次 make 分配改为
sync.Pool 复用,统一切片表达式为 [:0]、变量命名为 scanBuf,
并补充对应的单元测试。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:55:12 +08:00
yangjianbo
ae1ba45350 perf(service): jitterTTL 改用 rand/v2 并移除锁 2026-02-06 21:22:38 +08:00
yangjianbo
c4182f8c33 perf(service): 移除 jitter 随机数全局锁 2026-02-06 21:20:25 +08:00
yangjianbo
8672b2f3ec chore(gateway): 提升 max_idle_conns 并补齐 env 2026-02-06 20:48:48 +08:00
yangjianbo
de753a149e chore(deploy): 补齐连接池默认与 8G 参数 2026-02-06 20:44:08 +08:00
yangjianbo
2d4bbbf49d feat: 优化codex冷启动, 还有连接池数据库配置信息 2026-02-06 20:31:42 +08:00
shaw
9f4c1ef9f9 fix(ops): 添加 token 相关字段白名单避免误脱敏
在敏感字段检测中添加白名单,排除 API 参数和用量统计字段:
- max_tokens, max_completion_tokens, max_output_tokens
- completion_tokens, prompt_tokens, total_tokens
- input_tokens, output_tokens
- cache_creation_input_tokens, cache_read_input_tokens

这些字段名虽然包含 "token" 但只是数值参数,不应被脱敏处理。
2026-02-06 19:47:14 +08:00
Wesley Liddick
a381910e86 Merge pull request #489 from LLLLLLiulei/feat/import-export-bundle
feat: implement account & proxy import/export with migration-ready JSON bundles
2026-02-06 16:29:52 +08:00
shaw
d182ef0391 fix(gateway): 移除 PR #316 引入的工具名转换逻辑
移除响应阶段的工具名/schema/description 转换逻辑,修复第三方工具调用时
工具名被错误转换的问题(如 Task → task)。

移除内容:
- 工具名相关正则变量(toolPrefixRe, toolNameBoundaryRe 等)
- openCodeToolOverrides 和 claudeToolNameOverrides 映射表
- 工具名转换函数(normalizeToolNameForClaude, normalizeToolNameForOpenCode 等)
- 响应体工具名替换函数(replaceToolNamesInText, replaceToolNamesInResponseBody 等)
- 参数名转换函数(normalizeParamNameForOpenCode, rewriteParamKeysInValue)
- 工具描述清理函数(sanitizeToolDescription)
- 输入 schema 转换函数(normalizeToolInputSchema)
- 模型 ID 正则替换函数(replaceModelIDInText)

保留内容:
- 系统提示词清理(sanitizeSystemText)
- Claude Code 指纹 headers 处理
- 模型 ID 映射(通过 JSON 对象操作)
2026-02-06 16:09:58 +08:00
LLLLLLiulei
7319122e92 merge upstream/main 2026-02-06 11:33:45 +08:00
yangjianbo
792bef615c Merge branch 'main' into test 2026-02-06 09:59:15 +08:00
yangjianbo
ee01f80dc1 test(backend): 修复 usage 类型断言未检查 2026-02-06 09:54:29 +08:00
yangjianbo
98671a73f4 Merge branch 'main' of https://github.com/mt21625457/aicodex2api
# Conflicts:
#	backend/internal/service/gateway_cached_tokens_test.go
2026-02-06 09:35:46 +08:00
yangjianbo
f33a950103 fix(兼容): 将 Kimi cached_tokens 映射到 Claude 标准 cache_read_input_tokens
Kimi 等 Claude 兼容 API 返回缓存信息使用 OpenAI 风格的 cached_tokens 字段,
而非 Claude 标准的 cache_read_input_tokens,导致客户端收不到缓存命中信息且
内部计费缓存折扣为 0。

新增 reconcileCachedTokens 辅助函数,在 cache_read_input_tokens == 0 且
cached_tokens > 0 时自动填充,覆盖流式(message_start/message_delta)和
非流式两种响应路径。对 Claude 原生上游无影响。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 09:27:42 +08:00
程序猿MT
132bf34b69 Merge branch 'Wei-Shaw:main' into main 2026-02-06 08:53:52 +08:00
shaw
01b08e1e43 chore: 前端增加opus4.6模型映射 2026-02-06 08:50:45 +08:00
yangjianbo
000a943cce Merge branch 'main' into test 2026-02-06 08:43:42 +08:00
yangjianbo
c6a456c7c7 fix(兼容): 将 Kimi cached_tokens 映射到 Claude 标准 cache_read_input_tokens
Kimi 等 Claude 兼容 API 返回缓存信息使用 OpenAI 风格的 cached_tokens 字段,
而非 Claude 标准的 cache_read_input_tokens,导致客户端收不到缓存命中信息且
内部计费缓存折扣为 0。

新增 reconcileCachedTokens 辅助函数,在 cache_read_input_tokens == 0 且
cached_tokens > 0 时自动填充,覆盖流式(message_start/message_delta)和
非流式两种响应路径。对 Claude 原生上游无影响。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 08:42:55 +08:00
Wesley Liddick
cc2329d4fd Merge pull request #496 from mt21625457/main
feat(模型): 添加 gpt-5.3 Codex 映射与价格配置
2026-02-06 08:37:24 +08:00
yangjianbo
f82e346f02 Merge branch 'main' into test 2026-02-06 08:12:40 +08:00