跳转到内容
18.1k

Proxy API 格式

opencodex 以多种客户端方言提供一个本地代理。Codex 客户端可以使用 Responses API,兼容 OpenAI 的应用可以使用 Chat Completions,而 Claude Code 可以使用 Anthropic Messages,而不需要每个上游提供方都实现每一种格式。

标准转换路径如下:

client dialect → internal Responses model → provider adapter → provider wire format
provider events → internal adapter events → client dialect

Responses 表示是这座桥的中心。原生兼容的路由可以跳过部分转换并直接透传请求, 但认证、路由、准入控制和响应安全仍然发生在代理边界。请在 Configuration 中配置监听器和准入密钥;当一个公开模型 ID 需要在多个目标之间选择时,请使用 Combos。

携带凭据的模型、图像、视频和搜索请求不会自动跟随 HTTP 重定向,包括同源重定向。请配置最终上游 API URL,而不是会重定向的别名。服务器不会向重定向目标重新发送凭据或请求正文。各响应处理路径保留原有的错误处理或转发行为;原生 Responses 和 compact 路径仍可向客户端返回原始 3xx 和 Location。客户端的重定向行为与此服务器传输策略是不同的边界。

部分 xAI Chat Completions 拒绝会以 HTTP 403 加上 I can't help with that request. 这类拒绝句返回,而不是 HTTP 200 加 finish_reason: content_filter。Codex 把 403 当作传输失败,因此用户回合不会被记录,同一请求会被重试。

在非 combo 的 Responses 请求上,OpenCodex 会把该 allowlist 中的 403 改写为 HTTP 200 Responses,status: "incomplete",incomplete_details.reason: "content_filter"。openai-chat 适配器路径和 openai-responses passthrough(grok-4.6 / grok-4.5 OAuth)都会改写。流式响应使用同一 incomplete 边界。空正文 403 仍是错误。订阅、额度、权限以及 not allowed to use this model 的 403 仍是错误。combo 故障切换仍会看到原始 HTTP 403。

在 Responses 端点上,当请求声明了工具目录时,原生直通响应若调用目录之外由客户端执行的工具,本轮会失败而不会转发该调用:流式响应发送带有错误代码 undeclared_tool_call 的 response.failed 事件,然后发送 data: [DONE];缓冲式 JSON 返回 HTTP 502 和相同错误代码。拒绝发生在响应进入续接状态之前。只有 authMode: "forward" 提供方或未声明目录的请求才跳过这一拒绝。

Chat Completions 和 Messages 端点支持延迟提供的工具目录:客户端可先声明部分目录,再通过自己的工具注册表在运行时发现其余工具;完整声明边界由客户端注册表决定,而不是翻译后的目录快照。目录之外的调用会转发给客户端验证;但针对显式空目录 tools: [] 的调用仍会被拒绝。此类拒绝在每种协议中都保留 undeclared_tool_call:

  • **Chat Completions:**发送包含带有该错误代码的 OpenAI 风格 error 对象的 data: 帧,然后关闭流,不发送成功完成标记或 [DONE];缓冲式 JSON 返回 HTTP 502 和该代码。
  • **Messages:**发送 Anthropic event: error 帧,正文为 { "type": "error", "error": { "type": "api_error", "code": "undeclared_tool_call", ... } },不发送成功的 message_stop 或 [DONE];缓冲式 JSON 返回 HTTP 502 api_error 和该代码。确定性的目录违规不会被报告为可重试的 overloaded_error(HTTP 529)。

此外,在所有入站协议中,提供方返回的 default. 命名空间调用都会规范化为客户端声明的裸名称,即使延迟目录规则关闭了上述拒绝检查。

原生 Messages 也会识别与 tools: [] 一同提供的系统消息内联工具定义。这些名称在被永久移除前仍可调用,但不会授权其他客户端工具。托管 MCP 调用和服务器工具的参数流保留原生格式。

