[code-mode] Reject remote image URLs from output helpers (#27732)

## Summary

- reject HTTP(S) image URLs from the shared code-mode output-image
normalization path
- return a concise model-visible tool error so the model can recover on
its next turn
- apply the targeted rejection to both `image()` and `generatedImage()`
- leave other non-empty image URL values to existing downstream handling

The returned error is:

> Tool call failed: remote image URLs are not supported in tool outputs.
Pass a base64 data URI instead

## Why

Responses Lite cannot lower a remote image URL emitted from a structured
tool output. Rejecting HTTP(S) values in the Codex harness preserves the
tool-call metadata and gives the model a recoverable next turn instead
of invalidating the sample.

## Test coverage

The regression is covered primarily by a `test_codex()` agent
integration test that simulates the Responses API exchange and asserts
the failed model-visible exec output. A supplemental runtime test covers
both `http://` and `https://` inputs across both image output helpers.

## Test plan

- `cd codex-rs && just test -p codex-code-mode`
- `cd codex-rs && just test -p codex-code-mode-protocol`
- `cd codex-rs && just test -p codex-core
code_mode_image_helper_rejects_remote_url`
- `cd codex-rs && just fmt`
- `git diff --check origin/main...HEAD`

Related context: https://github.com/openai/openai/pull/1022346
This commit is contained in:
rka-oai
2026-06-12 02:49:17 -07:00
committed by GitHub
Unverified
parent 693082f3c4
commit c09df9e353
4 changed files with 95 additions and 41 deletions
+3 -5
View File
@@ -5,6 +5,7 @@ use codex_code_mode_protocol::FunctionCallOutputContentItem;
use codex_code_mode_protocol::ImageDetail;
const IMAGE_HELPER_EXPECTS_MESSAGE: &str = "image expects a non-empty image URL string, an object with image_url and optional detail, or a raw MCP image block";
const REMOTE_IMAGE_URL_ERROR: &str = "Tool call failed: remote image URLs are not supported in tool outputs. Pass a base64 data URI instead";
const CODEX_IMAGE_DETAIL_META_KEY: &str = "codex/imageDetail";
pub(super) fn serialize_output_text(
@@ -59,11 +60,8 @@ pub(super) fn normalize_output_image(
return Err(IMAGE_HELPER_EXPECTS_MESSAGE.to_string());
}
let lower = image_url.to_ascii_lowercase();
if !(lower.starts_with("http://")
|| lower.starts_with("https://")
|| lower.starts_with("data:"))
{
return Err("image expects an http(s) or data URL".to_string());
if lower.starts_with("http://") || lower.starts_with("https://") {
return Err(REMOTE_IMAGE_URL_ERROR.to_string());
}
let detail = detail_override.or(detail);