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