- 02 Feb, 2026 8 commits
-
-
shaw authored
## 新增功能 - 新增 docker-compose.local.yml:使用本地目录存储数据,便于迁移和备份 - 新增 docker-deploy.sh:一键部署脚本,自动生成安全密钥(JWT_SECRET、TOTP_ENCRYPTION_KEY、POSTGRES_PASSWORD) - 新增 deploy/.gitignore:忽略运行时数据目录 ## 优化改进 - docker-compose.local.yml 包含 PGDATA 环境变量修复,解决 PostgreSQL 18 Alpine 数据丢失问题 - 脚本自动设置 .env 文件权限为 600,增强安全性 - 脚本显示生成的凭证,方便用户记录 ## 文档更新 - 更新 README.md(英文版):新增"快速开始"章节,添加部署版本对比表 - 更新 README_CN.md(中文版):同步英文版更新 - 更新 deploy/README.md:详细说明两种部署方式和迁移方法 ## 使用方式 一键部署: ```bash curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh | bash docker-compose -f docker-compose.local.yml up -d ``` 轻松迁移: ```bash tar czf sub2api-complete.tar.gz deploy/ # 传输到新服务器后直接解压启动即可 ```
-
Wesley Liddick authored
fix(billing): 修复 Gemini 接口缓存 token 统计
-
Wesley Liddick authored
feat(gateway): Gemini API Key 账户跳过模型映射检查,直接透传
-
shaw authored
- 新增 AnnouncementBell 组件,支持 Modal 弹窗和 Markdown 渲染 - 移除 Dashboard 横幅和独立公告页面 - 铃铛位置在 Header 文档按钮左侧,显示未读红点 - 支持点击查看详情、标记已读、全部已读等操作 - 完善国际化,移除所有硬编码中文 - 修复 AnnouncementTargetingEditor watch 循环问题
-
liuxiongfeng authored
extractGeminiUsage 函数未提取 cachedContentTokenCount, 导致计费时缓存读取 token 始终为 0。 修复: - 提取 usageMetadata.cachedContentTokenCount - 设置 CacheReadInputTokens 字段 - InputTokens 减去缓存 token(与 response_transformer 逻辑一致)
-
liuxiongfeng authored
Gemini API Key 账户通常代理上游服务,模型支持由上游判断, 本地不需要预先配置模型映射。
-
Wesley Liddick authored
feat(announcements): admin/user announcement system
-
Wesley Liddick authored
feat: add support for using TLS to connect to Redis
-
- 31 Jan, 2026 1 commit
-
-
iBenzene authored
-
- 30 Jan, 2026 7 commits
-
-
iBenzene authored
-
ducky authored
-
ducky authored
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.
-
Wesley Liddick authored
chore: upgrade Antigravity User-Agent to 1.15.8
-
shaw authored
-
shaw authored
修复GO-2026-4341和GO-2026-4340两个标准库漏洞
-
liuxiongfeng authored
-
- 28 Jan, 2026 6 commits
-
-
shaw authored
-
Wesley Liddick authored
feat(purchase): 增加购买订阅 iframe 页面与配置
-
shaw authored
当新分组创建后立即绑定账号时,调度器会错误地将空快照视为有效缓存命中, 导致返回没有可调度的账号。现在空快照会触发数据库回退查询。
-
ducky authored
- 新增 /purchase 页面(iframe + 新窗口兜底) - 管理员系统设置可配置开关与URL - 非 simple mode 才在侧边栏展示入口
-
Wesley Liddick authored
fix(openai-oauth): 改进错误处理和代理支持
-
Wesley Liddick authored
feat(gemini): 为 Gemini 原生平台添加图片计费支持
-
- 27 Jan, 2026 4 commits
-
-
Gemini Wen authored
Prevents panic when ErrorFrom is called in test contexts where gin.CreateTestContext doesn't set up an HTTP request. Co-Authored-By:Claude Opus 4.5 <noreply@anthropic.com>
-
Gemini Wen authored
- Update VERSION from 0.1.46 to 0.1.61 - Remove ForceHTTP2 tests for OpenAI OAuth client (ForceHTTP2 was removed) - Update createOpenAIReqClient test to use new single-arg signature Co-Authored-By:Claude Opus 4.5 <noreply@anthropic.com>
-
Gemini Wen authored
- 使用 ApplicationError 返回详细错误信息到前端 - 添加 User-Agent: codex-cli/0.91.0 - 移除 ForceHTTP2 以兼容 HTTP 代理 - 修复代理获取失败时静默忽略的问题 - 500 错误时记录完整错误日志 Co-Authored-By:Claude Opus 4.5 <noreply@anthropic.com>
-
shaw authored
message_delta 应完全覆盖 message_start 的 usage 数据, 而非仅在值为 0 时才更新。
-
- 26 Jan, 2026 10 commits
-
-
song authored
对齐 Antigravity 平台的图片计费逻辑: - 添加 extractImageSize() 方法提取图片尺寸 - Forward() 和 ForwardNative() 返回 ImageCount/ImageSize - 支持分组自定义图片价格和倍率
-
shaw authored
修复发布通知发送失败的问题,原因是 tag message 中包含未闭合的 Markdown 格式标记(如 user_id 中的 _ 被解析为斜体开始)导致 Telegram API 返回解析错误。 添加 sed 命令转义 _、*、` 和 [ 字符,避免被 Telegram Markdown 解析器错误处理。
-
Wesley Liddick authored
fix(ratelimit): 修复 OpenAI usage_limit_reached 错误的重置时间解析
-
shaw authored
修复 API Key 账号 base_url 末尾带斜杠时导致的双斜杠问题
-
shaw authored
-
ianshaw authored
- 问题:OpenAI 的 usage_limit_reached 错误(需 37 小时重置)被错误地设置为 5 分钟 - 原因:handle429 只检查 Anthropic 响应头,没有解析 OpenAI 响应体中的 resets_in_seconds - 修复:新增 parseOpenAIRateLimitResetTime 函数解析 OpenAI 响应体 - 影响:避免调度器不断尝试已达配额上限的账户
-
Wesley Liddick authored
fix(gemini): 修复 thoughtSignature 跨账号验证错误
-
Wesley Liddick authored
fix(subscription): 修复订阅调整逻辑,已过期订阅从当前时间计算
-
Wesley Liddick authored
fix(oauth): 修复 OAuth 令牌刷新时 missing_project_id 误报问题
-
shaw authored
新增功能: - 支持 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
-
- 25 Jan, 2026 4 commits
-
-
ianshaw authored
## 问题背景 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 -
ianshaw authored
## 问题描述 在使用 Gemini 模型(gemini-3-flash-preview)时,出现 400 错误: "Unable to submit request because Thought signature is not valid" ## 根本原因 在 `request_transformer.go` 的 `buildParts()` 函数中: - 对于 `tool_use` 和 `thinking` 块,当 `allowDummyThought=true`(Gemini 模型)时 - 代码会无条件将客户端传入的真实 `thoughtSignature` 覆盖成 dummy 值 - 导致 Gemini API 验证签名失败(签名与上下文不匹配) ## 修复方案 修改 signature 处理逻辑: 1. **优先透传真实 signature**:如果客户端提供了有效的 signature,保留它 2. **缺失时才使用 dummy**:只有在 signature 缺失且是 Gemini 模型时,才使用 dummy signature 3. **Claude 模型特殊处理**:将 dummy signature 视为缺失,避免透传到需要真实签名的链路 ## 修改内容 ### request_transformer.go - `thinking` 块(第 367-386 行):优先透传真实 signature - `tool_use` 块(第 411-418 行):优先透传真实 signature ### request_transformer_test.go - 修改测试用例名称,反映新的行为 - 新增测试用例验证"缺失时才使用 dummy"的逻辑 ## 影响范围 - 修复 Gemini 模型在多轮对话中使用 tool_use 时的签名验证错误 - 不影响 Claude 模型的现有行为 - 提高跨账号切换时的稳定性 相关问题:#[issue_number]
-
Gemini Wen authored
- 已过期订阅延长时,从当前时间开始增加天数 - 已过期订阅不允许负向调整(缩短) - 未过期订阅保持原逻辑,从原过期时间增减 Co-Authored-By:Claude Sonnet 4.5 <noreply@anthropic.com>
-
shaw authored
- 解析 x-codex-* 响应头获取正确的重置时间 - 7d 限制用尽时使用 codex_7d_reset_after_seconds - 提取 Normalize() 方法统一窗口规范化逻辑
-