win
f25dd04e0b
feat(risk): 风控数据管道与风控中心
...
CI / test (push) Failing after 1m31s
CI / golangci-lint (push) Failing after 3s
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 2s
- DB Migration 081: 新增 account_behavior_hourly / account_risk_scores 表
- 行为采集:Gateway/OpenAI Gateway RecordUsage 注入 fire-and-forget CollectBehaviorAsync
- SQL 打分引擎:CTE 加权特征向量 → risk_score [0-1],UPSERT 保留 idle_override
- RiskSettings:Redis 缓存 → DB fallback → 默认值(observe 模式)
- REST API:/admin/risk/summary|accounts|accounts/:id|settings
- 前端:Pinia store + RiskControlView + 6 子组件(donut/radar/line 纯 SVG 图表)
- 侧边栏新增 Risk Control 入口(ShieldExclamationIcon)
- 反风控优化:移除 Antigravity 后台定时刷新,改为按需刷新避免 idle 封号
2026-03-28 03:07:17 +08:00
win
85ed193ff0
feat(tls): 更新 DoWithTLS 所有调用点至新三模式签名
...
CI / test (push) Failing after 10s
CI / golangci-lint (push) Failing after 6s
Security Scan / backend-security (push) Failing after 8s
Security Scan / frontend-security (push) Failing after 7s
- DoWithTLS 签名变更:(bool/profile) → (TLSMode, profile)
- 所有调用方传入 account.GetTLSMode() 以支持 node/utls/off 三模式
- gateway_service.go、gemini_messages_compat、forward_as_* 全部更新
- claude_usage_service 的 ClaudeUsageFetchOptions 新增 TLSMode 字段
- 新增 decompressResponseBody(gzip/brotli/deflate)到 http_upstream.go
- 新增 antigravity_privacy_service.go(setAntigravityPrivacy)
- admin_service 新增 ForceOpenAIPrivacy/EnsureAntigravityPrivacy/ForceAntigravityPrivacy
- antigravity.Client 新增 SetUserSettings/FetchUserInfo API
2026-03-27 22:29:17 +08:00
shaw
574fa9dfbd
feat(tls-fingerprint): 新增 TLS 指纹 Profile 数据库管理及代码质量优化
...
新增功能:
- 新增 TLS 指纹 Profile CRUD 管理(Ent schema + 迁移 + Admin API + 前端管理界面)
- 支持账号绑定数据库中的自定义 TLS Profile,或随机选择(profile_id=-1)
- HTTPUpstream.DoWithTLS 接口从 bool 改为 *tlsfingerprint.Profile,支持按账号指定 Profile
- AccountUsageService 注入 TLSFingerprintProfileService,统一 usage 场景与网关的 Profile 解析逻辑
代码优化:
- 删除已被 TLSFingerprintProfileService 完全取代的 registry.go 死代码(418 行)
- 提取 3 个 dialer 的重复 TLS 握手逻辑为 performTLSHandshake() 共用函数
- 修复 GetTLSFingerprintProfileID 缺少 json.Number 处理的 bug
- gateway_service.Forward 中 ResolveTLSProfile 从重试循环内重复调用改为预解析局部变量
- 删除冗余的 buildClientHelloSpec() 单行 wrapper 和 int64(e.ID) 无效转换
- tls_fingerprint_profile_cache.go 日志从 log.Printf 改为 slog 结构化日志
- dialer_capture_test.go 添加 //go:build integration 标签,防止 CI 失败
- 去重 TestProfileExpectation 类型至共享 test_types_test.go
- 修复 9 个测试文件缺少 tlsfingerprint import 的编译错误
- 修复 error_policy_integration_test.go 中 handleError 回调签名被错误替换的问题
2026-03-27 22:00:07 +08:00
QTom
c2cf79154a
feat(antigravity): 从 LoadCodeAssist 复用 TierInfo 提取 plan_type
...
复用已有 GetTier() 返回的 tier ID(free-tier / g1-pro-tier /
g1-ultra-tier),通过 TierIDToPlanType 映射为 Free / Pro / Ultra,
在 loadProjectIDWithRetry 中顺带提取并写入 credentials.plan_type;
前端增加 Abnormal 异常套餐红色标记。
Made-with: Cursor
2026-03-27 21:34:01 +08:00
QTom
96b71a1399
fix(ratelimit): OpenAI 401 token_invalidated/token_revoked 及 402 deactivated_workspace 标记账号异常
...
- 401 token_invalidated / token_revoked: OAuth token 被永久作废,跳过临时不可调度逻辑,直接 SetError
- 402 deactivated_workspace: 解析 detail.code 字段,标记工作区已停用
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:33:31 +08:00
QTom
71ade841fb
fix(privacy): 刷新令牌失败时也尝试设置 OpenAI 隐私模式
...
刷新失败不代表 access_token 无效,在后台定时刷新(不可重试错误 +
重试耗尽)和前端批量/单次刷新的失败路径中,均利用可能仍有效的
access_token 调用隐私设置。
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:33:26 +08:00
QTom
dcc341b846
fix(gateway): 修复 OpenAI→Anthropic 转换路径 system prompt 被静默丢弃的 bug
...
injectClaudeCodePrompt 和 systemIncludesClaudeCodePrompt 的 type switch
无法匹配 json.RawMessage 类型(Go typed nil 陷阱),导致 ForwardAsResponses
和 ForwardAsChatCompletions 路径中用户 system prompt 被替换为仅 Claude Code
banner。新增 normalizeSystemParam 将 json.RawMessage 转为标准 Go 类型。
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:33:02 +08:00
win
088a508e60
fix: Gemini CLI 指纹全面修复
...
CI / test (push) Failing after 1m33s
CI / golangci-lint (push) Failing after 6s
Security Scan / backend-security (push) Failing after 5s
Security Scan / frontend-security (push) Failing after 6s
- User-Agent: GeminiCLI/0.1.5 → GeminiCLI/0.33.1/{model} ({platform}; {arch})
格式、版本、大小写全部对齐真实 Gemini CLI 0.33.1
- 新增 x-goog-api-client: gl-node/24.13.1 (匹配 google-auth-library DefaultTransporter)
- ideType: ANTIGRAVITY → IDE_UNSPECIFIED (修复身份泄露,真实 Gemini CLI 用 IDE_UNSPECIFIED)
- Token 交换/刷新: 添加 google-api-nodejs-client UA + x-goog-api-client
- 版本号可通过环境变量 GEMINI_CLI_VERSION 覆盖
2026-03-27 13:07:18 +08:00
win
2279bde564
fix: 心跳接入启动 + 网关错误去重
...
CI / test (push) Failing after 1m32s
CI / golangci-lint (push) Failing after 32s
Security Scan / backend-security (push) Failing after 32s
Security Scan / frontend-security (push) Failing after 1m32s
- AntigravityGatewayService 嵌入心跳,构造时自动启动
- Forward() 方法中注册心跳(首次 API 调用触发,后续更新 token)
- 新建 gateway_errors.go: WriteClaudeErrorResponse/WriteGoogleErrorResponse 共享实现
- antigravity writeGoogleError 去掉手写映射,统一用 googleapi.HTTPStatusToGoogleStatus()
- gemini writeClaudeError/writeGoogleError 委托到共享实现
- 新增 docs/antigravity-fingerprint-diagnostic.md 诊断手册
2026-03-27 12:11:22 +08:00
win
ffe6a5e331
feat: Antigravity 100% 指纹还原 + BoringCrypto TLS
...
CI / test (push) Failing after 4s
CI / golangci-lint (push) Failing after 3s
Security Scan / backend-security (push) Failing after 1m0s
Security Scan / frontend-security (push) Failing after 32s
Antigravity:
- Client ID 保留双 ID 支持(二进制确认两个都存在)
- Daily URL 去掉 .sandbox 后缀(日志确认)
- Redirect URI /callback → /oauth-callback(extension.js 确认)
- User-Agent 动态 OS/arch: antigravity/{ver} {os}/{arch}
- 新增 x-goog-api-client: gl-go/{goVer} gax-go/v2 grpc-go/1.81.0-dev
- googleapis 不再走 Node.js proxy → Go 原生 TLS(匹配真实 BoringCrypto)
- 新增 Go 后端心跳服务(每5分钟 loadCodeAssist + fetchAvailableModels)
- Dockerfile 切换 BoringCrypto 编译(CGO_ENABLED=1 GOEXPERIMENT=boringcrypto)
GeminiCLI:
- User-Agent 动态化: GeminiCLI/0.1.5 ({OS}; {ARCH})
- AI Studio 请求补上 User-Agent
Claude:
- CLI 版本 2.1.84, 包版本 0.74.0, 运行时 v24.3.0
- Token 交换 axios/1.13.6, timeout 15s
- proxy.js 仅服务 api.anthropic.com(Claude 专属)
架构变更:
- Node.js proxy 仅用于 Claude (api.anthropic.com)
- Antigravity (googleapis) 走 Go 原生 HTTP + GOST proxy
- TLS 指纹: Go BoringCrypto ≈ 真实 Antigravity BoringCrypto
2026-03-27 02:24:03 +08:00
win
f5abc62fd3
fix: 三节点部署脚本修复 + sub2api 容器代理透传
...
CI / test (push) Failing after 12s
CI / golangci-lint (push) Failing after 6s
Security Scan / backend-security (push) Failing after 5s
Security Scan / frontend-security (push) Failing after 5s
- GOST 下载 URL 修复:补全版本号 (gost_3.2.6_linux_amd64.tar.gz)
- CN 中转机服务名改为 gost-sub2api-relay,避免与现有 gost-relay 冲突
- CN 中转机监听协议改为 http(兼容 node-tls-proxy 的 HTTP CONNECT)
- 美国落地机服务名改为 gost-sub2api-exit
- sub2api 容器透传 HTTPS_PROXY/HTTP_PROXY 环境变量(解决 OAuth 超时)
- ops_cleanup 日志字段名避免触发 ERROR 误判
- 添加密码重置脚本和 SOCKS5 服务文件
2026-03-26 12:09:05 +08:00
win
e5d78f8e56
refactor: 将自定义代码集中到 antigravity/ 目录和 *_antigravity.go 文件
...
CI / test (push) Failing after 39s
CI / golangci-lint (push) Failing after 3s
Security Scan / backend-security (push) Failing after 4s
Security Scan / frontend-security (push) Failing after 3s
- antigravity/node-tls-proxy/ ← 原 tools/node-tls-proxy
- antigravity/firewall/ ← 原 tools/firewall
- antigravity/maintenance/ ← 原 tools/maintenance
- repository/http_upstream_antigravity.go ← Node.js 代理 3 个方法(原在 http_upstream.go)
- service/identity_service_antigravity.go ← ApplyDefaultFingerprintOverrides + NewIdentityServiceWithSalt
- service/account_antigravity.go ← Gemini TLS 指纹扩展函数
对上游文件 http_upstream.go 的钩子调用精简为 2 处 if 块(共 14 行)
对上游文件 account.go Gemini 分支精简为 1 行函数调用
便于 upstream rebase 时快速识别和保留自定义改动
2026-03-25 11:37:27 +08:00
win
068b0cbc39
revert: 移除 Sora sidecar,还原 sora_sdk_client.go 到原版
2026-03-25 11:37:27 +08:00
win
3c8ffd3efc
fix: 双模型审查 Critical 修复
...
1. Sora session_key 按 accountID 隔离(消除跨账号指纹关联)
2. 有 per-account 代理的 Sora 账号跳过 sidecar(保持代理 IP)
3. 请求体用 base64 编码传输(防止二进制数据损坏)
4. Node.js 代理 Body 用 GetBody 安全复制(修复重试时 Body 枯竭)
2026-03-25 11:37:27 +08:00
win
4a92f1903f
fix: 架构审查修复 3 个 bug
...
1. instanceSalt 空值兼容:salt 为空时保持原始 hash 格式不变
避免升级后所有 user_id hash 突变触发 Anthropic 检测
2. doViaNodeTLSProxy 克隆请求:不修改原始 req 对象
修复重试时 URL 已被改写导致请求失败
3. Sora doSoraBackendJSON 漏改:补上 sidecar 路由
2026-03-25 11:37:27 +08:00
win
4037eebd37
feat: Sora 请求优先走 curl_cffi sidecar(Chrome 指纹绕过 Cloudflare)
2026-03-25 11:37:27 +08:00
win
f5fdd41aea
feat: 实例级隔离 — salt + 指纹版本可配置
...
- 新增 gateway.instance_salt: 不同 sub2api 实例对相同输入产生不同 hash
影响 user_id 重写和 session hash,防止跨实例指纹关联
- 新增 gateway.fingerprint_defaults: CLI 版本号/SDK 版本/OS/Arch 可配置
每个实例可设不同值,与其他 sub2api 部署区分
- constants.go + identity_service.go 支持启动时覆盖默认指纹
- wire_gen.go 启动时读取配置并应用覆盖
2026-03-25 11:37:27 +08:00
win
f68dc13a1a
fix: 更新 Claude CLI 指纹版本 2.1.22→2.1.81, SDK 0.70.0→0.80.0
2026-03-25 11:37:27 +08:00
Wesley Liddick
4b1ffc23f5
Merge pull request #1240 from Zqysl/qingyu/fix-openai-passthrough-429-rate-limits
...
fix(openai): persist passthrough 429 rate limits
2026-03-24 19:02:40 +08:00
Wesley Liddick
c7137dffa8
Merge pull request #1218 from LvyuanW/openai-runtime-recheck
...
fix(openai): prevent rescheduling rate-limited accounts
2026-03-24 15:21:18 +08:00
Wesley Liddick
8e834fd9f5
Merge pull request #1204 from Eilen6316/fix/smtp-config-stability-and-refresh-test
...
fix(settings): prevent SMTP config overwrite and stabilize SMTP test after refresh
2026-03-24 15:19:24 +08:00
Wesley Liddick
02046744eb
Merge pull request #1212 from alfadb/fix/filter-empty-text-blocks-nested
...
fix(gateway): 修复 tool_result 嵌套内容中空 text block 导致上游 400 错误
2026-03-24 15:19:01 +08:00
Wesley Liddick
68d7ec9155
Merge pull request #1220 from weak-fox/feat/account-privacy-mode-filter
...
feat: 管理员账号列表支持按 Privacy 状态筛选
2026-03-24 15:18:30 +08:00
Wesley Liddick
5f41b74707
Merge pull request #1242 from Ethan0x0000/feat/anthropic-openai-endpoint-compat
...
支持 Anthropic Responses / Chat Completions 兼容端点并完善会话一致性与错误可观测性
2026-03-24 15:16:26 +08:00
QTom
91b1d812ce
feat(openai): Mobile RT 补全 plan_type、精确匹配账号、刷新时自动设置隐私
...
1. accounts/check 补全 plan_type:当 id_token 缺少 plan_type(如 Mobile RT),
自动调用 accounts/check 端点获取订阅类型
2. orgID 精确匹配账号:从 JWT 提取 poid 匹配正确账号,避免 Go map
遍历顺序随机导致 plan_type 不稳定
3. RT 刷新时设置隐私:调用 disableOpenAITraining 关闭训练数据共享,
结果存入 extra.privacy_mode,后续跳过重复设置
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:50:03 +08:00
shaw
995bee143a
feat: 支持自定义端点配置与展示
2026-03-24 10:22:08 +08:00
Ethan0x0000
2f8e10db46
fix(service): preserve anthropic usage fields across compat endpoints
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-24 09:32:34 +08:00
Ethan0x0000
5418e15e63
fix(service): normalize user agent for gemini session reuse
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-24 09:32:01 +08:00
Ethan0x0000
bcf84cc153
fix(service): normalize user agent for sticky session hashes
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-24 09:31:32 +08:00
qingyuzhang
ce8520c9e6
fix(openai): persist passthrough 429 rate limits
2026-03-24 01:48:25 +08:00
Ethan0x0000
4321adab71
feat(service): add ForwardAsResponses/ForwardAsChatCompletions on GatewayService
...
New forwarding methods on GatewayService for Anthropic platform groups:
- ForwardAsResponses: accept Responses body → convert to Anthropic →
forward to upstream → convert response back to Responses format.
Supports both streaming (SSE event-by-event conversion) and buffered
(accumulate then convert) response modes.
- ForwardAsChatCompletions: chain CC→Responses→Anthropic for request,
Anthropic→Responses→CC for response. Streaming uses dual state machine
chain with [DONE] marker.
Both methods reuse existing GatewayService infrastructure:
buildUpstreamRequest, Claude Code mimicry, cache control enforcement,
model mapping, and return UpstreamFailoverError for handler-level retry.
2026-03-23 16:24:22 +08:00
weak-fox
4838ab74b3
feat(admin): add account privacy mode filter
2026-03-23 10:16:52 +08:00
Wang Lvyuan
fef9259aaa
fix(openai): recheck runtime state from db before final account selection
2026-03-23 03:50:03 +08:00
Wang Lvyuan
ad7c10727a
fix(account): preserve runtime state during credentials-only updates
2026-03-23 03:49:28 +08:00
alfadb
70a9d0d3a2
fix(gateway): strip empty text blocks from nested tool_result content
...
Empty text blocks inside tool_result.content were not being filtered,
causing upstream 400 errors: 'text content blocks must be non-empty'.
Changes:
- Add stripEmptyTextBlocksFromSlice helper for recursive content filtering
- FilterThinkingBlocksForRetry now recurses into tool_result nested content
- Add StripEmptyTextBlocks pre-filter on initial request path to avoid
unnecessary 400+retry round-trips
- Add unit tests for nested empty text block scenarios
2026-03-22 17:26:44 +08:00
Ethan0x0000
7cd3824863
test(ops): add tests for setOpsEndpointContext and safeUpstreamURL
2026-03-21 23:49:50 +08:00
Ethan0x0000
db9021f9c1
feat(ops): propagate endpoint/request-type context in handlers; add UpstreamURL to upstream error events
2026-03-21 23:47:39 +08:00
Eilen6316
1fb29d59b7
fix(settings): prevent SMTP config overwrite and stabilize test after refresh
2026-03-21 23:36:30 +08:00
Ethan0x0000
8c4a217f03
feat(ops): add endpoint/model/request_type fields to error log structs + safeUpstreamURL
2026-03-21 23:30:13 +08:00
Wesley Liddick
186e36752d
Merge pull request #1194 from Ethan0x0000/feat/requested-upstream-model-semantics
...
feat(usage): 统一使用记录中的请求模型与上游模型语义
2026-03-21 14:02:10 +08:00
Wesley Liddick
421728a985
Merge pull request #1193 from xilu0/worktree-fix-thinking-block-log-level
...
fix: correct log levels for thinking block signature retry flow
2026-03-21 13:57:30 +08:00
Dave King
c64ed46d05
fix: correct log levels for thinking block signature retry flow
...
LegacyPrintf uses inferStdLogLevel() to infer log level from message
text. Any message containing the word "error" is classified as ERROR
level, causing the entire signature-retry recovery flow (which succeeds)
to produce spurious ERROR log entries.
Changes:
- Remove noisy [SignatureCheck] debug logs inside isThinkingBlockSignatureError
that were logging every detected signature check as ERROR
- Change retry-start log to WARN level via [warn] prefix
- Change retry-success log to INFO level by removing "error" from message
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 00:38:07 +00:00
Ethan0x0000
2c667a159c
fix(provider): retain upstream model for gemini compat and ws
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-21 01:24:59 +08:00
Ethan0x0000
bac408044f
fix(provider): preserve requested model in antigravity and sora
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-21 01:24:30 +08:00
Ethan0x0000
4edcfe1f7c
fix(usage): preserve requested model in gateway billing paths
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-21 01:23:54 +08:00
Ethan0x0000
7d312822c1
feat(usage): add requested model usage metadata helpers
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-21 01:22:16 +08:00
QTom
5c39e6f2fb
fix(ops_alert): wg.Add 竞态修复 + leader lock release context 泄漏
...
1. Start() 中 wg.Add(1) 从 run() goroutine 内部移到 go s.run() 之前,
防止 Stop().wg.Wait() 在 Add 之前返回导致孤儿 goroutine。
2. tryAcquireLeaderLock 返回的 release 闭包改用独立的
context.Background()+5s 超时,避免捕获的 evaluateOnce ctx
在 defer 执行时已过期导致锁释放失败(最长阻塞 90s TTL)。
2026-03-20 18:22:00 +08:00
Wesley Liddick
a225a241d7
Merge pull request #1162 from remxcode/main
...
feat(openai): 增加 gpt-5.4-mini/nano 模型支持与定价配置
2026-03-20 13:57:47 +08:00
Wesley Liddick
553a486d17
Merge pull request #1171 from wucm667/fix/quota-display-stale-after-reset
...
fix: quota display shows stale cumulative usage after daily/weekly reset
2026-03-20 13:54:18 +08:00
Jiahao Luo
4617ef2bb8
Fix OpenAI default model forwarding
2026-03-20 13:36:54 +08:00