feeeei
|
cbc2a3dd46
|
修复池模式 Gemini 账号被 429 打上账号级限流
- 429 的标记点在重试循环内,先于 CheckErrorPolicy 执行,池模式豁免只能落在
handleGeminiUpstreamError 自身;否则一次上游 429 会把账号锁到 PST 午夜,
即便重试已经成功返回客户端
- 判定条件与 HandleUpstreamError 对齐:自定义错误码优先级高于池模式;
401/403/529 仍委派给 RateLimitService,临时不可调度规则不受影响
- chat completions 路径的策略分发改为只有 None / Matched 才处理账号状态,
与 messages 兼容层的 switch 一致,ErrorPolicySkipped 不再漏进来
|
2026-08-08 16:51:48 +08:00 |
|
 Wesley LiddickandGitHub
|
cc67b1aca1
|
Merge pull request #5406 from bestony/fix/openai-oauth-routing-hints
fix(openai): forward OAuth routing hints
|
2026-08-08 10:58:53 +08:00 |
|
shaw
|
8ad0a5ff52
|
fix(deps): bump nanoid 3.3.16 -> 3.3.17 to clear GHSA-2v37-7h3g-55p8 audit gate
|
2026-08-08 10:48:42 +08:00 |
|
github-actions[bot]
|
68d8f122e4
|
chore: sync VERSION to 0.1.172 [skip ci]
|
2026-08-07 15:39:12 +00:00 |
|
 Wesley LiddickandGitHub
|
155c494964
|
Merge pull request #5399 from fengshao1227/fix/responses-anthropic-invalid-content-blocks
fix(apicompat): Responses→Anthropic 转换不再发出上游会拒收的 content block
|
2026-08-07 23:21:59 +08:00 |
|
 Wesley LiddickandGitHub
|
8991574873
|
Merge pull request #5345 from puppywang/fix/oauth-pending-account-takeover
fix(security): block OAuth account takeover via pending exchange
|
2026-08-07 23:20:22 +08:00 |
|
 Wesley LiddickandGitHub
|
8f7b0a314d
|
Merge pull request #5398 from Wei-Shaw/fix/openai-capacity-shed-stream-recovery
fix(gateway): 流内降载错误恢复 pre-output failover 并对客户端改写为可重试错误码
|
2026-08-07 23:11:20 +08:00 |
|
li
|
64090de664
|
fix(apicompat): Responses→Anthropic 转换不再发出上游会拒收的 content block
convertResponsesInputToAnthropic 的 default 分支把未知 item 的 content 逐字
透传成 Anthropic user 消息,Responses 专有的分片类型会原样进入上游请求体。
最典型的是工具执行后回放的 reasoning item:带 content 数组时,reasoning_text
块直接发给 Anthropic,上游回 400 Request body format invalid,而该 item 会一直
留在会话历史里,导致此后每一轮都继续失败。
同时修正两处会产出空内容消息的路径——Anthropic 拒收空内容消息与空白 text 块:
分片全部不可识别时,user 消息退化成 content:""、assistant 消息退化成单个空
text 块。
改动:
- type=reasoning 显式跳过。Anthropic 无法摄入 OpenAI reasoning:encrypted_content
不透明,thinking 重放需要上游签发的 signature。Codex 常见形态(只带 summary +
encrypted_content)本来就会被丢弃,这里让带 content 的形态行为一致。
- default 分支改走 convertResponsesUserToAnthropicContent 白名单转换,保留其中
可识别的文本/图片,丢弃其余分片。
- user / assistant 分支在转换结果为空内容或纯空白文本时跳过该消息。
Fixes #5329
|
2026-08-07 23:09:03 +08:00 |
|
 Wesley LiddickandGitHub
