shaw
|
0fd2e9216d
|
fix(scheduler): 修复 OpenAI 高级调度器审计发现的正确性与性能问题
针对 #3692 合并后审计发现的问题集中修复:
- previous_response_id 剥离条件改为按 call_id 全覆盖校验,
部分可重建的工具续链不再被误剥离(不受开关门控的行为回归)
- 粘性加权回退路径补分组归属校验并清理失效绑定,杜绝跨分组账号泄漏
- 账号列表页:无 OpenAI 账号时跳过分数计算、过滤池限定 openai 平台、
负载批查合并为账号并集一次查询,消除全表扫描与 Redis N+1
- 订阅优先模式下常规池不可用时回退订阅池等待计划,
busy-but-waitable 的订阅账号不再导致请求硬失败
- TopK/权重 DB 覆盖显式受总开关门控,与兄弟子开关语义一致
- 前端未分组 OpenAI 账号回退展示基础分,不再显示 "-"
- ListAllWithFilters 等能力正式进入 AccountRepository/AdminService 接口,
移除匿名接口断言与静默降级;负载批查失败补 warn 日志
- SelectAccountWithSchedulerForCapability 增加显式 previousResponseCanMove
参数,移除 "previous_response_can_move" 魔法字符串哨兵
- 设置写入路径补"基础权重不得全为零"聚合校验;
运行时设置批量读取失败的降级路径覆盖全部键并留痕
|
2026-07-06 11:43:16 +08:00 |
|
linshuboy
|
f26ca5661e
|
feat: add OpenAI advanced scheduler controls
Related: #1089, #408, #123
|
2026-07-05 17:24:38 +08:00 |
|
Bestony@Homelab
|
5436d0bf10
|
feat(admin): add group column settings
|
2026-07-02 15:04:36 +08:00 |
|
 DaydreamCodingandClaude 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 |
|
shaw
|
59e9356c51
|
feat: 抹除 Anthropic OAuth 请求中客户端 dateline 隐写指纹
对 /v1/messages 转发到 Anthropic OAuth/setup-token 账号的请求做 dateline
归一化,将 system prompt 与 <system-reminder> 块中 "Today's date is …"
语句里的 4 种撇号变体与 "/" 日期分隔符还原为 ASCII 撇号 + "-",抹除某些
客户端在检测到非官方 base URL 时注入的 3 bit 隐写指纹。API Key 账号不受
影响。新增系统设置开关 enable_client_dateline_normalization,默认开启。
|
2026-07-01 10:54:18 +08:00 |
|
shaw
|
bf4f006736
|
fix: 修复用户列表使用时间排序冲突
|
2026-06-30 13:36:36 +08:00 |
|
 DaydreamCodingandClaude 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 |
|
Heatherm Huang
|
39be1ec97f
|
feat: add grok subscription support
|
2026-06-26 10:36:09 +08:00 |
|
SMGDev
|
65ad7df4f4
|
fix(payment): 修复后端返回空supported_types时支付提供商卡片消失的问题
统一处理后端返回的null类型supported_types,将其标准化为空数组,避免调用includes()时报错导致卡片无法显示,同时修复多处相关的类型判断逻辑
|
2026-06-26 00:50:22 +08:00 |
|
dailingfei
|
8ce7b9a8f6
|
feat: configure Claude OAuth system prompt blocks
|
2026-06-13 04:12:13 +08:00 |
|
 DaydreamCodingandClaude Opus 4.8
|
329414ea4f
|
feat(admin): /admin/users 新增按用户 API Key 所在分组过滤
- 支持专用/公开/订阅/已禁用四类分组:按 api_keys.group_id 精确匹配,
排除软删除 key(EXISTS + DeletedAtIsNil);已禁用分组单独成区,
覆盖 key 仍挂在禁用分组上的用户
- 后端:UserListFilters.APIKeyGroupID;handler 解析 api_key_group_id;
repo HasAPIKeysWith 谓词;GetAllGroupsIncludingInactive 新接口
(/admin/groups/all?include_inactive=true)
- 前端:下拉按类型分区单选;UsersView 独立 allGroupsForApiKeyFilter
loader;分区标题用负数哨兵值修复 Vue :key 重复问题
- 测试:repo 集成 5/5(含软删除排除、多 key 去重、叠加 status 过滤)、
handler 单测 5/5、前端 vitest 6/6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-08 22:54:01 +08:00 |
|
 DaydreamCodingandClaude Opus 4.8
|
fe8952733a
|
fix(usage): 管理端错误请求页过滤与分列完善
- 错误请求标签补传 model/account_id/group_id 过滤(此前 loadAdminErrors 丢弃),admin handler
读取 model 查询参数走精确匹配
- 错误表格拆成 用户/API Key/账号 三独立列(上游行也显示用户),补 api_key_name/api_key_deleted,
已删除 key 显示红色「已删除」标记;i18n keyDeletedBadge 补入 errorLog 命名空间
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-05 14:00:57 +08:00 |
|
Wesley Liddick
|
ed8f5666c6
|
Merge pull request #2895 from wucm667/feat/usage-window-tooltip
feat(admin): 账号用量窗口 5h/7d 增加说明 tooltip
|
2026-06-01 09:57:03 +08:00 |
|
 DaydreamCodingandClaude Opus 4.8
