From c37ce405605a37738ce88df9947f38d8d4aa4ff7 Mon Sep 17 00:00:00 2001 From: Joe Gershenson Date: Tue, 21 Apr 2026 01:55:18 -0700 Subject: [PATCH] Polish pending transcript queue --- codex-rs/core/src/session/mod.rs | 2 +- codex-rs/core/src/session/tests.rs | 32 +++++++++++------------------- codex-rs/core/src/state/turn.rs | 12 +++++++---- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 326315a821..ae00152174 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -3041,7 +3041,7 @@ impl Session { self.get_pending_turn_input() .await .into_iter() - .map(PendingTurnInput::into_response_input_item) + .map(ResponseInputItem::from) .collect() } diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 0b19a278b0..486aa6f14a 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -350,19 +350,11 @@ async fn interrupting_regular_turn_waiting_on_startup_prewarm_emits_turn_aborted assert!(duration_ms.is_some()); let history = sess.clone_history().await; - let prompt_idx = history.raw_items().iter().position(|item| { - matches!( - item, - ResponseItem::Message { - role, - content, - .. - } if role == "user" - && content == &[ContentItem::InputText { - text: "first prompt".to_string() - }] - ) - }); + let expected_prompt = user_message("first prompt"); + let prompt_idx = history + .raw_items() + .iter() + .position(|item| item == &expected_prompt); let aborted_idx = history.raw_items().iter().position(|item| { let ResponseItem::Message { role, content, .. } = item else { return false; @@ -375,13 +367,13 @@ async fn interrupting_regular_turn_waiting_on_startup_prewarm_emits_turn_aborted TurnAborted::matches_text(text) }) }); - assert!( - prompt_idx.is_some_and(|prompt_idx| { - aborted_idx.is_some_and(|aborted_idx| prompt_idx < aborted_idx) - }), - "expected prompt to be recorded before the interrupted-turn marker: {:?}", - history.raw_items() - ); + let (Some(prompt_idx), Some(aborted_idx)) = (prompt_idx, aborted_idx) else { + panic!( + "expected prompt and interrupted-turn marker in history: {:?}", + history.raw_items() + ); + }; + assert!(prompt_idx < aborted_idx); } fn test_model_client_session() -> crate::client::ModelClientSession { diff --git a/codex-rs/core/src/state/turn.rs b/codex-rs/core/src/state/turn.rs index f47edcb920..79abc8e858 100644 --- a/codex-rs/core/src/state/turn.rs +++ b/codex-rs/core/src/state/turn.rs @@ -78,16 +78,20 @@ pub(crate) struct RunningTask { pub(crate) _timer: Option, } +/// Input queued for ordered transcript recording during an active turn. +/// +/// User prompts keep the original `UserInput` so client-visible turn items can +/// preserve UI-only spans such as `text_elements`; model-only response input +/// items can stay in their serialized Responses API form. #[derive(Clone, Debug, PartialEq)] pub(crate) enum PendingTurnInput { UserInput(Vec), ResponseInputItem(ResponseInputItem), } -impl PendingTurnInput { - #[cfg(test)] - pub(crate) fn into_response_input_item(self) -> ResponseInputItem { - match self { +impl From for ResponseInputItem { + fn from(value: PendingTurnInput) -> Self { + match value { PendingTurnInput::UserInput(input) => input.into(), PendingTurnInput::ResponseInputItem(input) => input, }