Update image outputs to default to high detail (#18386)

Do not assume the default `detail`.
This commit is contained in:
pakrym-oai
2026-04-18 11:01:12 -07:00
committed by GitHub
parent e3c2acb9cd
commit 53b1570367
35 changed files with 245 additions and 93 deletions

View File

@@ -24,6 +24,7 @@ use codex_protocol::config_types::Settings;
use codex_protocol::config_types::Verbosity;
use codex_protocol::error::CodexErr;
use codex_protocol::models::ContentItem;
use codex_protocol::models::DEFAULT_IMAGE_DETAIL;
use codex_protocol::models::FunctionCallOutputContentItem;
use codex_protocol::models::FunctionCallOutputPayload;
use codex_protocol::models::ImageDetail;
@@ -511,6 +512,7 @@ async fn resume_replays_legacy_js_repl_image_rollout_shapes() {
role: "user".to_string(),
content: vec![ContentItem::InputImage {
image_url: legacy_image_url.to_string(),
detail: Some(DEFAULT_IMAGE_DETAIL),
}],
end_turn: None,
phase: None,

View File

@@ -1970,14 +1970,16 @@ image("data:image/png;base64,AAA");
items[1],
serde_json::json!({
"type": "input_image",
"image_url": "https://example.com/image.jpg"
"image_url": "https://example.com/image.jpg",
"detail": "high"
}),
);
assert_eq!(
items[2],
serde_json::json!({
"type": "input_image",
"image_url": "data:image/png;base64,AAA"
"image_url": "data:image/png;base64,AAA",
"detail": "high"
}),
);

View File

@@ -1,5 +1,6 @@
use anyhow::Context;
use codex_protocol::models::ContentItem;
use codex_protocol::models::DEFAULT_IMAGE_DETAIL;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::EventMsg;
@@ -51,7 +52,7 @@ fn find_user_message_with_image(text: &str) -> Option<ResponseItem> {
fn extract_image_url(item: &ResponseItem) -> Option<String> {
match item {
ResponseItem::Message { content, .. } => content.iter().find_map(|span| match span {
ContentItem::InputImage { image_url } => Some(image_url.clone()),
ContentItem::InputImage { image_url, .. } => Some(image_url.clone()),
_ => None,
}),
_ => None,
@@ -150,7 +151,10 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu
ContentItem::InputText {
text: codex_protocol::models::local_image_open_tag_text(/*label_number*/ 1),
},
ContentItem::InputImage { image_url },
ContentItem::InputImage {
image_url,
detail: Some(DEFAULT_IMAGE_DETAIL),
},
ContentItem::InputText {
text: codex_protocol::models::image_close_tag_text(),
},
@@ -234,7 +238,10 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()>
ContentItem::InputText {
text: codex_protocol::models::image_open_tag_text(),
},
ContentItem::InputImage { image_url },
ContentItem::InputImage {
image_url,
detail: Some(DEFAULT_IMAGE_DETAIL),
},
ContentItem::InputText {
text: codex_protocol::models::image_close_tag_text(),
},

View File

@@ -787,7 +787,8 @@ async fn stdio_image_responses_round_trip() -> anyhow::Result<()> {
output[1],
json!({
"type": "input_image",
"image_url": OPENAI_PNG
"image_url": OPENAI_PNG,
"detail": "high"
})
);
server.verify().await;

View File

@@ -21,6 +21,6 @@ Scenario: Pre-turn auto-compaction with a context override emits the context dif
04:message/user:<ENVIRONMENT_CONTEXT:cwd=PRETURN_CONTEXT_DIFF_CWD>
05:message/user[4]:
[01] <image>
[02] <input_image:image_url>
[02] <input_image:detail,image_url>
[03] </image>
[04] USER_THREE

View File

@@ -533,7 +533,7 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> {
);
assert_eq!(
arr[1],
json!({"type": "input_image", "image_url": openai_png})
json!({"type": "input_image", "image_url": openai_png, "detail": "high"})
);
Ok(())

View File

@@ -631,7 +631,10 @@ async fn view_image_tool_treats_null_detail_as_omitted() -> anyhow::Result<()> {
.and_then(Value::as_array)
.expect("function_call_output should be a content item array");
assert_eq!(output_items.len(), 1);
assert_eq!(output_items[0].get("detail"), None);
assert_eq!(
output_items[0].get("detail").and_then(Value::as_str),
Some("high")
);
let image_url = output_items[0]
.get("image_url")
.and_then(Value::as_str)
@@ -728,7 +731,10 @@ async fn view_image_tool_resizes_when_model_lacks_original_detail_support() -> a
.and_then(Value::as_array)
.expect("function_call_output should be a content item array");
assert_eq!(output_items.len(), 1);
assert_eq!(output_items[0].get("detail"), None);
assert_eq!(
output_items[0].get("detail").and_then(Value::as_str),
Some("high")
);
let image_url = output_items[0]
.get("image_url")
@@ -829,7 +835,10 @@ async fn view_image_tool_does_not_force_original_resolution_with_capability_only
.and_then(Value::as_array)
.expect("function_call_output should be a content item array");
assert_eq!(output_items.len(), 1);
assert_eq!(output_items[0].get("detail"), None);
assert_eq!(
output_items[0].get("detail").and_then(Value::as_str),
Some("high")
);
let image_url = output_items[0]
.get("image_url")
.and_then(Value::as_str)