From 9ddf43936a55326b6f03385d55d54ec1217d229b Mon Sep 17 00:00:00 2001 From: David3u <3udavid@gmail.com> Date: Fri, 15 May 2026 16:18:27 -0400 Subject: [PATCH 1/2] Enable thinking level keybinds for other agents --- crates/agent_ui/src/config_options.rs | 58 ++++++++++++++++--- crates/agent_ui/src/conversation_view.rs | 9 ++- .../src/conversation_view/thread_view.rs | 22 +++++++ 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/crates/agent_ui/src/config_options.rs b/crates/agent_ui/src/config_options.rs index c1f9a09c22ff28..bba0f27cf156ea 100644 --- a/crates/agent_ui/src/config_options.rs +++ b/crates/agent_ui/src/config_options.rs @@ -28,6 +28,7 @@ pub struct ConfigOptionsView { selectors: Vec>, agent_server: Rc, fs: Arc, + persist_selected_categories_as_defaults: Vec, config_option_ids: Vec, _refresh_task: Task<()>, } @@ -37,10 +38,18 @@ impl ConfigOptionsView { config_options: Rc, agent_server: Rc, fs: Arc, + persist_selected_categories_as_defaults: Vec, window: &mut Window, cx: &mut Context, ) -> Self { - let selectors = Self::build_selectors(&config_options, &agent_server, &fs, window, cx); + let selectors = Self::build_selectors( + &config_options, + &agent_server, + &fs, + &persist_selected_categories_as_defaults, + window, + cx, + ); let config_option_ids = Self::config_option_ids(&config_options); let rx = config_options.watch(cx); @@ -61,6 +70,7 @@ impl ConfigOptionsView { selectors, agent_server, fs, + persist_selected_categories_as_defaults, config_option_ids, _refresh_task: refresh_task, } @@ -72,7 +82,7 @@ impl ConfigOptionsView { window: &mut Window, cx: &mut Context, ) -> bool { - let Some(config_id) = self.first_config_option_id(category) else { + let Some(config_id) = self.first_config_option_id(category.clone()) else { return false; }; @@ -93,7 +103,7 @@ impl ConfigOptionsView { favorites_only: bool, cx: &mut Context, ) -> bool { - let Some(config_id) = self.first_config_option_id(category) else { + let Some(config_id) = self.first_config_option_id(category.clone()) else { return false; }; @@ -101,6 +111,18 @@ impl ConfigOptionsView { return false; }; + if self + .persist_selected_categories_as_defaults + .contains(&category) + { + self.agent_server.set_default_config_option( + config_id.0.as_ref(), + Some(next_value.0.as_ref()), + self.fs.clone(), + cx, + ); + } + let task = self .config_options .set_config_option(config_id, next_value, cx); @@ -191,6 +213,7 @@ impl ConfigOptionsView { &self.config_options, &self.agent_server, &self.fs, + &self.persist_selected_categories_as_defaults, window, cx, ); @@ -201,6 +224,7 @@ impl ConfigOptionsView { config_options: &Rc, agent_server: &Rc, fs: &Arc, + persist_selected_categories_as_defaults: &[acp::SessionConfigOptionCategory], window: &mut Window, cx: &mut Context, ) -> Vec> { @@ -211,12 +235,17 @@ impl ConfigOptionsView { let config_options = config_options.clone(); let agent_server = agent_server.clone(); let fs = fs.clone(); + let should_persist_selected_value_as_default = + option.category.as_ref().is_some_and(|category| { + persist_selected_categories_as_defaults.contains(category) + }); cx.new(|cx| { ConfigOptionSelector::new( config_options, option.id.clone(), agent_server, fs, + should_persist_selected_value_as_default, window, cx, ) @@ -253,15 +282,15 @@ impl ConfigOptionSelector { config_id: acp::SessionConfigId, agent_server: Rc, fs: Arc, + should_persist_selected_value_as_default: bool, window: &mut Window, cx: &mut Context, ) -> Self { - let option_count = config_options + let option = config_options .config_options() - .iter() - .find(|opt| opt.id == config_id) - .map(count_config_options) - .unwrap_or(0); + .into_iter() + .find(|opt| opt.id == config_id); + let option_count = option.as_ref().map(count_config_options).unwrap_or(0); let is_searchable = option_count >= PICKER_THRESHOLD; @@ -276,6 +305,7 @@ impl ConfigOptionSelector { config_id, agent_server, fs, + should_persist_selected_value_as_default, window, picker_cx, ); @@ -409,6 +439,7 @@ struct ConfigOptionPickerDelegate { config_id: acp::SessionConfigId, agent_server: Rc, fs: Arc, + should_persist_selected_value_as_default: bool, filtered_entries: Vec, all_options: Vec, selected_index: usize, @@ -423,6 +454,7 @@ impl ConfigOptionPickerDelegate { config_id: acp::SessionConfigId, agent_server: Rc, fs: Arc, + should_persist_selected_value_as_default: bool, window: &mut Window, cx: &mut Context>, ) -> Self { @@ -459,6 +491,7 @@ impl ConfigOptionPickerDelegate { config_id, agent_server, fs, + should_persist_selected_value_as_default, filtered_entries, all_options, selected_index, @@ -564,6 +597,15 @@ impl PickerDelegate for ConfigOptionPickerDelegate { self.fs.clone(), cx, ); + } else { + if self.should_persist_selected_value_as_default { + self.agent_server.set_default_config_option( + self.config_id.0.as_ref(), + Some(option.value.0.as_ref()), + self.fs.clone(), + cx, + ); + } } let task = self.config_options.set_config_option( diff --git a/crates/agent_ui/src/conversation_view.rs b/crates/agent_ui/src/conversation_view.rs index 9383110e086e39..26933651b5b964 100644 --- a/crates/agent_ui/src/conversation_view.rs +++ b/crates/agent_ui/src/conversation_view.rs @@ -1087,7 +1087,14 @@ impl ConversationView { let fs = self.project.read(cx).fs().clone(); config_options_view = Some(cx.new(|cx| { - ConfigOptionsView::new(config_options, agent_server, fs, window, cx) + ConfigOptionsView::new( + config_options, + agent_server, + fs, + vec![acp::SessionConfigOptionCategory::ThoughtLevel], + window, + cx, + ) })); model_selector = None; mode_selector = None; diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index c9ef49215429b8..71adaaef64b1d5 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -9023,6 +9023,15 @@ impl ThreadView { fn cycle_thinking_effort(&mut self, cx: &mut Context) { let Some(thread) = self.as_native_thread(cx) else { + if let Some(config_options_view) = self.config_options_view.clone() { + config_options_view.update(cx, |view, cx| { + view.cycle_category_option( + acp::SessionConfigOptionCategory::ThoughtLevel, + false, + cx, + ) + }); + } return; }; @@ -9081,6 +9090,19 @@ impl ThreadView { window: &mut Window, cx: &mut Context, ) { + if self.as_native_thread(cx).is_none() { + if let Some(config_options_view) = self.config_options_view.clone() { + config_options_view.update(cx, |view, cx| { + view.toggle_category_picker( + acp::SessionConfigOptionCategory::ThoughtLevel, + window, + cx, + ) + }); + } + return; + } + let menu_handle = self.thinking_effort_menu_handle.clone(); window.defer(cx, move |window, cx| { menu_handle.toggle(window, cx); From fe046be2931ec51bfe9ad2bd1be46b4a269c121a Mon Sep 17 00:00:00 2001 From: David3u <3udavid@gmail.com> Date: Fri, 15 May 2026 16:19:05 -0400 Subject: [PATCH 2/2] Preselect the active thinking effort --- .../src/conversation_view/thread_view.rs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index 71adaaef64b1d5..5156e5b5633d9c 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -3908,9 +3908,9 @@ impl ThreadView { .cloned() }); - let label = selected + let active_effort = selected.clone().or(default_effort_level); + let label = active_effort .clone() - .or(default_effort_level) .map_or("Select Effort".into(), |effort| effort.name); let (label_color, icon) = if self.thinking_effort_menu_handle.is_deployed() { @@ -3966,11 +3966,16 @@ impl ThreadView { tooltip, ) .menu(move |window, cx| { - Some(ContextMenu::build(window, cx, |mut menu, _window, _cx| { + Some(ContextMenu::build(window, cx, |mut menu, window, cx| { menu = menu.header("Change Thinking Effort"); + let selected_index = active_effort.as_ref().and_then(|active_effort| { + supported_effort_levels + .iter() + .position(|level| level.value == active_effort.value) + }); for effort_level in supported_effort_levels.clone() { - let is_selected = selected + let is_selected = active_effort .as_ref() .is_some_and(|selected| selected.value == effort_level.value); let entry = ContextMenuEntry::new(effort_level.name) @@ -4027,6 +4032,13 @@ impl ThreadView { })); } + if let Some(selected_index) = selected_index { + menu.select_first(&menu::SelectFirst, window, cx); + for _ in 0..selected_index { + menu.select_next(&menu::SelectNext, window, cx); + } + } + menu })) })