agent: Add max mode on text threads (#31361)

Related discussions #30240 #30596

Release Notes:

- Added the ability to use max mode on text threads.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Alvaro Parker 2025-05-28 09:12:38 -04:00 committed by GitHub
parent 957e4adc3f
commit e314963f5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 160 additions and 35 deletions

View file

@ -1,7 +1,10 @@
use crate::language_model_selector::{
LanguageModelSelector, LanguageModelSelectorPopoverMenu, ToggleModelSelector,
use crate::{
language_model_selector::{
LanguageModelSelector, LanguageModelSelectorPopoverMenu, ToggleModelSelector,
},
max_mode_tooltip::MaxModeTooltip,
};
use agent_settings::AgentSettings;
use agent_settings::{AgentSettings, CompletionMode};
use anyhow::Result;
use assistant_slash_command::{SlashCommand, SlashCommandOutputSection, SlashCommandWorkingSet};
use assistant_slash_commands::{
@ -2008,17 +2011,17 @@ impl ContextEditor {
None => (ButtonStyle::Filled, None),
};
ButtonLike::new("send_button")
Button::new("send_button", "Send")
.label_size(LabelSize::Small)
.disabled(self.sending_disabled(cx))
.style(style)
.when_some(tooltip, |button, tooltip| {
button.tooltip(move |_, _| tooltip.clone())
})
.layer(ElevationIndex::ModalSurface)
.child(Label::new("Send"))
.children(
.key_binding(
KeyBinding::for_action_in(&Assist, &focus_handle, window, cx)
.map(|binding| binding.into_any_element()),
.map(|kb| kb.size(rems_from_px(12.))),
)
.on_click(move |_event, window, cx| {
focus_handle.dispatch_action(&Assist, window, cx);
@ -2058,6 +2061,45 @@ impl ContextEditor {
)
}
fn render_max_mode_toggle(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
let context = self.context().read(cx);
let active_model = LanguageModelRegistry::read_global(cx)
.default_model()
.map(|default| default.model)?;
if !active_model.supports_max_mode() {
return None;
}
let active_completion_mode = context.completion_mode();
let max_mode_enabled = active_completion_mode == CompletionMode::Max;
let icon = if max_mode_enabled {
IconName::ZedBurnModeOn
} else {
IconName::ZedBurnMode
};
Some(
IconButton::new("burn-mode", icon)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.toggle_state(max_mode_enabled)
.selected_icon_color(Color::Error)
.on_click(cx.listener(move |this, _event, _window, cx| {
this.context().update(cx, |context, _cx| {
context.set_completion_mode(match active_completion_mode {
CompletionMode::Max => CompletionMode::Normal,
CompletionMode::Normal => CompletionMode::Max,
});
});
}))
.tooltip(move |_window, cx| {
cx.new(|_| MaxModeTooltip::new().selected(max_mode_enabled))
.into()
})
.into_any_element(),
)
}
fn render_language_model_selector(&self, cx: &mut Context<Self>) -> impl IntoElement {
let active_model = LanguageModelRegistry::read_global(cx)
.default_model()
@ -2503,6 +2545,7 @@ impl Render for ContextEditor {
let provider = LanguageModelRegistry::read_global(cx)
.default_model()
.map(|default| default.provider);
let accept_terms = if self.show_accept_terms {
provider.as_ref().and_then(|provider| {
provider.render_accept_terms(LanguageModelProviderTosView::PromptEditorPopup, cx)
@ -2512,6 +2555,8 @@ impl Render for ContextEditor {
};
let language_model_selector = self.language_model_selector_menu_handle.clone();
let max_mode_toggle = self.render_max_mode_toggle(cx);
v_flex()
.key_context("ContextEditor")
.capture_action(cx.listener(ContextEditor::cancel))
@ -2551,31 +2596,28 @@ impl Render for ContextEditor {
})
.children(self.render_last_error(cx))
.child(
h_flex().w_full().relative().child(
h_flex()
.p_2()
.w_full()
.border_t_1()
.border_color(cx.theme().colors().border_variant)
.bg(cx.theme().colors().editor_background)
.child(
h_flex()
.gap_1()
.child(self.render_inject_context_menu(cx))
.child(ui::Divider::vertical())
.child(
div()
.pl_0p5()
.child(self.render_language_model_selector(cx)),
),
)
.child(
h_flex()
.w_full()
.justify_end()
.child(self.render_send_button(window, cx)),
),
),
h_flex()
.relative()
.py_2()
.pl_1p5()
.pr_2()
.w_full()
.justify_between()
.border_t_1()
.border_color(cx.theme().colors().border_variant)
.bg(cx.theme().colors().editor_background)
.child(
h_flex()
.gap_0p5()
.child(self.render_inject_context_menu(cx))
.when_some(max_mode_toggle, |this, element| this.child(element)),
)
.child(
h_flex()
.gap_1()
.child(self.render_language_model_selector(cx))
.child(self.render_send_button(window, cx)),
),
)
}
}