shaw
0dec1ad292
fix(service): 消除 isOpenAIGPT56Model 重复声明,统一到 openai_model_alias.go
...
PR #3898 与 #3909 各自新增了同名函数(billing 精确匹配版 / gateway
前缀匹配版),合并后 internal/service 编译失败。保留前缀匹配语义作为
唯一实现:对 normalizeKnownOpenAICodexModel 的输出(gpt-5.6-* 精确
基名)canonicalize 幂等且精确分支命中,计费行为不变;同时保住
gpt-5.6-*-max 等后缀变体的识别。
v0.1.150
2026-07-10 14:09:07 +08:00
Wesley Liddick
8b96acde97
Merge pull request #3898 from Arron196/feat/gpt-5.6-cache-billing-stats
...
feat(openai): 支持 GPT-5.6 系列缓存写入计费与统计
2026-07-10 13:57:29 +08:00
Wesley Liddick
5c9748cef9
Merge pull request #3922 from fengshao1227/fix/user-breakdown-request-type-filter
...
fix(admin): GetUserBreakdown request_type 筛选使用字符串解析
2026-07-10 13:56:40 +08:00
Wesley Liddick
312ab1f0bd
Merge pull request #3926 from fengshao1227/fix/ws-passthrough-reasoning-effort-candidates
...
fix(usage): WS passthrough effort 提取补入映射后模型候选
2026-07-10 13:46:25 +08:00
li
ea9f40b63f
fix(frontend): UserBreakdownParams.request_type 类型从 number 改为 UsageRequestType
2026-07-10 12:38:21 +08:00
li
b9b013a088
fix(usage): WS passthrough effort 提取补入映射后模型候选
...
Fixes #3924
2026-07-10 11:56:47 +08:00
li
dda8f78733
fix(admin): GetUserBreakdown 使用 ParseUsageRequestType 解析 request_type
...
Fixes #3920
2026-07-10 11:43:44 +08:00
Wesley Liddick
ddb1a210ce
Merge pull request #3912 from superman2003/fix/audit-concurrency-and-recovery
...
fix: harden billing concurrency and payment recovery
2026-07-10 11:38:45 +08:00
Wesley Liddick
301c99a26c
Merge pull request #3916 from Wei-Shaw/fix/reasoning-effort-model-candidates
...
fix: effort 提取改用模型候选列表,修复后缀模型用量元数据丢失
2026-07-10 11:16:35 +08:00
shaw
c3ae5fc3c5
fix(usage): effort 提取改用模型候选列表,修复后缀模型元数据丢失
...
#3909 将 effort 提取的模型参数改为 firstNonEmpty(upstreamModel, ...),
而 OAuth 的 normalizeCodexModel 会剥掉模型 effort 后缀
(gpt-5.4-xhigh -> gpt-5.4),导致后缀式模型且 body 无显式
reasoning 字段的请求在 usage 元数据中丢失 effort。
extractOpenAIReasoningEffortFromBody/extractOpenAIReasoningEffort
改为接受模型候选变参:显式 effort 的 max 保留判定沿用第一个非空
候选(映射后模型),后缀推导回退依次尝试每个候选(原始模型名兜底)。
纯元数据修复,不改变任何转发行为。
2026-07-10 11:09:06 +08:00
Wesley Liddick
cddcf49044
Merge pull request #3884 from CHOS1N11111/codex/add-parallel-tool-calls-compat
...
Add parallel_tool_calls compatibility mapping
2026-07-10 11:01:03 +08:00
Wesley Liddick
9389503c56
Merge pull request #3913 from fengshao1227/fix/en-locale-missing-keys
...
fix(i18n): 补齐 en 语言包 overview 和 resources 缺失 key
2026-07-10 10:59:49 +08:00
Wesley Liddick
72ef0b3884
Merge pull request #3909 from githubbzxs/fix/gpt56-max-compact
...
fix: support GPT-5.6 max reasoning effort
2026-07-10 10:57:35 +08:00
superman2003
fc66a30ffc
fix: harden billing concurrency and payment recovery
2026-07-10 10:56:49 +08:00
li
e984b4e2e1
fix(i18n): 补齐 en 语言包 overview 和 resources 缺失 key
...
Fixes #3909
2026-07-10 10:45:44 +08:00
Wesley Liddick
066a85949a
Merge pull request #3905 from fengshao1227/fix/codex-client-version-bump
...
fix(openai): 升级 Codex 客户端版本至 0.144.1,修复 gpt-5.6-luna 404
2026-07-10 10:43:51 +08:00
Wesley Liddick
3099362074
Merge pull request #3906 from Wei-Shaw/fix/compact-sse-raw-output-item-preservation
...
fix(compact): SSE→JSON 保留 raw output_item.done 并为 unary 等待补下游心跳(修复 #3887)
2026-07-10 10:41:02 +08:00
psyche
80b3d4c1f8
fix: 兼容 GPT-5.6 max 推理强度
2026-07-10 10:39:16 +08:00
shaw
000f6dc655
fix(compact): 终态 output 非空但缺 compaction 时从事件流补入(146 等价性收尾)
...
146 纯流式透传下 Codex 只从 raw output_item.done 收集 item,无论终态
output 形态如何都能拿到 compaction;SSE→JSON 提取链路此前仅在终态 output
为空时修补。补齐最后一处不等价:compact 请求终态 output 非空但缺
compaction、事件流中存在(done 优先 added 兜底)时以 raw JSON 追加。
门控:仅 compact 路径 + 仅缺失时触发,已含 compaction 或非 compact
请求逐字节不变。
Refs #3887 #3777
2026-07-10 10:25:09 +08:00
benjamin
5c15d32ff7
test(repository): stabilize expired lock reconciliation
2026-07-10 10:18:50 +08:00
shaw
ae9a01d852
fix(compact): 二轮审计加固——心跳字节不得污染 failover 判定与并发写安全
...
对首轮修复的对抗式审计发现并修复以下问题:
1. failover 判定污染(真实回归风险):handler 以 "Forward 前后
c.Writer.Size() 是否变化" 判定响应是否已写出并据此放弃换号。心跳注释
字节会使该判定恒真,compact 请求一旦在上游等待期间发过心跳,上游
429/5xx 将不再 failover。新增
OpenAICompactKeepaliveAdjustedWrittenSize(扣除心跳字节、互斥锁下
一致读取、仅心跳字节归一化为未写哨兵 -1),快照、failover 比较与
openAIForwardErrorAlreadyCommunicated 三处判定统一改用该口径;无心跳
请求完全等价于原 c.Writer.Size()。
2. 并发写竞争:心跳 goroutine 与未被显式拦截的写回路径(Forward 内部
本地拒绝等)存在 ResponseWriter 数据竞争。StartOpenAICompactSSE-
Keepalive 现将 c.Writer 替换为 openAICompactKeepaliveWriter:写侧
方法(Header/Write/WriteString/WriteHeader/WriteHeaderNow/Flush)
先在互斥锁下停拍,读侧(Status/Size/Written)仅加锁不停拍——任何
请求侧响应构造与心跳从构造上互斥,热路径状态读取不误杀心跳。
3. 语义拦截补齐:rejectIfCyberSessionBlocked(在用户槽位长等待之后
执行的直接 c.JSON)与 writeOpenAIFastPolicyBlockedResponse 在心跳
提交后降级为 response.failed 终止事件;未提交时先停拍再写 JSON,
状态码语义不变。失败事件 errType 参数化(permission_error 等)。
4. reconstruct 混合形态:done 事件存在但 compaction 只在
output_item.added 中时也要补入;done 已含 compaction 时跳过 added,
避免无 id 可去重时收集两份(Codex 要求恰好一个)。
5. 观测性:logOpenAIRemoteCompactOutcome 对心跳提交后的失败(wire 200)
以 GetOpsStreamError 纠正 outcome,不再误记 succeeded。
新增 5 个测试:failover 口径不变式、包装器停拍语义(-race)、fast
policy 提交前后两态、混合 done/added 形态(含去重)。
Refs #3887 #3777
2026-07-10 10:18:16 +08:00
benjamin
0a5f34a2ef
fix(openai): recognize Windows websocket resets
2026-07-10 10:11:21 +08:00
benjamin
062af81fb5
fix(openai): preserve explicit GPT-5.6 cache write prices
2026-07-10 10:00:47 +08:00
shaw
2cffe1cf5f
fix(compact): SSE→JSON 保留 raw output_item.done 并为 unary 等待补下游心跳(修复 #3887)
...
#3887 报告 v0.1.149(已含 #3880 桥接修复)remote compact 仍失败且持续
计费。核实为 #3880 明示的两个遗留:
1. 上游对 unary compact 返回 SSE 且 compaction item 只出现在 raw
response.output_item.done、终态 completed.response.output 为空
(#3777 实录形态)时,reconstructResponseOutputFromSSE 只累加
text/function_call/reasoning 三类 delta,compaction item 被丢弃,
桥接合成 0 个 output_item.done,Codex 报 "expected exactly one
compaction output item, got 0" 后盲目重试,每次重试重新消耗上游
compact 配额。
2. 桥接为全缓冲写回:上游 unary 完成前(大上下文可达数分钟,且上游
处理期间不发送任何字节)下游连响应头都收不到,反向代理
(Nginx/Cloudflare Tunnel)空闲超时掐断连接同样触发盲重连
(同类问题见 #2243/#2976)。
修复:
- reconstructResponseOutputFromSSE 优先以 raw JSON 逐字节收集
output_item.done item(协议上的最终完整形态),不经窄结构体,
encrypted_content/summary/opaque 等 compact 专属字段全部保留;
无 done 事件时退回收集 output_item.added 中的 compaction 类 item;
两者皆无才回到原 delta 重建。path-based v1 JSON 写回同样受益。
- 新增 openAICompactSSEKeepalive:body-signal 客户端流式 compact 在
上游等待期间按 gateway.stream_keepalive_interval 向下游写 SSE 注释
行心跳(eventsource 解析层直接忽略)。首拍延迟一个间隔,快速失败
仍走 JSON+状态码;首拍后状态码固化为 200,桥接/错误链路
(writeOpenAICompactSSEBridge、errorResponse、
handleStreamingAwareError、ensureForwardErrorResponse、
writeOpenAINonStreamingProtocolError)统一降级为 response.failed
终止事件并标记 ops 流内错误。
- API-key 账号的 compact 上游请求也强制 accept: application/json
(#3777 期望行为 4;透传白名单原会放行客户端的 text/event-stream)。
测试:#3777 实录形态经 handleSSEToJSON / 透传 / path-based 三条链路
的修补断言;raw-done 优先不与 delta 重复;added 回退门控;心跳提交、
提交后 2xx 续写、提交后失败降级、未提交行为不变;-race 通过。
Fixes #3887
Refs #3777 #3875 #3880
2026-07-10 09:56:56 +08:00
li
657c4f97d9
fix(openai): 升级 Codex 客户端版本至 0.144.1,修复 gpt-5.6-luna 404
...
Fixes #3895
2026-07-10 09:56:33 +08:00
benjamin
383f61d0e9
fix(openai): align GPT-5.6 billing with official pricing
2026-07-10 09:42:31 +08:00
benjamin
4a2b10c94e
feat(openai): support GPT-5.6 cache write billing
2026-07-10 09:08:58 +08:00
github-actions[bot]
12d811bd76
chore: sync VERSION to 0.1.149 [skip ci]
2026-07-09 14:57:53 +00:00
CHOS1N
ad8afc8a2e
Add parallel_tool_calls compatibility mapping
...
Preserve Chat Completions parallel_tool_calls when converting requests to the Responses API, and map Responses parallel_tool_calls back when falling back to Chat Completions upstreams.
Cover both true and explicit false values so clients can disable parallel tool calls without the field being dropped by omitempty.
2026-07-09 22:52:35 +08:00
Wesley Liddick
dd1a116f48
Merge pull request #3881 from Wei-Shaw/feat/version-rollback
...
feat: 版本徽章新增近3个历史版本在线回退与手动回退指引
v0.1.149
2026-07-09 22:39:41 +08:00
Wesley Liddick
2e61914c48
Merge pull request #3880 from Wei-Shaw/fix/compact-body-signal-sse-bridge
...
fix(compact): body-signal 客户端流式请求的响应合成回 SSE(修复 #3875)
2026-07-09 22:39:31 +08:00
shaw
92b283d9eb
fix: 修复 SSE 桥接 appendEvent 中 errcheck 告警
2026-07-09 22:34:13 +08:00
shaw
1c2e6503c6
feat: 版本徽章新增近3个历史版本在线回退与手动回退指引
...
后端:
- UpdateService 新增 ListRollbackVersions/RollbackToVersion,回退目标强制
限定为比当前版本更旧的近3个正式版本(排除当前/更新/预发布/草稿),
越界返回 400 ROLLBACK_VERSION_NOT_ALLOWED;下载复用既有 HTTPS 域名
白名单 + checksum 校验 + 原子换二进制管线
- GitHubReleaseClient 新增 FetchRecentReleases(releases 列表 API)
- 新增 GET /admin/system/rollback-versions;POST /admin/system/rollback
支持可选 {"version"} body,无 body 保持原 .backup 本地回退行为不变
- 端点均在 /admin 组 adminAuth(IsAdmin+TokenVersion)保护内
前端:
- VersionBadge「已是最新版本」状态下新增版本回退面板:radio 卡片选择
近3个版本,手动回退方式按部署形态 tab 切换(脚本部署 curl 命令 /
Docker 镜像 tag 指引),支持一键复制;release 构建提供一键回退并
复用重启流程;源码构建仅提示不支持在线回退
- 下拉根元素重置 whitespace-normal,修复 sidebar-brand 的
white-space:nowrap 继承导致的长文本溢出裁切
测试:服务层过滤/排序/上限/非法目标拒绝、handler 双模式与鉴权错误映射、
GitHub client 列表拉取、前端 API 请求体行为共 16 个新增用例
2026-07-09 22:30:04 +08:00
shaw
16c0613b21
fix(compact): body-signal 客户端流式请求的响应合成回 SSE
...
v0.1.147 的 body-signal 提升(#3804)把 Codex remote compact v2 的流式
/responses 请求改写为上游 unary /responses/compact(JSON),但把 JSON
文档原样写回给了按 Responses SSE 协议消费的客户端。Codex 只从
response.output_item.done 收集 item 且必须收到 response.completed,
收到 JSON 后报 "stream disconnected before completion: stream closed
before response.completed" 无限重连,每次重连再白烧一次上游 compact
配额(#3875,v0.1.146 无提升逻辑故正常)。
修复保留提升的全部收益(requireCompact 调度过滤、compact 模型映射、
白名单归一化、上游 unary JSON),补上协议转换缺失的响应半程:
- handler 在 body-signal 提升时记录原始 body 的 stream:true 意图
(MarkOpenAICompactClientStream);path-based 请求不标记,Codex v1
unary 协议与链式 sub2api 的 JSON 写回行为保持不变。
- 四个非流式写回点(handleNonStreamingResponse / handleSSEToJSON /
handleNonStreamingResponsePassthrough / handlePassthroughSSEToJSON)
对已标记的 2xx JSON 响应经 writeOpenAICompactSSEBridge 合成最小
Responses SSE:每个 output[] item 一条 response.output_item.done
(原始字段逐字节保留),最后一条 response.completed 携带完整
response 对象。
- 按 codex-rs 解析器硬约束兜底:先 json.Compact 防 pretty JSON 换行
破坏 SSE 帧;response.id 缺失时注入 resp_*(必填 string);usage
缺 input_tokens/output_tokens/total_tokens 整数字段时整体删除,
避免整条 completed 事件解析失败。
- 非 2xx 一律保持 JSON 原样,Codex 依赖 HTTP 状态码走重试链路。
新增 9 个 service 测试 + 4 个 handler 测试覆盖合成形态、id/usage 兜底、
path-based 不受影响、主链路/透传链路/上游 SSE 提取再合成三条端到端。
Fixes #3875
Refs #3777
2026-07-09 21:40:51 +08:00
shaw
1a3cc2a787
refactor: 重新设计用量页布局并新增延迟健康列
...
- /admin/usage 明细区收进单卡片:三个下划线 tab(用量明细/错误请求/用户排行) + 自适应筛选栏 + 内容
- 用户 Token 排行收编为第三个 tab:去掉独立邮箱搜索,懒挂载,点击行下钻回用量明细并回显用户
- 首Token/耗时合并为延迟列(首字/总耗时):阈值 10s/30s/60s 与 1min/3min/5min 四档配色,色条上下两段短渐变过渡(from-40% to-60%),管理端与用户端 /usage 共用
- 时长格式 ≥1min 简化为 Xm Ys、≥1h 为 Xh Ym
- UsageFilters/UsageTable/OpsErrorLogTable 增加 flat 嵌入模式(默认关闭不影响其他使用方)
2026-07-09 21:09:40 +08:00
Wesley Liddick
e2c731abe4
Merge pull request #3873 from Wei-Shaw/fix/post-merge-audit-followups
...
fix: 落实 #3867-#3870 合并审计的全部跟进项
2026-07-09 20:13:21 +08:00
shaw
7918b1a9c5
fix: 落实 #3867-#3870 合并审计的全部跟进项
...
透传规则(跟进 #3868/#3870,refs #3857):
- CC/Messages 4 条协议转换路径改用共享 helper,走语义状态推断 +
body 归一化,使按错误码配置的透传规则也能命中(原先传 0 恒不命中)
- helper 增加 platform 参数:本服务同时承载 openai/grok 平台账号,
规则须按 account.Platform 匹配,消除硬编码平台错配
- /v1/responses 两条路径命中透传规则时补记 ops 上游错误事件,
对齐 CC/Messages 与 antigravity 先例,消除监控盲区
用户角色管理(跟进 #3869):
- 补齐 EN 语言包缺失的 admin.users.form.roleLabel
- 新增"最后一个管理员不可降级"守卫,覆盖跨管理员互降致零 admin 锁死
- 角色变更/创建管理员落审计日志(含操作者 actor_admin_id)
2026-07-09 20:06:09 +08:00
Wesley Liddick
10102807e2
Merge pull request #3869 from Birditch/feat/admin-user-role-and-token-ranking
...
feat(admin): 用户角色管理 + 用户 Token 排行
2026-07-09 19:50:01 +08:00
Wesley Liddick
751cf5eea3
Merge pull request #3870 from fengshao1227/fix/response-failed-passthrough-rules
...
fix(gateway): CC/Messages 路径 SSE response.failed 应用错误透传规则
2026-07-09 19:49:32 +08:00
Wesley Liddick
a8505877ff
Merge pull request #3868 from wucm667/fix/openai-sse-response-failed-error-passthrough
...
fix: OpenAI SSE response.failed 应用错误透传规则
2026-07-09 19:49:04 +08:00
Wesley Liddick
f3380dbd62
Merge pull request #3867 from heathermhuang/codex/postmerge-grok-issues-3848-3861
...
fix: Grok OAuth, image, usage, and quota handling
2026-07-09 19:48:32 +08:00
shaw
feef0bc0b1
chore: update sponsors
2026-07-09 19:08:00 +08:00
github-actions[bot]
0ee51b45f8
chore: sync VERSION to 0.1.147 [skip ci]
2026-07-09 10:10:28 +00:00
li
8f97953e51
fix(gateway): SSE response.failed 应用错误透传规则,不再硬编码 502
...
Fixes #3857
2026-07-09 18:09:37 +08:00
Birditch and Claude Opus 4.8
b062b36646
feat(admin): 用量记录页新增"用户 Token 排行"面板
...
- 在 /admin/usage 新增按用户聚合的 Token 排行表(输入/输出/缓存/总 Token、请求数、费用)
- 支持按列排序、邮箱搜索、Top N (20/50/100/200),点击行下钻到该用户
- 复用现有筛选(用户/时间/模型/分组等)与既有 KPI 卡片、逐条日志
- 后端对 /admin/dashboard/user-breakdown 做加法扩展(向后兼容):
- UserBreakdownItem 增加 input_tokens/output_tokens/cache_tokens
- 新增 sort_by(白名单排序,防注入,缺省仍按 actual_cost)
- 新增 sort_by 转发单元测试;更新 UsageView.spec 稳定桩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-09 06:04:22 -04:00
Birditch and Claude Opus 4.8
64fdc11ec4
feat(admin): 用户创建/编辑支持选择与修改角色 (user/admin)
...
- 创建用户时可指定角色,缺省仍为 user,不再硬编码为普通用户
- 编辑用户时可在 user/admin 之间切换角色
- 后端对角色做 admin/user 合法性校验
- 防锁死保护:管理员不能把自己降级为普通用户(与既有"不能禁用/删除 admin"保护一致;降级其他管理员仍允许)
- 前端创建/编辑弹窗新增角色下拉,复用既有 i18n 文案
- 新增角色创建/更新/非法值/防降级单元测试
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-07-09 06:04:06 -04:00
wucm667
1da3501af5
fix: apply error passthrough to OpenAI response.failed streams
2026-07-09 17:59:38 +08:00
Heatherm Huang
1a0a6ea9a8
fix: stabilize Grok quota probe model
2026-07-09 17:58:31 +08:00
Heatherm Huang
b480545c19
fix: improve Grok OAuth, image, and usage flows
2026-07-09 17:54:08 +08:00
Wesley Liddick
ba1f130d28
Merge pull request #3864 from fengshao1227/fix/frontend-i18n-and-site-logo-sanitize
...
fix(frontend): 补齐 en 语言包缺失 key 并对 site_logo 统一应用 sanitizeUrl
v0.1.147
2026-07-09 17:35:00 +08:00