mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] replace remote images with model-visible error text (#29417)
## What This PR will extend the existing centralized image-preparation path to replace HTTP(S) image inputs with a model visible error message. It won't "ruin" and break existing rollouts, but it will deprecate support for the pathway. App server clients should no longer use HTTP image urls if they'd like to upgrade. The HTTP image url pathway is currently resolved in the responsesapi. It is slow and not reccomended. ## Behavior - HTTP(S) image URL: replace with `input_text` - data URL: use the existing decode and resize path - other image URL schemes: leave unchanged This intentionally does not change app-server ingress. That validation remains a follow-up. ## Test plan - `just test -p codex-core -E 'test(/image_preparation|prepares_image_failures_before_history_insertion|prepares_resumed_history_before_installing_it|responses_lite_prepares_images/)'` — 7 passed - `just fix -p codex-core` - `just fmt`
This commit is contained in:
@@ -55,7 +55,7 @@ fn has_hosted_tool(tools: &[Value], tool_type: &str) -> bool {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn responses_lite_strips_data_image_detail() -> Result<()> {
|
||||
async fn responses_lite_prepares_images() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = responses::start_mock_server().await;
|
||||
@@ -68,6 +68,7 @@ async fn responses_lite_strips_data_image_detail() -> Result<()> {
|
||||
)
|
||||
.await;
|
||||
let image_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg==";
|
||||
let remote_image_url = "https://example.com/image.png";
|
||||
let mut builder = test_codex().with_model_info_override("gpt-5.4", |model_info| {
|
||||
model_info.use_responses_lite = true;
|
||||
configure_image_capable_model(model_info);
|
||||
@@ -76,10 +77,16 @@ async fn responses_lite_strips_data_image_detail() -> Result<()> {
|
||||
|
||||
test.codex
|
||||
.submit(Op::UserInput {
|
||||
items: vec![UserInput::Image {
|
||||
image_url: image_url.to_string(),
|
||||
detail: Some(ImageDetail::Original),
|
||||
}],
|
||||
items: vec![
|
||||
UserInput::Image {
|
||||
image_url: image_url.to_string(),
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
UserInput::Image {
|
||||
image_url: remote_image_url.to_string(),
|
||||
detail: Some(ImageDetail::High),
|
||||
},
|
||||
],
|
||||
final_output_json_schema: None,
|
||||
responsesapi_client_metadata: None,
|
||||
additional_context: Default::default(),
|
||||
@@ -92,20 +99,27 @@ async fn responses_lite_strips_data_image_detail() -> Result<()> {
|
||||
.await;
|
||||
|
||||
let request = response_mock.single_request();
|
||||
let input = request.input();
|
||||
let image = input
|
||||
.iter()
|
||||
.filter_map(|item| item.get("content").and_then(Value::as_array))
|
||||
.flatten()
|
||||
.find(|item| item.get("type").and_then(Value::as_str) == Some("input_image"))
|
||||
.context("request should contain an image")?;
|
||||
let user_content = request
|
||||
.input()
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find(|item| item.get("role").and_then(Value::as_str) == Some("user"))
|
||||
.and_then(|item| item.get("content").and_then(Value::as_array).cloned())
|
||||
.context("request should contain user content")?;
|
||||
assert_eq!(
|
||||
image,
|
||||
&serde_json::json!({
|
||||
"type": "input_image",
|
||||
"image_url": image_url
|
||||
})
|
||||
user_content,
|
||||
vec![
|
||||
serde_json::json!({
|
||||
"type": "input_image",
|
||||
"image_url": image_url
|
||||
}),
|
||||
serde_json::json!({
|
||||
"type": "input_text",
|
||||
"text": "image content omitted because remote image URLs are not supported"
|
||||
}),
|
||||
]
|
||||
);
|
||||
assert!(!request.body_json().to_string().contains(remote_image_url));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user