shaw
2cffe1cf5f
fix(compact): SSE→JSON 保留 raw output_item.done 并为 unary 等待补下游心跳(修复 #3887)
#3887 报告 v0.1.149(已含 #3880 桥接修复)remote compact 仍失败且持续
计费。核实为 #3880 明示的两个遗留:
1. 上游对 unary compact 返回 SSE 且 compaction item 只出现在 raw
response.output_item.done、终态 completed.response.output 为空
(#3777 实录形态)时,reconstructResponseOutputFromSSE 只累加
text/function_call/reasoning 三类 delta,compaction item 被丢弃,
桥接合成 0 个 output_item.done,Codex 报 "expected exactly one
compaction output item, got 0" 后盲目重试,每次重试重新消耗上游
compact 配额。
2. 桥接为全缓冲写回:上游 unary 完成前(大上下文可达数分钟,且上游
处理期间不发送任何字节)下游连响应头都收不到,反向代理
(Nginx/Cloudflare Tunnel)空闲超时掐断连接同样触发盲重连
(同类问题见 #2243/#2976)。
修复:
- reconstructResponseOutputFromSSE 优先以 raw JSON 逐字节收集
output_item.done item(协议上的最终完整形态),不经窄结构体,
encrypted_content/summary/opaque 等 compact 专属字段全部保留;
无 done 事件时退回收集 output_item.added 中的 compaction 类 item;
两者皆无才回到原 delta 重建。path-based v1 JSON 写回同样受益。
- 新增 openAICompactSSEKeepalive:body-signal 客户端流式 compact 在
上游等待期间按 gateway.stream_keepalive_interval 向下游写 SSE 注释
行心跳(eventsource 解析层直接忽略)。首拍延迟一个间隔,快速失败
仍走 JSON+状态码;首拍后状态码固化为 200,桥接/错误链路
(writeOpenAICompactSSEBridge、errorResponse、
handleStreamingAwareError、ensureForwardErrorResponse、
writeOpenAINonStreamingProtocolError)统一降级为 response.failed
终止事件并标记 ops 流内错误。
- API-key 账号的 compact 上游请求也强制 accept: application/json
(#3777 期望行为 4;透传白名单原会放行客户端的 text/event-stream)。
测试:#3777 实录形态经 handleSSEToJSON / 透传 / path-based 三条链路
的修补断言;raw-done 优先不与 delta 重复;added 回退门控;心跳提交、
提交后 2xx 续写、提交后失败降级、未提交行为不变;-race 通过。
Fixes #3887
Refs #3777 #3875 #3880
2026-07-10 09:56:56 +08:00
..
2026-07-09 14:57:53 +00:00
2026-07-09 15:38:59 +08:00
2026-07-10 09:56:56 +08:00
2026-07-09 15:38:59 +08:00
2026-07-07 03:27:11 +08:00
2026-07-01 14:25:46 +08:00
2026-07-09 14:06:57 +08:00
2026-07-09 14:06:57 +08:00
2026-07-08 08:37:29 +08:00
2026-07-01 14:25:46 +08:00