|
de904c433e
|
Merge pull request #5396 from Brisbanehuang/codex/upstream-response-model-audit
feat(usage): 增加上游响应模型审计
|
2026-08-07 23:00:46 +08:00 |
|
shaw
|
14a27f1960
|
test(gateway): 校准 error 帧边界 flush 期望至 pre-output failover 新契约
可重试类 error 帧按设计不再算客户端输出(保留在 attempt 缓冲中,
为随后的 response.failed 保住 pre-output failover),因此不在自身
边界单独 flush,而是与终止帧一起出站(1 次 flush)。原用例按旧行为
断言 2 次 flush 导致 CI 失败。
同时补充不可重试类(invalid_request)error 帧仍在边界 flush 的对照
用例,锁住两类错误帧的行为区分。
|
2026-08-07 22:55:42 +08:00 |
|
shaw
|
c33c3208e3
|
fix(gateway): 流内降载错误恢复 pre-output failover 并对客户端改写为可重试错误码
上游容量降载的真实序列是「event: error → event: response.failed」。此前
{"type":"error"} 帧被当作首个客户端输出立即 flush,clientOutputStarted 被固化,
随后的 response.failed 永远进不了 pre-output failover 分支,降载错误被原样转发;
Codex CLI 对 server_is_overloaded/slow_down 按闭集判致命,直接终止会话并提示
"Selected model is at capacity. Please try a different model."。
修复:
- 可重试类 error 帧不再算客户端输出,恢复既有的同账号重试+切号链路;
不可重试类(content_policy/invalid_request 等)维持原样转发,保留上游错误细节
- 必须转发给客户端时(流中途已有输出 / WS 桥接),把 server_is_overloaded、
slow_down 改写为致命集之外的 server_error,触发 Codex 内置退避重试;
错误消息原样保留,rate_limit_exceeded 等其他错误码一律不动
- 监控、计费与账号状态判定均基于改写前的原始事件
|
2026-08-07 22:42:33 +08:00 |
|
白宦成
|
de349187d9
|
fix(openai): harden priority routing hints
|
2026-08-07 21:47:54 +08:00 |
|
白宦成
|
815035fcc9
|
fix(openai): send OAuth routing hints
|
2026-08-07 21:47:53 +08:00 |
|
白宦成
|
915cc7e7bd
|
fix(openai): stop injecting legacy beta on OAuth responses
|
2026-08-07 21:47:53 +08:00 |
|
Brisbanehuang
|
db0bff82c7
|
feat(usage): audit upstream response models
(cherry picked from commit 839036224f795c8ee5dc6718a2a14372a45eea44)
|
2026-08-07 09:40:11 -04:00 |
|
 Wesley LiddickandGitHub
|
e88fc52ce6
|
Merge pull request #5383 from fengshao1227/fix/responses-tool-parameters-null-type
fix(openai): 修正 Responses 工具 Schema 中显式为 null 的 parameters.type
|
2026-08-07 21:06:10 +08:00 |
|
 Wesley LiddickandGitHub
|
045b620d0d
|
Merge pull request #5391 from fengshao1227/fix/codex-plan-gated-image-model-no-cooldown
fix(ratelimit): 图片模型被 Codex 文本端点拒绝时不再写模型冷却
|
2026-08-07 21:05:58 +08:00 |
|
 Wesley LiddickandGitHub
