mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Persist built-in image results reported as generating (#28656)
## Why #27920 stopped persisting image-generation items unless their status was `completed`, preventing failed standalone extension items with empty results from being saved. Built-in image generation can instead emit a terminal `response.output_item.done` containing a complete base64 PNG while the item status remains `generating`. In that case, app-server emits no `savedPath`, so Codex Apps can render the inline image but cannot expose a file artifact. ## What changed - Persist image-generation items whenever `result` contains image data. Failed terminal items still have empty results and remain unpersisted. - Update the existing built-in image-generation integration test to cover a terminal `generating` item and verify both `saved_path` and the written PNG bytes. ## Validation - Confirmed with a raw built-in websocket trace: the image progressed through `in_progress`, `generating`, and `partial_image`, then emitted one `response.output_item.done` with `status: "generating"` and a complete PNG result. - `just test -p codex-core builtin_image_generation_call_persisted` is currently blocked before test execution by a pre-existing compile error in `thread-store/src/thread_metadata_sync.rs:171`.
This commit is contained in:
committed by
GitHub
Unverified
parent
172b2218a5
commit
1315198853
@@ -579,7 +579,7 @@ pub(crate) async fn finalize_turn_item(
|
||||
}
|
||||
}
|
||||
if let TurnItem::ImageGeneration(image_item) = &mut *turn_item
|
||||
&& image_item.status == "completed"
|
||||
&& !image_item.result.is_empty()
|
||||
{
|
||||
persist_image_generation_item(sess, turn_context, image_item).await;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ async fn web_search_item_is_emitted() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> {
|
||||
async fn builtin_image_generation_call_persisted() -> anyhow::Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_mock_server().await;
|
||||
@@ -369,7 +369,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(call_id, "completed", "A tiny blue square", "Zm9v"),
|
||||
ev_image_generation_call(call_id, "generating", "A tiny blue square", "Zm9v"),
|
||||
ev_completed("resp-1"),
|
||||
]);
|
||||
mount_sse_once(&server, first_response).await;
|
||||
@@ -422,7 +422,7 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> {
|
||||
assert_eq!(completed.0.id, call_id);
|
||||
assert!(completed.1 > 0);
|
||||
assert_eq!(end.call_id, call_id);
|
||||
assert_eq!(end.status, "completed");
|
||||
assert_eq!(end.status, "generating");
|
||||
assert_eq!(end.revised_prompt, Some("A tiny blue square".to_string()));
|
||||
assert_eq!(end.result, "Zm9v");
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user