From e6907106f055b4b524b3d873d077ead726bb3a41 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 3 Nov 2025 11:27:59 -0800 Subject: [PATCH] Fix issues with applying editor history Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: Ben Kunkle Co-authored-by: Agus Zubiaga --- crates/zeta2/src/zeta2.rs | 5 +++++ crates/zeta_cli/src/example.rs | 27 ++++++++++++++++----------- crates/zeta_cli/src/main.rs | 7 ++++--- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/crates/zeta2/src/zeta2.rs b/crates/zeta2/src/zeta2.rs index ed8f0b12c79374aaac4f115bed77e03132f63889..27fb7e836ee3ae9ec0197e4bcf0238b70167a73e 100644 --- a/crates/zeta2/src/zeta2.rs +++ b/crates/zeta2/src/zeta2.rs @@ -135,6 +135,7 @@ impl ContextMode { } } +#[derive(Debug)] pub enum ZetaDebugInfo { ContextRetrievalStarted(ZetaContextRetrievalStartedDebugInfo), SearchQueriesGenerated(ZetaSearchQueryDebugInfo), @@ -144,17 +145,20 @@ pub enum ZetaDebugInfo { EditPredicted(ZetaEditPredictionDebugInfo), } +#[derive(Debug)] pub struct ZetaContextRetrievalStartedDebugInfo { pub project: Entity, pub timestamp: Instant, pub search_prompt: String, } +#[derive(Debug)] pub struct ZetaContextRetrievalDebugInfo { pub project: Entity, pub timestamp: Instant, } +#[derive(Debug)] pub struct ZetaEditPredictionDebugInfo { pub request: predict_edits_v3::PredictEditsRequest, pub retrieval_time: TimeDelta, @@ -164,6 +168,7 @@ pub struct ZetaEditPredictionDebugInfo { pub response_rx: oneshot::Receiver>, } +#[derive(Debug)] pub struct ZetaSearchQueryDebugInfo { pub project: Entity, pub timestamp: Instant, diff --git a/crates/zeta_cli/src/example.rs b/crates/zeta_cli/src/example.rs index e0f9e51c0c68234d48d03c5e598b0ddf8497b2f8..083b021a8da9d09fb134483ac36b543398576f5f 100644 --- a/crates/zeta_cli/src/example.rs +++ b/crates/zeta_cli/src/example.rs @@ -13,6 +13,7 @@ use clap::ValueEnum; use collections::HashSet; use futures::AsyncWriteExt as _; use gpui::{AsyncApp, Entity, http_client::Url}; +use language::Buffer; use project::{Project, ProjectPath}; use pulldown_cmark::CowStr; use serde::{Deserialize, Serialize}; @@ -331,15 +332,16 @@ impl NamedExample { } } + #[must_use] pub async fn apply_edit_history( &self, project: &Entity, cx: &mut AsyncApp, - ) -> Result<()> { + ) -> Result>> { use cloud_llm_client::udiff::DiffLine; use std::fmt::Write; - #[derive(Default)] + #[derive(Debug, Default)] struct Edit { context: String, deletion_start: Option, @@ -359,7 +361,13 @@ impl NamedExample { while let Some(diff_line) = diff_lines.next() { match diff_line { - DiffLine::OldPath { path } => old_path = Some(path), + DiffLine::OldPath { path } => { + mem::take(&mut pending); + old_path = Some(path) + } + DiffLine::HunkHeader(_) => { + mem::take(&mut pending); + } DiffLine::NewPath { path } => { if old_path.is_none() { anyhow::bail!( @@ -382,7 +390,7 @@ impl NamedExample { writeln!(&mut pending.addition, "{add}")?; } - DiffLine::HunkHeader(_) | DiffLine::Garbage => {} + DiffLine::Garbage => {} } let commit_pending = match diff_lines.peek() { @@ -396,7 +404,7 @@ impl NamedExample { Some(DiffLine::Deletion(_)) => { // start a new cluster if we have any additions specifically // if we only have deletions, we continue to aggregate them - pending.addition.is_empty() + !pending.addition.is_empty() } _ => false, }; @@ -404,10 +412,6 @@ impl NamedExample { if commit_pending { let edit = mem::take(&mut pending); - if edit.addition.is_empty() || edit.deletion_start.is_none() { - return anyhow::Ok(()); - } - let Some(old_path) = old_path.as_deref() else { anyhow::bail!("Missing old path (`---`) header") }; @@ -444,6 +448,7 @@ impl NamedExample { // TODO is it worth using project search? buffer.update(cx, |buffer, cx| { let text = buffer.text(); + // todo! check there's only one if let Some(context_offset) = text.find(&edit.context) { let end = context_offset + edit.context.len(); let start = if let Some(deletion_start) = edit.deletion_start { @@ -456,13 +461,13 @@ impl NamedExample { anyhow::Ok(()) } else { - anyhow::bail!("Failed to match context"); + anyhow::bail!("Failed to match context:\n{}", edit.context); } })??; } } - anyhow::Ok(()) + anyhow::Ok(open_buffers) } } diff --git a/crates/zeta_cli/src/main.rs b/crates/zeta_cli/src/main.rs index 168264f8f845522b5e29315f21496cbdb8a65dd8..b2822c2e1efb31dc4149f9e8814ab6664d334796 100644 --- a/crates/zeta_cli/src/main.rs +++ b/crates/zeta_cli/src/main.rs @@ -372,6 +372,8 @@ async fn zeta2_predict( })? .await; + let _edited_buffers = example.apply_edit_history(&project, cx).await?; + let cursor_path = RelPath::new(&example.example.cursor_path, PathStyle::Posix)?.into_arc(); let cursor_buffer = project @@ -420,15 +422,12 @@ async fn zeta2_predict( zeta.register_buffer(&cursor_buffer, &project, cx); })?; - example.apply_edit_history(&project, cx).await?; - let (prediction_task, mut debug_rx) = zeta.update(cx, |zeta, cx| { let receiver = zeta.debug_info(); let prediction_task = zeta.request_prediction(&project, &cursor_buffer, cursor_anchor, cx); (prediction_task, receiver) })?; - prediction_task.await.context("No prediction")?; let mut response = None; let mut excerpts_text = String::new(); @@ -456,6 +455,8 @@ async fn zeta2_predict( } } + prediction_task.await.context("No prediction")?; + println!("## Excerpts\n"); println!("{excerpts_text}");