diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 8820e4a73d..e058284abc 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -31,7 +31,7 @@ use markdown::{HeadingLevelStyles, Markdown, MarkdownElement, MarkdownStyle}; use parking_lot::Mutex; use project::Project; use settings::Settings as _; -use text::Anchor; +use text::{Anchor, BufferSnapshot}; use theme::ThemeSettings; use ui::{Disclosure, Divider, DividerColor, KeyBinding, Tooltip, prelude::*}; use util::ResultExt; @@ -61,7 +61,7 @@ pub struct AcpThreadView { thread_state: ThreadState, diff_editors: HashMap>, message_editor: Entity, - message_set_from_history: bool, + message_set_from_history: Option, _message_editor_subscription: Subscription, mention_set: Arc>, notifications: Vec>, @@ -144,14 +144,28 @@ impl AcpThreadView { editor }); - let message_editor_subscription = cx.subscribe(&message_editor, |this, _, event, _| { - if let editor::EditorEvent::BufferEdited = &event { - if !this.message_set_from_history { - this.message_history.borrow_mut().reset_position(); + let message_editor_subscription = + cx.subscribe(&message_editor, |this, editor, event, cx| { + if let editor::EditorEvent::BufferEdited = &event { + let buffer = editor + .read(cx) + .buffer() + .read(cx) + .as_singleton() + .unwrap() + .read(cx) + .snapshot(); + if let Some(message) = this.message_set_from_history.clone() + && message.version() != buffer.version() + { + this.message_set_from_history = None; + } + + if this.message_set_from_history.is_none() { + this.message_history.borrow_mut().reset_position(); + } } - this.message_set_from_history = false; - } - }); + }); let mention_set = mention_set.clone(); @@ -178,7 +192,7 @@ impl AcpThreadView { project: project.clone(), thread_state: Self::initial_state(agent, workspace, project, window, cx), message_editor, - message_set_from_history: false, + message_set_from_history: None, _message_editor_subscription: message_editor_subscription, mention_set, notifications: Vec::new(), @@ -424,11 +438,21 @@ impl AcpThreadView { window: &mut Window, cx: &mut Context, ) { + if self.message_set_from_history.is_none() && !self.message_editor.read(cx).is_empty(cx) { + self.message_editor.update(cx, |editor, cx| { + editor.move_up(&Default::default(), window, cx); + }); + return; + } + self.message_set_from_history = Self::set_draft_message( self.message_editor.clone(), self.mention_set.clone(), self.project.clone(), - self.message_history.borrow_mut().prev(), + self.message_history + .borrow_mut() + .prev() + .map(|blocks| blocks.as_slice()), window, cx, ); @@ -440,14 +464,35 @@ impl AcpThreadView { window: &mut Window, cx: &mut Context, ) { - self.message_set_from_history = Self::set_draft_message( + if self.message_set_from_history.is_none() { + self.message_editor.update(cx, |editor, cx| { + editor.move_down(&Default::default(), window, cx); + }); + return; + } + + let mut message_history = self.message_history.borrow_mut(); + let next_history = message_history.next(); + + let set_draft_message = Self::set_draft_message( self.message_editor.clone(), self.mention_set.clone(), self.project.clone(), - self.message_history.borrow_mut().next(), + Some( + next_history + .map(|blocks| blocks.as_slice()) + .unwrap_or_else(|| &[]), + ), window, cx, ); + // If we reset the text to an empty string because we ran out of history, + // we don't want to mark it as coming from the history + self.message_set_from_history = if next_history.is_some() { + set_draft_message + } else { + None + }; } fn open_agent_diff(&mut self, _: &OpenAgentDiff, window: &mut Window, cx: &mut Context) { @@ -481,15 +526,13 @@ impl AcpThreadView { message_editor: Entity, mention_set: Arc>, project: Entity, - message: Option<&Vec>, + message: Option<&[acp::ContentBlock]>, window: &mut Window, cx: &mut Context, - ) -> bool { + ) -> Option { cx.notify(); - let Some(message) = message else { - return false; - }; + let message = message?; let mut text = String::new(); let mut mentions = Vec::new(); @@ -553,7 +596,8 @@ impl AcpThreadView { } } - true + let snapshot = snapshot.as_singleton().unwrap().2.clone(); + Some(snapshot.text) } fn handle_thread_event(