agent.rs

  1use collections::{HashMap, IndexMap};
  2use gpui::SharedString;
  3use schemars::{JsonSchema, json_schema};
  4use serde::{Deserialize, Serialize};
  5use std::{borrow::Cow, path::PathBuf, sync::Arc};
  6
  7#[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug, Default)]
  8pub struct AgentSettingsContent {
  9    /// Whether the Agent is enabled.
 10    ///
 11    /// Default: true
 12    pub enabled: Option<bool>,
 13    /// Whether to show the agent panel button in the status bar.
 14    ///
 15    /// Default: true
 16    pub button: Option<bool>,
 17    /// Where to dock the agent panel.
 18    ///
 19    /// Default: right
 20    pub dock: Option<AgentDockPosition>,
 21    /// Default width in pixels when the agent panel is docked to the left or right.
 22    ///
 23    /// Default: 640
 24    pub default_width: Option<f32>,
 25    /// Default height in pixels when the agent panel is docked to the bottom.
 26    ///
 27    /// Default: 320
 28    pub default_height: Option<f32>,
 29    /// The default model to use when creating new chats and for other features when a specific model is not specified.
 30    pub default_model: Option<LanguageModelSelection>,
 31    /// Model to use for the inline assistant. Defaults to default_model when not specified.
 32    pub inline_assistant_model: Option<LanguageModelSelection>,
 33    /// Model to use for generating git commit messages. Defaults to default_model when not specified.
 34    pub commit_message_model: Option<LanguageModelSelection>,
 35    /// Model to use for generating thread summaries. Defaults to default_model when not specified.
 36    pub thread_summary_model: Option<LanguageModelSelection>,
 37    /// Additional models with which to generate alternatives when performing inline assists.
 38    pub inline_alternatives: Option<Vec<LanguageModelSelection>>,
 39    /// The default profile to use in the Agent.
 40    ///
 41    /// Default: write
 42    pub default_profile: Option<Arc<str>>,
 43    /// Which view type to show by default in the agent panel.
 44    ///
 45    /// Default: "thread"
 46    pub default_view: Option<DefaultAgentView>,
 47    /// The available agent profiles.
 48    pub profiles: Option<IndexMap<Arc<str>, AgentProfileContent>>,
 49    /// Whenever a tool action would normally wait for your confirmation
 50    /// that you allow it, always choose to allow it.
 51    ///
 52    /// This setting has no effect on external agents that support permission modes, such as Claude Code.
 53    ///
 54    /// Set `agent_servers.claude.default_mode` to `bypassPermissions`, to disable all permission requests when using Claude Code.
 55    ///
 56    /// Default: false
 57    pub always_allow_tool_actions: Option<bool>,
 58    /// Where to show a popup notification when the agent is waiting for user input.
 59    ///
 60    /// Default: "primary_screen"
 61    pub notify_when_agent_waiting: Option<NotifyWhenAgentWaiting>,
 62    /// Whether to play a sound when the agent has either completed its response, or needs user input.
 63    ///
 64    /// Default: false
 65    pub play_sound_when_agent_done: Option<bool>,
 66    /// Whether to stream edits from the agent as they are received.
 67    ///
 68    /// Default: false
 69    pub stream_edits: Option<bool>,
 70    /// Whether to display agent edits in single-file editors in addition to the review multibuffer pane.
 71    ///
 72    /// Default: true
 73    pub single_file_review: Option<bool>,
 74    /// Additional parameters for language model requests. When making a request
 75    /// to a model, parameters will be taken from the last entry in this list
 76    /// that matches the model's provider and name. In each entry, both provider
 77    /// and model are optional, so that you can specify parameters for either
 78    /// one.
 79    ///
 80    /// Default: []
 81    #[serde(default)]
 82    pub model_parameters: Vec<LanguageModelParameters>,
 83    /// What completion mode to enable for new threads
 84    ///
 85    /// Default: normal
 86    pub preferred_completion_mode: Option<CompletionMode>,
 87    /// Whether to show thumb buttons for feedback in the agent panel.
 88    ///
 89    /// Default: true
 90    pub enable_feedback: Option<bool>,
 91    /// Whether to have edit cards in the agent panel expanded, showing a preview of the full diff.
 92    ///
 93    /// Default: true
 94    pub expand_edit_card: Option<bool>,
 95    /// Whether to have terminal cards in the agent panel expanded, showing the whole command output.
 96    ///
 97    /// Default: true
 98    pub expand_terminal_card: Option<bool>,
 99    /// Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages in the agent panel.
100    ///
101    /// Default: false
102    pub use_modifier_to_send: Option<bool>,
103}
104
105impl AgentSettingsContent {
106    pub fn set_dock(&mut self, dock: AgentDockPosition) {
107        self.dock = Some(dock);
108    }
109
110    pub fn set_model(&mut self, language_model: LanguageModelSelection) {
111        // let model = language_model.id().0.to_string();
112        // let provider = language_model.provider_id().0.to_string();
113        // self.default_model = Some(LanguageModelSelection {
114        //     provider: provider.into(),
115        //     model,
116        // });
117        self.default_model = Some(language_model)
118    }
119
120    pub fn set_inline_assistant_model(&mut self, provider: String, model: String) {
121        self.inline_assistant_model = Some(LanguageModelSelection {
122            provider: provider.into(),
123            model,
124        });
125    }
126
127    pub fn set_commit_message_model(&mut self, provider: String, model: String) {
128        self.commit_message_model = Some(LanguageModelSelection {
129            provider: provider.into(),
130            model,
131        });
132    }
133
134    pub fn set_thread_summary_model(&mut self, provider: String, model: String) {
135        self.thread_summary_model = Some(LanguageModelSelection {
136            provider: provider.into(),
137            model,
138        });
139    }
140
141    pub fn set_always_allow_tool_actions(&mut self, allow: bool) {
142        self.always_allow_tool_actions = Some(allow);
143    }
144
145    pub fn set_play_sound_when_agent_done(&mut self, allow: bool) {
146        self.play_sound_when_agent_done = Some(allow);
147    }
148
149    pub fn set_single_file_review(&mut self, allow: bool) {
150        self.single_file_review = Some(allow);
151    }
152
153    pub fn set_use_modifier_to_send(&mut self, always_use: bool) {
154        self.use_modifier_to_send = Some(always_use);
155    }
156
157    pub fn set_profile(&mut self, profile_id: Arc<str>) {
158        self.default_profile = Some(profile_id);
159    }
160}
161#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
162pub struct AgentProfileContent {
163    pub name: Arc<str>,
164    #[serde(default)]
165    pub tools: IndexMap<Arc<str>, bool>,
166    /// Whether all context servers are enabled by default.
167    pub enable_all_context_servers: Option<bool>,
168    #[serde(default)]
169    pub context_servers: IndexMap<Arc<str>, ContextServerPresetContent>,
170}
171
172#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema)]
173pub struct ContextServerPresetContent {
174    pub tools: IndexMap<Arc<str>, bool>,
175}
176
177#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
178#[serde(rename_all = "snake_case")]
179pub enum AgentDockPosition {
180    Left,
181    #[default]
182    Right,
183    Bottom,
184}
185
186#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
187#[serde(rename_all = "snake_case")]
188pub enum DefaultAgentView {
189    #[default]
190    Thread,
191    TextThread,
192}
193
194#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
195#[serde(rename_all = "snake_case")]
196pub enum NotifyWhenAgentWaiting {
197    #[default]
198    PrimaryScreen,
199    AllScreens,
200    Never,
201}
202
203#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
204pub struct LanguageModelSelection {
205    pub provider: LanguageModelProviderSetting,
206    pub model: String,
207}
208
209#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
210#[serde(rename_all = "snake_case")]
211pub enum CompletionMode {
212    #[default]
213    Normal,
214    #[serde(alias = "max")]
215    Burn,
216}
217
218#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
219pub struct LanguageModelParameters {
220    pub provider: Option<LanguageModelProviderSetting>,
221    pub model: Option<SharedString>,
222    pub temperature: Option<f32>,
223}
224
225#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
226pub struct LanguageModelProviderSetting(pub String);
227
228impl JsonSchema for LanguageModelProviderSetting {
229    fn schema_name() -> Cow<'static, str> {
230        "LanguageModelProviderSetting".into()
231    }
232
233    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
234        json_schema!({
235            "enum": [
236                "amazon-bedrock",
237                "anthropic",
238                "copilot_chat",
239                "deepseek",
240                "google",
241                "lmstudio",
242                "mistral",
243                "ollama",
244                "openai",
245                "openrouter",
246                "vercel",
247                "x_ai",
248                "zed.dev"
249            ]
250        })
251    }
252}
253
254impl From<String> for LanguageModelProviderSetting {
255    fn from(provider: String) -> Self {
256        Self(provider)
257    }
258}
259
260impl From<&str> for LanguageModelProviderSetting {
261    fn from(provider: &str) -> Self {
262        Self(provider.to_string())
263    }
264}
265
266#[derive(Default, PartialEq, Deserialize, Serialize, Clone, JsonSchema, Debug)]
267pub struct AllAgentServersSettings {
268    pub gemini: Option<BuiltinAgentServerSettings>,
269    pub claude: Option<BuiltinAgentServerSettings>,
270
271    /// Custom agent servers configured by the user
272    #[serde(flatten)]
273    pub custom: HashMap<SharedString, CustomAgentServerSettings>,
274}
275
276#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
277pub struct BuiltinAgentServerSettings {
278    /// Absolute path to a binary to be used when launching this agent.
279    ///
280    /// This can be used to run a specific binary without automatic downloads or searching `$PATH`.
281    #[serde(rename = "command")]
282    pub path: Option<PathBuf>,
283    /// If a binary is specified in `command`, it will be passed these arguments.
284    pub args: Option<Vec<String>>,
285    /// If a binary is specified in `command`, it will be passed these environment variables.
286    pub env: Option<HashMap<String, String>>,
287    /// Whether to skip searching `$PATH` for an agent server binary when
288    /// launching this agent.
289    ///
290    /// This has no effect if a `command` is specified. Otherwise, when this is
291    /// `false`, Zed will search `$PATH` for an agent server binary and, if one
292    /// is found, use it for threads with this agent. If no agent binary is
293    /// found on `$PATH`, Zed will automatically install and use its own binary.
294    /// When this is `true`, Zed will not search `$PATH`, and will always use
295    /// its own binary.
296    ///
297    /// Default: true
298    pub ignore_system_version: Option<bool>,
299    /// The default mode to use for this agent.
300    ///
301    /// Note: Not only all agents support modes.
302    ///
303    /// Default: None
304    pub default_mode: Option<String>,
305}
306
307#[derive(Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
308pub struct CustomAgentServerSettings {
309    #[serde(rename = "command")]
310    pub path: PathBuf,
311    #[serde(default)]
312    pub args: Vec<String>,
313    pub env: Option<HashMap<String, String>>,
314    /// The default mode to use for this agent.
315    ///
316    /// Note: Not only all agents support modes.
317    ///
318    /// Default: None
319    pub default_mode: Option<String>,
320}