From 743180342a57892417dbbcfc6e6a0232dbe966e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Kondzior?= Date: Thu, 30 Oct 2025 17:19:32 +0100 Subject: [PATCH] agent_ui: Insert thread summary as proper mention URI (#40722) This ensures the thread summary is treated as a tracked mention with accessible context. Changes: - Fixed `MessageEditor::insert_thread_summary()` to use proper mention URI format - Added test coverage to verify the fix Release Notes: - Fixed an issue where "New From Summary" was not properly inserting thread summaries as contextual mentions when creating new threads. Thread summaries are now inserted as proper mention URIs. --- crates/agent_ui/src/acp/message_editor.rs | 100 +++++++++++++++++++--- 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 35bde2c84d5e9aa5d14ec92dc0579b9fcd849904..90991182dc77e00c07fb7c7330695f72da9a2f44 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -235,8 +235,16 @@ impl MessageEditor { window: &mut Window, cx: &mut Context, ) { + let uri = MentionUri::Thread { + id: thread.id.clone(), + name: thread.title.to_string(), + }; + let content = format!("{}\n", uri.as_link()); + + let content_len = content.len() - 1; + let start = self.editor.update(cx, |editor, cx| { - editor.set_text(format!("{}\n", thread.title), window, cx); + editor.set_text(content, window, cx); editor .buffer() .read(cx) @@ -245,18 +253,8 @@ impl MessageEditor { .text_anchor }); - self.confirm_mention_completion( - thread.title.clone(), - start, - thread.title.len(), - MentionUri::Thread { - id: thread.id.clone(), - name: thread.title.to_string(), - }, - window, - cx, - ) - .detach(); + self.confirm_mention_completion(thread.title, start, content_len, uri, window, cx) + .detach(); } #[cfg(test)] @@ -1601,6 +1599,7 @@ mod tests { use gpui::{ AppContext, Entity, EventEmitter, FocusHandle, Focusable, TestAppContext, VisualTestContext, }; + use language_model::LanguageModelRegistry; use lsp::{CompletionContext, CompletionTriggerKind}; use project::{CompletionIntent, Project, ProjectPath}; use serde_json::json; @@ -2746,6 +2745,81 @@ mod tests { _ => panic!("Expected Text mention for small file"), } } + #[gpui::test] + async fn test_insert_thread_summary(cx: &mut TestAppContext) { + init_test(cx); + cx.update(LanguageModelRegistry::test); + + let fs = FakeFs::new(cx.executor()); + fs.insert_tree("/project", json!({"file": ""})).await; + let project = Project::test(fs, [Path::new(path!("/project"))], cx).await; + + let (workspace, cx) = + cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx)); + + let text_thread_store = cx.new(|cx| TextThreadStore::fake(project.clone(), cx)); + let history_store = cx.new(|cx| HistoryStore::new(text_thread_store, cx)); + + // Create a thread metadata to insert as summary + let thread_metadata = agent::DbThreadMetadata { + id: acp::SessionId("thread-123".into()), + title: "Previous Conversation".into(), + updated_at: chrono::Utc::now(), + }; + + let message_editor = cx.update(|window, cx| { + cx.new(|cx| { + let mut editor = MessageEditor::new( + workspace.downgrade(), + project.clone(), + history_store.clone(), + None, + Default::default(), + Default::default(), + "Test Agent".into(), + "Test", + EditorMode::AutoHeight { + min_lines: 1, + max_lines: None, + }, + window, + cx, + ); + editor.insert_thread_summary(thread_metadata.clone(), window, cx); + editor + }) + }); + + // Construct expected values for verification + let expected_uri = MentionUri::Thread { + id: thread_metadata.id.clone(), + name: thread_metadata.title.to_string(), + }; + let expected_link = format!("[@{}]({})", thread_metadata.title, expected_uri.to_uri()); + + message_editor.read_with(cx, |editor, cx| { + let text = editor.text(cx); + + assert!( + text.contains(&expected_link), + "Expected editor text to contain thread mention link.\nExpected substring: {}\nActual text: {}", + expected_link, + text + ); + + let mentions = editor.mentions(); + assert_eq!( + mentions.len(), + 1, + "Expected exactly one mention after inserting thread summary" + ); + + assert!( + mentions.contains(&expected_uri), + "Expected mentions to contain the thread URI" + ); + }); + } #[gpui::test] async fn test_whitespace_trimming(cx: &mut TestAppContext) {