settings.rs

  1use std::path::PathBuf;
  2
  3use crate::AgentServerCommand;
  4use anyhow::Result;
  5use collections::HashMap;
  6use gpui::{App, SharedString};
  7use schemars::JsonSchema;
  8use serde::{Deserialize, Serialize};
  9use settings::{Settings, SettingsSources, SettingsUi};
 10
 11pub fn init(cx: &mut App) {
 12    AllAgentServersSettings::register(cx);
 13}
 14
 15#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug, SettingsUi)]
 16pub struct AllAgentServersSettings {
 17    pub gemini: Option<BuiltinAgentServerSettings>,
 18    pub claude: Option<CustomAgentServerSettings>,
 19
 20    /// Custom agent servers configured by the user
 21    #[serde(flatten)]
 22    pub custom: HashMap<SharedString, CustomAgentServerSettings>,
 23}
 24
 25#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
 26pub struct BuiltinAgentServerSettings {
 27    /// Absolute path to a binary to be used when launching this agent.
 28    ///
 29    /// This can be used to run a specific binary without automatic downloads or searching `$PATH`.
 30    #[serde(rename = "command")]
 31    pub path: Option<PathBuf>,
 32    /// If a binary is specified in `command`, it will be passed these arguments.
 33    pub args: Option<Vec<String>>,
 34    /// If a binary is specified in `command`, it will be passed these environment variables.
 35    pub env: Option<HashMap<String, String>>,
 36    /// Whether to skip searching `$PATH` for an agent server binary when
 37    /// launching this agent.
 38    ///
 39    /// This has no effect if a `command` is specified. Otherwise, when this is
 40    /// `false`, Zed will search `$PATH` for an agent server binary and, if one
 41    /// is found, use it for threads with this agent. If no agent binary is
 42    /// found on `$PATH`, Zed will automatically install and use its own binary.
 43    /// When this is `true`, Zed will not search `$PATH`, and will always use
 44    /// its own binary.
 45    ///
 46    /// Default: true
 47    pub ignore_system_version: Option<bool>,
 48}
 49
 50impl BuiltinAgentServerSettings {
 51    pub(crate) fn custom_command(self) -> Option<AgentServerCommand> {
 52        self.path.map(|path| AgentServerCommand {
 53            path,
 54            args: self.args.unwrap_or_default(),
 55            env: self.env,
 56        })
 57    }
 58}
 59
 60impl From<AgentServerCommand> for BuiltinAgentServerSettings {
 61    fn from(value: AgentServerCommand) -> Self {
 62        BuiltinAgentServerSettings {
 63            path: Some(value.path),
 64            args: Some(value.args),
 65            env: value.env,
 66            ..Default::default()
 67        }
 68    }
 69}
 70
 71#[derive(Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
 72pub struct CustomAgentServerSettings {
 73    #[serde(flatten)]
 74    pub command: AgentServerCommand,
 75}
 76
 77impl settings::Settings for AllAgentServersSettings {
 78    const KEY: Option<&'static str> = Some("agent_servers");
 79
 80    type FileContent = Self;
 81
 82    fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
 83        let mut settings = AllAgentServersSettings::default();
 84
 85        for AllAgentServersSettings {
 86            gemini,
 87            claude,
 88            custom,
 89        } in sources.defaults_and_customizations()
 90        {
 91            if gemini.is_some() {
 92                settings.gemini = gemini.clone();
 93            }
 94            if claude.is_some() {
 95                settings.claude = claude.clone();
 96            }
 97
 98            // Merge custom agents
 99            for (name, config) in custom {
100                // Skip built-in agent names to avoid conflicts
101                if name != "gemini" && name != "claude" {
102                    settings.custom.insert(name.clone(), config.clone());
103                }
104            }
105        }
106
107        Ok(settings)
108    }
109
110    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
111}