Skip to content

优化 openai websocket mode v2 网关#714

Closed
mt21625457 wants to merge 135 commits intoWei-Shaw:mainfrom
mt21625457:dev-upstream-clean
Closed

优化 openai websocket mode v2 网关#714
mt21625457 wants to merge 135 commits intoWei-Shaw:mainfrom
mt21625457:dev-upstream-clean

Conversation

@mt21625457
Copy link
Contributor

@mt21625457 mt21625457 commented Mar 2, 2026

Summary

  • merge latest fixes from test into dev first
  • rebase onto upstream/main and collapse into a single clean commit
  • align OpenAI WebSocket mode v2 gateway/protocol/forwarder related paths with test baseline

Commit

Notes

  • direct push to upstream main is not permitted for current account, so this PR is submitted for merge into Wei-Shaw/sub2api:main.

yangjianbo and others added 30 commits February 24, 2026 11:58
为 OpenAI Responses 增加依赖自检与 panic recover 兜底,避免异常击穿请求链路。

为 Gateway/OpenAI/Sora 的使用量任务同步回退路径增加 panic 防护,并验证 panic 后后续任务仍可执行。

补充依赖检查与 recover 相关边界用例,覆盖不覆盖已写响应、无 panic 不写响应等行为。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 支持 Responses WS 入站路由与升级处理
- 将 WS 并发槽位改为按 turn 获取与释放,避免长连接占槽
- 为 WS 入站补齐每轮 usage 记录与首 token 指标
- 收敛协议行为:v2 入站仅允许 response.create
- 增加可携带 close code 的错误类型并细化客户端关闭语义
- 统一 WS 模式日志标记 openai_ws_mode=true

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 合并 function_call_output 校验入口,减少重复遍历 input

- WS ingress 改为单次 json.Unmarshal,并统一字段提取

- usage 提取统一为 gjson 路径,补充 benchmark 对比

- 修复 OpenAIWSMode 标记与相关测试断言

- 修复 lint 问题(errcheck/ineffassign)
- 抽取 function_call_output 预校验 helper,改为早返回

- 抽取用户/账号槽位获取 helper,收敛等待队列分支

- WS ingress 事件类型解析改为 switch,减少 if 嵌套
- 后端新增 request_type 字段与查询过滤优先级,保留 stream/openai_ws_mode 兼容
- 前端新增 request_type 类型与解析工具,统一 WS/流式/同步展示与筛选
- 增加迁移脚本、接口适配与回归单测,修复 request_type 回退兼容缺陷

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 修复 WS error 事件连接复用污染风险,统一标记连接为 broken

- 写超时继承父 context,降低客户端断连后的资源占用

- 增加连接池后台心跳/清理机制并拆分读写锁,提升连接健康性

- 增强协议决策与状态存储超时策略,补齐告警日志

- 下调消息读上限并统一并发参数来源,修复配置不一致

- 新增与强化 forwarder/pool/state_store/protocol/handler 单元测试
- 恢复 OpenAI 会话哈希为 SHA-256,避免粘性键兼容性回归
- 恢复 WS 获取路径 3 秒清理周期,降低关闭连接占坑窗口
- 在 OpenAI handler 早期校验前恢复请求上下文埋点
- 补充哈希算法与清理间隔回归测试

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 为分组存在性校验增加 groupRepo 空指针防护,避免运行时崩溃
- 在批量绑定成功后回写混合渠道预加载快照,防止同批次漏检
- 批量加载用户分组倍率失败时自动回退到逐用户查询
- 补充并更新 unit 回归测试覆盖上述场景

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
针对 054_drop_legacy_cache_columns.sql 增加受控兼容规则,允许历史数据库 checksum 与当前文件 checksum 在白名单条件下通过校验。

