Support larger prompt images on gpt-5.4

Resolved 💬 1 comment Opened Mar 13, 2026 by 0xSMW Closed Apr 18, 2026

What issue are you seeing?

Local prompt images are still forced through the old 2048x768 resize-to-fit path even when the active model is gpt-5.4, which can accept much larger prompt images.

The important detail is that detail: "original" is not the default local-image upload path. It is only used when the view_image tool explicitly requests original detail. Normal UserInput::LocalImage uploads still hardcode PromptImageMode::ResizeToFit, so images that should be preserved for gpt-5.4 get downscaled before they ever reach the model.

Relevant code before the fix:

// codex-rs/protocol/src/models.rs
UserInput::LocalImage { path } => {
    image_index += 1;
    local_image_content_items_with_label_number(
        &path,
        Some(image_index),
        PromptImageMode::ResizeToFit,
    )
}
// codex-rs/utils/image/src/lib.rs
pub enum PromptImageMode {
    ResizeToFit,
    Original,
}

pub fn load_and_resize_to_fit(path: &Path) -> Result<EncodedImage, ImageProcessingError> {
    load_for_prompt(path, PromptImageMode::ResizeToFit)
}

let encoded =
    if mode == PromptImageMode::Original || (width <= MAX_WIDTH && height <= MAX_HEIGHT) {
        // preserve original bytes / dimensions
    } else {
        let resized = dynamic.resize(MAX_WIDTH, MAX_HEIGHT, FilterType::Triangle);
        // send resized image
    };
// codex-rs/core/src/tools/handlers/view_image.rs
let image_mode = if use_original_detail {
    PromptImageMode::Original
} else {
    PromptImageMode::ResizeToFit
};

This means something like a 4096x2048 local image sent to gpt-5.4 is still resized to fit the legacy bounds, even though that image is already within the model's supported prompt-image size.

What steps can reproduce the bug?

  1. Start Codex with gpt-5.4.
  2. Submit a local image that is larger than 2048x768 but smaller than 6000x6000.
  3. Inspect the outgoing input_image payload sent to the Responses API.
  4. Notice that the image dimensions have already been reduced to fit the hardcoded resize bounds.

A minimal repro looks like this conceptually:

let original_width = 4096;
let original_height = 2048;
let image = ImageBuffer::from_pixel(original_width, original_height, Rgba([20u8, 40, 60, 255]));
image.save(&abs_path)?;

let TestCodex {
    codex,
    cwd,
    session_configured,
    ..
} = test_codex().with_model("gpt-5.4").build(&server).await?;

codex
    .submit(Op::UserTurn {
        items: vec![UserInput::LocalImage { path: abs_path }],
        cwd: cwd.path().to_path_buf(),
        approval_policy: AskForApproval::Never,
        sandbox_policy: SandboxPolicy::DangerFullAccess,
        model: session_configured.model.clone(),
        final_output_json_schema: None,
        effort: None,
        summary: None,
        service_tier: None,
        collaboration_mode: None,
        personality: None,
    })
    .await?;

What is the expected behavior?

If a model supports larger prompt images, the default local-image upload path should preserve the original resolution whenever the image already fits within that model's limit.

For gpt-5.4, a 4096x2048 local image should be sent at 4096x2048, not resized down to the legacy 2048x768 path.

detail: "original" should remain an explicit opt-in for tool-driven image inspection, but it should not be the only way to avoid downscaling on models that already support much larger prompt images.

Additional information

I validated a local fix that keeps the current layering intact by moving the resize policy into model metadata rather than overloading Original:

pub enum PromptImageMode {
    ResizeToFit { max_width: u32, max_height: u32 },
    Original,
}

impl ModelInfo {
    pub fn prompt_image_mode(&self) -> PromptImageMode {
        PromptImageMode::ResizeToFit {
            max_width: self.max_prompt_image_width,
            max_height: self.max_prompt_image_height,
        }
    }
}

That shape allows gpt-5.4 to use 6000x6000 prompt-image bounds while preserving existing behavior for models that should stay on 2048x768, and it leaves explicit detail: "original" behavior unchanged.

Local validation for that fix was:

cargo test -p codex-utils-image respects_custom_resize_to_fit_bounds
cargo test -p codex-protocol prompt_image_mode_uses_model_resize_limits
cargo test -p codex-core gpt_5_4_local_images_keep_resolution_within_large_resize_bounds
cargo test -p codex-core view_image_tool_
cargo check -p codex-api --tests
cargo check -p codex-app-server --tests

I have the fix pushed on 0xSMW:smw/gpt-5-4-prompt-image-bounds at 0d1cf902c if maintainers want a concrete reference implementation.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