客户端表面 端点 成功的非流式结果 成功的流式或套接字结果
OpenAI Responses POST /v1/responses Responses JSON Responses SSE,或通过 WebSocket 传输的 Responses JSON 文本帧
OpenAI Chat Completions POST /v1/chat/completions chat.completion JSON 以 chat.completion.chunk SSE 结尾并带 [DONE]
Anthropic Messages POST /v1/messages Anthropic message JSON Anthropic Messages SSE
Anthropic token count POST /v1/messages/count_tokens { "input_tokens": number } 不适用
模型发现 GET /v1/models 目录或显式 Desktop 快照 不适用
语音和 Realtime POST /v1/live, POST /v1/realtime/calls 转发的调用创建响应 独立的 sideband WebSocket 双向转发帧
Responses compaction POST /v1/responses/compact 替换历史 JSON 不适用

这是 opencodex 原生的数据平面形状。请求体必须是一个包含非空 model 的 JSON 对象。input 可以是字符串,也可以是 Responses 项目数组。

区域 接受的形态
模型和输入 必需的非空 model;可选的字符串 input 或项目数组
消息项 user、developer、system 和 assistant 消息;字符串内容,或适用于该角色的类型化内容块
内容块 当其父项允许时,可包含文本、输入图像、输入文件、输出文本、拒绝,以及 reasoning summary/text 块
工具历史 function_call、function_call_output、custom_tool_call 和 custom_tool_call_output 项
工具 函数工具以及宽松的内建或托管工具条目;tool_choice 接受 auto、none、required、命名的 function/custom 选择、托管选择,或 allowed_tools
推理 reasoning.effort 和 reasoning.summary(auto、concise、detailed 或 none)
续接和缓存 previous_response_id、store 和 prompt_cache_key
生成控制 max_output_tokens、temperature、top_p、stop、presence_penalty 和 frequency_penalty
服务和执行 stream、service_tier、parallel_tool_calls、instructions、metadata 和 user
扩展 Responses 字段 兼容路由接受 background、include、prompt、text 和 truncation

未知项目类型会作为宽松的类型化项被接受,以保证前向兼容。已翻译的适配器只处理它们能识别的项目类型,并且可能会拒绝其提供方无法表示的特性。

当 stream: true 时,响应为 text/event-stream。桥会发出 Responses 事件,例如 response.created、输出项和文本/工具增量,以及且仅有一个终止的 response.completed、response.failed 或 response.incomplete 事件。正常的流以 data: [DONE] 结束。

当 stream: false 或未提供 stream 时,同样的适配器事件会被收集为一个 Responses JSON 对象。两种形式都会保留所选模型、输出项、终止状态和 usage。

canonical ChatGPT Codex 路由的上游只接受 SSE,因此仅对上游请求使用 stream: true。 OpenCodex 会在有界限制内验证终止流,再将其折叠为客户端请求的 JSON 形式;显式 store 值不会 改变。验证失败时会返回错误,而不会以 HTTP 200 返回部分 JSON。限制为:每帧 4 MiB、transcript 和重建源各 32 MiB、100,000 个 SSE 帧,以及 10,000 个重建输出项。stallTimeoutSec 同时控制 首个 body byte 和后续静默间隔;当其为 0,或因本地上游默认禁用时,不会立即超时,只保留独立的 15 分钟整轮上限。流式客户端的行为不变。

面向客户端的 Responses SSE 帧按 SSE 块分隔符之前的原始字节计算,每帧限制为 4 MiB。对于 HTTP,未终止的上游帧一旦超过该限制,会以合成的 response.failed 事件并随后发送 data: [DONE] 的方式 fail closed。对于 Responses WebSocket 桥,相同情况会发送 502 websocket_protocol_error 并取消上游 reader。已经完整到达的 Responses 终止帧具有优先权;其后的超大或格式错误字节会被丢弃,而不会把已经完成的轮次替换为传输失败。

