shaw
60da9ba178
fix(frontend): refine grok icon, palette and i18n
2026-07-01 18:49:33 +08:00
shaw
8c2d9b9a12
chore(openai): remove gpt-5.3-codex from OpenAI default model list
...
移除 OpenAI OAuth 账号默认模型列表中的 gpt-5.3-codex(后端 DefaultModels、前端 openai 白名单及 UseKeyModal 目录),保留 gpt-5.3-codex-spark 与计费/别名/messages-dispatch 相关逻辑不变。
2026-07-01 15:54:34 +08:00
DaydreamCoding and Claude Sonnet 5
bdf7ead157
feat(spark-shadow): OpenAI Spark 链接型影子账号
...
背景:gpt-5.3-codex-spark 使用独立于 codex 全局(5h/7d)的配额窗口(数据源是
/wham/usage 响应体的 codex_bengalfox,而非 codex 全局用的 x-codex-* 响应头),且
只能挂在已完成 OAuth 授权的 OpenAI 账号下复用其登录态,不能作为独立账号单独接入。
为此新增“链接型影子账号”(spark shadow account):影子账号本身不持有任何凭据,
通过 parent_account_id 指向母账号,凭据/token/代理透传自母账号并共享母账号的刷新
周期,仅在配额维度(quota_dimension=spark)和用量窗口上与母账号完全独立调度、互不
连坐。
实现:
- 数据模型:migration 154(+154a)给 accounts 表加 parent_account_id /
quota_dimension 列 + 4 条约束(维度合法 / parent⟺非 global 维度一致 / 禁自指 /
FK)+ 2 个 CONCURRENTLY 索引(母账号索引 + 每母账号至多一个影子的唯一索引)。
- 创建:POST /api/v1/admin/accounts/:id/shadow(CreateShadow)—— 一母一影(唯一
索引兜底并发竞态),继承母账号 proxy/分组/并发/优先级(显式传参可覆盖),默认
model_mapping 恒等映射到 spark(拒绝非 spark 模型),母账号必须是真实的 OpenAI
OAuth 账号(非影子)。
- 凭据透传:resolveCredentialAccount 把影子解析回母账号,GetAccessToken / 请求头
/ WS 三条路径统一走此函数;影子自身 Credentials 恒为空(仅允许写 model_mapping),
凭据写入的汇聚点 persistAccountCredentials 对影子早返 no-op,防止误写。
- 调度:parentHealthyForShadow 只看母账号是否仍是 OpenAI OAuth + 凭据/传输是否
可用(active、token 未过期、未处于 401/刷新失败/传输故障导致的临时不可调度冷却),
刻意不看母账号的 global 限流窗口——两条 429 道互不连坐。
- 用量:影子的 codex_5h/7d 走 OpenAIQuotaService.QueryUsage(/wham/usage 的
codex_bengalfox),与母账号走的 WSv2 探测(/responses 头)完全独立的数据源、
刷新节流与 staleness 判定。
- 备份:ExportData 显式排除影子账号(影子不持凭据,通用凭据型导入强制
credentials 非空、无法表达父子链接),按 skipped_shadows 计数提示前端。
- 前端:账号操作菜单新增“创建 Spark 影子”入口,影子行展示回填的母账号信息
(邮箱 / plan / 隐私模式 / 订阅到期 / chatgpt_account_id),批量操作自动跳过
影子账号。
说明:migrations 目录用完整文件名(而非纯数字前缀)标识迁移,故本次新增的
154_account_spark_shadow.sql / 154a_..._notx.sql 与已有的
154_add_ops_system_logs_api_key_id.sql 按序号共存,与目录里 145/151 已有的
先例一致。
测试:新增约 20 个测试文件,覆盖 handler(CreateShadow 校验 / 母账号信息回填)、
repository(影子 round-trip / 一母一影唯一索引 / 迁移 schema)、service(凭据
透传三路径 / 调度母健康门 / 用量窗口来源与刷新节流 / CRS 母账号不变量 / 各类
早返与 fail-closed 场景)及前端组件(账号列表 / 操作菜单 / 用量重置)。
验证(镜像 CI;golangci-lint 首次全量分析耗时过长被跳过,其余全部实测):
- gofmt -l:干净
- go build ./... / go vet ./...:通过
- go test ./... -count=1:全绿(全部包 ok,含 internal/service、
internal/repository、migrations)
- go test -tags integration ./internal/repository/... ./internal/service/...
(真实 Postgres,testcontainers):全绿,含迁移幂等性
(TestMigrationsRunner_IsIdempotent_AndSchemaIsUpToDate)与影子相关全部用例
- pnpm lint:check / pnpm typecheck / pnpm build(真实 vite 构建)/
pnpm vitest run:全绿(124 文件 760 用例)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-07-01 12:21:45 +08:00
Wesley Liddick
5f62625ae6
Merge pull request #3577 from heathermhuang/codex/fix-english-ui-cjk
...
fix: remove Chinese strings from English UI
2026-07-01 11:35:04 +08:00
Heatherm Huang
1158cf31bc
fix: require localized interval validation
2026-06-30 22:31:21 +08:00
Heatherm Huang
41bb15d302
fix: remove remaining English fallbacks
2026-06-30 22:27:37 +08:00
Heatherm Huang
b4f38b092f
fix: preserve zh locale in i18n cleanup
2026-06-30 22:06:27 +08:00
Heatherm Huang
6e54776509
fix: localize English UI strings
2026-06-30 20:05:23 +08:00
PMExtra
cafc95c3e2
feat: align user usage analytics with admin
2026-06-30 15:31:28 +08:00
shaw
345d5c6b56
chore: update sponsors
2026-06-30 14:11:14 +08:00
Wesley Liddick
76e0d90736
Merge pull request #3509 from wucm667/fix/refund-pending-not-success
...
fix(payment): 退款 pending 不再当成最终成功,避免站内账务与网关状态不一致
2026-06-30 13:38:04 +08:00
shaw
bf4f006736
fix: 修复用户列表使用时间排序冲突
2026-06-30 13:36:36 +08:00
wucm667
7316d83027
fix(payment): 区分退款 pending 并收敛匿名查单
2026-06-30 10:00:48 +08:00
Heatherm Huang
4a7148e203
fix: support grok cli compatibility routes
2026-06-29 17:53:19 +08:00
Wesley Liddick
bebafe7697
Merge pull request #3437 from imfangwenjie/fix/api-base-fetch
...
fix(frontend): use configured API base for direct requests
2026-06-29 09:23:13 +08:00
shaw
9a0fbcc87d
chore: update sponsors
2026-06-26 17:32:50 +08:00
DaydreamCoding and Claude Opus 4.8
819fda34d9
feat(codex-detect): codex_cli_only 检测加固 + 引擎指纹统一信号列表 + 账号级 app-server
...
将 codex_cli_only 客户端识别从「单一 strict 开关 + 固定 OR 头集合」重构为
可逐项管理的引擎指纹信号列表,加固整条判定链,并补齐账号级 app-server 控制、
对齐前端设置文案。
判定链(每步可短路):
- 账号未开 codex_cli_only → 不限制;gateway.force_codex_cli → 旁路放行
- 全局黑名单命中(OR 宽 deny)→ 立即拒
- 身份候选:官方 UA(strict,仅前缀)/ 官方 originator(OR)/ 全局白名单(双因子 AND)
/ 全局 app-server 开关 OR 账号 app-server 开关;均不命中 → 拒
- 版本门(仅官方候选):UA 须可解析引擎版本,再校验 [min,max] 区间
- 引擎指纹 AND 硬门:按信号列表逐条勾选 AND、每条行内变体 OR;无 Required 信号 → 放行
引擎指纹信号列表(唯一真源)
- 新增 openai.EngineFingerprintSignal 类型 + EvaluateEngineFingerprint 求值器
(勾选 AND / 行内变体 OR / 无勾选 → 放行)
- CodexRestrictionPolicy 增 EngineFingerprintSignals;信号列表单一决定是否启用指纹门,
不再保留独立「要求引擎指纹」总开关(与「信号全不选」语义重复)
- 新设置键 codex_cli_only_engine_fingerprint_signals(默认只勾 x-codex- 前缀);
旧 body 指纹开关幂等迁移并入信号列表;wire 接线
- 黑/白名单自由条目、命名预设、版本区间 全局设置管线
- gateway 缺 settingService(仅测试/误配可达)时指纹门回退默认种子信号、失败关闭,
不再因零值 policy(nil 信号)失败开放
账号级 Codex app-server(替换已失效的 ClaudeCode 放行机制)
- account.IsCodexCLIOnlyAppServerAllowed() 读 extra.codex_cli_only_allow_app_server,
仅在 codex_cli_only 开启时生效;候选身份门「全局 OR 账号」,与旧系统双层控制对齐
- 移除已无入口的 claude_code 预设机制(allowedClientRegistry / MatchAllowedClients /
账号 GetCodexCLIOnlyAllowedClients / reason);白名单 AllowedClientEntry / IsAllowedClientMatch 保留
门加固(反伪 + 写入校验)
- 官方 UA 访问门改 strict:IsCodexOfficialClientRequestStrict 仅前缀匹配,收窄「浏览器前缀 +
中段 codex token」伪造面(strict 仍保留 Codex 家族前缀与 UA 尾部兜底,故对「任意前缀 +
官方尾部 (name;ver)」仍放行——与 UA 可伪造、真正反伪靠引擎指纹门的设计一致)
- 官方客户端识别扩展:新增 codex-tui/、codex_vscode_copilot/ 前缀 + UA 尾部 (name;ver) 兜底
(恢复 CODEX_INTERNAL_ORIGINATOR_OVERRIDE 的真实 client,如 cccc→codex-tui),originator 改
精确集。该识别经 IsCodexOfficialClientByHeaders 被 passthrough 复用,故透传的官方判定一并
修正(codex-tui 等不再被误改写 UA)——非「行为不变」,属有意修正
- 白名单写入校验 ValidateCodexWhitelistEntriesJSON + AllowedClientEntry.IsWhitelistable:
双因子 AND 条目须可命中(非空 originator + 非空 ua_contains),拒绝写入会静默失效的死规则;
黑名单(OR 宽 deny,允许 originator-only)不受约束
管理端 / 前端
- handler / DTO / settings_view / 契约测试;gateway 接入判定链
- 信号列表编辑器(替换 body 开关)、api 类型、SettingsView;无勾选给常驻警告
- Create/Edit/Bulk 三弹窗「Codex Only」下新增 app-server 开关(OR 合并全局)
- 文案:UA/Originator → User-Agent/Originator;黑/白名单重命名为 User-Agent/Originator 黑/白名单;
「允许 App Server 第三方客户端」→「Codex app-server」+ 简介示例;i18n zh/en 同步
- 移除死代码 HasCodex*Fingerprint helper
测试:引擎指纹求值器 / 账号 app-server(OR 语义)/ detector(含 N1 strict、失败关闭)/
白名单写入校验 / BulkEdit spec 等;后端 build + service/openai/admin 单测全绿,前端 vue-tsc + vitest 全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-26 16:19:41 +08:00
Wesley Liddick
2fc4fef847
Merge pull request #3310 from heathermhuang/codex/grok-subscription-support
...
feat: add grok subscription support
2026-06-26 15:41:52 +08:00
Wesley Liddick
683a8d8096
Merge pull request #3421 from syx0310/fork/openai-codex-pat-auth-upstream
...
feat: add codex personal access token auth
2026-06-26 11:15:38 +08:00
Heatherm Huang
720db8983f
test: harden grok quota readiness
2026-06-26 10:42:21 +08:00
Heatherm Huang
939905b8c7
fix: refine grok quota pause behavior
2026-06-26 10:37:37 +08:00
Heatherm Huang
0d28642181
feat: add grok quota probe parity
2026-06-26 10:37:37 +08:00
Heatherm Huang
f29ccc7dfb
fix: reduce grok oauth account-risk paths
2026-06-26 10:36:09 +08:00
Heatherm Huang
39be1ec97f
feat: add grok subscription support
2026-06-26 10:36:09 +08:00
Wesley Liddick
fd9c945fab
Merge pull request #3470 from wucm667/fix/order-currency-symbol-from-field
...
fix(admin): 订单金额币种符号读取 currency 字段,修复 USD 渠道显示为 ¥
2026-06-26 09:46:02 +08:00
Wesley Liddick
94c059c99e
Merge pull request #3471 from wucm667/fix/antigravity-standard-tier-empty-project-fallback
...
fix(antigravity): standard-tier 账号 project_id 为空时兜底,避免全部请求 500
2026-06-26 09:45:54 +08:00
Wesley Liddick
0bff6f9ac5
Merge pull request #3482 from SMGoro/fix/payment
...
fix(payment): 修复后端返回空supported_types时支付提供商卡片消失的问题
2026-06-26 09:42:33 +08:00
Wesley Liddick
e89f4b43c0
Merge pull request #3433 from feitianbubu/fix/cc-terminal-attribution-header
...
fix(keys): add CLAUDE_CODE_ATTRIBUTION_HEADER=0 to Claude Code terminal templates
2026-06-26 09:38:57 +08:00
imfangwenjie
2a58a57a7c
fix(frontend): use configured API base for direct requests
...
Route direct fetch calls, setup requests, gateway usage checks, and ops WebSocket connections through the configured API base instead of assuming same-origin backend paths.
Also derive OAuth callback suggestions from the configured API base so split frontend/API deployments show usable redirect URLs.
2026-06-26 02:42:44 +08:00
SMGDev
65ad7df4f4
fix(payment): 修复后端返回空supported_types时支付提供商卡片消失的问题
...
统一处理后端返回的null类型supported_types,将其标准化为空数组,避免调用includes()时报错导致卡片无法显示,同时修复多处相关的类型判断逻辑
2026-06-26 00:50:22 +08:00
wucm667
650c50e34b
fix(antigravity): add project fallback for standard tier
2026-06-25 16:29:33 +08:00
wucm667
55242ffac1
fix(admin): 订单金额币种符号读取 currency 字段
2026-06-25 16:23:45 +08:00
shaw
30adee43bc
feat(admin/accounts): confirm before OpenAI weekly limit reset
2026-06-24 21:56:03 +08:00
feitianbubu
28e7adef09
fix(keys): add CLAUDE_CODE_ATTRIBUTION_HEADER=0 to Claude Code terminal templates
2026-06-23 18:27:49 +08:00
syx0310
32df33a1c3
feat: add codex personal access token auth
2026-06-22 16:07:41 +00:00
SavitarC
51d722906c
fix(usage): 显示缓存 Token 明细
2026-06-18 14:34:13 +08:00
Wesley Liddick
2e0ff1cfd5
Merge pull request #3258 from bwliangc/feat/channel-monitor-jitter
...
feat(渠道监控): 检测间隔支持正负随机抖动配置
2026-06-16 16:58:23 +08:00
Wesley Liddick
16765bde69
Merge pull request #3230 from DaydreamCoding/feat/openai-cyber-policy-passthrough
...
feat(openai): cyber_policy 硬阻断全链路透传、审计与计费
2026-06-16 16:55:51 +08:00
shaw
b816949291
feat(openai-quota): query + reset rate-limit credits for OpenAI accounts
...
Adds an admin-side action that mirrors the Codex Desktop "rate-limit reset"
flow against chatgpt.com upstream for OpenAI OAuth accounts.
Backend
- OpenAIQuotaService.QueryUsage / ResetCredit hit /wham/usage and
/wham/rate-limit-reset-credits/consume with the Codex Desktop header set,
reusing OpenAITokenProvider for refreshed tokens and PrivacyClientFactory
for the impersonated Chrome TLS fingerprint.
- Honors the account's configured proxy by reading the eager-loaded
account.Proxy directly (falls back to proxyRepo only when missing).
- GET /api/v1/admin/openai/accounts/:id/quota
POST /api/v1/admin/openai/accounts/:id/reset-quota
- Wire DI for the new service + handler dependency.
Frontend
- OpenAIQuotaResetCell renders a single action row in AccountUsageCell's
OpenAI section: the existing local "查询" (active sampling) is injected
via #pre-actions, alongside a "次数 N" button that doubles as the
upstream query trigger and the available-credit indicator, and a "重置"
button that consumes one credit.
- No duplicate 5h/7d window display; the local UsageProgressBar owns those
bars to avoid confusion.
2026-06-16 16:55:07 +08:00
bwlc and Claude Fable 5
c70c6a2659
feat(渠道监控): 检测间隔支持正负随机抖动配置
...
新增 jitter_seconds 配置:每轮调度在 interval 基础上 ± [0, jitter]
均匀随机偏移触发,避免多个监控以固定节奏同步请求上游。
- ent schema 新增 jitter_seconds 字段(默认 0),附迁移 151
- 校验:jitter >= 0 且 interval - jitter >= 15s(创建/更新均校验)
- runner 由固定 ticker 改为每轮重新随机化的 timer,0 抖动时行为不变
- 前端监控表单新增「随机抖动 (± 秒)」输入框,上限随间隔联动
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-12 22:09:53 +08:00
DaydreamCoding and Claude Opus 4.8
b62b573f7f
feat(openai): cyber_policy 硬阻断全链路透传、审计与计费
...
上游对单次请求下发 error.code=cyber_policy 硬阻断时,网关在所有端点
(/v1/responses、/v1/chat/completions、/v1/messages、WebSocket)及流式/
非流式路径下,将该结果原样透传给客户端,绝不 failover、换号或同步拦截;
命中后异步完成审计与计费:
- 风控中心记录 cyber_policy 留痕并发送通知邮件,落库先于发信,SMTP 阻塞
不影响留痕
- ops 错误请求记录,状态码对齐客户端实际接收(流式 200 / 非流式 400)
- 用量明细标记 request_type=cyber,按上游真实 token 计费,HTTP 与
WebSocket 计费口径统一,零 token 命中不误扣
- 会话级自动屏蔽(管理员开关,默认关):命中的会话在可配 TTL 内本地拦截
不再发往上游,仅屏蔽该会话不影响同 Key 其他会话
- 封号计数排除开关:可选让 cyber 命中不计入自动封号,命中当次不判定且
历史行在违规计数中一并排除
WebSocket 多轮连接下 cyber 标记按 turn 生命周期管理,逐轮独立检测与记录;
透传的错误响应不被兜底逻辑追加内容污染。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-12 01:47:01 +08:00
shaw
0acf00c4a1
Add admin compliance acknowledgement gate
2026-06-10 14:16:51 +08:00
shaw
d662c97302
feat: claude-fable-5
2026-06-10 08:58:06 +08:00
Wesley Liddick
870cefddf5
Merge pull request #3097 from NeckBozia/fix/5h-resets-at-stale
...
fix(usage): sync 5h ResetsAt to SessionWindowEnd and zero expired window
2026-06-08 09:08:23 +08:00
NeckBozia
16bc876935
fix(usage): sync 5h ResetsAt to SessionWindowEnd and zero expired window
...
active poll 拿到新 5h ResetsAt 时只回写了 Extra.session_window_utilization,
没回写 SessionWindowEnd column;estimateSetupTokenUsage 读这个 column 作为 5h
窗口结束时间,导致被动采样模式下 dashboard 显示 utilization > 0 但 reset
时间渲染为「现在」。
- syncActiveToPassive 增加 UpdateSessionWindowEnd 回写
- estimateSetupTokenUsage 抄齐 Codex 分支的过期归零 guard,避免 active
poll 没回写时 UI 渲染矛盾
- UsageProgressBar 区分「待刷新」/「现在」语义;i18n key 中英补齐
2026-06-07 15:23:45 +08:00
feitianbubu
f5cecea5b4
fix(ui): 放开 Select 下拉选项区高度,避免选项被截断
...
将 .select-options 的 max-h-60(240px,约 6 项)放大到 max-h-80(320px,约 8 项),修复账号管理状态筛选 7 个选项时第 7 项「不可调度」被滚动隐藏、看似缺失的问题。overflow-y-auto 保留,超长列表仍可滚动。
2026-06-07 13:41:21 +08:00
wsxfs
aea2950b18
fix(auth): 修复 Linux DO 登录误进入邮箱验证
2026-06-06 13:05:07 +08:00
Wesley Liddick
427d591212
Merge pull request #2930 from touwaeriol/feat/image-token-billing
...
fix(billing): channel pricing override for image generation + display image_output_tokens
2026-06-06 09:28:46 +08:00
DaydreamCoding and Claude Opus 4.8
cf12bc521b
fix(usage): 用量明细虚拟表对可空字段渲染崩溃致整表空白
...
- formatDuration 兜底 null(duration_ms 后端为 *int,count_tokens/失败等请求无耗时)
- tokens/cost 单元格与 CSV 导出加 (x ?? 0) 防御
- duration_ms 前端类型改 number|null,对齐后端指针,编译器从此拦未保护用法
- DataTable 虚拟化加固:initialRect 一屏兜底 + 过滤 0 高度读数
根因:渲染对 null 调 .toFixed() 抛错→Vue 弃整个 tbody→空白;虚拟化只渲可视行故呈概率性。
非 b3847fa 引入(formatDuration 自首个 commit 即存在)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-05 14:00:57 +08:00
DaydreamCoding and Claude Opus 4.8
cfb195c7b2
feat(usage): 记录并展示失败请求(用户端+管理端)
...
- 记录失败请求并在用户端/管理端展示;分类下拉改用统一 Select 组件
- 模型过滤改后端 ILIKE 模糊匹配;新增「Key 名称」列(含已删除标记)与按 Key 过滤;时间列移至末列
- 用户可见「已删除 key 失败请求」:OpsErrorLogFilter 加 MatchDeletedKeyOwner,用户侧归属
放宽为 (user_id OR deleted_key_owner_user_id),让 key 原所有者能看到删除 key 后继续请求
导致的认证失败记录(他人仍 NotFound,不泄露存在性)
- 迁移 148:ops_error_logs 用户+时间索引
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-05 14:00:57 +08:00