agent_ai: Insert thread summary as proper mention uri

Paweł Kondzior created

Change summary

crates/agent_ui/src/acp/message_editor.rs | 99 +++++++++++++++++++++---
1 file changed, 86 insertions(+), 13 deletions(-)

Detailed changes

crates/agent_ui/src/acp/message_editor.rs 🔗

@@ -234,8 +234,16 @@ impl MessageEditor {
         window: &mut Window,
         cx: &mut Context<Self>,
     ) {
+        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)
@@ -244,18 +252,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.clone(), start, content_len, uri, window, cx)
+            .detach();
     }
 
     #[cfg(test)]
@@ -2746,4 +2744,79 @@ mod tests {
             _ => panic!("Expected Text mention for small file"),
         }
     }
+
+    #[gpui::test]
+    async fn test_insert_thread_summary(cx: &mut TestAppContext) {
+        init_test(cx);
+
+        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 context_store = cx.new(|cx| ContextStore::fake(project.clone(), cx));
+        let history_store = cx.new(|cx| HistoryStore::new(context_store, cx));
+
+        // Create a thread metadata to insert as summary
+        let thread_metadata = agent2::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"
+            );
+        });
+    }
 }