From f8dddf0a5c36e853ad0e50f1ceed8f08671f9ed6 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:20:09 -0300 Subject: [PATCH] assistant2: Tweak the settings UI (#23845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Screenshot 2025-01-29 at 2 59 59 PM Release Notes: - N/A --- .../assistant2/src/assistant_configuration.rs | 90 ++++++++++++------- crates/assistant2/src/assistant_panel.rs | 4 +- .../language_models/src/provider/anthropic.rs | 4 +- .../language_models/src/provider/deepseek.rs | 6 +- crates/language_models/src/provider/google.rs | 4 +- .../language_models/src/provider/lmstudio.rs | 11 ++- crates/language_models/src/provider/ollama.rs | 9 +- .../language_models/src/provider/open_ai.rs | 4 +- 8 files changed, 82 insertions(+), 50 deletions(-) diff --git a/crates/assistant2/src/assistant_configuration.rs b/crates/assistant2/src/assistant_configuration.rs index efecfe729a..9e98f53f02 100644 --- a/crates/assistant2/src/assistant_configuration.rs +++ b/crates/assistant2/src/assistant_configuration.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use collections::HashMap; use gpui::{AnyView, App, EventEmitter, FocusHandle, Focusable, Subscription}; use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry}; -use ui::{prelude::*, ElevationIndex}; +use ui::{prelude::*, Divider, DividerColor, ElevationIndex}; use zed_actions::assistant::DeployPromptLibrary; pub struct AssistantConfiguration { @@ -91,38 +91,47 @@ impl AssistantConfiguration { .cloned(); v_flex() - .gap_2() + .gap_1p5() .child( h_flex() .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| { parent.child( - h_flex().justify_end().child( - Button::new( - SharedString::from(format!("new-thread-{provider_id}")), - "Open New Thread", - ) - .icon_position(IconPosition::Start) - .icon(IconName::Plus) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::ModalSurface) - .on_click(cx.listener({ - let provider = provider.clone(); - move |_this, _event, _window, cx| { - cx.emit(AssistantConfigurationEvent::NewThread( - provider.clone(), - )) - } - })), - ), + Button::new( + SharedString::from(format!("new-thread-{provider_id}")), + "Start New Thread", + ) + .icon_position(IconPosition::Start) + .icon(IconName::Plus) + .icon_size(IconSize::Small) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::ModalSurface) + .label_size(LabelSize::Small) + .on_click(cx.listener({ + let provider = provider.clone(); + move |_this, _event, _window, cx| { + cx.emit(AssistantConfigurationEvent::NewThread( + provider.clone(), + )) + } + })), ) }), ) .child( div() .p(DynamicSpacing::Base08.rems(cx)) - .bg(cx.theme().colors().surface_background) + .bg(cx.theme().colors().editor_background) .border_1() .border_color(cx.theme().colors().border_variant) .rounded_md() @@ -143,26 +152,43 @@ impl Render for AssistantConfiguration { v_flex() .id("assistant-configuration") .track_focus(&self.focus_handle(cx)) - .bg(cx.theme().colors().editor_background) + .bg(cx.theme().colors().panel_background) .size_full() .overflow_y_scroll() .child( - h_flex().p(DynamicSpacing::Base16.rems(cx)).child( - Button::new("open-prompt-library", "Open Prompt Library") - .style(ButtonStyle::Filled) - .full_width() - .icon(IconName::Book) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .on_click(|_event, _window, cx| cx.dispatch_action(&DeployPromptLibrary)), - ), + 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") + .style(ButtonStyle::Filled) + .layer(ElevationIndex::ModalSurface) + .full_width() + .icon(IconName::Book) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .on_click(|_event, _window, cx| { + cx.dispatch_action(&DeployPromptLibrary) + }), + ), ) + .child(Divider::horizontal().color(DividerColor::Border)) .child( v_flex() .p(DynamicSpacing::Base16.rems(cx)) .mt_1() .gap_6() .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( providers .into_iter() diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 926fd4cdd6..0590b59c0d 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -613,7 +613,7 @@ impl AssistantPanel { }) .unwrap_or_else(|| SharedString::from("Loading Summary…")), ActiveView::History | ActiveView::PromptEditorHistory => "History".into(), - ActiveView::Configuration => "Configuration".into(), + ActiveView::Configuration => "Assistant Settings".into(), }; let sub_title = match self.active_view { @@ -700,7 +700,7 @@ impl AssistantPanel { IconButton::new("configure-assistant", IconName::Settings) .icon_size(IconSize::Small) .style(ButtonStyle::Subtle) - .tooltip(Tooltip::text("Configure Assistant")) + .tooltip(Tooltip::text("Assistant Settings")) .on_click(move |_event, window, cx| { window.dispatch_action(OpenConfiguration.boxed_clone(), cx); }), diff --git a/crates/language_models/src/provider/anthropic.rs b/crates/language_models/src/provider/anthropic.rs index c0a62c32ed..0a3e018674 100644 --- a/crates/language_models/src/provider/anthropic.rs +++ b/crates/language_models/src/provider/anthropic.rs @@ -689,7 +689,7 @@ impl Render for ConfigurationView { .child(h_flex().child(Label::new(INSTRUCTIONS[1])).child( Button::new("anthropic_console", ANTHROPIC_CONSOLE_URL) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| cx.open_url(ANTHROPIC_CONSOLE_URL)) @@ -703,6 +703,8 @@ impl Render for ConfigurationView { .px_2() .py_1() .bg(cx.theme().colors().editor_background) + .border_1() + .border_color(cx.theme().colors().border_variant) .rounded_md() .child(self.render_api_key_editor(cx)), ) diff --git a/crates/language_models/src/provider/deepseek.rs b/crates/language_models/src/provider/deepseek.rs index 1d32706bf2..71c219c5ea 100644 --- a/crates/language_models/src/provider/deepseek.rs +++ b/crates/language_models/src/provider/deepseek.rs @@ -506,7 +506,7 @@ impl Render for ConfigurationView { h_flex().child(Label::new(INSTRUCTIONS[1])).child( Button::new("deepseek_console", DEEPSEEK_CONSOLE_URL) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _window, cx| cx.open_url(DEEPSEEK_CONSOLE_URL)), @@ -520,12 +520,14 @@ impl Render for ConfigurationView { .px_2() .py_1() .bg(cx.theme().colors().editor_background) + .border_1() + .border_color(cx.theme().colors().border_variant) .rounded_md() .child(self.render_api_key_editor(cx)), ) .child( Label::new(format!( - "Or set {} environment variable", + "Or set the {} environment variable.", DEEPSEEK_API_KEY_VAR )) .size(LabelSize::Small), diff --git a/crates/language_models/src/provider/google.rs b/crates/language_models/src/provider/google.rs index dfa57c1c8a..54a7fb0be2 100644 --- a/crates/language_models/src/provider/google.rs +++ b/crates/language_models/src/provider/google.rs @@ -452,7 +452,7 @@ impl Render for ConfigurationView { .child(h_flex().child(Label::new(INSTRUCTIONS[1])).child( Button::new("google_console", GOOGLE_CONSOLE_URL) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| cx.open_url(GOOGLE_CONSOLE_URL)) @@ -466,6 +466,8 @@ impl Render for ConfigurationView { .px_2() .py_1() .bg(cx.theme().colors().editor_background) + .border_1() + .border_color(cx.theme().colors().border_variant) .rounded_md() .child(self.render_api_key_editor(cx)), ) diff --git a/crates/language_models/src/provider/lmstudio.rs b/crates/language_models/src/provider/lmstudio.rs index 97a7559231..9096c3fb32 100644 --- a/crates/language_models/src/provider/lmstudio.rs +++ b/crates/language_models/src/provider/lmstudio.rs @@ -413,8 +413,7 @@ impl Render for ConfigurationView { let lmstudio_reqs = "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; - inline_code_bg.fade_out(0.5); + let inline_code_bg = cx.theme().colors().editor_foreground.opacity(0.05); if self.loading_models_task.is_some() { div().child(Label::new("Loading models...")).into_any() @@ -432,7 +431,7 @@ impl Render for ConfigurationView { .child( h_flex() .gap_0p5() - .child(Label::new("To get your first model, try running ")) + .child(Label::new("To get your first model, try running")) .child( div() .bg(inline_code_bg) @@ -457,7 +456,7 @@ impl Render for ConfigurationView { this.child( Button::new("lmstudio-site", "LM Studio") .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _window, cx| { @@ -472,7 +471,7 @@ impl Render for ConfigurationView { "Download LM Studio", ) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _window, cx| { @@ -485,7 +484,7 @@ impl Render for ConfigurationView { .child( Button::new("view-models", "Model Catalog") .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _window, cx| { diff --git a/crates/language_models/src/provider/ollama.rs b/crates/language_models/src/provider/ollama.rs index d936a7986b..a1acf5b695 100644 --- a/crates/language_models/src/provider/ollama.rs +++ b/crates/language_models/src/provider/ollama.rs @@ -452,8 +452,7 @@ impl Render for ConfigurationView { let ollama_reqs = "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; - inline_code_bg.fade_out(0.5); + let inline_code_bg = cx.theme().colors().editor_foreground.opacity(0.05); if self.loading_models_task.is_some() { div().child(Label::new("Loading models...")).into_any() @@ -496,7 +495,7 @@ impl Render for ConfigurationView { this.child( Button::new("ollama-site", "Ollama") .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| cx.open_url(OLLAMA_SITE)) @@ -509,7 +508,7 @@ impl Render for ConfigurationView { "Download Ollama", ) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| { @@ -522,7 +521,7 @@ impl Render for ConfigurationView { .child( Button::new("view-models", "All Models") .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| cx.open_url(OLLAMA_LIBRARY_URL)), diff --git a/crates/language_models/src/provider/open_ai.rs b/crates/language_models/src/provider/open_ai.rs index 36742b0035..846c98b13d 100644 --- a/crates/language_models/src/provider/open_ai.rs +++ b/crates/language_models/src/provider/open_ai.rs @@ -502,7 +502,7 @@ impl Render for ConfigurationView { .child(h_flex().child(Label::new(INSTRUCTIONS[1])).child( Button::new("openai_console", OPENAI_CONSOLE_URL) .style(ButtonStyle::Subtle) - .icon(IconName::ExternalLink) + .icon(IconName::ArrowUpRight) .icon_size(IconSize::XSmall) .icon_color(Color::Muted) .on_click(move |_, _, cx| cx.open_url(OPENAI_CONSOLE_URL)) @@ -518,6 +518,8 @@ impl Render for ConfigurationView { .px_2() .py_1() .bg(cx.theme().colors().editor_background) + .border_1() + .border_color(cx.theme().colors().border_variant) .rounded_md() .child(self.render_api_key_editor(cx)), )