Prune stale goal image placeholders

This commit is contained in:
Eric Traut
2026-06-10 17:34:08 -07:00
parent 2a68cb3d9c
commit b5b23f68e2
2 changed files with 53 additions and 7 deletions
+27 -7
View File
@@ -133,8 +133,22 @@ pub(crate) async fn materialize_goal_draft(
bail!("Goal objective must not be empty.");
}
let text_elements = draft.text_elements;
let mut active_paste_placeholders =
active_paste_placeholder_counts(&objective, &text_elements, &draft.pending_pastes);
let mut active_paste_placeholders = active_placeholder_counts(
&objective,
&text_elements,
draft
.pending_pastes
.iter()
.map(|(placeholder, _)| placeholder.as_str()),
);
let mut active_image_placeholders = active_placeholder_counts(
&objective,
&text_elements,
draft
.local_images
.iter()
.map(|image| image.placeholder.as_str()),
);
let mut output_dir = None;
let mut replacements = Vec::new();
@@ -157,6 +171,11 @@ pub(crate) async fn materialize_goal_draft(
let mut image_lines = Vec::new();
for (idx, image) in draft.local_images.iter().enumerate() {
if !image.placeholder.is_empty()
&& !take_active_placeholder(&mut active_image_placeholders, &image.placeholder)
{
continue;
}
let extension = image_extension(&image.path);
let path = join_goal_path(
&ensure_output_dir(store, codex_home, &mut output_dir).await?,
@@ -198,14 +217,15 @@ pub(crate) async fn materialize_goal_draft(
Ok(objective)
}
fn active_paste_placeholder_counts(
fn active_placeholder_counts<'a>(
objective: &str,
text_elements: &[TextElement],
pending_pastes: &[(String, String)],
placeholders: impl IntoIterator<Item = &'a str>,
) -> HashMap<String, usize> {
let mut counts = pending_pastes
.iter()
.map(|(placeholder, _)| (placeholder.clone(), 0))
let mut counts = placeholders
.into_iter()
.filter(|placeholder| !placeholder.is_empty())
.map(|placeholder| (placeholder.to_string(), 0))
.collect::<HashMap<_, _>>();
for element in text_elements {
if let Some(count) = element
+26
View File
@@ -121,3 +121,29 @@ async fn deleted_paste_placeholder_does_not_materialize_or_need_codex_home() {
assert_eq!(objective, "small goal");
assert!(store.writes.is_empty());
}
#[tokio::test]
async fn deleted_image_placeholder_does_not_materialize_or_need_codex_home() {
let temp_dir = tempfile::tempdir().expect("tempdir");
let image_path = temp_dir.path().join("local-image.png");
fs::write(&image_path, b"png bytes").expect("write image");
let mut store = RecordingStore::default();
let objective = materialize_goal_draft(
&mut store,
/*codex_home*/ None,
GoalDraft {
objective: "small goal".to_string(),
local_images: vec![LocalImageAttachment {
placeholder: "[Image #1]".to_string(),
path: image_path,
}],
..Default::default()
},
)
.await
.expect("materialize plain goal draft");
assert_eq!(objective, "small goal");
assert!(store.writes.is_empty());
}