diff --git a/codex-rs/core/src/guardian/prompt.rs b/codex-rs/core/src/guardian/prompt.rs index d43cbf631c..cb2a4ba4f0 100644 --- a/codex-rs/core/src/guardian/prompt.rs +++ b/codex-rs/core/src/guardian/prompt.rs @@ -87,6 +87,29 @@ pub(crate) async fn build_guardian_prompt_items( let (transcript_entries, omission_note) = render_guardian_transcript_entries(transcript_entries.as_slice()); + Ok(assemble_guardian_prompt_items( + transcript_entries, + omission_note, + retry_reason, + planned_action_json, + )) +} + +pub(crate) fn build_guardian_prewarm_prompt_items() -> Vec { + assemble_guardian_prompt_items( + vec![GUARDIAN_PREWARM_TRANSCRIPT_PLACEHOLDER.to_string()], + None, + None, + GUARDIAN_PREWARM_ACTION_PLACEHOLDER.to_string(), + ) +} + +fn assemble_guardian_prompt_items( + transcript_entries: Vec, + omission_note: Option, + retry_reason: Option, + planned_action_json: String, +) -> Vec { let mut items = Vec::new(); let mut push_text = |text: String| { items.push(UserInput::Text { @@ -116,31 +139,7 @@ pub(crate) async fn build_guardian_prompt_items( push_text(format!("{planned_action_json}\n")); push_text(GUARDIAN_APPROVAL_REQUEST_END.to_string()); push_text(GUARDIAN_OUTPUT_SCHEMA_INSTRUCTIONS.to_string()); - Ok(items) -} - -pub(crate) fn build_guardian_prewarm_prompt_items() -> Vec { - [ - GUARDIAN_TRANSCRIPT_INTRO, - GUARDIAN_TRANSCRIPT_START, - GUARDIAN_PREWARM_TRANSCRIPT_PLACEHOLDER, - "\n", - GUARDIAN_TRANSCRIPT_END, - GUARDIAN_ACTION_INTRO, - GUARDIAN_APPROVAL_REQUEST_START, - GUARDIAN_ACTION_ASSESSMENT_INSTRUCTIONS, - GUARDIAN_PLANNED_ACTION_JSON_LABEL, - GUARDIAN_PREWARM_ACTION_PLACEHOLDER, - "\n", - GUARDIAN_APPROVAL_REQUEST_END, - GUARDIAN_OUTPUT_SCHEMA_INSTRUCTIONS, - ] - .into_iter() - .map(|text| UserInput::Text { - text: text.to_string(), - text_elements: Vec::new(), - }) - .collect() + items } /// Keeps all user turns plus a bounded amount of recent assistant/tool context. diff --git a/codex-rs/core/src/guardian/tests.rs b/codex-rs/core/src/guardian/tests.rs index c06bfa822d..6393358167 100644 --- a/codex-rs/core/src/guardian/tests.rs +++ b/codex-rs/core/src/guardian/tests.rs @@ -140,7 +140,7 @@ async fn guardian_prewarm_prompt_matches_review_request_prefix() -> anyhow::Resu let (session, _turn) = guardian_test_session_and_turn(&server).await; let review_prompt = build_guardian_prompt_items( session.as_ref(), - Some("Retry because the previous attempt lost connectivity.".to_string()), + None, GuardianApprovalRequest::Shell { id: "shell-1".to_string(), command: vec!["git".to_string(), "push".to_string()], @@ -154,13 +154,12 @@ async fn guardian_prewarm_prompt_matches_review_request_prefix() -> anyhow::Resu let review_prompt = prompt_item_texts(review_prompt); let prewarm_prompt = prompt_item_texts(build_guardian_prewarm_prompt_items()); - assert_eq!(prewarm_prompt[0], review_prompt[0]); - assert_eq!(prewarm_prompt[1], review_prompt[1]); - assert!( - prewarm_prompt - .iter() - .any(|item| item.contains("guardian_prewarm")) - ); + assert_eq!(prewarm_prompt.len(), review_prompt.len()); + for index in [0, 1, 3, 4, 5, 6, 7, 9, 10] { + assert_eq!(prewarm_prompt[index], review_prompt[index]); + } + assert!(prewarm_prompt[2].contains("guardian prewarm placeholder")); + assert!(prewarm_prompt[8].contains("guardian_prewarm")); Ok(()) }