agent: Show checkmark for current profile, not default profile (#30314)

Cole Miller created

Closes #ISSUE

Release Notes:

- agent: Fixed a bug that caused the profile selector to display a
checkmark next to the wrong profile.

Change summary

crates/agent/src/profile_selector.rs | 34 +++++++++++++++++------------
crates/agent/src/thread.rs           | 33 ++++++++++------------------
2 files changed, 32 insertions(+), 35 deletions(-)

Detailed changes

crates/agent/src/profile_selector.rs 🔗

@@ -59,8 +59,12 @@ impl ProfileSelector {
         ContextMenu::build(window, cx, |mut menu, _window, cx| {
             let settings = AssistantSettings::get_global(cx);
             for (profile_id, profile) in self.profiles.builtin.iter() {
-                menu =
-                    menu.item(self.menu_entry_for_profile(profile_id.clone(), profile, settings));
+                menu = menu.item(self.menu_entry_for_profile(
+                    profile_id.clone(),
+                    profile,
+                    settings,
+                    cx,
+                ));
             }
 
             if !self.profiles.custom.is_empty() {
@@ -70,6 +74,7 @@ impl ProfileSelector {
                         profile_id.clone(),
                         profile,
                         settings,
+                        cx,
                     ));
                 }
             }
@@ -90,6 +95,7 @@ impl ProfileSelector {
         profile_id: AgentProfileId,
         profile: &AgentProfile,
         settings: &AssistantSettings,
+        cx: &App,
     ) -> ContextMenuEntry {
         let documentation = match profile.name.to_lowercase().as_str() {
             builtin_profiles::WRITE => Some("Get help to write anything."),
@@ -98,8 +104,12 @@ impl ProfileSelector {
             _ => None,
         };
 
-        let entry = ContextMenuEntry::new(profile.name.clone())
-            .toggleable(IconPosition::End, profile_id == settings.default_profile);
+        let current_profile_id = self.thread.read(cx).configured_profile_id();
+
+        let entry = ContextMenuEntry::new(profile.name.clone()).toggleable(
+            IconPosition::End,
+            Some(profile_id.clone()) == current_profile_id,
+        );
 
         let entry = if let Some(doc_text) = documentation {
             entry.documentation_aside(documentation_side(settings.dock), move |_| {
@@ -112,13 +122,11 @@ impl ProfileSelector {
         entry.handler({
             let thread_store = self.thread_store.clone();
             let profile_id = profile_id.clone();
-            let profile = profile.clone();
-
             let thread = self.thread.clone();
 
             move |_window, cx| {
                 thread.update(cx, |thread, cx| {
-                    thread.set_configured_profile(Some(profile.clone()), cx);
+                    thread.set_configured_profile_id(Some(profile_id.clone()), cx);
                 });
 
                 thread_store
@@ -134,14 +142,12 @@ impl ProfileSelector {
 impl Render for ProfileSelector {
     fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
         let settings = AssistantSettings::get_global(cx);
-        let profile = self
+        let profile_id = self
             .thread
-            .read_with(cx, |thread, _cx| thread.configured_profile())
-            .or_else(|| {
-                let profile_id = &settings.default_profile;
-                let profile = settings.profiles.get(profile_id);
-                profile.cloned()
-            });
+            .read(cx)
+            .configured_profile_id()
+            .unwrap_or(settings.default_profile.clone());
+        let profile = settings.profiles.get(&profile_id).cloned();
 
         let selected_profile = profile
             .map(|profile| profile.name.clone())

crates/agent/src/thread.rs 🔗

@@ -5,7 +5,7 @@ use std::sync::Arc;
 use std::time::Instant;
 
 use anyhow::{Result, anyhow};
-use assistant_settings::{AgentProfile, AgentProfileId, AssistantSettings, CompletionMode};
+use assistant_settings::{AgentProfileId, AssistantSettings, CompletionMode};
 use assistant_tool::{ActionLog, AnyToolCard, Tool, ToolWorkingSet};
 use chrono::{DateTime, Utc};
 use collections::HashMap;
@@ -359,7 +359,7 @@ pub struct Thread {
     >,
     remaining_turns: u32,
     configured_model: Option<ConfiguredModel>,
-    configured_profile: Option<AgentProfile>,
+    configured_profile_id: Option<AgentProfileId>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -381,8 +381,7 @@ impl Thread {
         let (detailed_summary_tx, detailed_summary_rx) = postage::watch::channel();
         let configured_model = LanguageModelRegistry::read_global(cx).default_model();
         let assistant_settings = AssistantSettings::get_global(cx);
-        let profile_id = &assistant_settings.default_profile;
-        let configured_profile = assistant_settings.profiles.get(profile_id).cloned();
+        let configured_profile_id = assistant_settings.default_profile.clone();
 
         Self {
             id: ThreadId::new(),
@@ -425,7 +424,7 @@ impl Thread {
             request_callback: None,
             remaining_turns: u32::MAX,
             configured_model,
-            configured_profile,
+            configured_profile_id: Some(configured_profile_id),
         }
     }
 
@@ -473,12 +472,7 @@ impl Thread {
             .completion_mode
             .unwrap_or_else(|| AssistantSettings::get_global(cx).preferred_completion_mode);
 
-        let configured_profile = serialized.profile.and_then(|profile| {
-            AssistantSettings::get_global(cx)
-                .profiles
-                .get(&profile)
-                .cloned()
-        });
+        let configured_profile_id = serialized.profile.clone();
 
         Self {
             id,
@@ -553,7 +547,7 @@ impl Thread {
             request_callback: None,
             remaining_turns: u32::MAX,
             configured_model,
-            configured_profile,
+            configured_profile_id,
         }
     }
 
@@ -609,16 +603,16 @@ impl Thread {
         cx.notify();
     }
 
-    pub fn configured_profile(&self) -> Option<AgentProfile> {
-        self.configured_profile.clone()
+    pub fn configured_profile_id(&self) -> Option<AgentProfileId> {
+        self.configured_profile_id.clone()
     }
 
-    pub fn set_configured_profile(
+    pub fn set_configured_profile_id(
         &mut self,
-        profile: Option<AgentProfile>,
+        id: Option<AgentProfileId>,
         cx: &mut Context<Self>,
     ) {
-        self.configured_profile = profile;
+        self.configured_profile_id = id;
         cx.notify();
     }
 
@@ -1126,10 +1120,7 @@ impl Thread {
                         provider: model.provider.id().0.to_string(),
                         model: model.model.id().0.to_string(),
                     }),
-                profile: this
-                    .configured_profile
-                    .as_ref()
-                    .map(|profile| AgentProfileId(profile.name.clone().into())),
+                profile: this.configured_profile_id.clone(),
                 completion_mode: Some(this.completion_mode),
             })
         })