新增单元测试覆盖兼容命中与未命中场景,避免后续回归。
yangjianbo and others added 27 commits February 28, 2026 22:42
- 重构 WS 账号调度器,增强熔断、粘连释放、趋势与软选择策略\n- 增加 pending tool call 状态存储与 ingress 自愈续链逻辑\n- 收敛 WS 模式为 off/ctx_pool,并补齐 shared/dedicated 兼容迁移\n- 前端账号弹窗同步调整 WS 模式选项与相关测试\n- 补充大规模后端单测与性能测试,更新示例配置与部署文件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 移除重复的 X-Forwarded-For/X-Forwarded-Proto/X-Forwarded-Host 透传\n- 保留 X-Real-IP 与 CF-Connecting-IP 作为后端来源

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- add groupID dimension to pending tool-call cache keys and APIs\n- propagate group-scoped reads/writes through ws state store and forwarder\n- update tests for group isolation and new signatures\n- align deploy config example ingress_mode_default with runtime default
- 收敛 OpenAI WSv2 ctx_pool ingress 归一化流程并补齐不变量测试
- 强化 usage 记录兜底与 request_id 回退策略,降低漏计费风险
- 引入计费补偿与状态存储相关改造,更新配置与迁移脚本
- 同步清理与归档规划文档并对现有测试矩阵做配套更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
统一补齐网关、缓存、计费补偿等路径的上下文超时控制,
避免后台任务和网络依赖在异常场景下无界阻塞。
同时补充并更新相关单元测试,覆盖关键超时与重试行为。
- 重构 WSv2 ingress 上下文池与标准化处理,补齐前向转发异常兜底
- 新增 usage 计费补偿与重试字段迁移,完善网关与仓储相关测试覆盖
- 清理历史 .planning 阶段与提案文档,更新示例配置项

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ContinueTurn 中止且未下发内容时补发 error 事件,避免会话双向等待
- previous_response_id 恢复失败后改为删除 ID 并完整重放输入
- 增加重试/恢复跳过及上游读错分类日志,便于线上排障
- 同步调整相关测试配置字段与本地缓存降级断言

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…id 导致上游报错

修复回归:之前的 drop_previous_response_id_function_call_fallback 策略在
hasFunctionCallOutput=true 且 set/align 均失败时,错误地移除 previous_response_id
但保留 function_call_output,导致上游报 "No tool call found for function call output
with call_id ..."。

function_call_output 与 previous_response_id 语义绑定不可分割,正确行为是
abort 后通过 error 事件通知客户端,客户端收到后重置并发送完整请求。

新增 21 个单元测试覆盖恢复策略、语义绑定、ContinueTurn 通知等核心路径。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
在三个核心文件中共添加 23 条排错日志,覆盖 WSv2 网关整条链路:

forwarder (7条):
- ingress_ws_session_init: 会话初始化参数
- ingress_ws_validate: 入口校验(mode/transport)
- ingress_ws_turn_begin: turn 开始时的完整状态快照
- ingress_ws_turn_completed: turn 成功完成的结果摘要
- ingress_ws_advance_wait_client: 等待客户端下一条消息
- ingress_ws_advance_read_fail: 客户端消息读取失败
- ingress_ws_acquire_lease_fail: 上游连接获取失败

context_pool (8条):
- ctx_pool_owner_wait_exhausted/canceled: owner 竞争等待耗尽/取消
- ctx_pool_full_no_migration/no_migration_candidate: 容量满降级
- ctx_pool_dial_fail/dial_ok: 上游拨号失败/成功
- ctx_pool_mark_broken: context 标记损坏
- ctx_pool_migration: 迁移执行成功

state_store (8条):
- BindResponseAccount/PendingToolCalls/SessionLastResponseID Redis 写失败
- GetResponseAccount legacy fallback
- GetResponsePendingToolCalls/SessionLastResponseID Redis 回源命中/失败

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
将 sendAndRelay 中的串行读写改为 goroutine+channel 并发泵模式,
解耦上游读取和客户端写入,降低端到端延迟。
排水模式通过 time.AfterFunc + pumpCancel 实现。

新增 55 个单元测试覆盖泵 goroutine 的所有代码路径:
正常事件流、终端/错误事件终止、读取错误传播、上下文取消、
缓冲行为、排水定时器集成、lease.MarkBroken 行为、
大消息传递、并发安全、多轮会话等场景。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- P1: pingContextUpstream 增加 connID 代次守卫,新增 markContextBrokenIfConnMatch
  防止旧连接 Ping 失败误杀已重建的新连接
- P2a: scheduleDelayedPing 改为 per-context 去重,同一 context 仅保留一个
  pendingPingTimer,连续 yield 只 Reset timer 不创建新 goroutine
