From 646f65511c1d89420e9f53ab49954d229b6107cb Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 2 Apr 2025 13:12:52 -0400 Subject: [PATCH] agent: Add newtype for profile IDs (#27939) This PR adds an `AgentProfileId` newtype for profile IDs that we can use instead of `Arc` everywhere. Release Notes: - N/A --- crates/agent/src/assistant.rs | 6 ++--- .../manage_profiles_modal.rs | 25 +++++++++++-------- .../assistant_configuration/tool_picker.rs | 6 ++--- crates/agent/src/profile_selector.rs | 6 ++--- crates/agent/src/thread_store.rs | 4 +-- .../assistant_settings/src/agent_profile.rs | 23 +++++++++++++++++ .../src/assistant_settings.rs | 16 +++++++----- 7 files changed, 59 insertions(+), 27 deletions(-) diff --git a/crates/agent/src/assistant.rs b/crates/agent/src/assistant.rs index e9fa9f5e2d..caae6b69da 100644 --- a/crates/agent/src/assistant.rs +++ b/crates/agent/src/assistant.rs @@ -23,7 +23,7 @@ mod ui; use std::sync::Arc; -use assistant_settings::AssistantSettings; +use assistant_settings::{AgentProfileId, AssistantSettings}; use client::Client; use command_palette_hooks::CommandPaletteFilter; use feature_flags::{Assistant2FeatureFlag, FeatureFlagAppExt}; @@ -82,11 +82,11 @@ pub struct NewThread { #[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)] pub struct ManageProfiles { #[serde(default)] - pub customize_tools: Option>, + pub customize_tools: Option, } impl ManageProfiles { - pub fn customize_tools(profile_id: Arc) -> Self { + pub fn customize_tools(profile_id: AgentProfileId) -> Self { Self { customize_tools: Some(profile_id), } diff --git a/crates/agent/src/assistant_configuration/manage_profiles_modal.rs b/crates/agent/src/assistant_configuration/manage_profiles_modal.rs index 3cdff03440..a4c72cbac9 100644 --- a/crates/agent/src/assistant_configuration/manage_profiles_modal.rs +++ b/crates/agent/src/assistant_configuration/manage_profiles_modal.rs @@ -2,7 +2,7 @@ mod profile_modal_header; use std::sync::Arc; -use assistant_settings::{AgentProfile, AssistantSettings}; +use assistant_settings::{AgentProfile, AgentProfileId, AssistantSettings}; use assistant_tool::ToolWorkingSet; use convert_case::{Case, Casing as _}; use editor::Editor; @@ -27,7 +27,7 @@ enum Mode { NewProfile(NewProfileMode), ViewProfile(ViewProfileMode), ConfigureTools { - profile_id: Arc, + profile_id: AgentProfileId, tool_picker: Entity, _subscription: Subscription, }, @@ -58,7 +58,7 @@ impl Mode { #[derive(Clone)] struct ProfileEntry { - pub id: Arc, + pub id: AgentProfileId, pub name: SharedString, pub navigation: NavigableEntry, } @@ -71,7 +71,7 @@ pub struct ChooseProfileMode { #[derive(Clone)] pub struct ViewProfileMode { - profile_id: Arc, + profile_id: AgentProfileId, fork_profile: NavigableEntry, configure_tools: NavigableEntry, } @@ -79,7 +79,7 @@ pub struct ViewProfileMode { #[derive(Clone)] pub struct NewProfileMode { name_editor: Entity, - base_profile_id: Option>, + base_profile_id: Option, } pub struct ManageProfilesModal { @@ -140,7 +140,7 @@ impl ManageProfilesModal { fn new_profile( &mut self, - base_profile_id: Option>, + base_profile_id: Option, window: &mut Window, cx: &mut Context, ) { @@ -158,7 +158,7 @@ impl ManageProfilesModal { pub fn view_profile( &mut self, - profile_id: Arc, + profile_id: AgentProfileId, window: &mut Window, cx: &mut Context, ) { @@ -172,7 +172,7 @@ impl ManageProfilesModal { fn configure_tools( &mut self, - profile_id: Arc, + profile_id: AgentProfileId, window: &mut Window, cx: &mut Context, ) { @@ -219,7 +219,7 @@ impl ManageProfilesModal { .and_then(|profile_id| settings.profiles.get(profile_id).cloned()); let name = mode.name_editor.read(cx).text(cx); - let profile_id: Arc = name.to_case(Case::Kebab).into(); + let profile_id = AgentProfileId(name.to_case(Case::Kebab).into()); let profile = AgentProfile { name: name.into(), @@ -261,7 +261,12 @@ impl ManageProfilesModal { } } - fn create_profile(&self, profile_id: Arc, profile: AgentProfile, cx: &mut Context) { + fn create_profile( + &self, + profile_id: AgentProfileId, + profile: AgentProfile, + cx: &mut Context, + ) { update_settings_file::(self.fs.clone(), cx, { move |settings, _cx| { settings.create_profile(profile_id, profile).log_err(); diff --git a/crates/agent/src/assistant_configuration/tool_picker.rs b/crates/agent/src/assistant_configuration/tool_picker.rs index d8bbf449a5..7ca6747a8e 100644 --- a/crates/agent/src/assistant_configuration/tool_picker.rs +++ b/crates/agent/src/assistant_configuration/tool_picker.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use assistant_settings::{ - AgentProfile, AgentProfileContent, AssistantSettings, AssistantSettingsContent, + AgentProfile, AgentProfileContent, AgentProfileId, AssistantSettings, AssistantSettingsContent, ContextServerPresetContent, VersionedAssistantSettingsContent, }; use assistant_tool::{ToolSource, ToolWorkingSet}; @@ -51,7 +51,7 @@ pub struct ToolPickerDelegate { thread_store: WeakEntity, fs: Arc, tools: Vec, - profile_id: Arc, + profile_id: AgentProfileId, profile: AgentProfile, matches: Vec, selected_index: usize, @@ -62,7 +62,7 @@ impl ToolPickerDelegate { fs: Arc, tool_set: Arc, thread_store: WeakEntity, - profile_id: Arc, + profile_id: AgentProfileId, profile: AgentProfile, cx: &mut Context, ) -> Self { diff --git a/crates/agent/src/profile_selector.rs b/crates/agent/src/profile_selector.rs index 92a3e68a0d..46a8cf4273 100644 --- a/crates/agent/src/profile_selector.rs +++ b/crates/agent/src/profile_selector.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use assistant_settings::{AgentProfile, AssistantSettings}; +use assistant_settings::{AgentProfile, AgentProfileId, AssistantSettings}; use fs::Fs; use gpui::{Action, Entity, FocusHandle, Subscription, WeakEntity, prelude::*}; use indexmap::IndexMap; @@ -15,7 +15,7 @@ use util::ResultExt as _; use crate::{ManageProfiles, ThreadStore, ToggleProfileSelector}; pub struct ProfileSelector { - profiles: IndexMap, AgentProfile>, + profiles: IndexMap, fs: Arc, thread_store: WeakEntity, focus_handle: FocusHandle, @@ -133,7 +133,7 @@ impl Render for ProfileSelector { .active_model() .map_or(false, |model| model.supports_tools()); - let icon = match profile_id.as_ref() { + let icon = match profile_id.as_str() { "write" => IconName::Pencil, "ask" => IconName::MessageBubbles, _ => IconName::UserRoundPen, diff --git a/crates/agent/src/thread_store.rs b/crates/agent/src/thread_store.rs index 3a3c497b16..bd976b104b 100644 --- a/crates/agent/src/thread_store.rs +++ b/crates/agent/src/thread_store.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use std::sync::Arc; use anyhow::{Result, anyhow}; -use assistant_settings::{AgentProfile, AssistantSettings}; +use assistant_settings::{AgentProfile, AgentProfileId, AssistantSettings}; use assistant_tool::{ToolId, ToolSource, ToolWorkingSet}; use chrono::{DateTime, Utc}; use collections::HashMap; @@ -202,7 +202,7 @@ impl ThreadStore { self.load_profile_by_id(&assistant_settings.default_profile, cx); } - pub fn load_profile_by_id(&self, profile_id: &Arc, cx: &Context) { + pub fn load_profile_by_id(&self, profile_id: &AgentProfileId, cx: &Context) { let assistant_settings = AssistantSettings::get_global(cx); if let Some(profile) = assistant_settings.profiles.get(profile_id) { diff --git a/crates/assistant_settings/src/agent_profile.rs b/crates/assistant_settings/src/agent_profile.rs index 00a7fbcedb..579e7f0f97 100644 --- a/crates/assistant_settings/src/agent_profile.rs +++ b/crates/assistant_settings/src/agent_profile.rs @@ -2,6 +2,29 @@ use std::sync::Arc; use gpui::SharedString; use indexmap::IndexMap; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[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()) + } +} /// A profile for the Zed Agent that controls its behavior. #[derive(Debug, Clone)] diff --git a/crates/assistant_settings/src/assistant_settings.rs b/crates/assistant_settings/src/assistant_settings.rs index 1f27b9f1fc..c5b496e23d 100644 --- a/crates/assistant_settings/src/assistant_settings.rs +++ b/crates/assistant_settings/src/assistant_settings.rs @@ -81,8 +81,8 @@ pub struct AssistantSettings { pub inline_alternatives: Vec, pub using_outdated_settings_version: bool, pub enable_experimental_live_diffs: bool, - pub default_profile: Arc, - pub profiles: IndexMap, AgentProfile>, + pub default_profile: AgentProfileId, + pub profiles: IndexMap, pub always_allow_tool_actions: bool, pub notify_when_agent_waiting: NotifyWhenAgentWaiting, } @@ -325,7 +325,7 @@ impl AssistantSettingsContent { } } - pub fn set_profile(&mut self, profile_id: Arc) { + pub fn set_profile(&mut self, profile_id: AgentProfileId) { let AssistantSettingsContent::Versioned(VersionedAssistantSettingsContent::V2(settings)) = self else { @@ -335,7 +335,11 @@ impl AssistantSettingsContent { settings.default_profile = Some(profile_id); } - pub fn create_profile(&mut self, profile_id: Arc, profile: AgentProfile) -> Result<()> { + pub fn create_profile( + &mut self, + profile_id: AgentProfileId, + profile: AgentProfile, + ) -> Result<()> { let AssistantSettingsContent::Versioned(VersionedAssistantSettingsContent::V2(settings)) = self else { @@ -436,9 +440,9 @@ pub struct AssistantSettingsContentV2 { /// The default profile to use in the Agent. /// /// Default: write - default_profile: Option>, + default_profile: Option, /// The available agent profiles. - pub profiles: Option, AgentProfileContent>>, + pub profiles: Option>, /// Whenever a tool action would normally wait for your confirmation /// that you allow it, always choose to allow it. ///