### 版本 v0.6.3(当前 latest release) 补充:已检查当前 main。PR #491(e6775a51)修复的是 `PassthroughSseUsageReader`,PR 描述明确说明不覆盖原生 `/v1/responses` 使用的独立 reader;本问题命中 `OpenAIResponsesPassthroughSseReader`。 ### 影响范围 Gateway / Protocol Adapter ### 环境信息 - macOS 15.7.3 (24G419) - CodexManager Desktop 0.6.3 - Codex Desktop 26.924.22138 - Codex CLI 0.155.1 - 模型:`gpt-6-sol` - 协议:`wire_api = "responses"`,HTTP SSE,`stream=true` - 实际链路:Codex Desktop → 本地透明转发器 → CodexManager `:48760` → `chatgpt.com/backend-api/codex/responses` - 新建短对话正常;长对话触发自动压缩时稳定复现 - 失败对话压缩前最后一轮约 206,627 input tokens,模型上下文窗口 258,400 ### 复现步骤 1. 让 Codex Desktop 通过 CodexManager 的原生 `POST /v1/responses` 路径工作。 2. 使用长对话,直到触发自动上下文压缩。 3. 当上游 SSE 返回 terminal error(本次为 `response protection is unavailable`)时观察 CodexManager 和 Codex 客户端。 4. Codex 客户端进入 `Reconnecting 1/5 ... 5/5`,最后显示: `stream disconnected before completion: stream closed before response.completed` 本次在同一轮中对多个候选账号重试,均出现相同行为。 ### 预期结果 CodexManager 应将上游 terminal error 以 Codex 能识别的、完整且可解析的 SSE 终止失败事件交付给下游(或在必要时规范化为 `response.failed`),使客户端显示真实上游错误并结束本次请求。 同时,诊断字段应能准确反映错误终态已经交付,而不是让客户端把它判断为“流在 `response.completed` 前无故关闭”。 ### 实际结果 CodexManager 已识别上游 terminal error,但诊断显示: - `stream_terminal_seen=true` - `stream_terminal_delivered=false` - `last_sse_event_type=error` - `stream_terminal_error=type=internal_error response protection is unavailable` - 上游 HTTP 已建立并返回 SSE,最终本地记录为 502 Codex 客户端没有显示真实的 `response protection is unavailable`,而是收到泛化错误 `stream closed before response.completed` 并重复重连。 这与 #485 不同:#485 是上游已返回 `response.completed`、下游随后 broken pipe;本问题是上游返回 terminal error,而原生 Responses 路径未让客户端正确识别该终态。 当前 main 中 `mark_terminal_delivered` 会识别 `response.completed`、`response.failed`、`response.incomplete`、`response.done` 和 `[DONE]`,但不识别通用 `event: error` / `type: error`。同时,PR #491 明确没有覆盖 `OpenAIResponsesPassthroughSseReader`。建议为原生 Responses reader 增加对应的错误终止透传/规范化回归测试。 上游产生 `response protection is unavailable` 本身可能是 OpenAI 侧问题;这里报告的是 CodexManager 没有把真实错误终态以客户端可识别的方式交付,导致错误被掩盖为缺少 `response.completed`。相关上游报告:openai/codex#52016、openai/codex#52043。 ### 脱敏日志 / 截图 ```shell event=gateway_bridge_stream_diagnostics adapter=Passthrough path=/v1/responses stream_terminal_seen=true stream_terminal_delivered=false stream_terminal_error="type=internal_error response protection is unavailable" last_sse_event_type=error Codex: Reconnecting 1/5 ... 5/5 stream disconnected before completion: stream closed before response.completed ``` 账号 ID、workspace ID、key ID、request ID、Cloudflare Ray ID、token/cookie 和请求正文均已省略。 ### 提交检查 - [x] 我已确认内容不包含敏感凭据 - [x] 我已阅读仓库的 SECURITY.md
Activity
poboll commentedon Oct 15, 2026
同样遇到了这个问题,感谢大佬推的PR!这个故障还是比较紧急的,大约可以什么时间发版~
补充一组针对 Codex 自动上下文压缩的对照测试,供定位参考。
环境与现象
stream disconnected before completion: response protection is unavailable。已观察到的对照结果
使用实际网关
POST /v1/responses,stream: true、store: false,在历史 input 的末尾放置{"type":"compaction_trigger"}:两个有效 OAuth 账号的后台 Compact 探测均成功。实际网关的成功请求收到
response.compaction.compacting、compaction输出项和response.completed,并返回x-codex-turn-state。失败流中的错误为:
{ "type": "response.failed", "error": { "type": "internal_error", "code": "upstream_error", "message": "response protection is unavailable" } }当前定位与待确认点
在本次历史拆分测试中,
web_search_call是已经定位到的触发条件。这不能证明所有该类型历史都会失败,也尚未区分是上游问题、搜索历史的特定字段/来源问题,还是网关兼容处理的问题。请求形态为:
{ "model": "gpt-5.6-sol", "instructions": "You are a helpful coding assistant.", "input": [ "...实际会话历史项(此处仅为形态示意)...", {"type": "compaction_trigger"} ], "stream": true, "store": false }建议检查原生 compaction 对 hosted web_search 历史项的兼容性,以及
NormalizeCompactionTriggerInputOrder前后的 HTTP/WS 请求规范化链路。仅在压缩请求中去掉web_search_call是目前观察到的规避方向,但仍需确认其中 action/sources 等信息的保留方式,避免丢失搜索上下文。尚未部署此方向的修复,也没有完成修复后的构建/回归;上述成功结果是对请求历史进行拆分后的实测。
qxcnm commentedon Oct 15, 2026
哥,今天晚上发吧,最近有点忙,在家里卖菜没顾上
qxcnm commentedon Oct 15, 2026
已更新