From 78da39e19b508c8b04af569d8c60d4cb75422c45 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 26 Feb 2025 13:02:36 -0500 Subject: [PATCH] assistant2: Add ability to delete past prompt editors (#25667) This PR adds the ability to delete past prompt editors in Assistant 2, the same way you can with threads. Release Notes: - N/A --- crates/assistant2/src/assistant_panel.rs | 6 +++ crates/assistant2/src/thread_history.rs | 37 ++++++++++++++++--- .../src/context_store.rs | 34 ++++++++++++++++- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index fb94a18e99ba90effdc778b4e0b1da38cc46939f..221c8562d272c3e11b6d68c906a6f0b728206e39 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -458,6 +458,12 @@ impl AssistantPanel { pub(crate) fn active_context_editor(&self) -> Option> { self.context_editor.clone() } + + pub(crate) fn delete_context(&mut self, path: PathBuf, cx: &mut Context) { + self.context_store + .update(cx, |this, cx| this.delete_local_context(path, cx)) + .detach_and_log_err(cx); + } } impl Focusable for AssistantPanel { diff --git a/crates/assistant2/src/thread_history.rs b/crates/assistant2/src/thread_history.rs index 89023175e426b6905015327e71a7432f76bbf28d..460fb6f420f83d87a8a335353d03f7e2c8767cb8 100644 --- a/crates/assistant2/src/thread_history.rs +++ b/crates/assistant2/src/thread_history.rs @@ -134,7 +134,13 @@ impl ThreadHistory { }) .ok(); } - HistoryEntry::Context(_context) => {} + HistoryEntry::Context(context) => { + self.assistant_panel + .update(cx, |this, cx| { + this.delete_context(context.path.clone(), cx); + }) + .ok(); + } } cx.notify(); @@ -344,11 +350,30 @@ impl RenderOnce for PastContext { .spacing(ListItemSpacing::Sparse) .child(Label::new(summary).size(LabelSize::Small).text_ellipsis()) .end_slot( - h_flex().gap_1p5().child( - Label::new(context_timestamp) - .color(Color::Muted) - .size(LabelSize::XSmall), - ), + h_flex() + .gap_1p5() + .child( + Label::new(context_timestamp) + .color(Color::Muted) + .size(LabelSize::XSmall), + ) + .child( + IconButton::new("delete", IconName::TrashAlt) + .shape(IconButtonShape::Square) + .icon_size(IconSize::XSmall) + .tooltip(Tooltip::text("Delete Prompt Editor")) + .on_click({ + let assistant_panel = self.assistant_panel.clone(); + let path = self.context.path.clone(); + move |_event, _window, cx| { + assistant_panel + .update(cx, |this, cx| { + this.delete_context(path.clone(), cx); + }) + .ok(); + } + }), + ), ) .on_click({ let assistant_panel = self.assistant_panel.clone(); diff --git a/crates/assistant_context_editor/src/context_store.rs b/crates/assistant_context_editor/src/context_store.rs index f5424ef712278a7515a8ffe58dfcb44ccdb8fd68..6fe289d305e7ef68987083eba886b456244054d5 100644 --- a/crates/assistant_context_editor/src/context_store.rs +++ b/crates/assistant_context_editor/src/context_store.rs @@ -9,7 +9,7 @@ use clock::ReplicaId; use collections::HashMap; use context_server::manager::ContextServerManager; use context_server::ContextServerFactoryRegistry; -use fs::Fs; +use fs::{Fs, RemoveOptions}; use futures::StreamExt; use fuzzy::StringMatchCandidate; use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity}; @@ -475,6 +475,38 @@ impl ContextStore { }) } + pub fn delete_local_context( + &mut self, + path: PathBuf, + cx: &mut Context, + ) -> Task> { + let fs = self.fs.clone(); + + cx.spawn(|this, mut cx| async move { + fs.remove_file( + &path, + RemoveOptions { + recursive: false, + ignore_if_not_exists: true, + }, + ) + .await?; + + this.update(&mut cx, |this, cx| { + this.contexts.retain(|context| { + context + .upgrade() + .and_then(|context| context.read(cx).path()) + != Some(&path) + }); + this.contexts_metadata + .retain(|context| context.path != path); + })?; + + Ok(()) + }) + } + fn loaded_context_for_path(&self, path: &Path, cx: &App) -> Option> { self.contexts.iter().find_map(|context| { let context = context.upgrade()?;