[imagegen] preserve image generation start events

This commit is contained in:
Josh Wright
2026-06-11 15:58:28 -07:00
parent 55aa071b17
commit d9aefa4159
4 changed files with 41 additions and 0 deletions

View File

@@ -133,6 +133,9 @@ pub(crate) async fn persist_image_generation_item(
image_item: &mut ImageGenerationItem,
) -> Option<AbsolutePathBuf> {
image_item.saved_path = None;
if image_item.result.is_empty() {
return None;
}
let session_id = sess.thread_id.to_string();
match save_image_generation_result(
&turn_context.config.codex_home,

View File

@@ -812,6 +812,17 @@ pub fn ev_image_generation_call(
})
}
pub fn ev_image_generation_call_added(id: &str, status: &str) -> Value {
serde_json::json!({
"type": "response.output_item.added",
"item": {
"type": "image_generation_call",
"id": id,
"status": status,
}
})
}
pub fn ev_function_call(call_id: &str, name: &str, arguments: &str) -> Value {
serde_json::json!({
"type": "response.output_item.done",

View File

@@ -20,6 +20,7 @@ use codex_utils_absolute_path::AbsolutePathBuf;
use core_test_support::responses::ev_assistant_message;
use core_test_support::responses::ev_completed;
use core_test_support::responses::ev_image_generation_call;
use core_test_support::responses::ev_image_generation_call_added;
use core_test_support::responses::ev_message_item_added;
use core_test_support::responses::ev_output_text_delta;
use core_test_support::responses::ev_reasoning_item;
@@ -372,6 +373,7 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> {
let first_response = sse(vec![
ev_response_created("resp-1"),
ev_image_generation_call_added(call_id, "in_progress"),
ev_image_generation_call(call_id, "completed", "A tiny blue square", "Zm9v"),
ev_completed("resp-1"),
]);
@@ -422,6 +424,10 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> {
assert_eq!(begin.call_id, call_id);
assert_eq!(started.0.id, call_id);
assert_eq!(started.0.status, "in_progress");
assert_eq!(started.0.revised_prompt, None);
assert_eq!(started.0.result, "");
assert_eq!(started.0.saved_path, None);
assert!(started.1 > 0);
assert_eq!(completed.0.id, call_id);
assert!(completed.1 > 0);

View File

@@ -892,6 +892,7 @@ pub enum ResponseItem {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
revised_prompt: Option<String>,
#[serde(default)]
result: String,
},
#[serde(alias = "compaction_summary")]
@@ -1811,6 +1812,26 @@ mod tests {
);
}
#[test]
fn response_item_parses_in_progress_image_generation_call_without_result() {
let item = serde_json::from_value::<ResponseItem>(serde_json::json!({
"id": "ig_123",
"type": "image_generation_call",
"status": "in_progress",
}))
.expect("in-progress image generation item should deserialize");
assert_eq!(
item,
ResponseItem::ImageGenerationCall {
id: "ig_123".to_string(),
status: "in_progress".to_string(),
revised_prompt: None,
result: String::new(),
}
);
}
#[test]
fn additional_permission_profile_is_empty_when_all_fields_are_none() {
assert_eq!(AdditionalPermissionProfile::default().is_empty(), true);