|
e79429b03f
|
Merge pull request #5392 from fengshao1227/fix/grok-405-failover-and-cooldown
fix(grok): 405 纳入 failover 与临时踢号,修复 Grok 会话粘性锁死
|
2026-08-07 21:05:46 +08:00 |
|
li
|
02fbcbe3ad
|
fix(ratelimit): 守卫按端点来源门控,并与冷却键对齐模型口径
上一版守卫只看模型类型,不区分请求从哪个端点进来。OAuth 账号的 /v1/images/*
上游同样是 Codex Responses(openai_images_responses.go → handleOpenAIImagesErrorResponse
→ handleOpenAIAccountUpstreamError → HandleUpstreamModelNotFound),所以专用生图
端点也会命中 plan-gated 分支。账号确实不具备生图能力时跳过冷却,会让调度层失去
唯一的刹车:每个请求都完整走一遍号池,对上游形成无上界的 400 放大。
改动:
- 新增 ctxkey.OpenAIImagesEndpoint 与 WithOpenAIImagesEndpoint /
OpenAIImagesEndpointFromContext,在 handler/openai_images.go 入口置位;
与 OpenAIImageGenerationIntent 区分——后者在 /v1/responses 带图片模型时也会置位。
- 守卫下移到 modelKey 计算之后,抽成 shouldSkipCodexPlanGatedImageModelCooldown,
仅在 plan-gated 分支、且非 /v1/images/* 入站时生效。
- 同时判断 requestedModel 与最终 modelKey:冷却键走 account.GetMappedModel,
账号可以把文本别名映射到 gpt-image-*,只判请求模型会漏掉这种形态。
|
2026-08-07 20:49:39 +08:00 |
|
li
|
b5d9fd21b0
|
fix(ratelimit): 图片模型被 Codex 文本端点拒绝时不再写模型冷却
gpt-image-* 被误发到 /v1/chat/completions 或 /v1/responses 时,Codex 会稳定
返回 400 codex_plan_gated_model。HandleUpstreamModelNotFound 把它当成账号能力
缺失,给每个账号写 30 分钟 model_rate_limits 冷却。failover 走完整个号池后,
池内每个账号都冷却了该图片模型,于是后续走对端点的 /v1/images/generations
请求也一并 503 no available accounts。
在 codex plan-gated 分支里对图片模型提前返回:仍然 failover 掉本次尝试,
但跳过 SetModelRateLimit 写入,不把号池对正确的生图请求整体下线。
Fixes #4828
|
2026-08-07 20:41:34 +08:00 |
|
li
|
146b8b6684
|
revert(grok): 撤回 405 账号级踢号,只保留 failover 分类
tempUnscheduleGrok 是账号级、全端点、全模型的下线,而 handleGrokAccountUpstreamError
有 8 个调用点(raw chat / Grok 媒体 / CC 管线 / WS HTTP 桥接 / responses),
/v1/responses 的 405 只证明该端点缺失,账号在其他端点上仍然健康。
仓库里已有相反的既定不变式:shouldApplyOpenAIAlphaSearchAccountErrorSideEffects
把 404/405 显式排除在账号状态写入之外,注释写明「端点不存在只说明该上游不支持
独立搜索,账号本身健康」。
failover 分类器加 405 单独就能解开 sticky 锁死(调度器选号时会即时改绑 sticky),
账号级冷却不是必需的。「405 不踢号但记住端点能力」按端点级负缓存另行处理。
|
2026-08-07 20:41:23 +08:00 |
|
li
|
a071b27b41
|
fix(grok): 405 纳入 failover 与临时踢号,修复 Grok 会话粘性锁死
Grok 分组里若有账号的自定义 base_url 只实现 /v1/chat/completions,对
/v1/responses 固定返回 405,会话 sticky 到该账号后就永久锁死:
1. shouldFailoverUpstreamError 不含 405,请求不进换号循环
2. handleGrokAccountUpstreamError 的 switch 不含 405,账号不进临时不可调度
3. 账号仍可调度,sticky 不清理,客户端自动重连继续绑同一个坏号
改动两处:
- shouldFailoverUpstreamError 增加 405,让请求可换号,sticky 随之更新
- handleGrokAccountUpstreamError 增加 405 → 30 分钟冷却,与 403 同级
Fixes #4668
|
2026-08-07 20:37:56 +08:00 |
|
li
|
379db19141
|
perf(openai): 工具 Schema 净化改为单次拼接,去掉逐路径全量重写
sjson.SetBytes 在 opts 为 nil 时 optimistic=false、inplace=false,每次调用都要
重扫整个文档并新建缓冲区拷贝,命中 N 处就是 N 次全量拷贝。/v1/responses 的 body
上限是 gateway.max_body_size(默认 256MB),构造请求能塞进百万级命中,会被放大
成 TB 级 memcpy。
改为收集 gjson 给出的绝对字节偏移后一次性拼接:全程一次分配、一次拷贝。
偏移不可用(Index 为 0)或与 body 对不上时跳过该处,而不是猜位置拼出损坏的 JSON。
实测(2000 处命中):旧写法 17740 次分配,新写法 18 次。
|
2026-08-07 20:37:44 +08:00 |
|
li
|
f3c94d2099
|
fix(openai): 修正 Responses 工具 Schema 中显式为 null 的 parameters.type
Codex Desktop 内置的 automation_update 工具会带 parameters.type = null,
OpenAI 直接回 400 invalid_function_parameters,而网关把该状态归一成可重试的
502 upstream_error。该工具定义还会沉进多轮会话历史,之后每一轮都继续失败,
同一份坏 Schema 在账号池里被反复重放。
在 OpenAIGatewayService.Forward 分流到 passthrough / Codex transform /
原生 ChatCompletions 之前,统一把显式为 null 的 parameters.type 补成
"object",覆盖顶层 tools[] 与多轮历史里 input[].tools[] 的嵌套工具定义。
只修正显式 null:缺失 type 的 Schema 本身合法,补写会收窄客户端语义,
因此保持原样。
Fixes #5364
|
2026-08-07 20:30:44 +08:00 |
|
 Wesley LiddickandGitHub
|
b8c0c00091
|
Merge pull request #5384 from fengshao1227/fix/ops-system-log-sink-flush-backoff
fix(ops): 系统日志落库失败后退避重试,避免拖垮数据库连接池
|
2026-08-07 20:20:20 +08:00 |
|
 Wesley LiddickandGitHub
|
bd9b12bbcb
|
Merge pull request #5380 from Wei-Shaw/fix/subscription-daily-midnight-reset
fix(subscription): 恢复日额度每天 0 点重置,修复手动重置后刷新时刻漂移
|
2026-08-07 19:49:08 +08:00 |
|
li
|
e687ca3e9d
|
fix(ops): 系统日志落库失败后退避重试,避免拖垮数据库连接池
OpsSystemLogSink 的 flush 没有任何失败退避:ticker 每 1 秒触发一次,每次都
带 5 秒超时打一批 COPY,失败后立刻在下一个 tick 再来一次。远程 PostgreSQL 上
COPY 被 context 取消会导致协议失步、连接被服务端 FATAL 终止,于是这条循环
变成持续的「占用连接 → 超时取消 → 销毁重建」;在 max_open 较小的连接池里,
日志通道会长期占满连接,业务侧最终报 Billing 503。
改为连续失败后指数退避(2s 起,翻倍,封顶 60s):
- 退避窗口内直接丢弃当前批次并计入 dropped_count,不再触达数据库;
- 任意一次成功立即清空失败计数与抑制窗口;
- 失败日志随退避天然收敛为每个窗口至多一条,并附带 failures/backoff。
Fixes #5265
|
2026-08-07 18:45:05 +08:00 |
|
shaw
|
99b357083e
|
fix(subscription): restore midnight daily quota reset
日额度窗口恢复日历日语义(配置时区每天 0 点刷新),修复 v0.1.170 引入的回归:
- 手动重置配额后日窗口锚点漂移到重置时刻,此后 0 点不再刷新
- 新建/续费订阅日窗口按购买或首用时刻滚动,而非 0 点刷新
日窗口三处锚点(激活/手动重置/续期)统一写入当天 0 点,自动重置改为跨日历日
边界触发;存量非 0 点锚点在下一个 0 点自愈,无需数据库迁移。周/月窗口保持
期限对齐滚动语义(含到期约束)不变,不回归 issue #5051 的月额度翻倍问题。
日卡一次性额度豁免逻辑保留。
|
2026-08-07 17:42:51 +08:00 |
|
 Wesley LiddickandGitHub
|
32e4de7942
|
Merge pull request #5231 from fengshao1227/fix/upstream-dial-timeout
fix(upstream): set explicit TCP dial timeout on upstream transports
|
2026-08-07 16:24:53 +08:00 |
|
 Wesley LiddickandGitHub
|
8f55e0a7cd
|
Merge pull request #5267 from wucm667/fix/issue-5264-model-plaza-composite
fix(model-plaza): show Composite group models
|
2026-08-07 16:17:52 +08:00 |
|
 Wesley LiddickandGitHub
|
5ec11885d1
|
Merge pull request #5307 from lenzhang/fix/ws-prewarm-continuation
fix(ws): allow Codex prewarm continuation
|
2026-08-07 16:15:11 +08:00 |
|
 Wesley LiddickandGitHub
|
c8af48d769
|
Merge pull request #5315 from wucm667/fix/issue-5312-ops-custom-error-range
fix(ops): preserve custom range in error lists
|
2026-08-07 16:15:00 +08:00 |
|
 Wesley LiddickandGitHub
|
dce0f6b4e3
|
Merge pull request #5337 from wucm667/fix/issue-5331-oauth-count-tokens-fallback
fix: avoid cooling OAuth accounts for HTML count token errors
|
2026-08-07 16:14:48 +08:00 |
|
 Wesley LiddickandGitHub
|
22ef761c27
|
Merge pull request #5309 from wucm667/fix/issue-5308-antigravity-gemini36
fix(antigravity): support Gemini 3.6 Flash models
|
2026-08-07 16:14:37 +08:00 |
|
 Wesley LiddickandGitHub
|
865002fd2c
|
Merge pull request #5317 from wucm667/fix/issue-5314-grok-video-task-id
fix(grok): bind video owners for task_id receipts
|
2026-08-07 16:14:25 +08:00 |
|
 Wesley LiddickandGitHub
|
93367b6db4
|
Merge pull request #5351 from Wei-Shaw/fix/codex-tui-default-identity
fix(openai): default OAuth identity to codex-tui
|
2026-08-07 10:17:00 +08:00 |
|
shaw
|
b6e53c9320
|
fix(frontend): align Codex UA setting copy
|
2026-08-07 10:06:28 +08:00 |
|
shaw
|
dbb42881c0
|
fix(openai): default OAuth identity to codex-tui
|
2026-08-07 09:56:03 +08:00 |
|
 Wesley LiddickandGitHub
|
e4b0e1b66b
|
Merge pull request #5338 from Wei-Shaw/fix/tencent-captcha-region-csp
修复腾讯验证码区域适配、重置与 CSP 加载
|
2026-08-07 08:37:50 +08:00 |
|
Puppywang
|
02e50cc22d
|
fix(security): block OAuth account takeover via pending exchange
|
2026-08-07 03:09:57 +08:00 |
|
shaw
|
287a9f386b
|
fix: 修复腾讯验证码票据过期与区域切换
|
2026-08-06 21:27:06 +08:00 |
|
shaw
|
8e102b3a0f
|
fix: 完善腾讯验证码区域适配与 CSP 白名单
修复国内站和国际站 SDK 构造、验证容器、票据重置及动态资源加载问题,并补充认证流程回归测试。
|
2026-08-06 20:34:37 +08:00 |
|
wucm667
|
e93f6b9953
|
fix: avoid cooling OAuth accounts for HTML count token errors
|
2026-08-06 20:31:56 +08:00 |
|
shaw
|
a19c9f8d8a
|
chore: update sponsors
|
2026-08-06 19:31:17 +08:00 |
|
shaw
|
a1936d42db
|
chore: update sponsors
|
2026-08-06 19:30:44 +08:00 |
|
shaw
|
c123caddd4
|
chore: update sponsors
|
2026-08-06 14:22:46 +08:00 |
|
 Wesley LiddickandGitHub
|
e08aee49ed
|
Merge pull request #5266 from shentry/fix/transient-streak-rate-dependence
fix(openai): keep transient failure streak from resetting on sparse traffic
|
2026-08-06 14:11:49 +08:00 |
|
 Wesley LiddickandGitHub
|
c9e60d1f26
|
Merge pull request #5031 from keaipiao/fix/easypay-error-utf8
fix(payment): preserve UTF-8 in EasyPay errors
|
2026-08-06 14:10:41 +08:00 |
|
 Wesley LiddickandGitHub
|
47c03c75d8
|
Merge pull request #5232 from fengshao1227/fix/billing-quantize-monetary-scale
fix(billing): quantize usage billing amounts to the NUMERIC(20,8) scale
|
2026-08-06 14:00:04 +08:00 |
|
wucm667
|
5b7a64334f
|
fix(grok): support task IDs for video owner binding
|
2026-08-06 04:30:10 +08:00 |
|