diff --git a/crates/assistant2/src/context.rs b/crates/assistant2/src/context.rs index 074ae18924..1aff6c982d 100644 --- a/crates/assistant2/src/context.rs +++ b/crates/assistant2/src/context.rs @@ -1,11 +1,8 @@ use gpui::SharedString; use language_model::{LanguageModelRequestMessage, MessageContent}; -use project::ProjectEntryId; use serde::{Deserialize, Serialize}; use util::post_inc; -use crate::thread::ThreadId; - #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)] pub struct ContextId(pub(crate) usize); @@ -26,10 +23,10 @@ pub struct Context { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ContextKind { - File(ProjectEntryId), + File, Directory, FetchedUrl, - Thread(ThreadId), + Thread, } pub fn attach_context_to_message( @@ -43,7 +40,7 @@ pub fn attach_context_to_message( for context in context.into_iter() { match context.kind { - ContextKind::File(_) => { + ContextKind::File => { file_context.push_str(&context.text); file_context.push('\n'); } @@ -57,7 +54,7 @@ pub fn attach_context_to_message( fetch_context.push_str(&context.text); fetch_context.push('\n'); } - ContextKind::Thread(_) => { + ContextKind::Thread => { thread_context.push_str(&context.name); thread_context.push('\n'); thread_context.push_str(&context.text); diff --git a/crates/assistant2/src/context_picker.rs b/crates/assistant2/src/context_picker.rs index dda25d0643..c9bfe07f56 100644 --- a/crates/assistant2/src/context_picker.rs +++ b/crates/assistant2/src/context_picker.rs @@ -14,6 +14,7 @@ use ui::{prelude::*, ListItem, ListItemSpacing}; use util::ResultExt; use workspace::Workspace; +use crate::context::ContextKind; use crate::context_picker::directory_context_picker::DirectoryContextPicker; use crate::context_picker::fetch_context_picker::FetchContextPicker; use crate::context_picker::file_context_picker::FileContextPicker; @@ -52,24 +53,24 @@ impl ContextPicker { let mut entries = Vec::new(); entries.push(ContextPickerEntry { name: "File".into(), - kind: ContextPickerEntryKind::File, + kind: ContextKind::File, icon: IconName::File, }); entries.push(ContextPickerEntry { name: "Folder".into(), - kind: ContextPickerEntryKind::Directory, + kind: ContextKind::Directory, icon: IconName::Folder, }); entries.push(ContextPickerEntry { name: "Fetch".into(), - kind: ContextPickerEntryKind::FetchedUrl, + kind: ContextKind::FetchedUrl, icon: IconName::Globe, }); if thread_store.is_some() { entries.push(ContextPickerEntry { name: "Thread".into(), - kind: ContextPickerEntryKind::Thread, + kind: ContextKind::Thread, icon: IconName::MessageCircle, }); } @@ -133,18 +134,10 @@ impl Render for ContextPicker { #[derive(Clone)] struct ContextPickerEntry { name: SharedString, - kind: ContextPickerEntryKind, + kind: ContextKind, icon: IconName, } -#[derive(Debug, Clone)] -enum ContextPickerEntryKind { - File, - Directory, - FetchedUrl, - Thread, -} - pub(crate) struct ContextPickerDelegate { context_picker: WeakView, workspace: WeakView, @@ -184,7 +177,7 @@ impl PickerDelegate for ContextPickerDelegate { self.context_picker .update(cx, |this, cx| { match entry.kind { - ContextPickerEntryKind::File => { + ContextKind::File => { this.mode = ContextPickerMode::File(cx.new_view(|cx| { FileContextPicker::new( self.context_picker.clone(), @@ -195,7 +188,7 @@ impl PickerDelegate for ContextPickerDelegate { ) })); } - ContextPickerEntryKind::Directory => { + ContextKind::Directory => { this.mode = ContextPickerMode::Directory(cx.new_view(|cx| { DirectoryContextPicker::new( self.context_picker.clone(), @@ -206,7 +199,7 @@ impl PickerDelegate for ContextPickerDelegate { ) })); } - ContextPickerEntryKind::FetchedUrl => { + ContextKind::FetchedUrl => { this.mode = ContextPickerMode::Fetch(cx.new_view(|cx| { FetchContextPicker::new( self.context_picker.clone(), @@ -217,7 +210,7 @@ impl PickerDelegate for ContextPickerDelegate { ) })); } - ContextPickerEntryKind::Thread => { + ContextKind::Thread => { if let Some(thread_store) = self.thread_store.as_ref() { this.mode = ContextPickerMode::Thread(cx.new_view(|cx| { ThreadContextPicker::new( diff --git a/crates/assistant2/src/context_picker/directory_context_picker.rs b/crates/assistant2/src/context_picker/directory_context_picker.rs index ecd8b6b70e..b37a7f38eb 100644 --- a/crates/assistant2/src/context_picker/directory_context_picker.rs +++ b/crates/assistant2/src/context_picker/directory_context_picker.rs @@ -11,10 +11,8 @@ use ui::{prelude::*, ListItem}; use util::ResultExt as _; use workspace::Workspace; -use crate::context::ContextKind; -use crate::context_picker::file_context_picker::codeblock_fence_for_path; use crate::context_picker::{ConfirmBehavior, ContextPicker}; -use crate::context_store::ContextStore; +use crate::context_store::{push_fenced_codeblock, ContextStore}; pub struct DirectoryContextPicker { picker: View>, @@ -189,6 +187,22 @@ impl PickerDelegate for DirectoryContextPickerDelegate { return; }; let path = mat.path.clone(); + + if self + .context_store + .update(cx, |context_store, _cx| { + if let Some(context_id) = context_store.included_directory(&path) { + context_store.remove_context(&context_id); + true + } else { + false + } + }) + .unwrap_or(true) + { + return; + } + let worktree_id = WorktreeId::from_usize(mat.worktree_id); let confirm_behavior = self.confirm_behavior; cx.spawn(|this, mut cx| async move { @@ -235,23 +249,15 @@ impl PickerDelegate for DirectoryContextPickerDelegate { let mut text = String::new(); for buffer in buffers { - text.push_str(&codeblock_fence_for_path(Some(&path), None)); - text.push_str(&buffer.read(cx).text()); - if !text.ends_with('\n') { - text.push('\n'); - } - - text.push_str("```\n"); + let buffer = buffer.read(cx); + let path = buffer.file().map_or(&path, |file| file.path()); + push_fenced_codeblock(&path, buffer.text(), &mut text); } this.delegate .context_store .update(cx, |context_store, _cx| { - context_store.insert_context( - ContextKind::Directory, - path.to_string_lossy().to_string(), - text, - ); + context_store.insert_directory(&path, text); })?; match confirm_behavior { @@ -280,16 +286,26 @@ impl PickerDelegate for DirectoryContextPickerDelegate { &self, ix: usize, selected: bool, - _cx: &mut ViewContext>, + cx: &mut ViewContext>, ) -> Option { let path_match = &self.matches[ix]; let directory_name = path_match.path.to_string_lossy().to_string(); + let added = self.context_store.upgrade().map_or(false, |context_store| { + context_store + .read(cx) + .included_directory(&path_match.path) + .is_some() + }); + Some( ListItem::new(ix) .inset(true) .toggle_state(selected) - .child(h_flex().gap_2().child(Label::new(directory_name))), + .child(h_flex().gap_2().child(Label::new(directory_name))) + .when(added, |el| { + el.end_slot(Label::new("Added").size(LabelSize::XSmall)) + }), ) } } diff --git a/crates/assistant2/src/context_picker/fetch_context_picker.rs b/crates/assistant2/src/context_picker/fetch_context_picker.rs index 45a0575911..5bdb02ba6b 100644 --- a/crates/assistant2/src/context_picker/fetch_context_picker.rs +++ b/crates/assistant2/src/context_picker/fetch_context_picker.rs @@ -11,7 +11,6 @@ use picker::{Picker, PickerDelegate}; use ui::{prelude::*, ListItem, ViewContext}; use workspace::Workspace; -use crate::context::ContextKind; use crate::context_picker::{ConfirmBehavior, ContextPicker}; use crate::context_store::ContextStore; @@ -201,7 +200,9 @@ impl PickerDelegate for FetchContextPickerDelegate { this.delegate .context_store .update(cx, |context_store, _cx| { - context_store.insert_context(ContextKind::FetchedUrl, url, text); + if context_store.included_url(&url).is_none() { + context_store.insert_fetched_url(url, text); + } })?; match confirm_behavior { @@ -230,13 +231,22 @@ impl PickerDelegate for FetchContextPickerDelegate { &self, ix: usize, selected: bool, - _cx: &mut ViewContext>, + cx: &mut ViewContext>, ) -> Option { + let added = self.context_store.upgrade().map_or(false, |context_store| { + context_store.read(cx).included_url(&self.url).is_some() + }); + Some( ListItem::new(ix) .inset(true) .toggle_state(selected) - .child(Label::new(self.url.clone())), + .child(Label::new(self.url.clone())) + .when(added, |child| { + child + .disabled(true) + .end_slot(Label::new("Added").size(LabelSize::XSmall)) + }), ) } } diff --git a/crates/assistant2/src/context_picker/file_context_picker.rs b/crates/assistant2/src/context_picker/file_context_picker.rs index 66aacf05c1..741515b3c8 100644 --- a/crates/assistant2/src/context_picker/file_context_picker.rs +++ b/crates/assistant2/src/context_picker/file_context_picker.rs @@ -1,5 +1,3 @@ -use std::fmt::Write as _; -use std::ops::RangeInclusive; use std::path::Path; use std::sync::atomic::AtomicBool; use std::sync::Arc; @@ -8,13 +6,12 @@ use fuzzy::PathMatch; use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, WeakModel, WeakView}; use picker::{Picker, PickerDelegate}; use project::{PathMatchCandidateSet, ProjectPath, WorktreeId}; -use ui::{prelude::*, ListItem}; +use ui::{prelude::*, ListItem, Tooltip}; use util::ResultExt as _; use workspace::Workspace; -use crate::context::ContextKind; use crate::context_picker::{ConfirmBehavior, ContextPicker}; -use crate::context_store::ContextStore; +use crate::context_store::{ContextStore, IncludedFile}; pub struct FileContextPicker { picker: View>, @@ -204,20 +201,37 @@ impl PickerDelegate for FileContextPickerDelegate { return; }; let path = mat.path.clone(); + + if self + .context_store + .update(cx, |context_store, _cx| { + match context_store.included_file(&path) { + Some(IncludedFile::Direct(context_id)) => { + context_store.remove_context(&context_id); + true + } + Some(IncludedFile::InDirectory(_)) => true, + None => false, + } + }) + .unwrap_or(true) + { + return; + } + let worktree_id = WorktreeId::from_usize(mat.worktree_id); let confirm_behavior = self.confirm_behavior; cx.spawn(|this, mut cx| async move { - let Some((entry_id, open_buffer_task)) = project + let Some(open_buffer_task) = project .update(&mut cx, |project, cx| { let project_path = ProjectPath { worktree_id, path: path.clone(), }; - let entry_id = project.entry_for_path(&project_path, cx)?.id; let task = project.open_buffer(project_path, cx); - Some((entry_id, task)) + Some(task) }) .ok() .flatten() @@ -231,20 +245,7 @@ impl PickerDelegate for FileContextPickerDelegate { this.delegate .context_store .update(cx, |context_store, cx| { - let mut text = String::new(); - text.push_str(&codeblock_fence_for_path(Some(&path), None)); - text.push_str(&buffer.read(cx).text()); - if !text.ends_with('\n') { - text.push('\n'); - } - - text.push_str("```\n"); - - context_store.insert_context( - ContextKind::File(entry_id), - path.to_string_lossy().to_string(), - text, - ); + context_store.insert_file(buffer.read(cx)); })?; match confirm_behavior { @@ -273,7 +274,7 @@ impl PickerDelegate for FileContextPickerDelegate { &self, ix: usize, selected: bool, - _cx: &mut ViewContext>, + cx: &mut ViewContext>, ) -> Option { let path_match = &self.matches[ix]; @@ -301,42 +302,36 @@ impl PickerDelegate for FileContextPickerDelegate { (file_name, Some(directory)) }; + let added = self + .context_store + .upgrade() + .and_then(|context_store| context_store.read(cx).included_file(&path_match.path)); + Some( - ListItem::new(ix).inset(true).toggle_state(selected).child( - h_flex() - .gap_2() - .child(Label::new(file_name)) - .children(directory.map(|directory| { - Label::new(directory) - .size(LabelSize::Small) - .color(Color::Muted) - })), - ), + ListItem::new(ix) + .inset(true) + .toggle_state(selected) + .child( + h_flex() + .gap_2() + .child(Label::new(file_name)) + .children(directory.map(|directory| { + Label::new(directory) + .size(LabelSize::Small) + .color(Color::Muted) + })), + ) + .when_some(added, |el, added| match added { + IncludedFile::Direct(_) => { + el.end_slot(Label::new("Added").size(LabelSize::XSmall)) + } + IncludedFile::InDirectory(dir_name) => { + let dir_name = dir_name.to_string_lossy().into_owned(); + + el.end_slot(Label::new("Included").size(LabelSize::XSmall)) + .tooltip(move |cx| Tooltip::text(format!("in {dir_name}"), cx)) + } + }), ) } } - -pub(crate) fn codeblock_fence_for_path( - path: Option<&Path>, - row_range: Option>, -) -> String { - let mut text = String::new(); - write!(text, "```").unwrap(); - - if let Some(path) = path { - if let Some(extension) = path.extension().and_then(|ext| ext.to_str()) { - write!(text, "{} ", extension).unwrap(); - } - - write!(text, "{}", path.display()).unwrap(); - } else { - write!(text, "untitled").unwrap(); - } - - if let Some(row_range) = row_range { - write!(text, ":{}-{}", row_range.start() + 1, row_range.end() + 1).unwrap(); - } - - text.push('\n'); - text -} diff --git a/crates/assistant2/src/context_picker/thread_context_picker.rs b/crates/assistant2/src/context_picker/thread_context_picker.rs index 42a5eebccd..1fedafc0a8 100644 --- a/crates/assistant2/src/context_picker/thread_context_picker.rs +++ b/crates/assistant2/src/context_picker/thread_context_picker.rs @@ -5,7 +5,6 @@ use gpui::{AppContext, DismissEvent, FocusHandle, FocusableView, Task, View, Wea use picker::{Picker, PickerDelegate}; use ui::{prelude::*, ListItem}; -use crate::context::ContextKind; use crate::context_picker::{ConfirmBehavior, ContextPicker}; use crate::context_store; use crate::thread::ThreadId; @@ -169,11 +168,11 @@ impl PickerDelegate for ThreadContextPickerDelegate { self.context_store .update(cx, |context_store, cx| { - context_store.insert_context( - ContextKind::Thread(thread.read(cx).id().clone()), - entry.summary.clone(), - thread.read(cx).text(), - ); + if let Some(context_id) = context_store.included_thread(&entry.id) { + context_store.remove_context(&context_id); + } else { + context_store.insert_thread(thread.read(cx)); + } }) .ok(); @@ -196,15 +195,22 @@ impl PickerDelegate for ThreadContextPickerDelegate { &self, ix: usize, selected: bool, - _cx: &mut ViewContext>, + cx: &mut ViewContext>, ) -> Option { let thread = &self.matches[ix]; + let added = self.context_store.upgrade().map_or(false, |ctx_store| { + ctx_store.read(cx).included_thread(&thread.id).is_some() + }); + Some( ListItem::new(ix) .inset(true) .toggle_state(selected) - .child(Label::new(thread.summary.clone())), + .child(Label::new(thread.summary.clone())) + .when(added, |el| { + el.end_slot(Label::new("Added").size(LabelSize::XSmall)) + }), ) } } diff --git a/crates/assistant2/src/context_store.rs b/crates/assistant2/src/context_store.rs index 76fafdf797..9751103fd7 100644 --- a/crates/assistant2/src/context_store.rs +++ b/crates/assistant2/src/context_store.rs @@ -1,6 +1,11 @@ -use gpui::SharedString; -use project::ProjectEntryId; +use std::fmt::Write as _; +use std::path::{Path, PathBuf}; +use collections::HashMap; +use gpui::SharedString; +use language::Buffer; + +use crate::thread::Thread; use crate::{ context::{Context, ContextId, ContextKind}, thread::ThreadId, @@ -9,6 +14,10 @@ use crate::{ pub struct ContextStore { context: Vec, next_context_id: ContextId, + files: HashMap, + directories: HashMap, + threads: HashMap, + fetched_urls: HashMap, } impl ContextStore { @@ -16,6 +25,10 @@ impl ContextStore { Self { context: Vec::new(), next_context_id: ContextId(0), + files: HashMap::default(), + directories: HashMap::default(), + threads: HashMap::default(), + fetched_urls: HashMap::default(), } } @@ -24,42 +37,154 @@ impl ContextStore { } pub fn drain(&mut self) -> Vec { + self.files.clear(); + self.directories.clear(); self.context.drain(..).collect() } pub fn clear(&mut self) { self.context.clear(); + self.files.clear(); + self.directories.clear(); } - pub fn insert_context( - &mut self, - kind: ContextKind, - name: impl Into, - text: impl Into, - ) { + pub fn insert_file(&mut self, buffer: &Buffer) { + let Some(file) = buffer.file() else { + return; + }; + + let path = file.path(); + + let id = self.next_context_id.post_inc(); + self.files.insert(path.to_path_buf(), id); + + let name = path.to_string_lossy().into_owned().into(); + + let mut text = String::new(); + push_fenced_codeblock(path, buffer.text(), &mut text); + self.context.push(Context { - id: self.next_context_id.post_inc(), - name: name.into(), - kind, + id, + name, + kind: ContextKind::File, + text: text.into(), + }); + } + + pub fn insert_directory(&mut self, path: &Path, text: impl Into) { + let id = self.next_context_id.post_inc(); + self.directories.insert(path.to_path_buf(), id); + + let name = path.to_string_lossy().into_owned().into(); + + self.context.push(Context { + id, + name, + kind: ContextKind::Directory, + text: text.into(), + }); + } + + pub fn insert_thread(&mut self, thread: &Thread) { + let context_id = self.next_context_id.post_inc(); + self.threads.insert(thread.id().clone(), context_id); + + self.context.push(Context { + id: context_id, + name: thread.summary().unwrap_or("New thread".into()), + kind: ContextKind::Thread, + text: thread.text().into(), + }); + } + + pub fn insert_fetched_url(&mut self, url: String, text: impl Into) { + let context_id = self.next_context_id.post_inc(); + self.fetched_urls.insert(url.clone(), context_id); + + self.context.push(Context { + id: context_id, + name: url.into(), + kind: ContextKind::FetchedUrl, text: text.into(), }); } pub fn remove_context(&mut self, id: &ContextId) { - self.context.retain(|context| context.id != *id); + let Some(ix) = self.context.iter().position(|c| c.id == *id) else { + return; + }; + + match self.context.remove(ix).kind { + ContextKind::File => { + self.files.retain(|_, p_id| p_id != id); + } + ContextKind::Directory => { + self.directories.retain(|_, p_id| p_id != id); + } + ContextKind::FetchedUrl => { + self.fetched_urls.retain(|_, p_id| p_id != id); + } + ContextKind::Thread => { + self.threads.retain(|_, p_id| p_id != id); + } + } } - pub fn contains_project_entry(&self, entry_id: ProjectEntryId) -> bool { - self.context.iter().any(|probe| match probe.kind { - ContextKind::File(probe_entry_id) => probe_entry_id == entry_id, - ContextKind::Directory | ContextKind::FetchedUrl | ContextKind::Thread(_) => false, - }) + pub fn included_file(&self, path: &Path) -> Option { + if let Some(id) = self.files.get(path) { + return Some(IncludedFile::Direct(*id)); + } + + if self.directories.is_empty() { + return None; + } + + let mut buf = path.to_path_buf(); + + while buf.pop() { + if let Some(_) = self.directories.get(&buf) { + return Some(IncludedFile::InDirectory(buf)); + } + } + + None } - pub fn contains_thread(&self, thread_id: &ThreadId) -> bool { - self.context.iter().any(|probe| match probe.kind { - ContextKind::Thread(ref probe_thread_id) => probe_thread_id == thread_id, - ContextKind::File(_) | ContextKind::Directory | ContextKind::FetchedUrl => false, - }) + pub fn included_directory(&self, path: &Path) -> Option { + self.directories.get(path).copied() + } + + pub fn included_thread(&self, thread_id: &ThreadId) -> Option { + self.threads.get(thread_id).copied() + } + + pub fn included_url(&self, url: &str) -> Option { + self.fetched_urls.get(url).copied() } } + +pub enum IncludedFile { + Direct(ContextId), + InDirectory(PathBuf), +} + +pub(crate) fn push_fenced_codeblock(path: &Path, content: String, buf: &mut String) { + buf.reserve(content.len() + 64); + + write!(buf, "```").unwrap(); + + if let Some(extension) = path.extension().and_then(|ext| ext.to_str()) { + write!(buf, "{} ", extension).unwrap(); + } + + write!(buf, "{}", path.display()).unwrap(); + + buf.push('\n'); + buf.push_str(&content); + + if !buf.ends_with('\n') { + buf.push('\n'); + } + + buf.push_str("```\n"); +} diff --git a/crates/assistant2/src/context_strip.rs b/crates/assistant2/src/context_strip.rs index 35ed504f9c..66aee3463c 100644 --- a/crates/assistant2/src/context_strip.rs +++ b/crates/assistant2/src/context_strip.rs @@ -3,14 +3,12 @@ use std::rc::Rc; use editor::Editor; use gpui::{AppContext, FocusHandle, Model, View, WeakModel, WeakView}; use language::Buffer; -use project::ProjectEntryId; use ui::{prelude::*, KeyBinding, PopoverMenu, PopoverMenuHandle, Tooltip}; use workspace::Workspace; -use crate::context::ContextKind; use crate::context_picker::{ConfirmBehavior, ContextPicker}; use crate::context_store::ContextStore; -use crate::thread::{Thread, ThreadId}; +use crate::thread::Thread; use crate::thread_store::ThreadStore; use crate::ui::ContextPill; use crate::{AssistantPanel, ToggleContextPicker}; @@ -62,20 +60,19 @@ impl ContextStrip { fn suggested_file(&self, cx: &ViewContext) -> Option { let workspace = self.workspace.upgrade()?; let active_item = workspace.read(cx).active_item(cx)?; - let entry_id = *active_item.project_entry_ids(cx).first()?; - - if self.context_store.read(cx).contains_project_entry(entry_id) { - return None; - } let editor = active_item.to_any().downcast::().ok()?.read(cx); let active_buffer = editor.buffer().read(cx).as_singleton()?; - let file = active_buffer.read(cx).file()?; - let title = file.path().to_string_lossy().into_owned().into(); + let path = active_buffer.read(cx).file()?.path(); + + if self.context_store.read(cx).included_file(path).is_some() { + return None; + } + + let title = path.to_string_lossy().into_owned().into(); Some(SuggestedContext::File { - entry_id, title, buffer: active_buffer.downgrade(), }) @@ -95,13 +92,13 @@ impl ContextStrip { if self .context_store .read(cx) - .contains_thread(active_thread.id()) + .included_thread(active_thread.id()) + .is_some() { return None; } Some(SuggestedContext::Thread { - id: active_thread.id().clone(), title: active_thread.summary().unwrap_or("Active Thread".into()), thread: weak_active_thread, }) @@ -230,12 +227,10 @@ pub enum SuggestContextKind { #[derive(Clone)] pub enum SuggestedContext { File { - entry_id: ProjectEntryId, title: SharedString, buffer: WeakModel, }, Thread { - id: ThreadId, title: SharedString, thread: WeakModel, }, @@ -251,32 +246,15 @@ impl SuggestedContext { pub fn accept(&self, context_store: &mut ContextStore, cx: &mut AppContext) { match self { - Self::File { - entry_id, - title, - buffer, - } => { - let Some(buffer) = buffer.upgrade() else { - return; + Self::File { buffer, title: _ } => { + if let Some(buffer) = buffer.upgrade() { + context_store.insert_file(buffer.read(cx)); }; - let text = buffer.read(cx).text(); - - context_store.insert_context( - ContextKind::File(*entry_id), - title.clone(), - text.clone(), - ); } - Self::Thread { id, title, thread } => { - let Some(thread) = thread.upgrade() else { - return; + Self::Thread { thread, title: _ } => { + if let Some(thread) = thread.upgrade() { + context_store.insert_thread(thread.read(cx)); }; - - context_store.insert_context( - ContextKind::Thread(id.clone()), - title.clone(), - thread.read(cx).text(), - ); } } } diff --git a/crates/assistant2/src/ui/context_pill.rs b/crates/assistant2/src/ui/context_pill.rs index b5c79d3473..fb926386e2 100644 --- a/crates/assistant2/src/ui/context_pill.rs +++ b/crates/assistant2/src/ui/context_pill.rs @@ -33,10 +33,10 @@ impl RenderOnce for ContextPill { px(4.) }; let icon = match self.context.kind { - ContextKind::File(_) => IconName::File, + ContextKind::File => IconName::File, ContextKind::Directory => IconName::Folder, ContextKind::FetchedUrl => IconName::Globe, - ContextKind::Thread(_) => IconName::MessageCircle, + ContextKind::Thread => IconName::MessageCircle, }; h_flex()