agent: Add "max mode" toggle (#29549)
This PR adds a "max mode" toggle to the Agent panel, for models that support it. Only visible to folks in the `new-billing` feature flag. Icon is just a placeholder. Release Notes: - N/A
This commit is contained in:
parent
e3c987e2fb
commit
ce93961fe0
14 changed files with 87 additions and 1 deletions
|
@ -1293,6 +1293,7 @@ impl ActiveThread {
|
||||||
let request = language_model::LanguageModelRequest {
|
let request = language_model::LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![request_message],
|
messages: vec![request_message],
|
||||||
tools: vec![],
|
tools: vec![],
|
||||||
stop: vec![],
|
stop: vec![],
|
||||||
|
|
|
@ -460,6 +460,7 @@ impl CodegenAlternative {
|
||||||
LanguageModelRequest {
|
LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
temperature: None,
|
temperature: None,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use editor::{
|
||||||
ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, EditorEvent, EditorMode,
|
ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, EditorEvent, EditorMode,
|
||||||
EditorStyle, MultiBuffer,
|
EditorStyle, MultiBuffer,
|
||||||
};
|
};
|
||||||
|
use feature_flags::{FeatureFlagAppExt, NewBillingFeatureFlag};
|
||||||
use file_icons::FileIcons;
|
use file_icons::FileIcons;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::future::Shared;
|
use futures::future::Shared;
|
||||||
|
@ -33,6 +34,7 @@ use theme::ThemeSettings;
|
||||||
use ui::{Disclosure, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*};
|
use ui::{Disclosure, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
use zed_llm_client::CompletionMode;
|
||||||
|
|
||||||
use crate::assistant_model_selector::AssistantModelSelector;
|
use crate::assistant_model_selector::AssistantModelSelector;
|
||||||
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
|
use crate::context_picker::{ContextPicker, ContextPickerCompletionProvider};
|
||||||
|
@ -50,7 +52,6 @@ pub struct MessageEditor {
|
||||||
thread: Entity<Thread>,
|
thread: Entity<Thread>,
|
||||||
incompatible_tools_state: Entity<IncompatibleToolsState>,
|
incompatible_tools_state: Entity<IncompatibleToolsState>,
|
||||||
editor: Entity<Editor>,
|
editor: Entity<Editor>,
|
||||||
#[allow(dead_code)]
|
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
project: Entity<Project>,
|
project: Entity<Project>,
|
||||||
context_store: Entity<ContextStore>,
|
context_store: Entity<ContextStore>,
|
||||||
|
@ -419,6 +420,37 @@ impl MessageEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_max_mode_toggle(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
|
||||||
|
if !cx.has_flag::<NewBillingFeatureFlag>() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = LanguageModelRegistry::read_global(cx)
|
||||||
|
.default_model()
|
||||||
|
.map(|default| default.model.clone())?;
|
||||||
|
if !model.supports_max_mode() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let active_completion_mode = self.thread.read(cx).completion_mode();
|
||||||
|
|
||||||
|
Some(
|
||||||
|
IconButton::new("max-mode", IconName::SquarePlus)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.toggle_state(active_completion_mode == Some(CompletionMode::Max))
|
||||||
|
.on_click(cx.listener(move |this, _event, _window, cx| {
|
||||||
|
this.thread.update(cx, |thread, _cx| {
|
||||||
|
thread.set_completion_mode(match active_completion_mode {
|
||||||
|
Some(CompletionMode::Max) => Some(CompletionMode::Normal),
|
||||||
|
Some(CompletionMode::Normal) | None => Some(CompletionMode::Max),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
.tooltip(Tooltip::text("Max Mode"))
|
||||||
|
.into_any_element(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn render_editor(
|
fn render_editor(
|
||||||
&self,
|
&self,
|
||||||
font_size: Rems,
|
font_size: Rems,
|
||||||
|
@ -579,6 +611,7 @@ impl MessageEditor {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
.children(self.render_max_mode_toggle(cx))
|
||||||
.child(self.model_selector.clone())
|
.child(self.model_selector.clone())
|
||||||
.map({
|
.map({
|
||||||
let focus_handle = focus_handle.clone();
|
let focus_handle = focus_handle.clone();
|
||||||
|
@ -1100,6 +1133,7 @@ impl MessageEditor {
|
||||||
let request = language_model::LanguageModelRequest {
|
let request = language_model::LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![request_message],
|
messages: vec![request_message],
|
||||||
tools: vec![],
|
tools: vec![],
|
||||||
stop: vec![],
|
stop: vec![],
|
||||||
|
|
|
@ -276,6 +276,7 @@ impl TerminalInlineAssistant {
|
||||||
LanguageModelRequest {
|
LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![request_message],
|
messages: vec![request_message],
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
|
|
@ -34,6 +34,7 @@ use settings::Settings;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use util::{ResultExt as _, TryFutureExt as _, post_inc};
|
use util::{ResultExt as _, TryFutureExt as _, post_inc};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use zed_llm_client::CompletionMode;
|
||||||
|
|
||||||
use crate::context::{AgentContext, ContextLoadResult, LoadedContext};
|
use crate::context::{AgentContext, ContextLoadResult, LoadedContext};
|
||||||
use crate::thread_store::{
|
use crate::thread_store::{
|
||||||
|
@ -290,6 +291,7 @@ pub struct Thread {
|
||||||
summary: Option<SharedString>,
|
summary: Option<SharedString>,
|
||||||
pending_summary: Task<Option<()>>,
|
pending_summary: Task<Option<()>>,
|
||||||
detailed_summary_state: DetailedSummaryState,
|
detailed_summary_state: DetailedSummaryState,
|
||||||
|
completion_mode: Option<CompletionMode>,
|
||||||
messages: Vec<Message>,
|
messages: Vec<Message>,
|
||||||
next_message_id: MessageId,
|
next_message_id: MessageId,
|
||||||
last_prompt_id: PromptId,
|
last_prompt_id: PromptId,
|
||||||
|
@ -339,6 +341,7 @@ impl Thread {
|
||||||
summary: None,
|
summary: None,
|
||||||
pending_summary: Task::ready(None),
|
pending_summary: Task::ready(None),
|
||||||
detailed_summary_state: DetailedSummaryState::NotGenerated,
|
detailed_summary_state: DetailedSummaryState::NotGenerated,
|
||||||
|
completion_mode: None,
|
||||||
messages: Vec::new(),
|
messages: Vec::new(),
|
||||||
next_message_id: MessageId(0),
|
next_message_id: MessageId(0),
|
||||||
last_prompt_id: PromptId::new(),
|
last_prompt_id: PromptId::new(),
|
||||||
|
@ -394,6 +397,7 @@ impl Thread {
|
||||||
summary: Some(serialized.summary),
|
summary: Some(serialized.summary),
|
||||||
pending_summary: Task::ready(None),
|
pending_summary: Task::ready(None),
|
||||||
detailed_summary_state: serialized.detailed_summary_state,
|
detailed_summary_state: serialized.detailed_summary_state,
|
||||||
|
completion_mode: None,
|
||||||
messages: serialized
|
messages: serialized
|
||||||
.messages
|
.messages
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -518,6 +522,14 @@ impl Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn completion_mode(&self) -> Option<CompletionMode> {
|
||||||
|
self.completion_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_completion_mode(&mut self, mode: Option<CompletionMode>) {
|
||||||
|
self.completion_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self, id: MessageId) -> Option<&Message> {
|
pub fn message(&self, id: MessageId) -> Option<&Message> {
|
||||||
let index = self
|
let index = self
|
||||||
.messages
|
.messages
|
||||||
|
@ -930,6 +942,12 @@ impl Thread {
|
||||||
self.remaining_turns -= 1;
|
self.remaining_turns -= 1;
|
||||||
|
|
||||||
let mut request = self.to_completion_request(cx);
|
let mut request = self.to_completion_request(cx);
|
||||||
|
request.mode = if model.supports_max_mode() {
|
||||||
|
self.completion_mode
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if model.supports_tools() {
|
if model.supports_tools() {
|
||||||
request.tools = self
|
request.tools = self
|
||||||
.tools()
|
.tools()
|
||||||
|
@ -967,6 +985,7 @@ impl Thread {
|
||||||
let mut request = LanguageModelRequest {
|
let mut request = LanguageModelRequest {
|
||||||
thread_id: Some(self.id.to_string()),
|
thread_id: Some(self.id.to_string()),
|
||||||
prompt_id: Some(self.last_prompt_id.to_string()),
|
prompt_id: Some(self.last_prompt_id.to_string()),
|
||||||
|
mode: None,
|
||||||
messages: vec![],
|
messages: vec![],
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
@ -1063,6 +1082,7 @@ impl Thread {
|
||||||
let mut request = LanguageModelRequest {
|
let mut request = LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![],
|
messages: vec![],
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
|
|
@ -2981,6 +2981,7 @@ impl CodegenAlternative {
|
||||||
Ok(LanguageModelRequest {
|
Ok(LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages,
|
messages,
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
|
|
@ -294,6 +294,7 @@ impl TerminalInlineAssistant {
|
||||||
Ok(LanguageModelRequest {
|
Ok(LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages,
|
messages,
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
|
|
@ -2559,6 +2559,7 @@ impl AssistantContext {
|
||||||
let mut completion_request = LanguageModelRequest {
|
let mut completion_request = LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: Vec::new(),
|
messages: Vec::new(),
|
||||||
tools: Vec::new(),
|
tools: Vec::new(),
|
||||||
stop: Vec::new(),
|
stop: Vec::new(),
|
||||||
|
|
|
@ -573,6 +573,7 @@ impl ExampleInstance {
|
||||||
let request = LanguageModelRequest {
|
let request = LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![LanguageModelRequestMessage {
|
messages: vec![LanguageModelRequestMessage {
|
||||||
role: Role::User,
|
role: Role::User,
|
||||||
content: vec![MessageContent::Text(to_prompt(assertion.description))],
|
content: vec![MessageContent::Text(to_prompt(assertion.description))],
|
||||||
|
|
|
@ -1746,6 +1746,7 @@ impl GitPanel {
|
||||||
let request = LanguageModelRequest {
|
let request = LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![LanguageModelRequestMessage {
|
messages: vec![LanguageModelRequestMessage {
|
||||||
role: Role::User,
|
role: Role::User,
|
||||||
content: vec![content.into()],
|
content: vec![content.into()],
|
||||||
|
|
|
@ -240,6 +240,26 @@ pub trait LanguageModel: Send + Sync {
|
||||||
/// Whether this model supports tools.
|
/// Whether this model supports tools.
|
||||||
fn supports_tools(&self) -> bool;
|
fn supports_tools(&self) -> bool;
|
||||||
|
|
||||||
|
/// Returns whether this model supports "max mode";
|
||||||
|
fn supports_max_mode(&self) -> bool {
|
||||||
|
if self.provider_id().0 != ZED_CLOUD_PROVIDER_ID {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX_MODE_CAPABLE_MODELS: &[CloudModel] = &[
|
||||||
|
CloudModel::Anthropic(anthropic::Model::Claude3_7Sonnet),
|
||||||
|
CloudModel::Anthropic(anthropic::Model::Claude3_7SonnetThinking),
|
||||||
|
];
|
||||||
|
|
||||||
|
for model in MAX_MODE_CAPABLE_MODELS {
|
||||||
|
if self.id().0 == model.id() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn tool_input_format(&self) -> LanguageModelToolSchemaFormat {
|
fn tool_input_format(&self) -> LanguageModelToolSchemaFormat {
|
||||||
LanguageModelToolSchemaFormat::JsonSchema
|
LanguageModelToolSchemaFormat::JsonSchema
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use gpui::{
|
||||||
use image::{DynamicImage, ImageDecoder, codecs::png::PngEncoder, imageops::resize};
|
use image::{DynamicImage, ImageDecoder, codecs::png::PngEncoder, imageops::resize};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
use zed_llm_client::CompletionMode;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||||
pub struct LanguageModelImage {
|
pub struct LanguageModelImage {
|
||||||
|
@ -252,6 +253,7 @@ pub struct LanguageModelRequestTool {
|
||||||
pub struct LanguageModelRequest {
|
pub struct LanguageModelRequest {
|
||||||
pub thread_id: Option<String>,
|
pub thread_id: Option<String>,
|
||||||
pub prompt_id: Option<String>,
|
pub prompt_id: Option<String>,
|
||||||
|
pub mode: Option<CompletionMode>,
|
||||||
pub messages: Vec<LanguageModelRequestMessage>,
|
pub messages: Vec<LanguageModelRequestMessage>,
|
||||||
pub tools: Vec<LanguageModelRequestTool>,
|
pub tools: Vec<LanguageModelRequestTool>,
|
||||||
pub stop: Vec<String>,
|
pub stop: Vec<String>,
|
||||||
|
|
|
@ -922,6 +922,7 @@ impl RulesLibrary {
|
||||||
LanguageModelRequest {
|
LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![LanguageModelRequestMessage {
|
messages: vec![LanguageModelRequestMessage {
|
||||||
role: Role::System,
|
role: Role::System,
|
||||||
content: vec![body.to_string().into()],
|
content: vec![body.to_string().into()],
|
||||||
|
|
|
@ -559,6 +559,7 @@ impl SummaryIndex {
|
||||||
let request = LanguageModelRequest {
|
let request = LanguageModelRequest {
|
||||||
thread_id: None,
|
thread_id: None,
|
||||||
prompt_id: None,
|
prompt_id: None,
|
||||||
|
mode: None,
|
||||||
messages: vec![LanguageModelRequestMessage {
|
messages: vec![LanguageModelRequestMessage {
|
||||||
role: Role::User,
|
role: Role::User,
|
||||||
content: vec![prompt.into()],
|
content: vec![prompt.into()],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue