Add setting to allow disabling the Assistant (#9706)
This PR adds a new `assistant.enabled` setting that controls whether the Zed Assistant is enabled. Some users have requested the ability to disable the AI-related features in Zed if they don't use them. Changing `assistant.enabled` to `false` will hide the Assistant icon in the status bar (taking priority over the `assistant.button` setting) as well as filter out the `assistant:` actions. The Assistant is enabled by default. Release Notes: - Added an `assistant.enabled` setting to control whether the Assistant is enabled.
This commit is contained in:
parent
4dc61f7ccd
commit
c6d479715d
7 changed files with 100 additions and 37 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -318,6 +318,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"client",
|
"client",
|
||||||
"collections",
|
"collections",
|
||||||
|
"command_palette_hooks",
|
||||||
"ctor",
|
"ctor",
|
||||||
"editor",
|
"editor",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
"assistant": {
|
"assistant": {
|
||||||
// Version of this setting.
|
// Version of this setting.
|
||||||
"version": "1",
|
"version": "1",
|
||||||
|
// Whether the assistant is enabled.
|
||||||
|
"enabled": true,
|
||||||
// Whether to show the assistant panel button in the status bar.
|
// Whether to show the assistant panel button in the status bar.
|
||||||
"button": true,
|
"button": true,
|
||||||
// Where to dock the assistant panel. Can be 'left', 'right' or 'bottom'.
|
// Where to dock the assistant panel. Can be 'left', 'right' or 'bottom'.
|
||||||
|
|
|
@ -14,6 +14,7 @@ anyhow.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
client.workspace = true
|
client.workspace = true
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
|
command_palette_hooks.workspace = true
|
||||||
editor.workspace = true
|
editor.workspace = true
|
||||||
fs.workspace = true
|
fs.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
|
|
|
@ -10,11 +10,12 @@ pub use assistant_panel::AssistantPanel;
|
||||||
use assistant_settings::{AssistantSettings, OpenAiModel, ZedDotDevModel};
|
use assistant_settings::{AssistantSettings, OpenAiModel, ZedDotDevModel};
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
use client::{proto, Client};
|
use client::{proto, Client};
|
||||||
|
use command_palette_hooks::CommandPaletteFilter;
|
||||||
pub(crate) use completion_provider::*;
|
pub(crate) use completion_provider::*;
|
||||||
use gpui::{actions, AppContext, SharedString};
|
use gpui::{actions, AppContext, Global, SharedString};
|
||||||
pub(crate) use saved_conversation::*;
|
pub(crate) use saved_conversation::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::Settings;
|
use settings::{Settings, SettingsStore};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
@ -182,10 +183,61 @@ enum MessageStatus {
|
||||||
Error(SharedString),
|
Error(SharedString),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The state pertaining to the Assistant.
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Assistant {
|
||||||
|
/// Whether the Assistant is enabled.
|
||||||
|
enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Global for Assistant {}
|
||||||
|
|
||||||
|
impl Assistant {
|
||||||
|
const NAMESPACE: &'static str = "assistant";
|
||||||
|
|
||||||
|
fn set_enabled(&mut self, enabled: bool, cx: &mut AppContext) {
|
||||||
|
if self.enabled == enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.enabled = enabled;
|
||||||
|
|
||||||
|
if !enabled {
|
||||||
|
CommandPaletteFilter::update_global(cx, |filter, _cx| {
|
||||||
|
filter.hide_namespace(Self::NAMESPACE);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandPaletteFilter::update_global(cx, |filter, _cx| {
|
||||||
|
filter.show_namespace(Self::NAMESPACE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(client: Arc<Client>, cx: &mut AppContext) {
|
pub fn init(client: Arc<Client>, cx: &mut AppContext) {
|
||||||
|
cx.set_global(Assistant::default());
|
||||||
AssistantSettings::register(cx);
|
AssistantSettings::register(cx);
|
||||||
completion_provider::init(client, cx);
|
completion_provider::init(client, cx);
|
||||||
assistant_panel::init(cx);
|
assistant_panel::init(cx);
|
||||||
|
|
||||||
|
CommandPaletteFilter::update_global(cx, |filter, _cx| {
|
||||||
|
filter.hide_namespace(Assistant::NAMESPACE);
|
||||||
|
});
|
||||||
|
cx.update_global(|assistant: &mut Assistant, cx: &mut AppContext| {
|
||||||
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
|
||||||
|
assistant.set_enabled(settings.enabled, cx);
|
||||||
|
});
|
||||||
|
cx.observe_global::<SettingsStore>(|cx| {
|
||||||
|
cx.update_global(|assistant: &mut Assistant, cx: &mut AppContext| {
|
||||||
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
|
||||||
|
assistant.set_enabled(settings.enabled, cx);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -55,6 +55,11 @@ pub fn init(cx: &mut AppContext) {
|
||||||
|workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| {
|
|workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| {
|
||||||
workspace
|
workspace
|
||||||
.register_action(|workspace, _: &ToggleFocus, cx| {
|
.register_action(|workspace, _: &ToggleFocus, cx| {
|
||||||
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
if !settings.enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
workspace.toggle_panel_focus::<AssistantPanel>(cx);
|
workspace.toggle_panel_focus::<AssistantPanel>(cx);
|
||||||
})
|
})
|
||||||
.register_action(AssistantPanel::inline_assist)
|
.register_action(AssistantPanel::inline_assist)
|
||||||
|
@ -229,6 +234,11 @@ impl AssistantPanel {
|
||||||
_: &InlineAssist,
|
_: &InlineAssist,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
) {
|
) {
|
||||||
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
if !settings.enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let Some(assistant) = workspace.panel::<AssistantPanel>(cx) else {
|
let Some(assistant) = workspace.panel::<AssistantPanel>(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -1217,7 +1227,12 @@ impl Panel for AssistantPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon(&self, cx: &WindowContext) -> Option<IconName> {
|
fn icon(&self, cx: &WindowContext) -> Option<IconName> {
|
||||||
Some(IconName::Ai).filter(|_| AssistantSettings::get_global(cx).button)
|
let settings = AssistantSettings::get_global(cx);
|
||||||
|
if !settings.enabled || !settings.button {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(IconName::Ai)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self, _cx: &WindowContext) -> Option<&'static str> {
|
fn icon_tooltip(&self, _cx: &WindowContext) -> Option<&'static str> {
|
||||||
|
|
|
@ -160,6 +160,7 @@ fn open_ai_url() -> String {
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
pub struct AssistantSettings {
|
pub struct AssistantSettings {
|
||||||
|
pub enabled: bool,
|
||||||
pub button: bool,
|
pub button: bool,
|
||||||
pub dock: AssistantDockPosition,
|
pub dock: AssistantDockPosition,
|
||||||
pub default_width: Pixels,
|
pub default_width: Pixels,
|
||||||
|
@ -201,42 +202,26 @@ impl AssistantSettingsContent {
|
||||||
AssistantSettingsContent::Versioned(settings) => match settings {
|
AssistantSettingsContent::Versioned(settings) => match settings {
|
||||||
VersionedAssistantSettingsContent::V1(settings) => settings.clone(),
|
VersionedAssistantSettingsContent::V1(settings) => settings.clone(),
|
||||||
},
|
},
|
||||||
AssistantSettingsContent::Legacy(settings) => {
|
AssistantSettingsContent::Legacy(settings) => AssistantSettingsContentV1 {
|
||||||
if let Some(open_ai_api_url) = settings.openai_api_url.as_ref() {
|
enabled: None,
|
||||||
AssistantSettingsContentV1 {
|
|
||||||
button: settings.button,
|
button: settings.button,
|
||||||
dock: settings.dock,
|
dock: settings.dock,
|
||||||
default_width: settings.default_width,
|
default_width: settings.default_width,
|
||||||
default_height: settings.default_height,
|
default_height: settings.default_height,
|
||||||
provider: Some(AssistantProvider::OpenAi {
|
provider: if let Some(open_ai_api_url) = settings.openai_api_url.as_ref() {
|
||||||
default_model: settings
|
Some(AssistantProvider::OpenAi {
|
||||||
.default_open_ai_model
|
default_model: settings.default_open_ai_model.clone().unwrap_or_default(),
|
||||||
.clone()
|
|
||||||
.unwrap_or_default(),
|
|
||||||
api_url: open_ai_api_url.clone(),
|
api_url: open_ai_api_url.clone(),
|
||||||
}),
|
})
|
||||||
}
|
} else {
|
||||||
} else if let Some(open_ai_model) = settings.default_open_ai_model.clone() {
|
settings.default_open_ai_model.clone().map(|open_ai_model| {
|
||||||
AssistantSettingsContentV1 {
|
AssistantProvider::OpenAi {
|
||||||
button: settings.button,
|
|
||||||
dock: settings.dock,
|
|
||||||
default_width: settings.default_width,
|
|
||||||
default_height: settings.default_height,
|
|
||||||
provider: Some(AssistantProvider::OpenAi {
|
|
||||||
default_model: open_ai_model,
|
default_model: open_ai_model,
|
||||||
api_url: open_ai_url(),
|
api_url: open_ai_url(),
|
||||||
}),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AssistantSettingsContentV1 {
|
|
||||||
button: settings.button,
|
|
||||||
dock: settings.dock,
|
|
||||||
default_width: settings.default_width,
|
|
||||||
default_height: settings.default_height,
|
|
||||||
provider: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +249,7 @@ pub enum VersionedAssistantSettingsContent {
|
||||||
impl Default for VersionedAssistantSettingsContent {
|
impl Default for VersionedAssistantSettingsContent {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::V1(AssistantSettingsContentV1 {
|
Self::V1(AssistantSettingsContentV1 {
|
||||||
|
enabled: None,
|
||||||
button: None,
|
button: None,
|
||||||
dock: None,
|
dock: None,
|
||||||
default_width: None,
|
default_width: None,
|
||||||
|
@ -275,6 +261,10 @@ impl Default for VersionedAssistantSettingsContent {
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
|
#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
|
||||||
pub struct AssistantSettingsContentV1 {
|
pub struct AssistantSettingsContentV1 {
|
||||||
|
/// Whether the Assistant is enabled.
|
||||||
|
///
|
||||||
|
/// Default: true
|
||||||
|
enabled: Option<bool>,
|
||||||
/// Whether to show the assistant panel button in the status bar.
|
/// Whether to show the assistant panel button in the status bar.
|
||||||
///
|
///
|
||||||
/// Default: true
|
/// Default: true
|
||||||
|
@ -340,6 +330,7 @@ impl Settings for AssistantSettings {
|
||||||
|
|
||||||
for value in [default_value].iter().chain(user_values) {
|
for value in [default_value].iter().chain(user_values) {
|
||||||
let value = value.upgrade();
|
let value = value.upgrade();
|
||||||
|
merge(&mut settings.enabled, value.enabled);
|
||||||
merge(&mut settings.button, value.button);
|
merge(&mut settings.button, value.button);
|
||||||
merge(&mut settings.dock, value.dock);
|
merge(&mut settings.dock, value.dock);
|
||||||
merge(
|
merge(
|
||||||
|
|
|
@ -3073,6 +3073,7 @@ mod tests {
|
||||||
notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
|
notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
|
||||||
workspace::init(app_state.clone(), cx);
|
workspace::init(app_state.clone(), cx);
|
||||||
Project::init_settings(cx);
|
Project::init_settings(cx);
|
||||||
|
command_palette::init(cx);
|
||||||
language::init(cx);
|
language::init(cx);
|
||||||
editor::init(cx);
|
editor::init(cx);
|
||||||
project_panel::init_settings(cx);
|
project_panel::init_settings(cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue