assistant2: Tweak the settings UI (#23845)
This PR does some somewhat light UI adjustment to the Assistant 2 settings view. The Prompt Library section should feature the default prompts in the future, so that's why it's been separated that way. <img width="800" alt="Screenshot 2025-01-29 at 2 59 59 PM" src="https://github.com/user-attachments/assets/7b033bde-51ab-44d5-9e53-3f72b8ff5f51" /> Release Notes: - N/A
This commit is contained in:
parent
a03b7624f1
commit
f8dddf0a5c
8 changed files with 82 additions and 50 deletions
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{AnyView, App, EventEmitter, FocusHandle, Focusable, Subscription};
|
use gpui::{AnyView, App, EventEmitter, FocusHandle, Focusable, Subscription};
|
||||||
use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry};
|
use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry};
|
||||||
use ui::{prelude::*, ElevationIndex};
|
use ui::{prelude::*, Divider, DividerColor, ElevationIndex};
|
||||||
use zed_actions::assistant::DeployPromptLibrary;
|
use zed_actions::assistant::DeployPromptLibrary;
|
||||||
|
|
||||||
pub struct AssistantConfiguration {
|
pub struct AssistantConfiguration {
|
||||||
|
@ -91,22 +91,32 @@ impl AssistantConfiguration {
|
||||||
.cloned();
|
.cloned();
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_2()
|
.gap_1p5()
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.child(Headline::new(provider_name.clone()).size(HeadlineSize::Small))
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_2()
|
||||||
|
.child(
|
||||||
|
Icon::new(provider.icon())
|
||||||
|
.size(IconSize::Small)
|
||||||
|
.color(Color::Muted),
|
||||||
|
)
|
||||||
|
.child(Label::new(provider_name.clone())),
|
||||||
|
)
|
||||||
.when(provider.is_authenticated(cx), |parent| {
|
.when(provider.is_authenticated(cx), |parent| {
|
||||||
parent.child(
|
parent.child(
|
||||||
h_flex().justify_end().child(
|
|
||||||
Button::new(
|
Button::new(
|
||||||
SharedString::from(format!("new-thread-{provider_id}")),
|
SharedString::from(format!("new-thread-{provider_id}")),
|
||||||
"Open New Thread",
|
"Start New Thread",
|
||||||
)
|
)
|
||||||
.icon_position(IconPosition::Start)
|
.icon_position(IconPosition::Start)
|
||||||
.icon(IconName::Plus)
|
.icon(IconName::Plus)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
.style(ButtonStyle::Filled)
|
.style(ButtonStyle::Filled)
|
||||||
.layer(ElevationIndex::ModalSurface)
|
.layer(ElevationIndex::ModalSurface)
|
||||||
|
.label_size(LabelSize::Small)
|
||||||
.on_click(cx.listener({
|
.on_click(cx.listener({
|
||||||
let provider = provider.clone();
|
let provider = provider.clone();
|
||||||
move |_this, _event, _window, cx| {
|
move |_this, _event, _window, cx| {
|
||||||
|
@ -115,14 +125,13 @@ impl AssistantConfiguration {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.p(DynamicSpacing::Base08.rems(cx))
|
.p(DynamicSpacing::Base08.rems(cx))
|
||||||
.bg(cx.theme().colors().surface_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().colors().border_variant)
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
|
@ -143,26 +152,43 @@ impl Render for AssistantConfiguration {
|
||||||
v_flex()
|
v_flex()
|
||||||
.id("assistant-configuration")
|
.id("assistant-configuration")
|
||||||
.track_focus(&self.focus_handle(cx))
|
.track_focus(&self.focus_handle(cx))
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().panel_background)
|
||||||
.size_full()
|
.size_full()
|
||||||
.overflow_y_scroll()
|
.overflow_y_scroll()
|
||||||
.child(
|
.child(
|
||||||
h_flex().p(DynamicSpacing::Base16.rems(cx)).child(
|
v_flex()
|
||||||
|
.p(DynamicSpacing::Base16.rems(cx))
|
||||||
|
.gap_1()
|
||||||
|
.child(Headline::new("Prompt Library").size(HeadlineSize::Small))
|
||||||
|
.child(
|
||||||
Button::new("open-prompt-library", "Open Prompt Library")
|
Button::new("open-prompt-library", "Open Prompt Library")
|
||||||
.style(ButtonStyle::Filled)
|
.style(ButtonStyle::Filled)
|
||||||
|
.layer(ElevationIndex::ModalSurface)
|
||||||
.full_width()
|
.full_width()
|
||||||
.icon(IconName::Book)
|
.icon(IconName::Book)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.icon_position(IconPosition::Start)
|
.icon_position(IconPosition::Start)
|
||||||
.on_click(|_event, _window, cx| cx.dispatch_action(&DeployPromptLibrary)),
|
.on_click(|_event, _window, cx| {
|
||||||
|
cx.dispatch_action(&DeployPromptLibrary)
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.child(Divider::horizontal().color(DividerColor::Border))
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.p(DynamicSpacing::Base16.rems(cx))
|
.p(DynamicSpacing::Base16.rems(cx))
|
||||||
.mt_1()
|
.mt_1()
|
||||||
.gap_6()
|
.gap_6()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.gap_0p5()
|
||||||
|
.child(Headline::new("LLM Providers").size(HeadlineSize::Small))
|
||||||
|
.child(
|
||||||
|
Label::new("Add at least one provider to use AI-powered features.")
|
||||||
|
.color(Color::Muted),
|
||||||
|
),
|
||||||
|
)
|
||||||
.children(
|
.children(
|
||||||
providers
|
providers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -613,7 +613,7 @@ impl AssistantPanel {
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| SharedString::from("Loading Summary…")),
|
.unwrap_or_else(|| SharedString::from("Loading Summary…")),
|
||||||
ActiveView::History | ActiveView::PromptEditorHistory => "History".into(),
|
ActiveView::History | ActiveView::PromptEditorHistory => "History".into(),
|
||||||
ActiveView::Configuration => "Configuration".into(),
|
ActiveView::Configuration => "Assistant Settings".into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let sub_title = match self.active_view {
|
let sub_title = match self.active_view {
|
||||||
|
@ -700,7 +700,7 @@ impl AssistantPanel {
|
||||||
IconButton::new("configure-assistant", IconName::Settings)
|
IconButton::new("configure-assistant", IconName::Settings)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.tooltip(Tooltip::text("Configure Assistant"))
|
.tooltip(Tooltip::text("Assistant Settings"))
|
||||||
.on_click(move |_event, window, cx| {
|
.on_click(move |_event, window, cx| {
|
||||||
window.dispatch_action(OpenConfiguration.boxed_clone(), cx);
|
window.dispatch_action(OpenConfiguration.boxed_clone(), cx);
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -689,7 +689,7 @@ impl Render for ConfigurationView {
|
||||||
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||||
Button::new("anthropic_console", ANTHROPIC_CONSOLE_URL)
|
Button::new("anthropic_console", ANTHROPIC_CONSOLE_URL)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| cx.open_url(ANTHROPIC_CONSOLE_URL))
|
.on_click(move |_, _, cx| cx.open_url(ANTHROPIC_CONSOLE_URL))
|
||||||
|
@ -703,6 +703,8 @@ impl Render for ConfigurationView {
|
||||||
.px_2()
|
.px_2()
|
||||||
.py_1()
|
.py_1()
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.child(self.render_api_key_editor(cx)),
|
.child(self.render_api_key_editor(cx)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -506,7 +506,7 @@ impl Render for ConfigurationView {
|
||||||
h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||||
Button::new("deepseek_console", DEEPSEEK_CONSOLE_URL)
|
Button::new("deepseek_console", DEEPSEEK_CONSOLE_URL)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _window, cx| cx.open_url(DEEPSEEK_CONSOLE_URL)),
|
.on_click(move |_, _window, cx| cx.open_url(DEEPSEEK_CONSOLE_URL)),
|
||||||
|
@ -520,12 +520,14 @@ impl Render for ConfigurationView {
|
||||||
.px_2()
|
.px_2()
|
||||||
.py_1()
|
.py_1()
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.child(self.render_api_key_editor(cx)),
|
.child(self.render_api_key_editor(cx)),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Label::new(format!(
|
Label::new(format!(
|
||||||
"Or set {} environment variable",
|
"Or set the {} environment variable.",
|
||||||
DEEPSEEK_API_KEY_VAR
|
DEEPSEEK_API_KEY_VAR
|
||||||
))
|
))
|
||||||
.size(LabelSize::Small),
|
.size(LabelSize::Small),
|
||||||
|
|
|
@ -452,7 +452,7 @@ impl Render for ConfigurationView {
|
||||||
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||||
Button::new("google_console", GOOGLE_CONSOLE_URL)
|
Button::new("google_console", GOOGLE_CONSOLE_URL)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| cx.open_url(GOOGLE_CONSOLE_URL))
|
.on_click(move |_, _, cx| cx.open_url(GOOGLE_CONSOLE_URL))
|
||||||
|
@ -466,6 +466,8 @@ impl Render for ConfigurationView {
|
||||||
.px_2()
|
.px_2()
|
||||||
.py_1()
|
.py_1()
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.child(self.render_api_key_editor(cx)),
|
.child(self.render_api_key_editor(cx)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -413,8 +413,7 @@ impl Render for ConfigurationView {
|
||||||
let lmstudio_reqs =
|
let lmstudio_reqs =
|
||||||
"To use LM Studio as a provider for Zed assistant, it needs to be running with at least one model downloaded.";
|
"To use LM Studio as a provider for Zed assistant, it needs to be running with at least one model downloaded.";
|
||||||
|
|
||||||
let mut inline_code_bg = cx.theme().colors().editor_background;
|
let inline_code_bg = cx.theme().colors().editor_foreground.opacity(0.05);
|
||||||
inline_code_bg.fade_out(0.5);
|
|
||||||
|
|
||||||
if self.loading_models_task.is_some() {
|
if self.loading_models_task.is_some() {
|
||||||
div().child(Label::new("Loading models...")).into_any()
|
div().child(Label::new("Loading models...")).into_any()
|
||||||
|
@ -432,7 +431,7 @@ impl Render for ConfigurationView {
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_0p5()
|
.gap_0p5()
|
||||||
.child(Label::new("To get your first model, try running "))
|
.child(Label::new("To get your first model, try running"))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.bg(inline_code_bg)
|
.bg(inline_code_bg)
|
||||||
|
@ -457,7 +456,7 @@ impl Render for ConfigurationView {
|
||||||
this.child(
|
this.child(
|
||||||
Button::new("lmstudio-site", "LM Studio")
|
Button::new("lmstudio-site", "LM Studio")
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _window, cx| {
|
.on_click(move |_, _window, cx| {
|
||||||
|
@ -472,7 +471,7 @@ impl Render for ConfigurationView {
|
||||||
"Download LM Studio",
|
"Download LM Studio",
|
||||||
)
|
)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _window, cx| {
|
.on_click(move |_, _window, cx| {
|
||||||
|
@ -485,7 +484,7 @@ impl Render for ConfigurationView {
|
||||||
.child(
|
.child(
|
||||||
Button::new("view-models", "Model Catalog")
|
Button::new("view-models", "Model Catalog")
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _window, cx| {
|
.on_click(move |_, _window, cx| {
|
||||||
|
|
|
@ -452,8 +452,7 @@ impl Render for ConfigurationView {
|
||||||
let ollama_reqs =
|
let ollama_reqs =
|
||||||
"Ollama must be running with at least one model installed to use it in the assistant.";
|
"Ollama must be running with at least one model installed to use it in the assistant.";
|
||||||
|
|
||||||
let mut inline_code_bg = cx.theme().colors().editor_background;
|
let inline_code_bg = cx.theme().colors().editor_foreground.opacity(0.05);
|
||||||
inline_code_bg.fade_out(0.5);
|
|
||||||
|
|
||||||
if self.loading_models_task.is_some() {
|
if self.loading_models_task.is_some() {
|
||||||
div().child(Label::new("Loading models...")).into_any()
|
div().child(Label::new("Loading models...")).into_any()
|
||||||
|
@ -496,7 +495,7 @@ impl Render for ConfigurationView {
|
||||||
this.child(
|
this.child(
|
||||||
Button::new("ollama-site", "Ollama")
|
Button::new("ollama-site", "Ollama")
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| cx.open_url(OLLAMA_SITE))
|
.on_click(move |_, _, cx| cx.open_url(OLLAMA_SITE))
|
||||||
|
@ -509,7 +508,7 @@ impl Render for ConfigurationView {
|
||||||
"Download Ollama",
|
"Download Ollama",
|
||||||
)
|
)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| {
|
.on_click(move |_, _, cx| {
|
||||||
|
@ -522,7 +521,7 @@ impl Render for ConfigurationView {
|
||||||
.child(
|
.child(
|
||||||
Button::new("view-models", "All Models")
|
Button::new("view-models", "All Models")
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| cx.open_url(OLLAMA_LIBRARY_URL)),
|
.on_click(move |_, _, cx| cx.open_url(OLLAMA_LIBRARY_URL)),
|
||||||
|
|
|
@ -502,7 +502,7 @@ impl Render for ConfigurationView {
|
||||||
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||||
Button::new("openai_console", OPENAI_CONSOLE_URL)
|
Button::new("openai_console", OPENAI_CONSOLE_URL)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _, cx| cx.open_url(OPENAI_CONSOLE_URL))
|
.on_click(move |_, _, cx| cx.open_url(OPENAI_CONSOLE_URL))
|
||||||
|
@ -518,6 +518,8 @@ impl Render for ConfigurationView {
|
||||||
.px_2()
|
.px_2()
|
||||||
.py_1()
|
.py_1()
|
||||||
.bg(cx.theme().colors().editor_background)
|
.bg(cx.theme().colors().editor_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.child(self.render_api_key_editor(cx)),
|
.child(self.render_api_key_editor(cx)),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue