mod agent_profile; use std::sync::Arc; use collections::IndexMap; use gpui::{App, Pixels, px}; use language_model::LanguageModel; use project::DisableAiSettings; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::{ DefaultAgentView, DockPosition, LanguageModelParameters, LanguageModelSelection, NotifyWhenAgentWaiting, RegisterSetting, Settings, }; pub use crate::agent_profile::*; pub const SUMMARIZE_THREAD_PROMPT: &str = include_str!("prompts/summarize_thread_prompt.txt"); pub const SUMMARIZE_THREAD_DETAILED_PROMPT: &str = include_str!("prompts/summarize_thread_detailed_prompt.txt"); #[derive(Clone, Debug, RegisterSetting)] pub struct AgentSettings { pub enabled: bool, pub button: bool, pub dock: DockPosition, pub default_width: Pixels, pub default_height: Pixels, pub default_model: Option, pub inline_assistant_model: Option, pub commit_message_model: Option, pub thread_summary_model: Option, pub inline_alternatives: Vec, pub default_profile: AgentProfileId, pub default_view: DefaultAgentView, pub profiles: IndexMap, pub always_allow_tool_actions: bool, pub notify_when_agent_waiting: NotifyWhenAgentWaiting, pub play_sound_when_agent_done: bool, pub single_file_review: bool, pub model_parameters: Vec, pub preferred_completion_mode: CompletionMode, pub enable_feedback: bool, pub expand_edit_card: bool, pub expand_terminal_card: bool, pub use_modifier_to_send: bool, pub message_editor_min_lines: usize, } impl AgentSettings { pub fn enabled(&self, cx: &App) -> bool { self.enabled && !DisableAiSettings::get_global(cx).disable_ai } pub fn temperature_for_model(model: &Arc, cx: &App) -> Option { let settings = Self::get_global(cx); for setting in settings.model_parameters.iter().rev() { if let Some(provider) = &setting.provider && provider.0 != model.provider_id().0 { continue; } if let Some(setting_model) = &setting.model && *setting_model != model.id().0 { continue; } return setting.temperature; } return None; } pub fn set_inline_assistant_model(&mut self, provider: String, model: String) { self.inline_assistant_model = Some(LanguageModelSelection { provider: provider.into(), model, }); } pub fn set_commit_message_model(&mut self, provider: String, model: String) { self.commit_message_model = Some(LanguageModelSelection { provider: provider.into(), model, }); } pub fn set_thread_summary_model(&mut self, provider: String, model: String) { self.thread_summary_model = Some(LanguageModelSelection { provider: provider.into(), model, }); } pub fn set_message_editor_max_lines(&self) -> usize { self.message_editor_min_lines * 2 } } #[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)] #[serde(rename_all = "snake_case")] pub enum CompletionMode { #[default] Normal, #[serde(alias = "max")] Burn, } impl From for cloud_llm_client::CompletionMode { fn from(value: CompletionMode) -> Self { match value { CompletionMode::Normal => cloud_llm_client::CompletionMode::Normal, CompletionMode::Burn => cloud_llm_client::CompletionMode::Max, } } } impl From for CompletionMode { fn from(value: settings::CompletionMode) -> Self { match value { settings::CompletionMode::Normal => CompletionMode::Normal, settings::CompletionMode::Burn => CompletionMode::Burn, } } } #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, JsonSchema)] pub struct AgentProfileId(pub Arc); impl AgentProfileId { pub fn as_str(&self) -> &str { &self.0 } } impl std::fmt::Display for AgentProfileId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl Default for AgentProfileId { fn default() -> Self { Self("write".into()) } } impl Settings for AgentSettings { fn from_settings(content: &settings::SettingsContent) -> Self { let agent = content.agent.clone().unwrap(); Self { enabled: agent.enabled.unwrap(), button: agent.button.unwrap(), dock: agent.dock.unwrap(), default_width: px(agent.default_width.unwrap()), default_height: px(agent.default_height.unwrap()), default_model: Some(agent.default_model.unwrap()), inline_assistant_model: agent.inline_assistant_model, commit_message_model: agent.commit_message_model, thread_summary_model: agent.thread_summary_model, inline_alternatives: agent.inline_alternatives.unwrap_or_default(), default_profile: AgentProfileId(agent.default_profile.unwrap()), default_view: agent.default_view.unwrap(), profiles: agent .profiles .unwrap() .into_iter() .map(|(key, val)| (AgentProfileId(key), val.into())) .collect(), always_allow_tool_actions: agent.always_allow_tool_actions.unwrap(), notify_when_agent_waiting: agent.notify_when_agent_waiting.unwrap(), play_sound_when_agent_done: agent.play_sound_when_agent_done.unwrap(), single_file_review: agent.single_file_review.unwrap(), model_parameters: agent.model_parameters, preferred_completion_mode: agent.preferred_completion_mode.unwrap().into(), enable_feedback: agent.enable_feedback.unwrap(), expand_edit_card: agent.expand_edit_card.unwrap(), expand_terminal_card: agent.expand_terminal_card.unwrap(), use_modifier_to_send: agent.use_modifier_to_send.unwrap(), message_editor_min_lines: agent.message_editor_min_lines.unwrap(), } } }