问题描述
部分第三方中转/反代网关(如 sub2api/claude2api 等社区中转服务)在转发 OpenAI Responses API 的 SSE 流式响应时存在解析 bug:
Responses API 的所有 SSE 事件名都以 response. 开头,比如:
response.output_text.delta
response.completed
一些中转服务的代码错误地对 SSE 流做了简单分词,如果匹配到 response 字符串就认为流已经结束,导致完整响应被提前截断,输出不完整就停止。
根因分析
在 open-codesign 的 CodexClient 实现中,SSE 解析是严格遵守协议的:
// packages/providers/src/codex/client.ts
const flushEvent = (dataLine: string) => {
// 只对精确 '[DONE]' 停止
if (dataLine.length === 0 || dataLine === '[DONE]') return;
// ...
// response.completed 只是保存最后一个事件,不会停止流
if (type === 'response.completed' || type === 'response.output_text.done') {
const response = (payload as { response?: unknown }).response;
if (response !== undefined) lastEvent = response;
}
};
// 继续循环直到 reader.read() 返回 done: true
所以问题不是出在 open-codesign 客户端,而是第三方中转网关自身对 SSE 的处理有 bug。现象就是:使用中转时更容易中途停止,响应不完整。
需要
@hqhq1025 在修复 4xx/5xx 诊断问题时,是否考虑:
- 在诊断提示里增加这条:如果你使用第三方中转服务且频繁遇到中途停止/截断,请先检查中转版本,某些旧版本中转对 Responses API SSE 分词有 bug
- 如果要做兼容性处理,是否考虑添加非流式 fallback 选项(当流式失败重试时用非流式)
问题描述
部分第三方中转/反代网关(如 sub2api/claude2api 等社区中转服务)在转发 OpenAI Responses API 的 SSE 流式响应时存在解析 bug:
Responses API 的所有 SSE 事件名都以
response.开头,比如:response.output_text.deltaresponse.completed一些中转服务的代码错误地对 SSE 流做了简单分词,如果匹配到
response字符串就认为流已经结束,导致完整响应被提前截断,输出不完整就停止。根因分析
在 open-codesign 的
CodexClient实现中,SSE 解析是严格遵守协议的:所以问题不是出在 open-codesign 客户端,而是第三方中转网关自身对 SSE 的处理有 bug。现象就是:使用中转时更容易中途停止,响应不完整。
需要
@hqhq1025 在修复 4xx/5xx 诊断问题时,是否考虑: