diff --git a/crates/assistant2/src/agent_profile.rs b/crates/assistant2/src/agent_profile.rs new file mode 100644 index 0000000000..e707704c7d --- /dev/null +++ b/crates/assistant2/src/agent_profile.rs @@ -0,0 +1,59 @@ +use std::sync::Arc; + +use collections::HashMap; +use gpui::SharedString; + +/// A profile for the Zed Agent that controls its behavior. +#[derive(Debug, Clone)] +pub struct AgentProfile { + /// The name of the profile. + pub name: SharedString, + pub tools: HashMap, bool>, + #[allow(dead_code)] + pub context_servers: HashMap, ContextServerPreset>, +} + +#[derive(Debug, Clone)] +pub struct ContextServerPreset { + #[allow(dead_code)] + pub tools: HashMap, bool>, +} + +impl AgentProfile { + pub fn read_only() -> Self { + Self { + name: "Read-only".into(), + tools: HashMap::from_iter([ + ("diagnostics".into(), true), + ("fetch".into(), true), + ("list-directory".into(), true), + ("now".into(), true), + ("path-search".into(), true), + ("read-file".into(), true), + ("regex-search".into(), true), + ("thinking".into(), true), + ]), + context_servers: HashMap::default(), + } + } + + pub fn code_writer() -> Self { + Self { + name: "Code Writer".into(), + tools: HashMap::from_iter([ + ("bash".into(), true), + ("delete-path".into(), true), + ("diagnostics".into(), true), + ("edit-files".into(), true), + ("fetch".into(), true), + ("list-directory".into(), true), + ("now".into(), true), + ("path-search".into(), true), + ("read-file".into(), true), + ("regex-search".into(), true), + ("thinking".into(), true), + ]), + context_servers: HashMap::default(), + } + } +} diff --git a/crates/assistant2/src/assistant.rs b/crates/assistant2/src/assistant.rs index 5224b097cc..d57fe78579 100644 --- a/crates/assistant2/src/assistant.rs +++ b/crates/assistant2/src/assistant.rs @@ -1,4 +1,5 @@ mod active_thread; +mod agent_profile; mod assistant_configuration; mod assistant_model_selector; mod assistant_panel; diff --git a/crates/assistant2/src/tool_selector.rs b/crates/assistant2/src/tool_selector.rs index 38ff11c2db..e14e206c6b 100644 --- a/crates/assistant2/src/tool_selector.rs +++ b/crates/assistant2/src/tool_selector.rs @@ -5,13 +5,19 @@ use gpui::Entity; use scripting_tool::ScriptingTool; use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip}; +use crate::agent_profile::AgentProfile; + pub struct ToolSelector { + profiles: Vec, tools: Arc, } impl ToolSelector { pub fn new(tools: Arc, _cx: &mut Context) -> Self { - Self { tools } + Self { + profiles: vec![AgentProfile::read_only(), AgentProfile::code_writer()], + tools, + } } fn build_context_menu( @@ -19,9 +25,31 @@ impl ToolSelector { window: &mut Window, cx: &mut Context, ) -> Entity { + let profiles = self.profiles.clone(); let tool_set = self.tools.clone(); ContextMenu::build_persistent(window, cx, move |mut menu, _window, cx| { let icon_position = IconPosition::End; + + menu = menu.header("Profiles"); + for profile in profiles.clone() { + menu = menu.toggleable_entry(profile.name.clone(), false, icon_position, None, { + let tools = tool_set.clone(); + move |_window, cx| { + tools.disable_source(ToolSource::Native, cx); + tools.enable( + ToolSource::Native, + &profile + .tools + .iter() + .filter_map(|(tool, enabled)| enabled.then(|| tool.clone())) + .collect::>(), + ); + } + }); + } + + menu = menu.separator(); + let tools_by_source = tool_set.tools_by_source(cx); let all_tools_enabled = tool_set.are_all_tools_enabled();