Repository navigation
[Provider compatibility] Responses v2 compaction fails with fresh hosted web_search_call history #6742
Description
Client or integration
Codex App 中观察到 remote compaction 失败;以下独立复现使用 Direct HTTP client(Python urllib + SSE),不依赖原用户会话。
Provider or upstream service
OpenAI ChatGPT/Codex subscription route,固定 main/gpt-6.1-sol,reasoning.effort=high。6 次探针的本地 usage 记录均关联到同一显式账户路由和模型,最终 wire effort 为 high,每次一次上游发送,未发生模型回退。
OpenCodex version
本机安装包与 health 报告 @bitkyc08/opencodex 2.70.0,macOS。
重要范围:这是带本地增量补丁的安装版本,不是干净的 2.70.0 发布包,也尚未在最新上游 dev 重跑。 本地包含模型目录、Jev 和压缩相关增量,不能仅根据版本号推断所有 2.70.0 都受影响。测试期间运行配置 hash 未变化。希望先报告可复现的请求形态,再确认当前上游是否也存在相同问题。
Endpoint or capability
POST /v1/responses,stream:true、store:false,历史末尾追加 {"type":"compaction_trigger"} 的 Responses v2 压缩。
Current behaviour
2026-10-08 12:02–12:03(UTC+8),在全新测试历史中先成功执行真实 hosted web search,再提交完整 output 进行压缩,约 1 秒后收到 SSE error / server_error,无 compaction 输出。
只删除历史中的 web_search_call,保留原 user message、reasoning 和 assistant message,其余压缩参数不变,即可得到 response.completed 和非空 compaction.encrypted_content。再仅使用该 compaction 项续聊,能正确恢复预设测试事实。
| 对照 | 入站 JSON 字节数 | 耗时 | SSE 终态 / 结果 |
|---|---|---|---|
| 全新真实 hosted search | 599 | 12.22s | completed;返回 search、open_page、find_in_page 三条 web_search_call |
| 完整真实历史压缩 | 3707 | 1.03s | error / server_error,无 compaction |
| 仅移除全部 web_search_call | 2903 | 7.54s | completed,非空 compaction,非 ocx1 前缀 |
| 仅凭压缩项续聊 | 3350 | 2.74s | completed,准确恢复 AZURE-KITE-731 / 17 |
| 保留其他历史,仅保留 search 类型的 web_search_call | 3244 | 1.02s | error / server_error |
| 保留其他历史,仅保留 open_page 类型的 web_search_call | 3118 | 1.09s | error / server_error |
所有客户端 HTTP 状态都是 200;失败由 SSE 终态识别,不能算成功。字节数是入站编码 JSON 大小,不是最终上游字节数或 token 数。
Expected behaviour
客户端应能够压缩刚刚成功生成的搜索会话并继续对话。如果所选压缩后端不接受某种历史 item,希望代理做语义保真的兼容处理,或返回明确、可恢复的错误,而不是 generic server_error 导致会话无法压缩。
这是具体客户端需求;不主张公开 Web search 文档保证所有订阅压缩接口都接受任意历史 item。
Minimal redacted request or reproduction
固定同一账户、模型和 thread-id;正常使用现有认证,不需要提供私人会话、凭据或合成的 search ID。以下字段是验证时使用的形态,main 是本机账户别名。
- 对
/v1/responses发送全新普通请求并完整收集 SSEresponse.completed.response.output:
{
"model": "main/gpt-6.1-sol",
"stream": true,
"store": false,
"reasoning": {"effort": "high"},
"instructions": "Follow the user request. Be concise.",
"tools": [{"type": "web_search"}],
"input": [{"role": "user", "content": "For this isolated test remember these facts: project codename AZURE-KITE-731; sample count 17. Use the real hosted web search tool to search official OpenAI documentation for Responses API web search output items. Then open the official documentation page once if available. Briefly name the output item type and cite the official page. Do not search for the test facts."}]
}- 确认返回真实
web_search_call(不是自造 ID,也不是本地函数工具)。令history = initial_input + completed_output;保留返回项原值,包括 reasoning,仅在内存中处理。 - 将如下 body 发给同一
/v1/responses。input实际替换为history + [{"type":"compaction_trigger"}],并加 headerx-codex-turn-metadata: {"request_kind":"compaction","compaction":{"trigger":"manual"}}:
{
"model": "main/gpt-6.1-sol",
"stream": true,
"store": false,
"reasoning": {"effort": "high"},
"instructions": "Compact the supplied conversation. Preserve the user test facts and useful cited evidence. Do not execute tools.",
"input": ["<replace with actual history items>", {"type": "compaction_trigger"}]
}- 严格对照:仅过滤
item.type == "web_search_call",其余历史、header、模型、账户和压缩参数不变,再发送一次。观察失败与完成终态的差别。 - 如成功,仅把返回的
compaction项及新问题What were the test project codename and sample count? Reply with only those two values.发给普通/v1/responses;不再附带原始测试事实。实测回答为AZURE-KITE-731, 17。 - 可选拆分对照:分别只保留真实
search/open_page搜索项,其他非搜索历史不变;本次两者都独立失败。find_in_page未单独隔离验证。
无需公布或保存 reasoning / compaction 密文。上面的第二个 JSON 是动态请求模板,字符串占位项不能直接作为 API 输入。
Actual response or error
完整历史及两种 action 单独保留时均收到:
{
"type": "error",
"error": {
"message": "An error occurred while processing your request. You can retry your request, or contact us through our help center at help.openai.com if the error persists.",
"type": "server_error",
"param": null,
"code": "server_error"
}
}此处按收集到的事件类型与 error 字段整理;没有把 OpenCodex usage 中的终态 502 当作上游原始 HTTP 502。
Upstream documentation
OpenAI Web search 文档 描述 hosted search 输出与 action。本报告没有找到可据以断言订阅后端 compaction_trigger 历史接受范围的公开契约,因此以上述真实客户端对照为依据。
Suggested mapping or implementation notes
已确认的是 hosted search 历史的存在与本次压缩失败相关;尚未确定责任在代理改写还是上游接受规则。
- 本机
stripItemIdsWhenUnstored在store:false时删除 item ID,包括web_search_call.id。这是待查方向,不是已证实根因;尚未捕获最终出站 body 或做保留真实 ID 的严格对照。 - 本机 passthrough 会补齐 search 的 query/queries,portable compaction body 处理仍保留 hosted search 历史。
- 不能把诊断性的过滤方案直接当作生产修复:应保留周边回答、引用和实际结果,避免丢失来源信息,也不应重新搜索或伪造搜索结果。
- 期望回归同时覆盖原始失败、成功压缩、压缩后续聊,以及失败时不替换原历史。
Additional context and attachments
已检索 open/closed issues 中的 web_search_call、compaction search、compaction_trigger search,未发现完全相同报告。
相关但不能认定同根因:#3071 / #3068 是 search 参数缺失的 400;#6504 是 Claude Code 长上下文与输入上限错误映射。本次不足 4 KB 即复现,并且保留 reasoning 的过滤对照能成功。
验证边界:
- 本报告是全新真实 hosted search 的 API 复现;未完成桌面手动压缩 UI 的独立复现。
- 未验证真正 native v1
/responses/compact。该入口可能回退到内部 Responses,不能仅凭入口名称判断分支。 - 本轮没有重测 Jev Auto/Fast → Luna,也没有绕过 OpenCodex 直连上游;不能断言所有模型、账户或搜索项都失败。
- 未在干净最新 dev 重跑,未证明首次引入版本,也尚未修复。
- 未上传账户标识、token、原用户历史或密文。
Checks
- I searched existing provider and compatibility issues.
- The request and response were redacted.
- The expected behaviour is based on an upstream specification or a concrete client requirement.
Activity
yuanyuanlove commentedon Oct 8, 2026
先撤回本报告:后续使用官方 Codex 0.160.0 app-server 绕过 OpenCodex 的两次全新搜索、手动压缩和续聊均成功;其本地搜索历史表示也与本文 API 探针不同。因此目前的复现不足以把原始故障归因于 OpenCodex,也不足以归因于 Codex。我们将继续使用最新官方版本对齐客户端、历史形态和请求链路,确认准确触发条件后再提交适当报告。本次关闭不表示原故障已修复。