每个终止的 Responses usage 对象都包含两个 detail 对象,即使提供方没有报告这些细节:

{
"input_tokens": 0,
"output_tokens": 0,
"total_tokens": 0,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens_details": { "reasoning_tokens": 0 }
}

在可用时,input_tokens_details 还可以包含 cache_write_tokens。始终存在的 detail 对象是严格 Responses 客户端的兼容性保证;零可能表示“未报告”,不一定表示“提供方没有进行此类工作”。

每个通过准入的 HTTP Responses 回复都带有 x-opencodex-request-id 标头,其中保存代理生成的 ocx-<32 hex> 形式 ID。它是将响应与请求日志及使用情况报告中对应记录关联起来的键。

代理始终生成此值,并覆盖调用方提供或上游返回的任何 ID,因此该值仅属于此代理,可安全地用作关联键。该标头列在 Access-Control-Expose-Headers 中,浏览器 JavaScript 因而可以跨源读取它;否则,即使自定义 x- 标头已在网络上传输,response.headers.get() 也无法看到它。

在身份验证或来源准入阶段被拒绝的 Responses 请求不会到达此包装层,也不会带有 ID。因此,缺少该标头意味着请求在写入日志之前已被拒绝。

当启用 websockets 时,客户端可以升级 /v1/responses,而不是发起 HTTP POST。 认证和 origin 准入会在 WebSocket 握手期间发生,不会在每个帧内重复。

客户端发送 JSON 文本帧:

{
"type": "response.create",
"model": "provider/model",
"input": "Hello",
"tools": [],
"generate": true
}

除 type 之外的一切都会成为 Responses 请求体,并且代理会强制该轮为流式。新的 response.create 会取代并取消该 socket 上的上一轮。response.processed 被接受为无操作确认。无法解析或无关的帧类型会被忽略。

服务器帧是 JSON 文本帧。成功的流式输出使用与 SSE data: 行中相同的 JSON 负载,只是不带 SSE 封装或 [DONE]。非流式的内部结果会被重新封装为 response.created,接着是零个或多个 response.output_item.done 帧,然后是一个终止帧。错误使用以下封装:

{
"type": "error",
"status": 502,
"error": {
"type": "upstream_error",
"message": "..."
},
"headers": {}
}

带 generate: false 的 warmup 帧不会调用上游。它会返回一个合成的 response.created,随后是 response.completed,两者都带空的 response id 且没有输出。

该端点接受与 OpenAI 兼容的 Chat Completions 请求,要求提供 model 和一个非空的 messages 数组。它会把 system、user、assistant 和 tool 消息转换为内部 Responses 项; 转换 function tools、tool choice、图像、reasoning effort 和受支持的 response formats; 运行标准的 Responses 路由管线;然后再把结果转换回去。

非流式输出的 object: "chat.completion"。流式输出使用 SSE 对象,object: "chat.completion.chunk"、 choice 增量、带 finish_reason 的终止 choice,以及 data: [DONE]。工具调用和 usage 信息会在源事件携带它们时被转换回去。

由于内部执行路径基于 Responses,因此提供方适配器可以施加更窄的特性集。例如,若请求中的某个特性无法被所选适配器表示,它会作为错误返回,而不是静默改变其含义。

这些端点使用 Claude Code 和兼容客户端所采用的 Anthropic Messages 方言。大多数请求会被转换为 Responses,按常规路由,然后再转换回 Anthropic JSON 或 Anthropic SSE。

转换后的 Messages 请求在重放推理数据时共享整个请求的转换预算,其中包含编码和解码产生的副本开销。 超出预算时返回 HTTP 413 和 translation_buffer_limit,不会为了满足限制而截断签名或不透明推理数据。 原生 Anthropic 透传使用独立的请求体大小限制。

