7.8 KiB
7.8 KiB
err.md
2026-06-26 独立 Codex Retry Gateway
设计边界
- 只解决 Codex 已可访问上游时的
reasoning_tokens = 516重试问题 - 不替代
cc-switch的协议路由转换 - 流式场景默认策略是:
- 先缓存上游流
- 一旦检测到命中
516 - 统一返回
502
当前已知限制
- 如果上游只支持 Chat Completions、而 Codex 当前链路需要 Responses 协议转换,这个项目不处理该转换
- 这个项目依赖 Codex / Codex Desktop 自身的自动重试能力
本次已确认并修复的问题
-
gateway.mjs非流式透传发头顺序错误- 现象:
ERR_HTTP_HEADERS_SENT - 根因:
writeHead()在copyHeadersToClient()之前调用 - 结果:正常
128响应也会被打断
- 现象:
-
PowerShell 脚本在
powershell.exe下的解析兼容性- 现象:脚本乱码并伴随解析异常
- 根因:新脚本初版包含中文运行时字符串,且
param(...)不在文件最前 - 处理:运行时输出改成 ASCII,并把
param(...)提前到文件顶部
-
stop-gateway.ps1与 PowerShell 内置只读变量$PID冲突- 现象:安装脚本在重启 gateway 时失败
- 处理:改用
$gatewayPid
-
start-gateway.ps1启动 Node 时路径带空格- 现象:gateway 进程启动后立刻退出
- 根因:
Start-Process参数未显式带引号 - 处理:改为手工拼带引号的
ArgumentList
-
PowerShell 单元素数组落盘时被拆成标量
- 现象:
reasoning_equals被写成516,不是[516] - 处理:在公共归一化函数里强制返回数组
- 现象:
-
旧脏配置迁移后出现嵌套/拼接 endpoints
- 现象:
endpoints可能变成嵌套数组,或出现一条用空格拼接的脏字符串 - 处理:安装脚本合并 endpoints 时做递归拍平和空白拆分
- 现象:
-
真实 Codex 客户端请求路径不是
/v1/responses- 现象:
codex exec在 gateway 关闭时真实报错地址是http://127.0.0.1:4610/responses - 结论:默认配置必须同时覆盖:
/responses/chat/completions/v1/responses/v1/chat/completions
- 现象:
-
UI 恢复动作最初采用“子进程拉起 restore 脚本”方案
- 现象:浏览器拿到
202,但临时config.toml、state.json、gateway.pid都没有变化 - 根因:恢复动作通过 detached 子进程接力时,链路可靠性不足,实际没有把恢复流程真正执行完
- 处理:改为当前 gateway 进程直接复制备份、清理状态并自我退出
- 现象:浏览器拿到
-
新增内嵌 UI 管理页
- 入口:
/__codex_retry_gateway/ui - 能力:
- 查看当前接管状态
- 热更新
reasoning_equals - 热更新
endpoints - 热更新
non_stream_status_code - 开关
log_match - 一键恢复 Codex 原设置
- 入口:
-
用户不接受
cc-switch路由模式,且不希望手工改设置
- 现象:仅有安装脚本和 UI 还不够,首次接管、再次拉起、重新打开 UI 仍需要手工串命令
- 处理:新增
launch-ui.ps1 - 结果:
- 首次运行自动安装并打开 UI
- 再次运行自动复用
state.json + config.json并重启 gateway - 平时规则调整和恢复统一回到 UI 内完成
- UI 需要动态显示实时日志、
516次数和占比
- 现象:原 UI 只能改配置,看不到运行中的命中趋势
- 处理:
- 在
gateway.mjs内增加运行期统计 - 增加日志接口
- UI 轮询显示“被检查响应总数 / 516 命中次数 / 516 占比 / 实时日志”
- 在
- 统计口径:
- 按本次 gateway 启动以来累计
516占比 =reasoning_tokens = 516的响应次数 / 被检查响应总数
- macOS / Linux 不能直接使用现有 PowerShell 管理脚本
- 现象:
launch-ui.ps1、restore-codex-config.ps1等入口绑定了 PowerShell 和 Windows 进程控制 - 处理:
- 新增跨平台
node管理核心 - 新增
.sh包装入口:launch-ui.shrestore-codex-config.shinstall-for-current-provider.shstart-gateway.shstop-gateway.sh
- 新增跨平台
- 结果:
- Windows 继续走
.ps1 - macOS / Linux 直接走
.sh - UI、状态文件、gateway 主逻辑保持同一套
- Windows 继续走
- Windows 主机上模拟 Unix shell 入口时存在路径与 Node 版本兼容问题
- 现象:
- Bash 入口最初找不到脚本路径
- Bash 默认
node版本过老,不支持现代语法 node.exe需要 Windows 路径,而 shell 侧是 POSIX 路径
- 处理:
- 测试改成相对 POSIX 路径执行
.sh .sh优先选择node.exe- 在 WSL / Bash 场景下把路径参数转换回 Windows 路径后再交给
node.exe
- 测试改成相对 POSIX 路径执行
- 上游流式连接中途终止时被误记为网关错误,首次瞬断也缺少最小重试
- 现象:
- 日志出现:
TypeError: terminatedTypeError: fetch failed
- 其中一部分来自上游 SSE 中途断流,另一部分来自上游首次连接瞬时失败
- 日志出现:
- 根因:
handleStreaming()直接把reader.read()抛出的AbortError/TypeError: terminated冒到统一错误处理proxyRequest()对上游fetch()没有做一次轻量重试,首个瞬断会直接返回502
- 处理:
- 新增预期流终止识别:
AbortErrorTypeError: terminated
- 这两类在流式处理中按“连接已结束”收口,不再记
[error] - 新增上游
fetch failed的一次自动重试 - 新增严格
502流式模式:- 默认不再抢先透传
200头和首个 chunk - 先缓存流,再根据
reasoning_tokens决定透传或返回502
- 默认不再抢先透传
- 新增预期流终止识别:
- 验证:
scripts/test-gateway-e2e.mjs- 新增
/responses流式覆盖 - 新增“上游半路断流不刷 error 日志”断言
- 新增“首次 fetch failed 后第二次成功恢复”断言
- 新增“流式
516统一返回502,不再先透传半截 chunk”断言
- 新增
scripts/test-install-restore.mjs继续通过
2026-06-26 实测证据
- 假上游 E2E
test-gateway-e2e.ps1通过- 已验证 root 路径和
/v1路径都能区分516与128
- 安装/恢复闭环
test-install-restore.ps1通过- 已验证 UI 页面、状态接口、日志接口、516 统计、热更新配置、UI 恢复闭环
- 一键启动入口
test-launch-ui.ps1通过- 已验证首次启动自动安装、再次启动自动复用、UI 页面可达、默认
516 -> 502规则仍生效
- Unix shell 入口
test-launch-ui-unix.ps1通过- 已验证
.sh入口能完成启动、透传、恢复闭环
- Bash 默认入口实机验证
bash ./scripts/launch-ui.sh --no-open通过- 输出
mode=reuse GET /__codex_retry_gateway/health返回200GET /__codex_retry_gateway/ui返回200GET /v1/models返回200,并继续透传到真实上游
- Bash 入口后的
codex exec实机验证- 命令退出码
0 - 最后一条消息文件返回
OK
- 命令退出码
- 当前真实 provider
- 当前 Codex 配置里的
base_url已可切到http://127.0.0.1:4610 - 当前 gateway 运行配置里的
upstream_base_url会指向用户自己的真实上游 GET /__codex_retry_gateway/health返回ok=trueGET /v1/models已经经本地 gateway 成功透传到真实上游GET /__codex_retry_gateway/ui已实机打开,页面显示当前 upstream、provider、config 路径和 516 规则
- 当前 Codex 配置里的
- 真实
codex exec- gateway 停止时,CLI 真实提示:
url: http://127.0.0.1:4610/responses- 并自动进入
Reconnecting...
- gateway 恢复后,
codex exec在临时目录再次成功返回OK
- gateway 停止时,CLI 真实提示: