diff --git a/assets/icons/thinking_mode.svg b/assets/icons/thinking_mode.svg new file mode 100644 index 0000000000000000000000000000000000000000..113d146e79142a744ec2317b61740ffbcc05d505 --- /dev/null +++ b/assets/icons/thinking_mode.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 93ef34228c3859a14ffaa240c93bbed652f5b20c..1a0581d40b9f0acb6a9f8747813d1121d1c9c1f6 100644 --- a/assets/keymaps/default-linux.json +++ b/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", }, }, { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index cfbe58ba7ef3b6939e28ab51e51fa3ed4ef33b73..0c02111c04d9452524d7f2847359e8657f23e32f 100644 --- a/assets/keymaps/default-macos.json +++ b/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", }, }, { diff --git a/assets/keymaps/default-windows.json b/assets/keymaps/default-windows.json index 9f134b8a8620c64495ec2869a23763e76be658e0..f232123ce951d57a864e9e4701c7e1d983186b89 100644 --- a/assets/keymaps/default-windows.json +++ b/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", }, }, { diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 5216d02f97fbb6df39f31f4e28871ce935e6fcf4..509d31e014bf8ce3ccd8c500c4c8fb105c186302 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/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); })) diff --git a/crates/agent_ui/src/agent_ui.rs b/crates/agent_ui/src/agent_ui.rs index 62d22c9a22faf0a5939dfe96473152db890ef333..0c4b8d6df8135093c6f0edfe742fb50bacd3c161 100644 --- a/crates/agent_ui/src/agent_ui.rs +++ b/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, ] ); diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs index 386414e7d7ddc223394a91381babf2f446a48be3..93866f625899f1c81600745b875c1fd68d1e947d 100644 --- a/crates/icons/src/icons.rs +++ b/crates/icons/src/icons.rs @@ -228,6 +228,7 @@ pub enum IconName { TerminalGhost, TextSnippet, TextThread, + ThinkingMode, Thread, ThreadFromSummary, ThumbsDown,