只有在满足以下全部条件时,原生 Anthropic 透传才有资格启用:

  • Claude Code 配置中尚未禁用原生透传;
  • 请求的模型以 claude 或 anthropic 开头;
  • 请求携带原生 Anthropic bearer 或 x-api-key 凭证;
  • 在非回环监听器上,请求还仅通过 x-opencodex-api-key 携带有效代理准入;并且
  • 没有配置的别名或模型映射把该 model id 声明为一个被路由目标。

符合条件的请求会以 Anthropic 方言转发,因此原生 beta 头、thinking 签名和订阅身份都能端到端保留。否则它会走 Responses 往返。

专用准入请求头绝不会转发。Authorization 或 x-api-key 中的代理准入密钥也会被移除, 而另一个请求头中的真实 Anthropic 凭据会保留。含逗号拼接的歧义凭据请求头会 fail closed。

POST /v1/messages/count_tokens 采用相同的模型解析和透传决策。符合原生条件的请求会转发到 Anthropic 的 count 端点。其他请求会使用本地文档化的估算值,对 system 内容、messages 和 tools 进行统计,并返回:

{ "input_tokens": 123 }

无法解析的日期型 Desktop ID 也可能是发现结果中缺失的真实原生模型 ID。现有信息不足以 解析该 ID 时,Messages 和 count-tokens 返回 HTTP 503 及固定错误 desktop_model_mapping_unavailable;这并不证明 模型无效。未知的旧版哈希别名仍返回 HTTP 400。两种情况都不会去除日期或回退到其他路由。 已知 ID、已注册映射、精确 modelMap 匹配及已识别的真实原生 ID 保持原有处理方式。 请刷新模型发现或重新应用已连接 hub 的配置后再试;仅重试本身不能保证解决。

未指定 format=desktop-config 时,使用以下普通目录契约:

契约 触发条件 顶层形态 模型 ID 行为
Anthropic model list anthropic-version 头或 ?flavor=anthropic,且没有 client_version { "data": [...] },包含 Anthropic model-info 条目 Claude Code 收到可读 ID;Desktop 可以收到其 profile-specific 别名族
Codex catalog client_version 查询参数 { "models": [...] } 原生和路由条目携带更丰富的 Codex catalog 字段、可见性、effort、WebSocket 和 multi-agent 元数据
Plain OpenAI list 两个触发条件都没有 { "object": "list", "data": [...] } 可见的原生 ID 是裸值;路由 ID 是别名或 provider/model

GET /v1/models?ids=desktop&format=desktop-config 显式选择 Desktop 快照,不依赖 user-agent。响应为 { "version": 1, "models": [...] },带有 Cache-Control: no-store。 客户端发送 Accept: application/json、anthropic-version: 2023-06-01 及现有数据访问凭证; 不需要管理员令牌,也不上传配置。条目是 hub 发放的 Desktop 配置模型,不是 Codex 目录行。

此格式与 ids=cli 或任意 client_version 一起使用时返回 HTTP 400。不指定格式时,上述普通 契约保持不变。Claude 关闭时返回 { "version": 1, "models": [] };已连接的 Desktop apply 会视为不可用,不写入替代配置。返回普通目录而非版本 1 的旧 hub 不受支持,客户端不会回退到 本地生成的 ID。

快照仍是只读模型列表,不是密钥轮换或配置上传 API。Desktop 密钥迁移、恢复与断开由现有 客户端连接流程处理。轮换保留模型条目和选择;CLI 的 rotation 区分 committed 与 rolled_back。断开会恢复管理设置,或对已确认的旧配置报告标准回退,同时保留用户字段和 后来有效的选择。冲突或未完成的恢复不会标为完成。需要重启 Desktop 才会读取磁盘变更; 断开不会自动撤销 hub 密钥。参见 Desktop 指南。 thinking 重放与提示缓存仍由独立的 #3719 跟进。

下文的账户绑定说明适用于原生 Codex 客户端。通过外部 API 密钥使用语音转写和 GPT-Live,请参阅英文音频 API 规范。

