Skip to content

[Bug] v0.6.3 原生 /v1/responses 的 terminal error 未被 Codex 识别,压缩显示缺少 response.completed #501

Closed

Description

@serein431

版本

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。

脱敏日志 / 截图

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 和请求正文均已省略。

提交检查

  • 我已确认内容不包含敏感凭据
  • 我已阅读仓库的 SECURITY.md

Activity

  1. poboll commented on Oct 15, 2026

    @poboll

    同样遇到了这个问题,感谢大佬推的PR!这个故障还是比较紧急的,大约可以什么时间发版~

    补充一组针对 Codex 自动上下文压缩的对照测试,供定位参考。

    环境与现象

    • CodexManager v0.6.3,OpenAI OAuth 账号池。
    • 测试模型:gpt-5.6-sol。
    • Codex 自动压缩后反复重连,提示:stream disconnected before completion: response protection is unavailable。

    已观察到的对照结果

    使用实际网关 POST /v1/responses,stream: true、store: false,在历史 input 的末尾放置 {"type":"compaction_trigger"}:

    历史内容 结果
    最小普通消息历史 成功
    普通消息 + reasoning 历史 成功
    function call / tool output 历史 成功
    原始历史去掉 web_search_call 项 成功
    保留原始 web_search_call 项的历史 失败,相同错误
    原始完整历史 失败,相同错误

    两个有效 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 等信息的保留方式,避免丢失搜索上下文。

    尚未部署此方向的修复,也没有完成修复后的构建/回归;上述成功结果是对请求历史进行拆分后的实测。

    Image Image Image
  2. qxcnm commented on Oct 15, 2026

    @qxcnm
    Owner

    同样遇到了这个问题,感谢大佬推的PR!这个故障还是比较紧急的,大约可以什么时间发版~

    补充一组针对 Codex 自动上下文压缩的对照测试,供定位参考。

    环境与现象

    • CodexManager v0.6.3,OpenAI OAuth 账号池。
    • 测试模型:gpt-5.6-sol。
    • Codex 自动压缩后反复重连,提示:stream disconnected before completion: response protection is unavailable。

    已观察到的对照结果

    使用实际网关 POST /v1/responses,stream: true、store: false,在历史 input 的末尾放置 {"type":"compaction_trigger"}:

    历史内容 结果
    最小普通消息历史 成功
    普通消息 + reasoning 历史 成功
    function call / tool output 历史 成功
    原始历史去掉 web_search_call 项 成功
    保留原始 web_search_call 项的历史 失败,相同错误
    原始完整历史 失败,相同错误
    两个有效 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 等信息的保留方式,避免丢失搜索上下文。

    尚未部署此方向的修复,也没有完成修复后的构建/回归;上述成功结果是对请求历史进行拆分后的实测。

    Image Image Image

    哥,今天晚上发吧,最近有点忙,在家里卖菜没顾上

  3. qxcnm commented on Oct 15, 2026

    @qxcnm
    Owner

    已更新

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions