Skip to content

fix: 修复图片生成与编辑请求的本地代理链路 - #2104

Merged
BigPizzaV3 merged 3 commits into
BigPizzaV3:mainfrom
MateralCMX:main
Sep 9, 2026
Merged

fix: 修复图片生成与编辑请求的本地代理链路#2104
BigPizzaV3 merged 3 commits into
BigPizzaV3:mainfrom
MateralCMX:main

Conversation

@MateralCMX

@MateralCMX MateralCMX commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

问题说明

Codex++ 启用本地协议代理后,Codex 内置的 image_gen 工具会向本地代理发送图片请求,但代理此前没有处理以下 Images API 路径:

  • POST /v1/images/generations
  • POST /v1/images/edits

这些请求会落入未知路径处理并返回 404,导致相同供应商在直连时可以正常生成图片,而通过 Codex++ 启动后无法使用图片生成和编辑功能。

修改内容

  • 为本地 helper 增加图片生成与编辑请求路由。
  • 支持以下路径形式:
    • /images/generations
    • /v1/images/generations
    • /v1/v1/images/generations
    • /codex/v1/images/generations
    • /images/edits
    • /v1/images/edits
    • /v1/v1/images/edits
    • /codex/v1/images/edits
  • 图片生成请求原样转发 JSON 请求体。
  • 图片编辑请求原样转发 multipart 请求体及其 boundary。
  • 透传上游响应状态码、响应体和 Content-Type
  • 沿用供应商现有鉴权配置,并兼容 no-auth 供应商。
  • 规范化包含 host、尾斜杠、/v1/v1/v1 的上游地址。
  • 防止 127.0.0.1:57321localhost:57321 和 IPv6 回环地址被误当作图片上游,从而形成递归代理。
  • 未知图片路径继续返回原有的 404 未知后端路径
  • 将图片请求等待响应头的专用超时设置为 10 分钟,以兼容耗时较长的图片生成任务。
  • 文本、音频及流式请求的原有超时保持不变。

兼容性

本次修改仅扩展 Images API 的代理能力,不改变现有 Responses、Chat Completions、Models 和 Audio Transcriptions 请求行为。

图片生成和编辑共享独立的 10 分钟响应头超时,不影响其他 API 请求。

测试

已完成以下验证:

  • launcher 测试:85/85 通过
  • protocol_proxy 串行测试:80/80 通过
  • relay_config 测试:145/145 通过
  • codex-plus-data 单元及集成测试通过
  • 图片 URL 规范化测试通过
  • JSON 图片生成请求转发测试通过
  • multipart 图片编辑请求转发测试通过
  • 上游错误状态码、响应体和 Content-Type 透传测试通过
  • no-auth 及回环地址检测测试通过
  • 10 分钟图片响应头超时断言通过
  • rustfmt --edition 2024 --check 通过
  • git diff --check 通过

真实链路验证

已使用本地构建版本完成真实请求验证:

  • POST /v1/images/generations 成功返回 HTTP 200
  • 成功接收并解析 b64_json
  • Base64 数据可解码为有效 PNG 图片
  • POST /v1/images/edits 成功完成真实图片编辑
  • Codex 原生图片工具返回 imageGeneration 项目,状态为 completed
  • 超过原 5 分钟限制的图片生成任务可继续等待,不会被代理提前中断

相关议题

Closes #747

Related to #1480

@BigPizzaV3 BigPizzaV3 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当前 PR 有编译阻塞问题:open_image_generations_proxy_request / open_image_edits_proxy_request 返回的是 UpstreamProxyResponse,但 crates/codex-plus-core/src/launcher.rshandle_image_proxy_connection 调用了 upstream.status()upstream.is_success();该结构体只有 status_codecontent_typeis_streamwire_apiresponse 字段。请改用 status_code(生成 HTTP 状态行)并按 200..300 判断成功,或直接从 response 读取状态,但不要移动后续仍需使用的字段。修复后请补跑三平台 artifact CI;当前 PR 没有任何 CI 结果,暂不能合并。

@MateralCMX

Copy link
Copy Markdown
Contributor Author

感谢审查。
关于“UpstreamProxyResponse 没有 status()is_success() 方法”的判断,我核对了 PR 基线对应的原仓库源码,该判断并不成立:

  • UpstreamProxyResponse 结构体定义:
    pub status_code: u16,
    pub content_type: String,
    pub is_stream: bool,
    pub wire_api: UpstreamWireApi,
    pub response: reqwest::Response,
    }
  • status()is_success() 方法实现:
    }
    pub fn is_success(&self) -> bool {
    (200..300).contains(&self.status_code)
    }
    }
    pub fn upstream_header_timeout() -> Duration {
    UPSTREAM_HEADER_TIMEOUT
  • 原仓库现有 Models handler 也在使用这两个方法:
    remote_addr_text: Option<String>,
    ) -> anyhow::Result<()> {
    let request_json = serde_json::from_str::<serde_json::Value>(request_body).ok();
    let upstream = match crate::protocol_proxy::open_responses_proxy_request_for_path(
    request_body,
    request_user_agent,
    path,
    )
    .await

我已经遵守审查中提出的实现建议,推送了提交 3baaeb6

  • 图片 handler 现在直接从 upstream.response 读取状态码和成功状态。
  • 没有移动或提前消费后续仍需使用的字段。
  • 响应体和 Content-Type 仍按原逻辑读取并透传。
  • 已重新通过 cargo check -p codex-plus-core
  • launcher 测试:85/85 通过。
  • protocol_proxy 测试:80/80 通过。
  • rustfmt --edition 2024 --checkgit diff --check 通过。

@BigPizzaV3

Copy link
Copy Markdown
Owner

已核对最新提交 3baaeb6:图片处理现在从 upstream.response 读取状态和成功标志,之前指出的 UpstreamProxyResponse 方法调用问题已解决。由于当前分支仍基于旧版 main,且 PR 页面没有任何 GitHub CI,请先 rebase 到最新 main,再触发 Windows、macOS arm64、macOS x64 三平台 artifact workflow,并补充相关 workspace 测试结果;CI 全绿后再进入合并队列。

@MateralCMX

Copy link
Copy Markdown
Contributor Author

我现在已经rebase到 48d4315

@BigPizzaV3

Copy link
Copy Markdown
Owner

收到 rebase 到 48d4315(后续已合到 07c3659)。请确认三点后即可合:1) 图片生成/编辑走本地代理链路的 UpstreamProxyResponse 状态读取没问题(已确认);2) 重新触发并跑通 Windows、macOS x64、macOS arm64 三平台 artifact workflow——当前分支仍显示『无 checks』;3) 补充相关 protocol_proxy 回归测试结果。三平台 CI 全绿我立即通过。

@BigPizzaV3 BigPizzaV3 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审通过。已核实:你已在最新提交 6583027 中从 images 的 upstream response 读取状态/成功标志(UpstreamProxyResponse.status()/is_success()),之前指出的方法缺失问题解决;本地 protocol_proxy 测试 80/80 通过;与最新 main(含 #2106 的 内联)三-way merge 无冲突。虽 fork 分支无 GitHub checks,但本地验证充分,予以合并。感谢。

@BigPizzaV3
BigPizzaV3 merged commit 4baa688 into BigPizzaV3:main Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 使用codex++会拦截image gen工具无法正常生图。

2 participants