Skip to content

Codex image bridge 向 /responses/compact 注入 tool_choice,导致远程压缩 100% 失败:400 "Unknown parameter: 'tool_choice'"(v0.1.140+ 回归) #3629

Description

@seng1e

环境

  • sub2api v0.1.142(官方 docker 镜像),v0.1.140 起均受影响
  • 触发条件:channel 级或账号级开启 codex_image_generation_bridge + Codex CLI 客户端调用 /responses/compact(server-side compaction)+ OpenAI OAuth 账号

现象

开启 image bridge 后,所有经过网关的 /responses/compact 请求 100% 失败,上游返回:

{"error": {"message": "Unknown parameter: 'tool_choice'.", "type": "invalid_request_error", "param": "tool_choice", "code": "unknown_parameter"}}

客户端收到 upstream_error 透传。普通 /responses 请求不受影响(该端点接受 tool_choice)。

日志时间线(每次失败前必有同一请求的两条注入日志):

INFO  service/openai_gateway_service.go:2804  [OpenAI] Injected /responses image_generation tool for Codex client
INFO  service/openai_gateway_service.go:2808  [OpenAI] Set /responses image_generation tool_choice=auto for Codex client
ERROR service/openai_gateway_service.go:4621  OpenAI upstream error 400 ... "Unknown parameter: 'tool_choice'." "param": "tool_choice"
WARN  handler/openai_gateway_handler.go:504   openai.forward_failed path=/responses/compact
WARN  handler/openai_gateway_handler.go:643   codex.remote_compact.failed

根因分析(基于 v0.1.142 源码)

  1. PR fix(openai): set tool_choice auto for Codex image bridge #3498(e5f7836b,v0.1.140 发布)为 Codex image bridge 新增 ensureOpenAIResponsesImageGenerationToolChoiceAuto,向请求体注入 tool_choice: "auto"openai_codex_transform.go:757)。
  2. Forward 内的 image bridge 处理块(openai_gateway_service.go ~2799-2810)没有豁免 compact 请求——尽管同函数上文已经算出了 isCompactRequest。compact 请求同样被注入 tools:[image_generation] + tool_choice:"auto"
  3. handler 层的 compact 字段白名单清理 normalizeOpenAICompactRequestBodyopenai_gateway_handler.go:209)在 Forward 之前执行,挡不住之后注入的字段。
  4. ChatGPT 上游 /responses/compact 端点不接受 tool_choice → 400,命中 passthrough 规则后原样回给客户端,账号 failover 也救不了(换任何账号都同样 400)。

复现

  1. channel 或账号开启 codex_image_generation_bridge(openai 平台)。
  2. 用会触发 server-side compaction 的新版 Codex CLI 走网关,等待会话压缩(或直接 POST /responses/compact)。
  3. 观察上述日志序列与 400。

建议修复

compact 是会话压缩请求,注入画图工具本身也无意义,建议 bridge 注入块直接豁免 compact:

if imageGenerationAllowed && !isCompactRequest && (codexImageGenerationBridgeEnabled || ...) {

或在 compact 路径最终发往上游前再跑一次 normalizeOpenAICompactRequestBody 兜底。另外 openai_ws_forwarder.go:2683 有同样的 tool_choice 注入,如 WS 通路可能承载 compact 请求,建议一并检查。

影响

随着用户升级到默认启用 server-side compaction 的 Codex 客户端,任何开启 image bridge 的部署的远程压缩都会全量失败,且从客户端报错(upstream_error)很难定位到是网关注入导致的。

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