|
bf24b61139
|
perf(usage): 优化 /admin/usage 打开速度与刷新响应
根因:页面 mount 并发 6 个请求,其中 5 个在原始 usage_logs 上 live 聚合,
且有 1 个重复 getModelStats。优化(不引入预聚合):
前端
- UsageView 经 :model-options 下传 model 列表,移除 UsageFilters 重复的
getModelStats(mount 请求 6→5,少一次 usage_logs 全表 GROUP BY model)
- 刷新/换筛选保留旧模型数据(invalidateModelStatsCache 只失效标记不清空数据),
图表不再闪空,刷新期间页面保持可交互
后端
- GetStatsWithFilters 4 条聚合 errgroup 并行(仅 *sql.DB 连接池路径,ent.Tx
顺序回退以保事务内不并发),endpoint 明细 best-effort;抑制取消级联噪声日志
- /admin/usage/stats 复用 dashboard 的 newSnapshotCache 30s 处理器层缓存,按
filters+窗口为 key;前端手动刷新带 nocache=1 强制回源(刷新=最新)
注:自合并提交 4c8396c 迁移而来,仅取"列表打开速度与刷新响应"部分;原提交的
"审计查看弹窗大 body 渲染"改动(AuditLogModal / audit-log-format / 审计 i18n)
依赖尚未迁移的审计功能(d8389ade),本次已排除。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-05-30 18:56:08 +08:00 |
|
 DaydreamCodingandClaude Opus 4.7
|
b60d8bb4cc
|
feat(usage): 在 /admin/usage 支持查看已删除用户的历史使用情况
用户软删除后使用记录仍在,但身份(邮箱)被 ent 软删除拦截器隐藏。本次在
三条管理员只读路径定点穿透软删除过滤,并把删除状态传播到前端标记,零新表/
迁移/回填:
- 后端穿透:富化 usage 日志(loadUsers)、用户搜索(ListWithFilters +
UserListFilters.IncludeDeleted)、点击详情(GetByIDIncludeDeleted /
GetUserIncludeDeleted + getById ?include_deleted 分支)
- 状态传播:service.User / dto.User 新增 DeletedAt;SearchUsers 标记 deleted
- 前端:表格与余额弹窗展示"已删除"徽标、筛选下拉标注并排序、点击走
include_deleted;新增 i18n admin.usage.userDeletedBadge
- 安全:普通用户 usage 仅查本人(无 PII 泄漏);主用户列表与默认 getById
行为不变(已删用户仍 404);仅 admin 搜索设 IncludeDeleted
后端 build / 三态 vet / unit 全量 / 仓储集成全绿;前端 typecheck / vitest /
改动文件 eslint 全清。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-30 17:52:18 +08:00 |
|
 wucm667andClaude Opus 4.8
|
c256a5441a
|
feat(admin): 账号用量窗口 5h/7d 增加说明 tooltip
在账号管理列表"用量窗口"列表头增加一个说明性 HelpTooltip,
解释 5h / 7d 是上游账号(如 OpenAI ChatGPT、Claude)官方的滚动
用量窗口限制,由上游设定、非 sub2api 配置、与映射模型无关,且
窗口滚动到期后自动重置、无法在 sub2api 端解除。
复用现有 HelpTooltip 组件(teleport 到 body,避免表格裁剪),
单个 ⓘ 图标置于列表头,避免每行重复。新增 i18n key
admin.accounts.usageWindowsHint(zh/en 同步)。纯展示说明,
不改用量计算与后端逻辑。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-05-29 20:57:29 +08:00 |
|
lyen1688
|
1b2d8873b0
|
feat: 完善前置拦截审核运行态
|
2026-05-28 20:05:24 +08:00 |
|
Wesley Liddick
|
cc077862b3
|
Merge pull request #2797 from wucm667/feat/account-list-created-at-column
feat(admin): 账号管理列表新增创建时间列
|
2026-05-27 22:10:21 +08:00 |
|
lyen1688
|
f597c1581b
|
feat(group): 支持自定义 /v1/models 模型列表
|
2026-05-27 18:00:45 +08:00 |
|
wucm667
|
b6a38ddab7
|
feat(admin): 账号管理列表新增创建时间列
|
2026-05-26 19:59:12 +08:00 |
|
Wesley Liddick
|
bebc082306
|
Merge pull request #2766 from DaydreamCoding/feat/user-platform-quota
feat(quota): 用户 × 平台 USD 配额
|
2026-05-26 14:13:18 +08:00 |
|
lyen1688
|
23f3d426c6
|
feat: 支持内容审计风险阈值配置
|
2026-05-26 13:58:02 +08:00 |
|
 DaydreamCodingandClaude Opus 4.7
