diff --git a/Cargo.lock b/Cargo.lock index de1a822637bf3b31d62bfec0108f274fbe89050a..54828500eaff2c0bcac339352b38ac870d2a0176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,9 +372,9 @@ dependencies = [ name = "assistant" version = "0.1.0" dependencies = [ - "anthropic", "anyhow", "assets", + "assistant_settings", "assistant_slash_command", "assistant_tool", "async-watch", @@ -406,13 +406,11 @@ dependencies = [ "language_model_selector", "language_models", "languages", - "lmstudio", "log", "lsp", "markdown", "menu", "multi_buffer", - "ollama", "open_ai", "ordered-float 2.10.1", "parking_lot", @@ -457,9 +455,9 @@ dependencies = [ name = "assistant2" version = "0.1.0" dependencies = [ - "anthropic", "anyhow", "assets", + "assistant_settings", "assistant_tool", "async-watch", "chrono", @@ -485,14 +483,11 @@ dependencies = [ "language_model", "language_model_selector", "language_models", - "lmstudio", "log", "lsp", "markdown", "menu", "multi_buffer", - "ollama", - "open_ai", "ordered-float 2.10.1", "parking_lot", "paths", @@ -501,10 +496,8 @@ dependencies = [ "proto", "rand 0.8.5", "rope", - "schemars", "serde", "serde_json", - "serde_json_lenient", "settings", "similar", "smol", @@ -523,6 +516,27 @@ dependencies = [ "zed_actions", ] +[[package]] +name = "assistant_settings" +version = "0.1.0" +dependencies = [ + "anthropic", + "anyhow", + "feature_flags", + "fs", + "gpui", + "language_model", + "lmstudio", + "log", + "ollama", + "open_ai", + "paths", + "schemars", + "serde", + "serde_json_lenient", + "settings", +] + [[package]] name = "assistant_slash_command" version = "0.1.0" @@ -16110,6 +16124,7 @@ dependencies = [ "assets", "assistant", "assistant2", + "assistant_settings", "assistant_tools", "async-watch", "audio", diff --git a/Cargo.toml b/Cargo.toml index 2688eff33418b203ad1041bdaefbfbb98094c29b..293bc3f7fa248ec421022b67c67f029656c60f33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/assets", "crates/assistant", "crates/assistant2", + "crates/assistant_settings", "crates/assistant_slash_command", "crates/assistant_tool", "crates/assistant_tools", @@ -194,6 +195,7 @@ anthropic = { path = "crates/anthropic" } assets = { path = "crates/assets" } assistant = { path = "crates/assistant" } assistant2 = { path = "crates/assistant2" } +assistant_settings = { path = "crates/assistant_settings" } assistant_slash_command = { path = "crates/assistant_slash_command" } assistant_tool = { path = "crates/assistant_tool" } assistant_tools = { path = "crates/assistant_tools" } diff --git a/crates/assistant/Cargo.toml b/crates/assistant/Cargo.toml index 6f05d7811ddfa3e499d798dd6fd87605d0069d48..ed889b0bb942835a4935ce562bebd7f037d5334b 100644 --- a/crates/assistant/Cargo.toml +++ b/crates/assistant/Cargo.toml @@ -21,9 +21,9 @@ test-support = [ ] [dependencies] -anthropic = { workspace = true, features = ["schemars"] } anyhow.workspace = true assets.workspace = true +assistant_settings.workspace = true assistant_slash_command.workspace = true assistant_tool.workspace = true async-watch.workspace = true @@ -52,13 +52,11 @@ language.workspace = true language_model.workspace = true language_model_selector.workspace = true language_models.workspace = true -lmstudio = { workspace = true, features = ["schemars"] } log.workspace = true lsp.workspace = true markdown.workspace = true menu.workspace = true multi_buffer.workspace = true -ollama = { workspace = true, features = ["schemars"] } open_ai = { workspace = true, features = ["schemars"] } ordered-float.workspace = true parking_lot.workspace = true diff --git a/crates/assistant/src/assistant.rs b/crates/assistant/src/assistant.rs index 6ac1d851f2cb2b62bff9989df0b59a3772abb83b..20f35958fd071b385336edfd15d21f90af7a51ed 100644 --- a/crates/assistant/src/assistant.rs +++ b/crates/assistant/src/assistant.rs @@ -1,7 +1,6 @@ #![cfg_attr(target_os = "windows", allow(unused, dead_code))] pub mod assistant_panel; -pub mod assistant_settings; mod context; pub mod context_store; mod inline_assistant; diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index c2055775035e77936cc310a66c2cf0e35e4e120c..69577ed9347dd66c02c4ea076d4e82d66f92c609 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -1,7 +1,6 @@ use crate::slash_command::file_command::codeblock_fence_for_path; use crate::slash_command_working_set::SlashCommandWorkingSet; use crate::{ - assistant_settings::{AssistantDockPosition, AssistantSettings}, humanize_token_count, prompt_library::open_prompt_library, prompts::PromptBuilder, @@ -21,6 +20,7 @@ use crate::{ ToggleModelSelector, }; use anyhow::Result; +use assistant_settings::{AssistantDockPosition, AssistantSettings}; use assistant_slash_command::{SlashCommand, SlashCommandOutputSection}; use assistant_tool::ToolWorkingSet; use client::{proto, zed_urls, Client, Status}; diff --git a/crates/assistant/src/inline_assistant.rs b/crates/assistant/src/inline_assistant.rs index 8acdaec50f4cfed05668ab34099979f842bb7620..4ea19d1912972c3a29e577cfb2bc90c1b0d6d684 100644 --- a/crates/assistant/src/inline_assistant.rs +++ b/crates/assistant/src/inline_assistant.rs @@ -1,9 +1,10 @@ use crate::{ - assistant_settings::AssistantSettings, humanize_token_count, prompts::PromptBuilder, - AssistantPanel, AssistantPanelEvent, CharOperation, CycleNextInlineAssist, - CyclePreviousInlineAssist, LineDiff, LineOperation, RequestType, StreamingDiff, + humanize_token_count, prompts::PromptBuilder, AssistantPanel, AssistantPanelEvent, + CharOperation, CycleNextInlineAssist, CyclePreviousInlineAssist, LineDiff, LineOperation, + RequestType, StreamingDiff, }; use anyhow::{anyhow, Context as _, Result}; +use assistant_settings::AssistantSettings; use client::{telemetry::Telemetry, ErrorExt}; use collections::{hash_map, HashMap, HashSet, VecDeque}; use editor::{ diff --git a/crates/assistant/src/terminal_inline_assistant.rs b/crates/assistant/src/terminal_inline_assistant.rs index 719e69256dc11655f586e08c2817353f8fc63fc6..df0ff24f3f8a235696e54c69cb50e1efc1dc4778 100644 --- a/crates/assistant/src/terminal_inline_assistant.rs +++ b/crates/assistant/src/terminal_inline_assistant.rs @@ -1,9 +1,9 @@ -use crate::assistant_settings::AssistantSettings; use crate::{ humanize_token_count, prompts::PromptBuilder, AssistantPanel, AssistantPanelEvent, RequestType, DEFAULT_CONTEXT_LINES, }; use anyhow::{Context as _, Result}; +use assistant_settings::AssistantSettings; use client::telemetry::Telemetry; use collections::{HashMap, VecDeque}; use editor::{ diff --git a/crates/assistant2/Cargo.toml b/crates/assistant2/Cargo.toml index d8d20c0c6103c634b87fbbf9dfa532ba256c83df..ca0e929525c2d9e843e67806982517ba5f58ccd1 100644 --- a/crates/assistant2/Cargo.toml +++ b/crates/assistant2/Cargo.toml @@ -13,9 +13,9 @@ path = "src/assistant.rs" doctest = false [dependencies] -anthropic = { workspace = true, features = ["schemars"] } anyhow.workspace = true assets.workspace = true +assistant_settings.workspace = true assistant_tool.workspace = true async-watch.workspace = true chrono.workspace = true @@ -45,9 +45,6 @@ lsp.workspace = true markdown.workspace = true menu.workspace = true multi_buffer.workspace = true -ollama = { workspace = true, features = ["schemars"] } -lmstudio = { workspace = true, features = ["schemars"] } -open_ai = { workspace = true, features = ["schemars"] } ordered-float.workspace = true parking_lot.workspace = true paths.workspace = true @@ -55,10 +52,8 @@ picker.workspace = true project.workspace = true proto.workspace = true rope.workspace = true -schemars.workspace = true serde.workspace = true serde_json.workspace = true -serde_json_lenient.workspace = true settings.workspace = true similar.workspace = true smol.workspace = true diff --git a/crates/assistant2/src/assistant.rs b/crates/assistant2/src/assistant.rs index 577c8b1925fd99c2d5fc88fc4bd38eb81af417e9..1397a2b62f070177748baab205e6030187724675 100644 --- a/crates/assistant2/src/assistant.rs +++ b/crates/assistant2/src/assistant.rs @@ -1,7 +1,6 @@ mod active_thread; mod assistant_model_selector; mod assistant_panel; -mod assistant_settings; mod buffer_codegen; mod context; mod context_picker; @@ -21,6 +20,7 @@ mod ui; use std::sync::Arc; +use assistant_settings::AssistantSettings; use client::Client; use command_palette_hooks::CommandPaletteFilter; use feature_flags::{Assistant2FeatureFlag, FeatureFlagAppExt}; @@ -31,7 +31,6 @@ use settings::Settings as _; use util::ResultExt; pub use crate::assistant_panel::AssistantPanel; -use crate::assistant_settings::AssistantSettings; pub use crate::inline_assistant::InlineAssistant; actions!( diff --git a/crates/assistant2/src/assistant_model_selector.rs b/crates/assistant2/src/assistant_model_selector.rs index bd243a708952701ee825b48cdfb8702188051a9c..c31b6bcba38cc0f6a5af6bd8966434471ff7e20e 100644 --- a/crates/assistant2/src/assistant_model_selector.rs +++ b/crates/assistant2/src/assistant_model_selector.rs @@ -1,3 +1,4 @@ +use assistant_settings::AssistantSettings; use fs::Fs; use gpui::{FocusHandle, View}; use language_model::LanguageModelRegistry; @@ -6,7 +7,7 @@ use settings::update_settings_file; use std::sync::Arc; use ui::{prelude::*, ButtonLike, PopoverMenuHandle, Tooltip}; -use crate::{assistant_settings::AssistantSettings, ToggleModelSelector}; +use crate::ToggleModelSelector; pub struct AssistantModelSelector { selector: View, diff --git a/crates/assistant2/src/assistant_panel.rs b/crates/assistant2/src/assistant_panel.rs index 556b260335a8c85232da4aaf2b857df2c560309a..4e704be5917c408ecb4fd5c268e202eea82f84b5 100644 --- a/crates/assistant2/src/assistant_panel.rs +++ b/crates/assistant2/src/assistant_panel.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use anyhow::Result; +use assistant_settings::{AssistantDockPosition, AssistantSettings}; use assistant_tool::ToolWorkingSet; use client::zed_urls; use fs::Fs; @@ -17,7 +18,6 @@ use workspace::dock::{DockPosition, Panel, PanelEvent}; use workspace::Workspace; use crate::active_thread::ActiveThread; -use crate::assistant_settings::{AssistantDockPosition, AssistantSettings}; use crate::message_editor::MessageEditor; use crate::thread::{Thread, ThreadError, ThreadId}; use crate::thread_history::{PastThread, ThreadHistory}; diff --git a/crates/assistant2/src/assistant_settings.rs b/crates/assistant2/src/assistant_settings.rs deleted file mode 100644 index 65d317f1e6cbe94ed4f6e76eb67674b97a24f920..0000000000000000000000000000000000000000 --- a/crates/assistant2/src/assistant_settings.rs +++ /dev/null @@ -1,526 +0,0 @@ -use std::sync::Arc; - -use ::open_ai::Model as OpenAiModel; -use anthropic::Model as AnthropicModel; -use gpui::Pixels; -use language_model::{CloudModel, LanguageModel}; -use lmstudio::Model as LmStudioModel; -use ollama::Model as OllamaModel; -use schemars::{schema::Schema, JsonSchema}; -use serde::{Deserialize, Serialize}; -use settings::{Settings, SettingsSources}; - -#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum AssistantDockPosition { - Left, - #[default] - Right, - Bottom, -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] -#[serde(tag = "name", rename_all = "snake_case")] -pub enum AssistantProviderContentV1 { - #[serde(rename = "zed.dev")] - ZedDotDev { default_model: Option }, - #[serde(rename = "openai")] - OpenAi { - default_model: Option, - api_url: Option, - available_models: Option>, - }, - #[serde(rename = "anthropic")] - Anthropic { - default_model: Option, - api_url: Option, - }, - #[serde(rename = "ollama")] - Ollama { - default_model: Option, - api_url: Option, - }, - #[serde(rename = "lmstudio")] - LmStudio { - default_model: Option, - api_url: Option, - }, -} - -#[derive(Debug, Default)] -pub struct AssistantSettings { - pub enabled: bool, - pub button: bool, - pub dock: AssistantDockPosition, - pub default_width: Pixels, - pub default_height: Pixels, - pub default_model: LanguageModelSelection, - pub inline_alternatives: Vec, - pub using_outdated_settings_version: bool, - pub enable_experimental_live_diffs: bool, -} - -/// Assistant panel settings -#[derive(Clone, Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum AssistantSettingsContent { - Versioned(VersionedAssistantSettingsContent), - Legacy(LegacyAssistantSettingsContent), -} - -impl JsonSchema for AssistantSettingsContent { - fn schema_name() -> String { - VersionedAssistantSettingsContent::schema_name() - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> Schema { - VersionedAssistantSettingsContent::json_schema(gen) - } - - fn is_referenceable() -> bool { - VersionedAssistantSettingsContent::is_referenceable() - } -} - -impl Default for AssistantSettingsContent { - fn default() -> Self { - Self::Versioned(VersionedAssistantSettingsContent::default()) - } -} - -impl AssistantSettingsContent { - pub fn is_version_outdated(&self) -> bool { - match self { - AssistantSettingsContent::Versioned(settings) => match settings { - VersionedAssistantSettingsContent::V1(_) => true, - VersionedAssistantSettingsContent::V2(_) => false, - }, - AssistantSettingsContent::Legacy(_) => true, - } - } - - fn upgrade(&self) -> AssistantSettingsContentV2 { - match self { - AssistantSettingsContent::Versioned(settings) => match settings { - VersionedAssistantSettingsContent::V1(settings) => AssistantSettingsContentV2 { - enabled: settings.enabled, - button: settings.button, - dock: settings.dock, - default_width: settings.default_width, - default_height: settings.default_width, - default_model: settings - .provider - .clone() - .and_then(|provider| match provider { - AssistantProviderContentV1::ZedDotDev { default_model } => { - default_model.map(|model| LanguageModelSelection { - provider: "zed.dev".to_string(), - model: model.id().to_string(), - }) - } - AssistantProviderContentV1::OpenAi { default_model, .. } => { - default_model.map(|model| LanguageModelSelection { - provider: "openai".to_string(), - model: model.id().to_string(), - }) - } - AssistantProviderContentV1::Anthropic { default_model, .. } => { - default_model.map(|model| LanguageModelSelection { - provider: "anthropic".to_string(), - model: model.id().to_string(), - }) - } - AssistantProviderContentV1::Ollama { default_model, .. } => { - default_model.map(|model| LanguageModelSelection { - provider: "ollama".to_string(), - model: model.id().to_string(), - }) - } - AssistantProviderContentV1::LmStudio { default_model, .. } => { - default_model.map(|model| LanguageModelSelection { - provider: "lmstudio".to_string(), - model: model.id().to_string(), - }) - } - }), - inline_alternatives: None, - enable_experimental_live_diffs: None, - }, - VersionedAssistantSettingsContent::V2(settings) => settings.clone(), - }, - AssistantSettingsContent::Legacy(settings) => AssistantSettingsContentV2 { - enabled: None, - button: settings.button, - dock: settings.dock, - default_width: settings.default_width, - default_height: settings.default_height, - default_model: Some(LanguageModelSelection { - provider: "openai".to_string(), - model: settings - .default_open_ai_model - .clone() - .unwrap_or_default() - .id() - .to_string(), - }), - inline_alternatives: None, - enable_experimental_live_diffs: None, - }, - } - } - - pub fn set_dock(&mut self, dock: AssistantDockPosition) { - match self { - AssistantSettingsContent::Versioned(settings) => match settings { - VersionedAssistantSettingsContent::V1(settings) => { - settings.dock = Some(dock); - } - VersionedAssistantSettingsContent::V2(settings) => { - settings.dock = Some(dock); - } - }, - AssistantSettingsContent::Legacy(settings) => { - settings.dock = Some(dock); - } - } - } - - pub fn set_model(&mut self, language_model: Arc) { - let model = language_model.id().0.to_string(); - let provider = language_model.provider_id().0.to_string(); - - match self { - AssistantSettingsContent::Versioned(settings) => match settings { - VersionedAssistantSettingsContent::V1(settings) => match provider.as_ref() { - "zed.dev" => { - log::warn!("attempted to set zed.dev model on outdated settings"); - } - "anthropic" => { - let api_url = match &settings.provider { - Some(AssistantProviderContentV1::Anthropic { api_url, .. }) => { - api_url.clone() - } - _ => None, - }; - settings.provider = Some(AssistantProviderContentV1::Anthropic { - default_model: AnthropicModel::from_id(&model).ok(), - api_url, - }); - } - "ollama" => { - let api_url = match &settings.provider { - Some(AssistantProviderContentV1::Ollama { api_url, .. }) => { - api_url.clone() - } - _ => None, - }; - settings.provider = Some(AssistantProviderContentV1::Ollama { - default_model: Some(ollama::Model::new(&model, None, None)), - api_url, - }); - } - "lmstudio" => { - let api_url = match &settings.provider { - Some(AssistantProviderContentV1::LmStudio { api_url, .. }) => { - api_url.clone() - } - _ => None, - }; - settings.provider = Some(AssistantProviderContentV1::LmStudio { - default_model: Some(lmstudio::Model::new(&model, None, None)), - api_url, - }); - } - "openai" => { - let (api_url, available_models) = match &settings.provider { - Some(AssistantProviderContentV1::OpenAi { - api_url, - available_models, - .. - }) => (api_url.clone(), available_models.clone()), - _ => (None, None), - }; - settings.provider = Some(AssistantProviderContentV1::OpenAi { - default_model: OpenAiModel::from_id(&model).ok(), - api_url, - available_models, - }); - } - _ => {} - }, - VersionedAssistantSettingsContent::V2(settings) => { - settings.default_model = Some(LanguageModelSelection { provider, model }); - } - }, - AssistantSettingsContent::Legacy(settings) => { - if let Ok(model) = OpenAiModel::from_id(&language_model.id().0) { - settings.default_open_ai_model = Some(model); - } - } - } - } -} - -#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)] -#[serde(tag = "version")] -pub enum VersionedAssistantSettingsContent { - #[serde(rename = "1")] - V1(AssistantSettingsContentV1), - #[serde(rename = "2")] - V2(AssistantSettingsContentV2), -} - -impl Default for VersionedAssistantSettingsContent { - fn default() -> Self { - Self::V2(AssistantSettingsContentV2 { - enabled: None, - button: None, - dock: None, - default_width: None, - default_height: None, - default_model: None, - inline_alternatives: None, - enable_experimental_live_diffs: None, - }) - } -} - -#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)] -pub struct AssistantSettingsContentV2 { - /// Whether the Assistant is enabled. - /// - /// Default: true - enabled: Option, - /// Whether to show the assistant panel button in the status bar. - /// - /// Default: true - button: Option, - /// Where to dock the assistant. - /// - /// Default: right - dock: Option, - /// Default width in pixels when the assistant is docked to the left or right. - /// - /// Default: 640 - default_width: Option, - /// Default height in pixels when the assistant is docked to the bottom. - /// - /// Default: 320 - default_height: Option, - /// The default model to use when creating new chats. - default_model: Option, - /// Additional models with which to generate alternatives when performing inline assists. - inline_alternatives: Option>, - /// Enable experimental live diffs in the assistant panel. - /// - /// Default: false - enable_experimental_live_diffs: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] -pub struct LanguageModelSelection { - #[schemars(schema_with = "providers_schema")] - pub provider: String, - pub model: String, -} - -fn providers_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - schemars::schema::SchemaObject { - enum_values: Some(vec![ - "anthropic".into(), - "google".into(), - "lmstudio".into(), - "ollama".into(), - "openai".into(), - "zed.dev".into(), - "copilot_chat".into(), - ]), - ..Default::default() - } - .into() -} - -impl Default for LanguageModelSelection { - fn default() -> Self { - Self { - provider: "openai".to_string(), - model: "gpt-4".to_string(), - } - } -} - -#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)] -pub struct AssistantSettingsContentV1 { - /// Whether the Assistant is enabled. - /// - /// Default: true - enabled: Option, - /// Whether to show the assistant panel button in the status bar. - /// - /// Default: true - button: Option, - /// Where to dock the assistant. - /// - /// Default: right - dock: Option, - /// Default width in pixels when the assistant is docked to the left or right. - /// - /// Default: 640 - default_width: Option, - /// Default height in pixels when the assistant is docked to the bottom. - /// - /// Default: 320 - default_height: Option, - /// The provider of the assistant service. - /// - /// This can be "openai", "anthropic", "ollama", "zed.dev" - /// each with their respective default models and configurations. - provider: Option, -} - -#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)] -pub struct LegacyAssistantSettingsContent { - /// Whether to show the assistant panel button in the status bar. - /// - /// Default: true - pub button: Option, - /// Where to dock the assistant. - /// - /// Default: right - pub dock: Option, - /// Default width in pixels when the assistant is docked to the left or right. - /// - /// Default: 640 - pub default_width: Option, - /// Default height in pixels when the assistant is docked to the bottom. - /// - /// Default: 320 - pub default_height: Option, - /// The default OpenAI model to use when creating new chats. - /// - /// Default: gpt-4-1106-preview - pub default_open_ai_model: Option, - /// OpenAI API base URL to use when creating new chats. - /// - /// Default: https://api.openai.com/v1 - pub openai_api_url: Option, -} - -impl Settings for AssistantSettings { - const KEY: Option<&'static str> = Some("assistant"); - - const PRESERVED_KEYS: Option<&'static [&'static str]> = Some(&["version"]); - - type FileContent = AssistantSettingsContent; - - fn load( - sources: SettingsSources, - _: &mut gpui::AppContext, - ) -> anyhow::Result { - let mut settings = AssistantSettings::default(); - - for value in sources.defaults_and_customizations() { - if value.is_version_outdated() { - settings.using_outdated_settings_version = true; - } - - let value = value.upgrade(); - merge(&mut settings.enabled, value.enabled); - merge(&mut settings.button, value.button); - merge(&mut settings.dock, value.dock); - merge( - &mut settings.default_width, - value.default_width.map(Into::into), - ); - merge( - &mut settings.default_height, - value.default_height.map(Into::into), - ); - merge(&mut settings.default_model, value.default_model); - merge(&mut settings.inline_alternatives, value.inline_alternatives); - merge( - &mut settings.enable_experimental_live_diffs, - value.enable_experimental_live_diffs, - ); - } - - Ok(settings) - } -} - -fn merge(target: &mut T, value: Option) { - if let Some(value) = value { - *target = value; - } -} - -#[cfg(test)] -mod tests { - use fs::Fs; - use gpui::{ReadGlobal, TestAppContext}; - - use super::*; - - #[gpui::test] - async fn test_deserialize_assistant_settings_with_version(cx: &mut TestAppContext) { - let fs = fs::FakeFs::new(cx.executor().clone()); - fs.create_dir(paths::settings_file().parent().unwrap()) - .await - .unwrap(); - - cx.update(|cx| { - let test_settings = settings::SettingsStore::test(cx); - cx.set_global(test_settings); - AssistantSettings::register(cx); - }); - - cx.update(|cx| { - assert!(!AssistantSettings::get_global(cx).using_outdated_settings_version); - assert_eq!( - AssistantSettings::get_global(cx).default_model, - LanguageModelSelection { - provider: "zed.dev".into(), - model: "claude-3-5-sonnet".into(), - } - ); - }); - - cx.update(|cx| { - settings::SettingsStore::global(cx).update_settings_file::( - fs.clone(), - |settings, _| { - *settings = AssistantSettingsContent::Versioned( - VersionedAssistantSettingsContent::V2(AssistantSettingsContentV2 { - default_model: Some(LanguageModelSelection { - provider: "test-provider".into(), - model: "gpt-99".into(), - }), - inline_alternatives: None, - enabled: None, - button: None, - dock: None, - default_width: None, - default_height: None, - enable_experimental_live_diffs: None, - }), - ) - }, - ); - }); - - cx.run_until_parked(); - - let raw_settings_value = fs.load(paths::settings_file()).await.unwrap(); - assert!(raw_settings_value.contains(r#""version": "2""#)); - - #[derive(Debug, Deserialize)] - struct AssistantSettingsTest { - assistant: AssistantSettingsContent, - } - - let assistant_settings: AssistantSettingsTest = - serde_json_lenient::from_str(&raw_settings_value).unwrap(); - - assert!(!assistant_settings.assistant.is_version_outdated()); - } -} diff --git a/crates/assistant2/src/inline_assistant.rs b/crates/assistant2/src/inline_assistant.rs index 73e539473f9bffb52562562cf6f88a34eb863151..275b0a6646ff4fa780cd926f45d240927956b2b7 100644 --- a/crates/assistant2/src/inline_assistant.rs +++ b/crates/assistant2/src/inline_assistant.rs @@ -1,13 +1,11 @@ -use crate::buffer_codegen::{BufferCodegen, CodegenAlternative, CodegenEvent}; -use crate::context_store::ContextStore; -use crate::inline_prompt_editor::{CodegenStatus, InlineAssistId, PromptEditor, PromptEditorEvent}; -use crate::thread_store::ThreadStore; -use crate::AssistantPanel; -use crate::{ - assistant_settings::AssistantSettings, prompts::PromptBuilder, - terminal_inline_assistant::TerminalInlineAssistant, -}; +use std::cmp; +use std::mem; +use std::ops::Range; +use std::rc::Rc; +use std::sync::Arc; + use anyhow::{Context as _, Result}; +use assistant_settings::AssistantSettings; use client::telemetry::Telemetry; use collections::{hash_map, HashMap, HashSet, VecDeque}; use editor::{ @@ -21,8 +19,6 @@ use editor::{ }; use feature_flags::{Assistant2FeatureFlag, FeatureFlagViewExt as _}; use fs::Fs; -use util::ResultExt; - use gpui::{ point, AppContext, FocusableView, Global, HighlightStyle, Model, Subscription, Task, UpdateGlobal, View, ViewContext, WeakModel, WeakView, WindowContext, @@ -34,15 +30,22 @@ use multi_buffer::MultiBufferRow; use parking_lot::Mutex; use project::{CodeAction, ProjectTransaction}; use settings::{Settings, SettingsStore}; -use std::{cmp, mem, ops::Range, rc::Rc, sync::Arc}; use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase}; use terminal_view::{terminal_panel::TerminalPanel, TerminalView}; use text::{OffsetRangeExt, ToPoint as _}; use ui::prelude::*; use util::RangeExt; +use util::ResultExt; use workspace::{dock::Panel, ShowConfiguration}; use workspace::{notifications::NotificationId, ItemHandle, Toast, Workspace}; +use crate::buffer_codegen::{BufferCodegen, CodegenAlternative, CodegenEvent}; +use crate::context_store::ContextStore; +use crate::inline_prompt_editor::{CodegenStatus, InlineAssistId, PromptEditor, PromptEditorEvent}; +use crate::thread_store::ThreadStore; +use crate::AssistantPanel; +use crate::{prompts::PromptBuilder, terminal_inline_assistant::TerminalInlineAssistant}; + pub fn init( fs: Arc, prompt_builder: Arc, diff --git a/crates/assistant_settings/Cargo.toml b/crates/assistant_settings/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d142541cf3feaf9255f7d1f43a468e9a73191baf --- /dev/null +++ b/crates/assistant_settings/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "assistant_settings" +version = "0.1.0" +edition = "2021" +publish = false +license = "GPL-3.0-or-later" + +[lints] +workspace = true + +[lib] +path = "src/assistant_settings.rs" + +[dependencies] +anthropic = { workspace = true, features = ["schemars"] } +anyhow.workspace = true +feature_flags.workspace = true +gpui.workspace = true +language_model.workspace = true +lmstudio = { workspace = true, features = ["schemars"] } +log.workspace = true +ollama = { workspace = true, features = ["schemars"] } +open_ai = { workspace = true, features = ["schemars"] } +schemars.workspace = true +serde.workspace = true +settings.workspace = true + +[dev-dependencies] +fs.workspace = true +gpui = { workspace = true, features = ["test-support"] } +paths.workspace = true +serde_json_lenient.workspace = true +settings = { workspace = true, features = ["test-support"] } diff --git a/crates/assistant_settings/LICENSE-GPL b/crates/assistant_settings/LICENSE-GPL new file mode 120000 index 0000000000000000000000000000000000000000..89e542f750cd3860a0598eff0dc34b56d7336dc4 --- /dev/null +++ b/crates/assistant_settings/LICENSE-GPL @@ -0,0 +1 @@ +../../LICENSE-GPL \ No newline at end of file diff --git a/crates/assistant/src/assistant_settings.rs b/crates/assistant_settings/src/assistant_settings.rs similarity index 99% rename from crates/assistant/src/assistant_settings.rs rename to crates/assistant_settings/src/assistant_settings.rs index 879838552bb7e6125427841b26ff0ace8913c4fb..c98182b24d1cd62e7ff0d20266ec3cbe07619d94 100644 --- a/crates/assistant/src/assistant_settings.rs +++ b/crates/assistant_settings/src/assistant_settings.rs @@ -41,6 +41,7 @@ pub enum AssistantProviderContentV1 { default_model: Option, api_url: Option, }, + #[serde(rename = "lmstudio")] LmStudio { default_model: Option, api_url: Option, @@ -335,8 +336,8 @@ fn providers_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema: enum_values: Some(vec![ "anthropic".into(), "google".into(), - "ollama".into(), "lmstudio".into(), + "ollama".into(), "openai".into(), "zed.dev".into(), "copilot_chat".into(), diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index ed26446e7429b615aab6906634381727a7f050cd..5b077cf378ce1b3895ac179b81aa4749e0045443 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -20,6 +20,7 @@ anyhow.workspace = true assets.workspace = true assistant.workspace = true assistant2.workspace = true +assistant_settings.workspace = true assistant_tools.workspace = true async-watch.workspace = true audio.workspace = true diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 48a0be9ef9f3090acdcdf93651867296326b9922..ea94a5ac6b5d262c64f348ae4d82221cd3c4672e 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -1,8 +1,8 @@ mod markdown_preview; mod repl_menu; -use assistant::assistant_settings::AssistantSettings; use assistant::AssistantPanel; +use assistant_settings::AssistantSettings; use editor::actions::{ AddSelectionAbove, AddSelectionBelow, DuplicateLineDown, GoToDiagnostic, GoToHunk, GoToPrevDiagnostic, GoToPrevHunk, MoveLineDown, MoveLineUp, SelectAll, SelectLargerSyntaxNode,