Connections > API keys 包含独立的听写和实时语音区域。数据密钥仅保留在表单内存中。听写会上传所选文件;语音连接检查不使用麦克风,而是等待会话确认。已配置不代表连接成功。

POST /v1/live 接受 ChatGPT/Codex App 的 Frameless call-creation 表面。 POST /v1/realtime/calls 接受 OpenAI Realtime 的 call-creation 表面。opencodex 会选择 一个符合条件的 OpenAI 家族路由,将 call-creation 请求规范化为上游认证模式,并转发有界响应。

完成调用创建后,客户端可以使用任一受支持的入站形式加入 sideband WebSocket:

  • /v1/live/{callId}
  • /v1/realtime/calls/{callId}
  • /v1/realtime?call_id={callId}

代理会规范化上游 join URL,然后在双向透明转发文本和二进制帧。客户端协议头会被保留,而上游认证仍由代理拥有。

Compaction 会为需要缩短长 Responses 会话的客户端返回替换历史。

路由类型 行为
Canonical ChatGPT 或官方 OpenAI 路由 将请求转发到原生 /responses/compact 端点,并使用已解析的账号和模型认证
Explicitly opted-in custom openai-responses gateway supportsNativeCompactEndpoint: true tries the native v1 endpoint for key/local/forward auth using the provider’s normal Responses transport; HTTP 404 uses portable fallback; OAuth retains routed compaction and credential resolution
其他路由模型 运行一次内部的、非流式、无工具的 compaction 轮次,并带 compaction_trigger;要求且只允许一个 synthetic compaction 项,其 encrypted_content 是一个 ocx1: 封装;把该摘要解码为 v1 替换历史

The custom v1 capability is independent of v2 supportsNativeCompactionTrigger and decodesNativeCompactionBlobs for replay. None grants canonical identity or caller credential forwarding; cross-provider overrides remain portable. See the canonical provider configuration before opting in.

原生 compact 响应会被缓冲,最大 32 MiB,即使其声明的 Content-Length 已经超过该限制也是如此。compact 专用失败包括:

状态 类型或 code 含义
400 invalid_request_error 非法的 JSON/主体形状或缺少 model
404 invalid_request_error 请求的 model 无法被路由
499 client_cancelled 客户端在转发或缓冲期间取消了请求
502 compact_response_too_large 原生 compact 输出超过 32 MiB
502 upstream_error 连接、读取,或合成 compaction 轮次失败
502 invalid_response_error 合成轮次没有产出恰好一个有效、非空的 ocx1: compaction 项

在仅绑定到 loopback 的情况下,数据平面准入不需要配置密钥。在远程绑定上,请使用下表。“Dedicated” 指 X-OpenCodex-API-Key;其他列指 Authorization: Bearer ... 和 x-api-key。

表面 Dedicated Bearer x-api-key
/v1/responses HTTP 和 WebSocket 接受 接受 被拒绝
/v1/responses/compact 接受 接受 被拒绝
/v1/chat/completions 接受 接受 被拒绝
/v1/messages 和 /v1/messages/count_tokens 接受 接受 接受
/v1/models 接受 接受 接受
/v1/live、/v1/realtime/calls 和 sideband join 接受 接受 接受

Responses 系列和 Chat 请求接受专用标头或 Bearer 字段中的代理密钥。在原生路由上,所选的已保存 Codex 凭据会替换 admission bearer;其他路由会移除该 bearer。代理密钥绝不会用作 upstream 凭据。如果还要提供独立的 provider bearer,请将代理密钥放在专用标头中。

