diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 243406277ede5530bc96de32f0c23bc349ddb93a..b407733a94cb842e2a99394aad839dc35251cc3f 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -250,7 +250,8 @@ "ctrl-alt-e": "agent::RemoveAllContext", "ctrl-shift-e": "project_panel::ToggleFocus", "ctrl-shift-enter": "agent::ContinueThread", - "alt-enter": "agent::ContinueWithBurnMode" + "alt-enter": "agent::ContinueWithBurnMode", + "ctrl-alt-b": "agent::ToggleBurnMode" } }, { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 5afb6e97c4badf97f6b1a0d45637ca3c81b7c638..a7b4319b94754ce7185a6effb7f92e9f93fd79ed 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -285,7 +285,8 @@ "cmd-alt-e": "agent::RemoveAllContext", "cmd-shift-e": "project_panel::ToggleFocus", "cmd-shift-enter": "agent::ContinueThread", - "alt-enter": "agent::ContinueWithBurnMode" + "alt-enter": "agent::ContinueWithBurnMode", + "cmd-alt-b": "agent::ToggleBurnMode" } }, { diff --git a/crates/agent/src/agent.rs b/crates/agent/src/agent.rs index f5ae6097a5dc64707a67e181611a380f5699e3cc..1e26e4231491d81f66a6a038f4ebf6d31f8378aa 100644 --- a/crates/agent/src/agent.rs +++ b/crates/agent/src/agent.rs @@ -89,6 +89,7 @@ actions!( ResetTrialEndUpsell, ContinueThread, ContinueWithBurnMode, + ToggleBurnMode, ] ); diff --git a/crates/agent/src/agent_panel.rs b/crates/agent/src/agent_panel.rs index 324f98c2fd2a2236b229d87c1e17e28f6ba7619e..9f9ddb5577ff11c71f3d70da426ccbcafb0dac14 100644 --- a/crates/agent/src/agent_panel.rs +++ b/crates/agent/src/agent_panel.rs @@ -67,8 +67,8 @@ use crate::{ AddContextServer, AgentDiffPane, ContextStore, ContinueThread, ContinueWithBurnMode, DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread, NewThread, OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ResetTrialEndUpsell, - ResetTrialUpsell, TextThreadStore, ThreadEvent, ToggleContextPicker, ToggleNavigationMenu, - ToggleOptionsMenu, + ResetTrialUpsell, TextThreadStore, ThreadEvent, ToggleBurnMode, ToggleContextPicker, + ToggleNavigationMenu, ToggleOptionsMenu, }; const AGENT_PANEL_KEY: &str = "agent_panel"; @@ -1304,6 +1304,24 @@ impl AgentPanel { } } + fn toggle_burn_mode( + &mut self, + _: &ToggleBurnMode, + _window: &mut Window, + cx: &mut Context, + ) { + self.thread.update(cx, |active_thread, cx| { + active_thread.thread().update(cx, |thread, _cx| { + let current_mode = thread.completion_mode(); + + thread.set_completion_mode(match current_mode { + CompletionMode::Max => CompletionMode::Normal, + CompletionMode::Normal => CompletionMode::Max, + }); + }); + }); + } + pub(crate) fn active_context_editor(&self) -> Option> { match &self.active_view { ActiveView::PromptEditor { context_editor, .. } => Some(context_editor.clone()), @@ -3065,6 +3083,7 @@ impl Render for AgentPanel { }); this.continue_conversation(window, cx); })) + .on_action(cx.listener(Self::toggle_burn_mode)) .child(self.render_toolbar(window, cx)) .children(self.render_upsell(window, cx)) .children(self.render_trial_end_upsell(window, cx)) diff --git a/crates/agent/src/message_editor.rs b/crates/agent/src/message_editor.rs index a53fc475f49062822a737e2f219ab30ac880b4ad..d5508ae8d4524687a8fc41e186dfca34bf70f0b6 100644 --- a/crates/agent/src/message_editor.rs +++ b/crates/agent/src/message_editor.rs @@ -51,7 +51,7 @@ use crate::thread::{MessageCrease, Thread, TokenUsageRatio}; use crate::thread_store::{TextThreadStore, ThreadStore}; use crate::{ ActiveThread, AgentDiffPane, Chat, ChatWithFollow, ExpandMessageEditor, Follow, NewThread, - OpenAgentDiff, RemoveAllContext, ToggleContextPicker, ToggleProfileSelector, + OpenAgentDiff, RemoveAllContext, ToggleBurnMode, ToggleContextPicker, ToggleProfileSelector, register_agent_preview, }; @@ -471,6 +471,22 @@ impl MessageEditor { } } + pub fn toggle_burn_mode( + &mut self, + _: &ToggleBurnMode, + _window: &mut Window, + cx: &mut Context, + ) { + self.thread.update(cx, |thread, _cx| { + let active_completion_mode = thread.completion_mode(); + + thread.set_completion_mode(match active_completion_mode { + CompletionMode::Max => CompletionMode::Normal, + CompletionMode::Normal => CompletionMode::Max, + }); + }); + } + fn render_max_mode_toggle(&self, cx: &mut Context) -> Option { let thread = self.thread.read(cx); let model = thread.configured_model(); @@ -492,13 +508,8 @@ impl MessageEditor { .icon_color(Color::Muted) .toggle_state(max_mode_enabled) .selected_icon_color(Color::Error) - .on_click(cx.listener(move |this, _event, _window, cx| { - this.thread.update(cx, |thread, _cx| { - thread.set_completion_mode(match active_completion_mode { - CompletionMode::Max => CompletionMode::Normal, - CompletionMode::Normal => CompletionMode::Max, - }); - }); + .on_click(cx.listener(|this, _event, window, cx| { + this.toggle_burn_mode(&ToggleBurnMode, window, cx); })) .tooltip(move |_window, cx| { cx.new(|_| MaxModeTooltip::new().selected(max_mode_enabled)) @@ -596,6 +607,7 @@ impl MessageEditor { .on_action(cx.listener(Self::remove_all_context)) .on_action(cx.listener(Self::move_up)) .on_action(cx.listener(Self::expand_message_editor)) + .on_action(cx.listener(Self::toggle_burn_mode)) .capture_action(cx.listener(Self::paste)) .gap_2() .p_2() diff --git a/crates/agent/src/ui/max_mode_tooltip.rs b/crates/agent/src/ui/max_mode_tooltip.rs index d1bd94c20102faea6e22c845ea03b3bb3dd09f38..97f7853a61bc2bc2766492e077e34c3f1b534abe 100644 --- a/crates/agent/src/ui/max_mode_tooltip.rs +++ b/crates/agent/src/ui/max_mode_tooltip.rs @@ -1,5 +1,6 @@ -use gpui::{Context, IntoElement, Render, Window}; -use ui::{prelude::*, tooltip_container}; +use crate::ToggleBurnMode; +use gpui::{Context, FontWeight, IntoElement, Render, Window}; +use ui::{KeyBinding, prelude::*, tooltip_container}; pub struct MaxModeTooltip { selected: bool, @@ -18,39 +19,48 @@ impl MaxModeTooltip { impl Render for MaxModeTooltip { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let icon = if self.selected { - IconName::ZedBurnModeOn + let (icon, color) = if self.selected { + (IconName::ZedBurnModeOn, Color::Error) } else { - IconName::ZedBurnMode + (IconName::ZedBurnMode, Color::Default) }; + let turned_on = h_flex() + .h_4() + .px_1() + .border_1() + .border_color(cx.theme().colors().border) + .bg(cx.theme().colors().text_accent.opacity(0.1)) + .rounded_sm() + .child( + Label::new("ON") + .size(LabelSize::XSmall) + .weight(FontWeight::SEMIBOLD) + .color(Color::Accent), + ); + let title = h_flex() - .gap_1() - .child(Icon::new(icon).size(IconSize::Small)) - .child(Label::new("Burn Mode")); + .gap_1p5() + .child(Icon::new(icon).size(IconSize::Small).color(color)) + .child(Label::new("Burn Mode")) + .when(self.selected, |title| title.child(turned_on)); + + let keybinding = KeyBinding::for_action(&ToggleBurnMode, window, cx) + .map(|kb| kb.size(rems_from_px(12.))); tooltip_container(window, cx, |this, _, _| { - this.gap_0p5() - .map(|header| if self.selected { - header.child( - h_flex() - .justify_between() - .child(title) - .child( - h_flex() - .gap_0p5() - .child(Icon::new(IconName::Check).size(IconSize::XSmall).color(Color::Accent)) - .child(Label::new("Turned On").size(LabelSize::XSmall).color(Color::Accent)) - ) - ) - } else { - header.child(title) - }) + this + .child( + h_flex() + .justify_between() + .child(title) + .children(keybinding) + ) .child( div() - .max_w_72() + .max_w_64() .child( - Label::new("Enables models to use large context windows, unlimited tool calls, and other capabilities for expanded reasoning, offering an unfettered agentic experience.") + Label::new("Enables models to use large context windows, unlimited tool calls, and other capabilities for expanded reasoning.") .size(LabelSize::Small) .color(Color::Muted) ) diff --git a/crates/assistant_context_editor/src/max_mode_tooltip.rs b/crates/assistant_context_editor/src/max_mode_tooltip.rs index d1bd94c20102faea6e22c845ea03b3bb3dd09f38..a3100d4367c7a7b43edc3cc2b9b3a821941074e6 100644 --- a/crates/assistant_context_editor/src/max_mode_tooltip.rs +++ b/crates/assistant_context_editor/src/max_mode_tooltip.rs @@ -1,4 +1,4 @@ -use gpui::{Context, IntoElement, Render, Window}; +use gpui::{Context, FontWeight, IntoElement, Render, Window}; use ui::{prelude::*, tooltip_container}; pub struct MaxModeTooltip { @@ -18,39 +18,40 @@ impl MaxModeTooltip { impl Render for MaxModeTooltip { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let icon = if self.selected { - IconName::ZedBurnModeOn + let (icon, color) = if self.selected { + (IconName::ZedBurnModeOn, Color::Error) } else { - IconName::ZedBurnMode + (IconName::ZedBurnMode, Color::Default) }; + let turned_on = h_flex() + .h_4() + .px_1() + .border_1() + .border_color(cx.theme().colors().border) + .bg(cx.theme().colors().text_accent.opacity(0.1)) + .rounded_sm() + .child( + Label::new("ON") + .size(LabelSize::XSmall) + .weight(FontWeight::SEMIBOLD) + .color(Color::Accent), + ); + let title = h_flex() - .gap_1() - .child(Icon::new(icon).size(IconSize::Small)) - .child(Label::new("Burn Mode")); + .gap_1p5() + .child(Icon::new(icon).size(IconSize::Small).color(color)) + .child(Label::new("Burn Mode")) + .when(self.selected, |title| title.child(turned_on)); tooltip_container(window, cx, |this, _, _| { - this.gap_0p5() - .map(|header| if self.selected { - header.child( - h_flex() - .justify_between() - .child(title) - .child( - h_flex() - .gap_0p5() - .child(Icon::new(IconName::Check).size(IconSize::XSmall).color(Color::Accent)) - .child(Label::new("Turned On").size(LabelSize::XSmall).color(Color::Accent)) - ) - ) - } else { - header.child(title) - }) + this + .child(title) .child( div() - .max_w_72() + .max_w_64() .child( - Label::new("Enables models to use large context windows, unlimited tool calls, and other capabilities for expanded reasoning, offering an unfettered agentic experience.") + Label::new("Enables models to use large context windows, unlimited tool calls, and other capabilities for expanded reasoning.") .size(LabelSize::Small) .color(Color::Muted) )