Wesley Liddick
16f150caae
Merge pull request #459 from IanShaw027/fix/gemini-error
...
fix(gemini): 为 Gemini 工具调用添加 thoughtSignature 避免 INVALID_ARGUMENT 错误
2026-02-03 14:48:50 +08:00
Wesley Liddick
7229b41fc7
Merge pull request #420 from shuike/feat-invitation-code
...
feat: 增加邀请码注册功能
2026-02-03 14:44:15 +08:00
Wesley Liddick
a09478f374
Merge pull request #316 from cyhhao/fix/claude-oauth-compat
...
fix(网关): 完善 Claude OAuth/Claude Code 兼容
2026-02-03 14:26:19 +08:00
shuike
6c86501d11
feat: 增加邀请码注册功能
2026-02-03 13:38:44 +08:00
Wesley Liddick
2f92b06869
Merge pull request #457 from touwaeriol/pr/group-copy-accounts
...
feat(groups): 添加从其他分组复制账号功能
2026-02-03 08:45:13 +08:00
ianshaw
03e94f9f53
fix(gemini): 为 Gemini 工具调用添加 thoughtSignature 避免 INVALID_ARGUMENT 错误
2026-02-03 06:01:29 +08:00
liuxiongfeng
ce1d2904c7
test: 为测试 stub 添加缺失的 GroupRepository 接口方法
...
新增 BindAccountsToGroup 和 GetAccountIDsByGroupIDs 方法的 stub 实现,
确保测试文件中的 mock 类型满足 GroupRepository 接口要求。
2026-02-02 22:06:37 +08:00
liuxiongfeng
e1a4a7b8c0
feat(groups): 添加从其他分组复制账号功能
...
- 创建分组时可选择从已有分组复制账号
- 编辑分组时支持同步账号(全量替换操作)
- 仅允许选择相同平台的源分组
- 添加完整的数据校验:去重、自引用检查、平台一致性检查
- 前端支持多选源分组,带提示说明操作行为
2026-02-02 21:47:47 +08:00
liuxiongfeng
b381e8ee73
refactor(billing): 简化 CalculateCostWithLongContext 逻辑
...
将 token 直接拆分为范围内和范围外两部分,分别调用 CalculateCost:
- 范围内:正常计费 (rateMultiplier)
- 范围外:双倍计费 (rateMultiplier × extraMultiplier)
代码更直观,便于理解和维护
2026-02-02 21:47:02 +08:00
liuxiongfeng
45e1429ae8
feat(billing): 添加 Gemini 200K 长上下文双倍计费功能
...
- 新增 CalculateCostWithLongContext 方法支持阈值双倍计费
- 新增 RecordUsageWithLongContext 方法专用于 Gemini 计费
- Gemini 超过 200K token 的部分按 2 倍费率计算
- 其他平台(Claude/OpenAI)完全不受影响
2026-02-02 21:47:02 +08:00
Wesley Liddick
325ed747d8
Merge pull request #455 from ZeroClover/feat/ops-ignore-invalid-api-key-errors
...
feat(ops): 支持过滤无效 API Key 错误,不写入错误日志
2026-02-02 20:28:00 +08:00
Zero Clover
ad1cdba338
feat(ops): 支持过滤无效 API Key 错误,不写入错误日志
...
新增 IgnoreInvalidApiKeyErrors 开关,启用后 INVALID_API_KEY 和
API_KEY_REQUIRED 错误将被完全跳过,不写入 Ops 错误日志。
这些错误由用户错误配置导致,与服务质量无关。
2026-02-02 20:16:17 +08:00
shaw
79fa18132b
fix(gateway): 修复 OAuth token 刷新后调度器缓存不一致问题
...
Token 刷新成功后,调度器缓存中的 Account 对象仍包含旧的 credentials,
导致在 Outbox 异步更新之前(最多 1 秒窗口)请求使用过期 token,
返回 403 错误(OAuth token has been revoked)。
修复方案:在 token 刷新成功后同步更新调度器缓存,确保调度获取的
Account 对象立即包含最新的 access_token 和 _token_version。
此修复覆盖所有 OAuth 平台:OpenAI、Claude、Gemini、Antigravity。
2026-02-02 20:05:37 +08:00
Wesley Liddick
cc7e67b01a
Merge pull request #445 from touwaeriol/fix/gemini-cache-token-billing
...
fix(billing): 修复 Gemini 接口缓存 token 统计
2026-02-02 15:22:46 +08:00
liuxiongfeng
4bfeeecb05
fix(billing): 修复 Gemini 接口缓存 token 统计
...
extractGeminiUsage 函数未提取 cachedContentTokenCount,
导致计费时缓存读取 token 始终为 0。
修复:
- 提取 usageMetadata.cachedContentTokenCount
- 设置 CacheReadInputTokens 字段
- InputTokens 减去缓存 token(与 response_transformer 逻辑一致)
2026-02-02 14:01:17 +08:00
liuxiongfeng
bbc7b4aeed
feat(gateway): Gemini API Key 账户跳过模型映射检查,直接透传
...
Gemini API Key 账户通常代理上游服务,模型支持由上游判断,
本地不需要预先配置模型映射。
2026-02-02 13:40:29 +08:00
cyhhao
adb77af1d9
fix: satisfy golangci-lint (nil checks, remove unused helpers)
2026-01-31 02:07:57 +08:00
cyhhao
3a34746668
refactor: stop rewriting tool descriptions; keep only system sentence rewrite
2026-01-31 02:01:51 +08:00
cyhhao
fe17058700
refactor: limit OpenCode keyword replacement to tool descriptions
2026-01-31 01:40:38 +08:00
ducky
9bee0a2071
chore: gofmt for golangci-lint
2026-01-30 17:28:53 +08:00
ducky
b7f69844e1
feat(announcements): add admin/user announcement system
...
Implements announcements end-to-end (admin CRUD + read status, user list + mark read) with OR-of-AND targeting. Also breaks the ent<->service import cycle by moving schema-facing constants/targeting into a new domain package.
2026-01-30 16:45:04 +08:00
cyhhao
fa454b1b99
fix: align Claude Code system banner with opencode latest
2026-01-29 15:37:07 +08:00
cyhhao
8375094c69
fix(oauth): match Claude CLI accept header and beta set
2026-01-29 15:31:29 +08:00
cyhhao
91079d3f15
chore(debug): emit Claude mimic fingerprint on credential-scope error
2026-01-29 15:17:46 +08:00
cyhhao
63412a9fcc
chore(debug): log Claude mimic fingerprint
2026-01-29 03:13:14 +08:00
cyhhao
d98648f03b
fix: rewrite OpenCode identity sentence to Claude Code
2026-01-29 03:03:40 +08:00
cyhhao
c37fe91672
fix(oauth): update Claude CLI fingerprint headers
2026-01-29 02:52:26 +08:00
cyhhao
4d40fb6b60
fix(oauth): merge anthropic-beta and force Claude Code headers in mimic mode
2026-01-29 02:36:28 +08:00
cyhhao
be3b788b8f
fix: also prefix next system block with Claude Code banner
2026-01-29 02:03:54 +08:00
cyhhao
723e54013a
fix(oauth): mimic Claude Code metadata and beta headers
2026-01-29 01:49:51 +08:00
cyhhao
4d566f68b6
chore: gofmt
2026-01-29 01:34:58 +08:00
cyhhao
31f817d189
fix: add newline separation for Claude Code system prompt
2026-01-29 01:28:43 +08:00
cyhhao
59231668c5
Merge branch 'main' of github.com:Wei-Shaw/sub2api
2026-01-29 01:16:36 +08:00
shaw
cadca752c4
修复SSE流式响应中usage数据被覆盖的问题
2026-01-28 18:36:21 +08:00
Wesley Liddick
edf215e6fd
Merge pull request #409 from DuckyProject/feat/purchase-subscription-iframe
...
feat(purchase): 增加购买订阅 iframe 页面与配置
2026-01-28 17:28:47 +08:00
ducky
04a509d45e
feat(purchase): 增加购买订阅 iframe 页面与配置
...
- 新增 /purchase 页面(iframe + 新窗口兜底)
- 管理员系统设置可配置开关与URL
- 非 simple mode 才在侧边栏展示入口
2026-01-28 13:54:32 +08:00
Wesley Liddick
269a659200
Merge pull request #406 from geminiwen/main
...
fix(openai-oauth): 改进错误处理和代理支持
2026-01-28 13:53:44 +08:00
Wesley Liddick
2c31bf46b5
Merge pull request #401 from slovx2/heihuzi_main
...
feat(gemini): 为 Gemini 原生平台添加图片计费支持
2026-01-28 13:51:14 +08:00
Gemini Wen
ab092e88a8
fix(openai-oauth): 改进错误处理和代理支持
...
- 使用 ApplicationError 返回详细错误信息到前端
- 添加 User-Agent: codex-cli/0.91.0
- 移除 ForceHTTP2 以兼容 HTTP 代理
- 修复代理获取失败时静默忽略的问题
- 500 错误时记录完整错误日志
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-01-27 19:13:01 +08:00
cyhhao
ffe43f6098
Merge branch 'main' of github.com:Wei-Shaw/sub2api
2026-01-27 11:09:11 +08:00
shaw
56a1e29cdd
fix(gateway): 修复 SSE 流式响应 usage 统计错误
...
message_delta 应完全覆盖 message_start 的 usage 数据,
而非仅在值为 0 时才更新。
2026-01-27 09:16:34 +08:00
song
0059a232a6
feat(gemini): 为 Gemini 原生平台添加图片计费支持
...
对齐 Antigravity 平台的图片计费逻辑:
- 添加 extractImageSize() 方法提取图片尺寸
- Forward() 和 ForwardNative() 返回 ImageCount/ImageSize
- 支持分组自定义图片价格和倍率
2026-01-26 20:51:40 +08:00
cyhhao
a161fcc89b
Merge branch 'main' of github.com:Wei-Shaw/sub2api
2026-01-26 10:44:38 +08:00
Wesley Liddick
e32c5f534f
Merge pull request #386 from IanShaw027/fix/openai-usage-limit-reset-time
...
fix(ratelimit): 修复 OpenAI usage_limit_reached 错误的重置时间解析
2026-01-26 10:22:42 +08:00
ianshaw
a55cfebd09
fix(ratelimit): 修复 OpenAI usage_limit_reached 错误的重置时间解析
...
- 问题:OpenAI 的 usage_limit_reached 错误(需 37 小时重置)被错误地设置为 5 分钟
- 原因:handle429 只检查 Anthropic 响应头,没有解析 OpenAI 响应体中的 resets_in_seconds
- 修复:新增 parseOpenAIRateLimitResetTime 函数解析 OpenAI 响应体
- 影响:避免调度器不断尝试已达配额上限的账户
2026-01-26 09:57:44 +08:00
Wesley Liddick
34cc02f8c7
Merge pull request #393 from IanShaw027/fix/gemini-thought-signature-preserve
...
fix(gemini): 修复 thoughtSignature 跨账号验证错误
2026-01-26 09:23:46 +08:00
Wesley Liddick
624d9fddb7
Merge pull request #391 from geminiwen/main
...
fix(subscription): 修复订阅调整逻辑,已过期订阅从当前时间计算
2026-01-26 09:23:29 +08:00
Wesley Liddick
47fbe43324
Merge pull request #385 from DDZS987/fix/oauth-token-refresh-missing-project-id-retry
...
fix(oauth): 修复 OAuth 令牌刷新时 missing_project_id 误报问题
2026-01-26 09:22:48 +08:00
shaw
1245f07a2d
feat(auth): 实现 TOTP 双因素认证功能
...
新增功能:
- 支持 Google Authenticator 等应用进行 TOTP 二次验证
- 用户可在个人设置中启用/禁用 2FA
- 登录时支持 TOTP 验证流程
- 管理后台可全局开关 TOTP 功能
安全增强:
- TOTP 密钥使用 AES-256-GCM 加密存储
- 添加 TOTP_ENCRYPTION_KEY 配置项,必须手动配置才能启用功能
- 防止服务重启导致加密密钥变更使用户无法登录
- 验证失败次数限制,防止暴力破解
配置说明:
- Docker 部署:在 .env 中设置 TOTP_ENCRYPTION_KEY
- 非 Docker 部署:在 config.yaml 中设置 totp.encryption_key
- 生成密钥命令:openssl rand -hex 32
2026-01-26 09:19:53 +08:00
ianshaw
839975b0cf
feat(gemini): 支持 Gemini CLI 粘性会话与跨账号 thoughtSignature 清理
...
## 问题背景
1. Gemini CLI 没有明确的会话标识(如 Claude Code 的 metadata.user_id)
2. thoughtSignature 与具体上游账号强绑定,跨账号使用会导致 400 错误
3. 粘性会话切换账号或 cache 丢失时,旧签名会导致请求失败
## 解决方案
### 1. Gemini CLI 会话标识提取
- 从 `x-gemini-api-privileged-user-id` header 和请求体中的 tmp 目录哈希生成会话标识
- 组合策略:SHA256(privileged-user-id + ":" + tmp_dir_hash)
- 正则提取:`/\.gemini/tmp/([A-Fa-f0-9]{64})`
### 2. 跨账号 thoughtSignature 清理
实现三种场景的智能清理:
1. **Cache 命中 + 账号切换**
- 粘性会话绑定的账号与当前选择的账号不同时清理
2. **同一请求内 failover 切换**
- 通过 sessionBoundAccountID 跟踪,检测重试时的账号切换
3. **Gemini CLI + Cache 未命中 + 含签名**
- 预防性清理,避免 cache 丢失后首次转发就 400
- 仅对 Gemini CLI 请求且请求体包含 thoughtSignature 时触发
## 修改内容
### backend/internal/handler/gemini_v1beta_handler.go
- 添加 `extractGeminiCLISessionHash` 函数提取 Gemini CLI 会话标识
- 添加 `isGeminiCLIRequest` 函数识别 Gemini CLI 请求
- 实现账号切换检测与 thoughtSignature 清理逻辑
- 添加 `geminiCLITmpDirRegex` 正则表达式
### backend/internal/service/gateway_service.go
- 添加 `GetCachedSessionAccountID` 方法查询粘性会话绑定的账号 ID
### backend/internal/service/gemini_native_signature_cleaner.go (新增)
- 实现 `CleanGeminiNativeThoughtSignatures` 函数
- 递归清理 JSON 中的所有 thoughtSignature 字段
- 支持任意 JSON 顶层类型(object/array)
### backend/internal/handler/gemini_cli_session_test.go (新增)
- 测试 Gemini CLI 会话哈希提取逻辑
- 测试 tmp 目录正则匹配
- 覆盖有/无 privileged-user-id 的场景
## 影响范围
- 修复 Gemini CLI 多轮对话时账号切换导致的 400 错误
- 提高粘性会话的稳定性和容错能力
- 不影响其他客户端(Claude Code 等)的会话标识生成
## 测试
- 单元测试:go test -tags=unit ./internal/handler -run TestExtractGeminiCLISessionHash
- 单元测试:go test -tags=unit ./internal/handler -run TestGeminiCLITmpDirRegex
- 编译验证:go build ./cmd/server
2026-01-26 04:40:38 +08:00