没有密钥且不使用 OAuth 的 Cursor 路由可以使用调用方单独提供的 bearer,但不能使用代理 secret 或自动补充的 ChatGPT main 凭据。Combo/policy 选择以及实际发生的 shadow/thread-spawn 路由改写不会将调用方的原始凭据传递给新目标。规范 OpenAI 路由仅在 JWT 包含 ChatGPT 账户声明,且任何显式账户标头都与该声明匹配时,才可在内部路由变更后恢复调用方的单个非代理密钥 bearer。 向可选的 OpenAI sidecar 转发调用方认证时,需要单个 JWT 以及显式提供且匹配的 chatgpt-account-id。即使提供了显式账户标头,opaque bearer 也不会跨路由变更恢复。 除此之外,最终目标必须拥有自己的配置、OAuth 或已保存凭据,否则请求会在本地失败。只有 thread-spawn 标记而没有路由变化时,不会移除凭据。

对于未配置密钥的 Cursor Chat 请求,只有实际计划了 OpenAI 辅助调用且存在规范的 Direct 候选时,才会补充已存储的 main 身份验证。无关的 Cursor 请求不会通过此流程占用 native main,因此不会延迟配置文件切换。辅助调用凭据仍受启动和切换保护限制,并与 Cursor bearer 分离。Pool 及明确指定账号的辅助调用保留现有账号选择。

Claude replay 只会以当前 turn 已取得所有权的内存 snapshot 保留 main 凭据,并且仅在最终目标为规范 ChatGPT 路由时恢复它。

错误会在需要时使用客户端方言的封装,但这些状态/code 含义是稳定的:

状态 类型或 code 含义
401 authentication_error 所需的代理准入凭证缺失或无效
403 origin_rejected 一条 Responses/OpenAI 数据平面请求或 WebSocket 升级来自不允许的 origin
503 combo_unavailable 所选 combo 中的所有目标都不可用、处于冷却、已禁用或以其他方式不具备资格
400 unreadable_encrypted_agent_task 一个加密的 v2 worker task 没有任何可处理它的合格规范 ChatGPT 目标或明确信任的 Responses 目标
426 upgrade_required Responses WebSocket 传输被禁用,或升级失败;请改用 HTTP

Anthropic 来源的失败会以 Anthropic 的错误封装呈现,因此该方言中的 origin 拒绝会是 403 permission_error,而不是 OpenAI 风格的 origin_rejected body。

代理把真正的后端密文视为不透明数据。结构有效的密文会逐字节保留:opencodex 不会对其解密、翻译其内容,或为另一个提供方重新加密。

某些 agent hook 历史上会把明文控制文本放进 encrypted_content 槽。为兼容起见,代理会把那部分明文拆分为文本片段,同时保持任何结构有效的 Fernet 片段不变。如果一个 agent_message 在该修复过程中失去了所有加密部分,它就会变成普通的 user message。如果当前的 v2 task 仍然真的是加密的,但所选路由目标无法读取原生 ChatGPT 密文,opencodex 会以 unreadable_encrypted_agent_task 失败,而不是把不可读字节发送给该提供方。有关 worker task 周边的客户端行为,请参见 Sub-agent Surface。

重放的推理项携带的 encrypted_content 只有生成它的 provider 和凭据才能读取。如果 opencodex 知道该对话上一次由另一个 provider 处理,它会在发送前移除这个 blob,并保留该项的摘要。如果那个 provider 还使用了不同的 endpoint 或凭据,该项的 rs_… id 也会被移除,因为它指向新目标无法查到的项。如果 opencodex 无从得知,例如代理重启之后,新目标会拒绝这个 blob:OpenAI 和 Azure OpenAI 返回 400 invalid_encrypted_content。此时 opencodex 会去掉上一个 provider 的推理状态(blob 和 rs_… id)后只重发一次请求;保留 id 会导致 Item with id 'rs_…' not found。

这项恢复适用于所有使用 Responses 协议的 adapter,因此 openai-responses 和 azure-openai 的行为相同。恢复成功后,该对话在同一目标上的后续轮次会在接下来五分钟内于首次发送前移除这些状态。重发计入请求的常规发送预算。普通的 400 和 429 不会以这种方式重发,5xx 也不会,只有一个狭窄的例外:对于携带加密工具输出的请求,响应体恰好是该解密拒绝的 502 会得到同样的一次重发。第二次拒绝会原样返回给客户端。遇到这种情况,请在目标 provider 上开始新的对话。