- P2b: normalizer 重构为纯透传 + callID 提取模式,所有边缘场景由
  recoverIngressPrevResponseNotFound 兜底
- P3: deploy/config.example.yaml 补充 upstream_conn_max_age_seconds 字段
- 补强测试覆盖并发回归、去重、busy 防护等场景

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
store_disabled=true 模式下,preflight ping 超时后的恢复逻辑会修改客户端 payload
(drop previous_response_id + 替换 input),导致 function_call_output 的 call_id
变成悬空引用,上游返回 "No tool call found" 错误。

全透传模式下 proxy 不应修改 payload,ping 失败时应:重连 → 原样转发 → 错误透传。

主要变更:
- 删除 preflight ping 失败时 forcePreferredConn 的三层恢复分支
  (strictAffinityBypass / dropPreviousResponseID / StatusPolicyViolation)
- 删除 acquire 失败时 forcePreferredConn 的恢复分支
  (ctx_pool_busy bypass / rehydrate / drop previous_response_id)
- 完整移除 strictAffinityBypassOnce 机制及 turnPreferredRehydrateTried 变量
- 新增 client preempt 支持:客户端可在 turn 未完成时发送新请求抢占当前 turn

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ESC 取消后存在无日志延迟,增加关键路径日志定位瓶颈:
- pump goroutine 因 context cancel 退出时记录 pump_alive_ms
- resetSessionLease 超过 100ms 时记录 elapsed_ms
- client_preempted abort 处理完成时记录 reset_elapsed_ms
- advanceToNextClientTurn 使用预缓存 payload 时记录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codex CLI 按 ESC 取消后会关闭旧 WebSocket 并新建连接发送下一条消息,
旧连接的 5 秒排水超时会阻塞上游 lease 释放,导致新连接等待时间过长。

将 clientReadErrCh 和 writeClientMessage 两条断连路径从排水模式改为
立即 pumpCancel + MarkBroken + return,使上游连接即时释放。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OpenAI 上游在服务重启/重部署时发送 StatusServiceRestart(1012) 或
TryAgainLater(1013) close frame。之前代码将其分类为 read_upstream →
FailRequest,导致整个 WS 会话终止,客户端需重建连接(~3s 延迟)。

改动:
- 新增 upstream_restart abort reason,分类为 ContinueTurn
- 新增 isOpenAIWSUpstreamRestartCloseError 检测 1012/1013 close code
- ContinueTurn 分支为 upstream_restart 始终补发 error 事件(连接级关闭,
  客户端未收到终端事件)
- 新增 classifyOpenAIWSIngressReadErrorClass 提取上游读错误分类逻辑
- 新增 advanceConsumePendingClientReadErr/advanceClientReadUnavailable
  辅助函数及对应日志
- 扩展 classifyOpenAIWSErrorEventFromRaw 识别更多 tool_output_not_found
  错误消息模式
- 补充相关单元测试覆盖

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…时主动注入

在 store_disabled 的 ctx_pool 模式下,客户端发送包含 function_call_output
的 turn 但不携带 previous_response_id 时,上游无法关联 tool call,
返回 "No tool call found for function call output" 错误。

根因:第 2827 行的 currentPreviousResponseID != "" 条件守卫导致整个
shouldKeep/注入逻辑被跳过,payload 原样透传;上游先发正常事件
(wrote_downstream=true)再报错,两层恢复机制全部失效。

修复:在 normalize 完成后、发送上游前,调用已有的
shouldInferIngressFunctionCallOutputPreviousResponseID 辅助函数检测该场景,
命中时通过 setPreviousResponseIDToRawPayload 注入 Gateway 跟踪的
lastTurnResponseID,使下游 shouldKeep 校验、强粘性连接选择、
内层恢复条件全部自动生效。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mt21625457 mt21625457 changed the title feat(gateway): align OpenAI WebSocket mode v2 with latest test fixes 优化 openai websocket mode v2 网关 Mar 2, 2026
@mt21625457 mt21625457 force-pushed the dev-upstream-clean branch from b561452 to dc8a318 Compare March 2, 2026 09:25
@mt21625457 mt21625457 closed this Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant