thread view: Improve thinking mode toggle UI (#47945)

Danilo Leal created

Add the icon to the left side of the message editor, add a new icon for
when the thinking mode is toggled on, and add a keybinding for the
action. Currently available under a feature flag-only but should be out
soon.

<img width="400" height="318" alt="Screenshot 2026-01-29 at 11  57@2x"
src="https://github.com/user-attachments/assets/e033ec83-746b-4fed-beb7-ed26e96cb60a"
/>

Release Notes:

- N/A

Change summary

assets/icons/thinking_mode.svg         | 13 +++++++++++++
assets/keymaps/default-linux.json      |  1 +
assets/keymaps/default-macos.json      |  1 +
assets/keymaps/default-windows.json    |  1 +
crates/agent_ui/src/acp/thread_view.rs | 27 +++++++++++++++++++--------
crates/agent_ui/src/agent_ui.rs        |  2 ++
crates/icons/src/icons.rs              |  1 +
7 files changed, 38 insertions(+), 8 deletions(-)

Detailed changes

assets/icons/thinking_mode.svg 🔗

@@ -0,0 +1,13 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_3950_76)">
+<path d="M9.95263 10.2625C10.0833 9.62316 9.95263 9.60567 10.9316 8.47947C11.5008 7.82462 11.9105 7.07307 11.9105 6.242C11.9105 5.22472 11.4979 4.24911 10.7637 3.52978C10.0294 2.81046 9.03341 2.40635 7.99495 2.40635C6.95647 2.40635 5.96054 2.81046 5.22622 3.52978C4.49192 4.24911 4.07938 5.22472 4.07938 6.242C4.07938 6.88128 4.2099 7.64842 5.05828 8.47947C6.03717 9.62442 5.90669 9.62316 6.03721 10.2625M9.95263 10.2625V12.3893C9.95263 13.0544 9.40226 13.5937 8.72322 13.5937H7.26668C6.58764 13.5937 6.03717 13.0544 6.03717 12.3893L6.03721 10.2625M9.95263 10.2625H7.99495H6.03721" stroke="#C6CAD0" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<path opacity="0.2" d="M12.3337 9.57205C13.1747 8.60454 13.78 7.49416 13.78 6.2663C13.78 4.76332 13.1704 3.3219 12.0857 2.25913C11.0008 1.19638 9.52923 0.599314 7.99494 0.599314C6.46065 0.599314 4.98921 1.19638 3.90429 2.25913C2.81939 3.3219 2.20988 4.76332 2.20988 6.2663C2.20988 7.21081 2.40273 8.34422 3.65616 9.57205" stroke="#C6CAD0" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<path opacity="0.06" d="M13.6508 10.7862C14.7471 9.52502 15.5363 8.07755 15.5363 6.47692C15.5363 4.51766 14.7416 2.63864 13.3276 1.25323C11.9133 -0.132159 9.99501 -0.910484 7.99494 -0.910484C5.99485 -0.910484 4.07671 -0.132159 2.66243 1.25323C1.24817 2.63864 0.453617 4.51766 0.453617 6.47692C0.453617 7.70816 0.705009 9.18567 2.33896 10.7862" stroke="#C6CAD0" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<path opacity="0.4" d="M9.95263 10.2625C10.0833 9.62316 9.95263 9.60567 10.9316 8.47947C11.5008 7.82462 11.9105 7.07307 11.9105 6.242C11.9105 5.22472 11.4979 4.24911 10.7637 3.52978C10.0294 2.81046 9.03341 2.40635 7.99495 2.40635C6.95647 2.40635 5.96054 2.81046 5.22622 3.52978C4.49192 4.24911 4.07938 5.22472 4.07938 6.242C4.07938 6.88128 4.2099 7.64842 5.05828 8.47947C6.03717 9.62442 5.90669 9.62316 6.03721 10.2625M9.95263 10.2625H7.99495H6.03721" fill="#C6CAD0"/>
+</g>
+<defs>
+<clipPath id="clip0_3950_76">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

assets/keymaps/default-linux.json 🔗

@@ -317,6 +317,7 @@
       "shift-tab": "agent::CycleModeSelector",
       "alt-tab": "agent::CycleFavoriteModels",
       "ctrl-;": "agent::OpenAddContextMenu",
+      "ctrl-alt-k": "agent::ToggleThinkingMode",
     },
   },
   {

assets/keymaps/default-macos.json 🔗

@@ -365,6 +365,7 @@
       "shift-tab": "agent::CycleModeSelector",
       "alt-tab": "agent::CycleFavoriteModels",
       "ctrl-;": "agent::OpenAddContextMenu",
+      "cmd-alt-k": "agent::ToggleThinkingMode",
     },
   },
   {

assets/keymaps/default-windows.json 🔗

@@ -319,6 +319,7 @@
       "shift-tab": "agent::CycleModeSelector",
       "alt-tab": "agent::CycleFavoriteModels",
       "ctrl-;": "agent::OpenAddContextMenu",
+      "ctrl-alt-k": "agent::ToggleThinkingMode",
     },
   },
   {

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

@@ -81,7 +81,7 @@ use crate::{
     CycleFavoriteModels, CycleModeSelector, EditFirstQueuedMessage, ExpandMessageEditor, Follow,
     KeepAll, NewThread, OpenAddContextMenu, OpenAgentDiff, OpenHistory, RejectAll, RejectOnce,
     RemoveFirstQueuedMessage, SelectPermissionGranularity, SendImmediately, SendNextQueuedMessage,
-    ToggleProfileSelector,
+    ToggleProfileSelector, ToggleThinkingMode,
 };
 
 const STOPWATCH_THRESHOLD: Duration = Duration::from_secs(30);
@@ -5868,13 +5868,13 @@ impl AcpThreadView {
                         h_flex()
                             .gap_0p5()
                             .child(self.render_add_context_button(cx))
-                            .child(self.render_follow_toggle(cx)),
+                            .child(self.render_follow_toggle(cx))
+                            .children(self.render_thinking_toggle(cx)),
                     )
                     .child(
                         h_flex()
                             .gap_1()
                             .children(self.render_token_usage(cx))
-                            .children(self.render_thinking_toggle(cx))
                             .when_some(self.as_active_thread(), |this, active| {
                                 this.children(active.profile_selector.clone()).map(|this| {
                                     // Either config_options_view OR (mode_selector + model_selector)
@@ -6253,18 +6253,22 @@ impl AcpThreadView {
 
         let thinking = thread.thinking_enabled();
 
-        let tooltip_label = if thinking {
-            "Disable Thinking Mode".to_string()
+        let (tooltip_label, icon) = if thinking {
+            ("Disable Thinking Mode", IconName::ThinkingMode)
         } else {
-            "Enable Thinking Mode".to_string()
+            ("Enable Thinking Mode", IconName::ToolThink)
         };
 
+        let focus_handle = self.message_editor.focus_handle(cx);
+
         Some(
-            IconButton::new("thinking-mode", IconName::ToolThink)
+            IconButton::new("thinking-mode", icon)
                 .icon_size(IconSize::Small)
                 .icon_color(Color::Muted)
                 .toggle_state(thinking)
-                .tooltip(Tooltip::text(tooltip_label))
+                .tooltip(move |_, cx| {
+                    Tooltip::for_action_in(tooltip_label, &ToggleThinkingMode, &focus_handle, cx)
+                })
                 .on_click(cx.listener(move |this, _, _window, cx| {
                     if let Some(thread) = this.as_native_thread(cx) {
                         thread.update(cx, |thread, cx| {
@@ -8148,6 +8152,13 @@ impl Render for AcpThreadView {
             .on_action(cx.listener(Self::handle_select_permission_granularity))
             .on_action(cx.listener(Self::open_permission_dropdown))
             .on_action(cx.listener(Self::open_add_context_menu))
+            .on_action(cx.listener(|this, _: &ToggleThinkingMode, _window, cx| {
+                if let Some(thread) = this.as_native_thread(cx) {
+                    thread.update(cx, |thread, cx| {
+                        thread.set_thinking_enabled(!thread.thinking_enabled(), cx);
+                    });
+                }
+            }))
             .on_action(cx.listener(|this, _: &SendNextQueuedMessage, window, cx| {
                 this.send_queued_message_at_index(0, true, window, cx);
             }))

crates/agent_ui/src/agent_ui.rs 🔗

@@ -137,6 +137,8 @@ actions!(
         ClearMessageQueue,
         /// Opens the permission granularity dropdown for the current tool call.
         OpenPermissionDropdown,
+        /// Toggles thinking mode for models that support extended thinking.
+        ToggleThinkingMode,
     ]
 );
 

crates/icons/src/icons.rs 🔗

@@ -228,6 +228,7 @@ pub enum IconName {
     TerminalGhost,
     TextSnippet,
     TextThread,
+    ThinkingMode,
     Thread,
     ThreadFromSummary,
     ThumbsDown,