Codex 原生普通 Lite 请求的搜索历史

Section titled “Codex 原生普通 Lite 请求的搜索历史”

当最终发出的请求未声明任何 hosted 搜索工具时(tools 或 Lite additional_tools 中都没有 web_search 或 web_search_preview,包括移除 provider 不支持的 hosted 工具之后),所有 Responses 目的地都会把未被同输入引用的回放 web_search_call 历史转为下文所述的带标签 assistant 参考说明,与是否启用该选项无关。原生 Sol 对这类历史会返回通用 server_error(#7250),因此在其他模型上搜索过的对话可以在当前请求没有搜索工具的路由上继续。名为 web_search 的 function 工具不算 hosted 声明。不会添加搜索工具、重新搜索或编造结果;被同输入 item_reference 引用的项保持结构化。已声明 hosted 搜索的请求保留结构化历史,除非下述选项生效。

已声明 hosted 搜索的普通请求默认保留结构化 hosted-search 历史,Responses Lite 请求也一样。若要选择有损参考说明,请在 config.json 中设置 providers.openai.projectResponsesLiteHostedSearchHistory: true(必须是布尔值,不能是字符串 "true")。该设置按 provider 配置且默认关闭;省略或设为 false 时保留结构化历史。即使已启用,也只有最终目的地精确为标准 ChatGPT Codex /responses 且当前有效意图明确选择 Responses Lite 的普通请求及原生 v2 compaction_trigger 压缩请求,才会把未被同输入引用的剩余 web_search_call 历史转为带标签的 assistant 参考说明。最终 x-openai-internal-codex-responses-lite header 值精确为 true 时选择 Lite;明确的 false 优先于 frame metadata。没有可识别 header 值时,采用有效字符串 map 中 client_metadata.ws_request_header_x_openai_internal_codex_responses_lite 的 true 值,沿用既有 WS metadata 语义。最终有效意图为非 Lite 或无法识别时保留结构化历史;格式无效的 metadata 不会覆盖明确的 HTTP true。模型名、订阅鉴权、hosted 声明缺失或仅有 additional_tools 都不能选择这项策略;不会为触发转换而改写 header 或 metadata。启用后适用于新 thread、fork、跨模型续聊、缓存未命中或重启,不依赖诊断设置。只有有效同 scope bridge memo 能证明并先恢复原函数调用及结果;ID 前缀、模型名或 memo 缺失不能判断来源。若同输入的 item_reference.id 精确指向某 hosted cell,该 cell 保留;store:false 会先移除引用,剩余 hosted 历史可投影。工具声明、Lite additional_tools、选择、call/result 配对、推理/原生密文、非 hosted 顺序及调用方 raw 历史保持原契约。

这是仅在上述显式启用的 Lite 边界内采用的有损历史策略,不是 hosted schema 非法或所有上游错误已修复的断言。说明标为不可信参考数据,复制 status/action 及 action 或顶层 sources 中允许的 URL/title/type,不是指令或网页正文;每字符串最多 2,048 个 UTF-16 单元、每列表 20 项、全部已投影说明共 65,536 字节,超出的 action 用省略说明替代,转换项不复制 ID 或未知字段。HTTP/SSE 与 WS 共用普通请求的最终 builder。

公开 OpenAI API 及其他目的地不新增普通或 native compact 投影。原生 /responses/compact 保持既有端点、账户清理及官方 opaque 输出路径,保留结构化 hosted 历史。portable/routed 摘要仍沿用原有触发条件与默认引用行为;共享 renderer 在这些既有路径中也补充顶层 sources 白名单保留。本次不增加重试、来源分类或新的 compaction summarizer。