|
6b39b344d8
|
feat(quota): 用户 × 平台 USD 配额
为用户在 anthropic/openai/gemini/antigravity 四个平台上提供日/周/月
三个窗口的 USD 配额管控。配额语义:未设置=不限制,0=禁用,>0=美元上限。
两层模型:
- 配置层:系统默认配额,以及 email/linuxdo/oidc/wechat/github/google/
dingtalk 七个鉴权来源的默认配额,存于 settings,以嵌套 JSON 整体读写
(系统 1 个 key + 每个来源 1 个 key),整体替换语义。
- 运行时层:user_platform_quota 表按用户记录实际配额,与配置层解耦。
后端:新增 ent schema 与 140_user_platform_quotas.sql 迁移、repository
与 service 端口、计费链路集成、管理端与用户端读写接口。
前端:管理端设置页配额编辑、用户配额管理 Modal、用户 Dashboard 展示、
中英文案。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-26 10:49:20 +08:00 |
|
wucm667
|
0d5c6f7cc7
|
feat(risk-control): 内容审计支持按模型生效
|
2026-05-21 21:18:43 +08:00 |
|
shaw
|
a613a587ba
|
feat: add subscription expiry email toggle
|
2026-05-21 14:27:50 +08:00 |
|
wucm667
|
3263ca63c7
|
feat(redeem): add redeem code batch update
|
2026-05-20 16:08:41 +08:00 |
|
shaw
|
878ad3b569
|
feat(openai-gateway): Codex OAuth 账号浏览器 UA 自动改写规避 Cloudflare
质询
|
2026-05-20 14:33:51 +08:00 |
|
Wesley Liddick
|
a84bf3fab9
|
Merge pull request #2521 from Brisbanehuang/codex/fix-subscription-model-scopes
fix: hide model scopes for non-antigravity plans
|
2026-05-19 17:15:15 +08:00 |
|
Brisbanehuang
|
26ca73a4cd
|
fix: hide model scopes for non-antigravity plans
|
2026-05-17 02:20:41 +08:00 |
|
shaw
|
a07a0dac63
|
feat: add configurable Antigravity user agent version
|
2026-05-11 22:25:20 +08:00 |
|
shaw
|
9377c96746
|
fix: 让消息 cache_control 改写默认关闭
|
2026-05-11 21:26:41 +08:00 |
|
lyen1688
|
af550fa64e
|
feat: 增加 GitHub 和 Google 邮箱快捷登录
|
2026-05-06 16:06:11 +08:00 |
|
Wesley Liddick
|
37f7c7128c
|
Merge pull request #2120 from gaoren002/fix/rate-limit-429-cooldown-config
fix(rate-limit): make 429 fallback cooldown configurable
|
2026-05-05 19:46:11 +08:00 |
|
shaw
|
73b872998e
|
feat: 添加 Anthropic 缓存 TTL 注入开关
|
2026-04-30 13:38:22 +08:00 |
|
gaoren002
|
4b904c887c
|
fix(rate-limit): make 429 fallback cooldown configurable
|
2026-04-30 03:01:39 +00:00 |
|
KnowSky404
|
764afbe37a
|
test: cover account bulk edit target scopes
|
2026-04-27 18:08:22 +08:00 |
|
IanShaw027
|
f35e967516
|
fix payment qr fallback and admin guidance
|
2026-04-22 07:33:14 -07:00 |
|
shaw
|
c6d25f69d5
|
chore: 恢复PAYMENT系列文件
|
2026-04-22 18:48:40 +08:00 |
|
IanShaw027
|
ad4600964e
|
fix(ci): clean up lint and dead code
|
2026-04-22 16:38:36 +08:00 |
|
IanShaw027
|
ca4e38aa01
|
fix(profile): stabilize binding compatibility and frontend checks
|
2026-04-22 14:57:47 +08:00 |
|
IanShaw027
|
84628108fc
|
fix(auth): preserve backward-compatible oauth defaults
|
2026-04-22 11:17:32 +08:00 |
|
IanShaw027
|
40f7e832b4
|
fix: restore wechat settings compatibility after rebase
|
2026-04-21 23:26:45 +08:00 |
|
IanShaw027
|
b22d00e541
|
feat: drive visible payment methods from enabled providers
|
2026-04-21 23:20:37 +08:00 |
|
IanShaw027
|
20062b44dc
|
frontend: normalize profile and admin i18n cleanup
|
2026-04-21 22:26:35 +08:00 |
|
IanShaw027
|
2cebb0dc60
|
feat(settings): support dual-mode wechat oauth defaults
|
2026-04-21 20:36:10 +08:00 |
|
IanShaw027
|
ee3f158f4e
|
fix(settings): restore wechat and payment config persistence
|
2026-04-21 17:35:12 +08:00 |
|
IanShaw027
|
d08757ce9e
|
refactor(admin): remove auth migration reports
|
2026-04-21 17:34:18 +08:00 |
|
IanShaw027
|
ed01c59916
|
feat: track authenticated user activity
|
2026-04-21 14:54:53 +08:00 |
|
IanShaw027
|
ebd053c87e
|
docs: clarify openai scheduler flag semantics
|
2026-04-21 13:07:40 +08:00 |
|
IanShaw027
|
ebe7524415
|
fix profile activity and migration remediation
|
2026-04-21 02:08:56 +08:00 |
|