1use collections::HashMap;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use settings_macros::{MergeFrom, with_fallible_options};
5use strum::EnumString;
6
7use std::sync::Arc;
8
9#[with_fallible_options]
10#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
11pub struct AllLanguageModelSettingsContent {
12 pub anthropic: Option<AnthropicSettingsContent>,
13 pub bedrock: Option<AmazonBedrockSettingsContent>,
14 pub deepseek: Option<DeepseekSettingsContent>,
15 pub google: Option<GoogleSettingsContent>,
16 pub lmstudio: Option<LmStudioSettingsContent>,
17 pub mistral: Option<MistralSettingsContent>,
18 pub ollama: Option<OllamaSettingsContent>,
19 pub opencode: Option<OpenCodeSettingsContent>,
20 pub open_router: Option<OpenRouterSettingsContent>,
21 pub openai: Option<OpenAiSettingsContent>,
22 pub openai_compatible: Option<HashMap<Arc<str>, OpenAiCompatibleSettingsContent>>,
23 pub vercel: Option<VercelSettingsContent>,
24 pub vercel_ai_gateway: Option<VercelAiGatewaySettingsContent>,
25 pub x_ai: Option<XAiSettingsContent>,
26 #[serde(rename = "zed.dev")]
27 pub zed_dot_dev: Option<ZedDotDevSettingsContent>,
28}
29
30#[with_fallible_options]
31#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
32pub struct AnthropicSettingsContent {
33 pub api_url: Option<String>,
34 pub available_models: Option<Vec<AnthropicAvailableModel>>,
35}
36
37#[with_fallible_options]
38#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
39pub struct AnthropicAvailableModel {
40 /// The model's name in the Anthropic API. e.g. claude-3-5-sonnet-latest, claude-3-opus-20240229, etc
41 pub name: String,
42 /// The model's name in Zed's UI, such as in the model selector dropdown menu in the assistant panel.
43 pub display_name: Option<String>,
44 /// The model's context window size.
45 pub max_tokens: u64,
46 /// A model `name` to substitute when calling tools, in case the primary model doesn't support tool calling.
47 pub tool_override: Option<String>,
48 /// Configuration of Anthropic's caching API.
49 pub cache_configuration: Option<LanguageModelCacheConfiguration>,
50 pub max_output_tokens: Option<u64>,
51 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
52 pub default_temperature: Option<f32>,
53 #[serde(default)]
54 pub extra_beta_headers: Vec<String>,
55 /// The model's mode (e.g. thinking)
56 pub mode: Option<ModelMode>,
57}
58
59#[with_fallible_options]
60#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
61pub struct AmazonBedrockSettingsContent {
62 pub available_models: Option<Vec<BedrockAvailableModel>>,
63 pub endpoint_url: Option<String>,
64 pub region: Option<String>,
65 pub profile: Option<String>,
66 pub authentication_method: Option<BedrockAuthMethodContent>,
67 pub allow_global: Option<bool>,
68 /// Enable the 1M token extended context window beta for supported Anthropic models.
69 pub allow_extended_context: Option<bool>,
70}
71
72#[with_fallible_options]
73#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
74pub struct BedrockAvailableModel {
75 pub name: String,
76 pub display_name: Option<String>,
77 pub max_tokens: u64,
78 pub cache_configuration: Option<LanguageModelCacheConfiguration>,
79 pub max_output_tokens: Option<u64>,
80 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
81 pub default_temperature: Option<f32>,
82 pub mode: Option<ModelMode>,
83}
84
85#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
86pub enum BedrockAuthMethodContent {
87 #[serde(rename = "named_profile")]
88 NamedProfile,
89 #[serde(rename = "sso")]
90 SingleSignOn,
91 #[serde(rename = "api_key")]
92 ApiKey,
93 /// IMDSv2, PodIdentity, env vars, etc.
94 #[serde(rename = "default")]
95 Automatic,
96}
97
98#[with_fallible_options]
99#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
100pub struct OllamaSettingsContent {
101 pub api_url: Option<String>,
102 pub auto_discover: Option<bool>,
103 pub available_models: Option<Vec<OllamaAvailableModel>>,
104 pub context_window: Option<u64>,
105}
106
107#[with_fallible_options]
108#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
109pub struct OllamaAvailableModel {
110 /// The model name in the Ollama API (e.g. "llama3.2:latest")
111 pub name: String,
112 /// The model's name in Zed's UI, such as in the model selector dropdown menu in the assistant panel.
113 pub display_name: Option<String>,
114 /// The Context Length parameter to the model (aka num_ctx or n_ctx)
115 pub max_tokens: u64,
116 /// The number of seconds to keep the connection open after the last request
117 pub keep_alive: Option<KeepAlive>,
118 /// Whether the model supports tools
119 pub supports_tools: Option<bool>,
120 /// Whether the model supports vision
121 pub supports_images: Option<bool>,
122 /// Whether to enable think mode
123 pub supports_thinking: Option<bool>,
124}
125
126#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, JsonSchema, MergeFrom)]
127#[serde(untagged)]
128pub enum KeepAlive {
129 /// Keep model alive for N seconds
130 Seconds(isize),
131 /// Keep model alive for a fixed duration. Accepts durations like "5m", "10m", "1h", "1d", etc.
132 Duration(String),
133}
134
135impl KeepAlive {
136 /// Keep model alive until a new model is loaded or until Ollama shuts down
137 pub fn indefinite() -> Self {
138 Self::Seconds(-1)
139 }
140}
141
142impl Default for KeepAlive {
143 fn default() -> Self {
144 Self::indefinite()
145 }
146}
147
148#[with_fallible_options]
149#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
150pub struct OpenCodeSettingsContent {
151 pub api_url: Option<String>,
152 pub available_models: Option<Vec<OpenCodeAvailableModel>>,
153}
154
155#[with_fallible_options]
156#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
157pub struct OpenCodeAvailableModel {
158 pub name: String,
159 pub display_name: Option<String>,
160 pub max_tokens: u64,
161 pub max_output_tokens: Option<u64>,
162 /// The API protocol to use for this model: "anthropic", "openai_responses", "openai_chat", or "google".
163 pub protocol: String,
164}
165
166#[with_fallible_options]
167#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
168pub struct LmStudioSettingsContent {
169 pub api_url: Option<String>,
170 pub api_key: Option<String>,
171 pub available_models: Option<Vec<LmStudioAvailableModel>>,
172}
173
174#[with_fallible_options]
175#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
176pub struct LmStudioAvailableModel {
177 pub name: String,
178 pub display_name: Option<String>,
179 pub max_tokens: u64,
180 pub supports_tool_calls: bool,
181 pub supports_images: bool,
182}
183
184#[with_fallible_options]
185#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
186pub struct DeepseekSettingsContent {
187 pub api_url: Option<String>,
188 pub available_models: Option<Vec<DeepseekAvailableModel>>,
189}
190
191#[with_fallible_options]
192#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
193pub struct DeepseekAvailableModel {
194 pub name: String,
195 pub display_name: Option<String>,
196 pub max_tokens: u64,
197 pub max_output_tokens: Option<u64>,
198}
199
200#[with_fallible_options]
201#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
202pub struct MistralSettingsContent {
203 pub api_url: Option<String>,
204 pub available_models: Option<Vec<MistralAvailableModel>>,
205}
206
207#[with_fallible_options]
208#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
209pub struct MistralAvailableModel {
210 pub name: String,
211 pub display_name: Option<String>,
212 pub max_tokens: u64,
213 pub max_output_tokens: Option<u64>,
214 pub max_completion_tokens: Option<u64>,
215 pub supports_tools: Option<bool>,
216 pub supports_images: Option<bool>,
217 pub supports_thinking: Option<bool>,
218}
219
220#[with_fallible_options]
221#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
222pub struct OpenAiSettingsContent {
223 pub api_url: Option<String>,
224 pub available_models: Option<Vec<OpenAiAvailableModel>>,
225}
226
227#[with_fallible_options]
228#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
229pub struct OpenAiAvailableModel {
230 pub name: String,
231 pub display_name: Option<String>,
232 pub max_tokens: u64,
233 pub max_output_tokens: Option<u64>,
234 pub max_completion_tokens: Option<u64>,
235 pub reasoning_effort: Option<OpenAiReasoningEffort>,
236 #[serde(default)]
237 pub capabilities: OpenAiModelCapabilities,
238}
239
240#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, EnumString, JsonSchema, MergeFrom)]
241#[serde(rename_all = "lowercase")]
242#[strum(serialize_all = "lowercase")]
243pub enum OpenAiReasoningEffort {
244 Minimal,
245 Low,
246 Medium,
247 High,
248 XHigh,
249}
250
251#[with_fallible_options]
252#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
253pub struct OpenAiCompatibleSettingsContent {
254 pub api_url: String,
255 pub available_models: Vec<OpenAiCompatibleAvailableModel>,
256}
257
258#[with_fallible_options]
259#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
260pub struct OpenAiModelCapabilities {
261 #[serde(default = "default_true")]
262 pub chat_completions: bool,
263}
264
265impl Default for OpenAiModelCapabilities {
266 fn default() -> Self {
267 Self {
268 chat_completions: default_true(),
269 }
270 }
271}
272
273#[with_fallible_options]
274#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
275pub struct OpenAiCompatibleAvailableModel {
276 pub name: String,
277 pub display_name: Option<String>,
278 pub max_tokens: u64,
279 pub max_output_tokens: Option<u64>,
280 pub max_completion_tokens: Option<u64>,
281 pub reasoning_effort: Option<OpenAiReasoningEffort>,
282 #[serde(default)]
283 pub capabilities: OpenAiCompatibleModelCapabilities,
284}
285
286#[with_fallible_options]
287#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
288pub struct OpenAiCompatibleModelCapabilities {
289 pub tools: bool,
290 pub images: bool,
291 pub parallel_tool_calls: bool,
292 pub prompt_cache_key: bool,
293 #[serde(default = "default_true")]
294 pub chat_completions: bool,
295}
296
297impl Default for OpenAiCompatibleModelCapabilities {
298 fn default() -> Self {
299 Self {
300 tools: true,
301 images: false,
302 parallel_tool_calls: false,
303 prompt_cache_key: false,
304 chat_completions: default_true(),
305 }
306 }
307}
308
309#[with_fallible_options]
310#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
311pub struct VercelSettingsContent {
312 pub api_url: Option<String>,
313 pub available_models: Option<Vec<VercelAvailableModel>>,
314}
315
316#[with_fallible_options]
317#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
318pub struct VercelAvailableModel {
319 pub name: String,
320 pub display_name: Option<String>,
321 pub max_tokens: u64,
322 pub max_output_tokens: Option<u64>,
323 pub max_completion_tokens: Option<u64>,
324}
325
326#[with_fallible_options]
327#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
328pub struct VercelAiGatewaySettingsContent {
329 pub api_url: Option<String>,
330 pub available_models: Option<Vec<VercelAiGatewayAvailableModel>>,
331}
332
333#[with_fallible_options]
334#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
335pub struct VercelAiGatewayAvailableModel {
336 pub name: String,
337 pub display_name: Option<String>,
338 pub max_tokens: u64,
339 pub max_output_tokens: Option<u64>,
340 pub max_completion_tokens: Option<u64>,
341 #[serde(default)]
342 pub capabilities: OpenAiCompatibleModelCapabilities,
343}
344
345#[with_fallible_options]
346#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
347pub struct GoogleSettingsContent {
348 pub api_url: Option<String>,
349 pub available_models: Option<Vec<GoogleAvailableModel>>,
350}
351
352#[with_fallible_options]
353#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
354pub struct GoogleAvailableModel {
355 pub name: String,
356 pub display_name: Option<String>,
357 pub max_tokens: u64,
358 pub mode: Option<ModelMode>,
359}
360
361#[with_fallible_options]
362#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
363pub struct XAiSettingsContent {
364 pub api_url: Option<String>,
365 pub available_models: Option<Vec<XaiAvailableModel>>,
366}
367
368#[with_fallible_options]
369#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
370pub struct XaiAvailableModel {
371 pub name: String,
372 pub display_name: Option<String>,
373 pub max_tokens: u64,
374 pub max_output_tokens: Option<u64>,
375 pub max_completion_tokens: Option<u64>,
376 pub supports_images: Option<bool>,
377 pub supports_tools: Option<bool>,
378 pub parallel_tool_calls: Option<bool>,
379}
380
381#[with_fallible_options]
382#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
383pub struct ZedDotDevSettingsContent {
384 pub available_models: Option<Vec<ZedDotDevAvailableModel>>,
385}
386
387#[with_fallible_options]
388#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
389pub struct ZedDotDevAvailableModel {
390 /// The provider of the language model.
391 pub provider: ZedDotDevAvailableProvider,
392 /// The model's name in the provider's API. e.g. claude-3-5-sonnet-20240620
393 pub name: String,
394 /// The name displayed in the UI, such as in the assistant panel model dropdown menu.
395 pub display_name: Option<String>,
396 /// The size of the context window, indicating the maximum number of tokens the model can process.
397 pub max_tokens: usize,
398 /// The maximum number of output tokens allowed by the model.
399 pub max_output_tokens: Option<u64>,
400 /// The maximum number of completion tokens allowed by the model (o1-* only)
401 pub max_completion_tokens: Option<u64>,
402 /// Override this model with a different Anthropic model for tool calls.
403 pub tool_override: Option<String>,
404 /// Indicates whether this custom model supports caching.
405 pub cache_configuration: Option<LanguageModelCacheConfiguration>,
406 /// The default temperature to use for this model.
407 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
408 pub default_temperature: Option<f32>,
409 /// Any extra beta headers to provide when using the model.
410 #[serde(default)]
411 pub extra_beta_headers: Vec<String>,
412 /// The model's mode (e.g. thinking)
413 pub mode: Option<ModelMode>,
414}
415
416#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
417#[serde(rename_all = "lowercase")]
418pub enum ZedDotDevAvailableProvider {
419 Anthropic,
420 OpenAi,
421 Google,
422}
423
424#[with_fallible_options]
425#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
426pub struct OpenRouterSettingsContent {
427 pub api_url: Option<String>,
428 pub available_models: Option<Vec<OpenRouterAvailableModel>>,
429}
430
431#[with_fallible_options]
432#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
433pub struct OpenRouterAvailableModel {
434 pub name: String,
435 pub display_name: Option<String>,
436 pub max_tokens: u64,
437 pub max_output_tokens: Option<u64>,
438 pub max_completion_tokens: Option<u64>,
439 pub supports_tools: Option<bool>,
440 pub supports_images: Option<bool>,
441 pub mode: Option<ModelMode>,
442 pub provider: Option<OpenRouterProvider>,
443}
444
445#[with_fallible_options]
446#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
447pub struct OpenRouterProvider {
448 order: Option<Vec<String>>,
449 #[serde(default = "default_true")]
450 allow_fallbacks: bool,
451 #[serde(default)]
452 require_parameters: bool,
453 #[serde(default)]
454 data_collection: DataCollection,
455 only: Option<Vec<String>>,
456 ignore: Option<Vec<String>>,
457 quantizations: Option<Vec<String>>,
458 sort: Option<String>,
459}
460
461#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
462#[serde(rename_all = "lowercase")]
463pub enum DataCollection {
464 #[default]
465 Allow,
466 Disallow,
467}
468
469fn default_true() -> bool {
470 true
471}
472
473/// Configuration for caching language model messages.
474#[with_fallible_options]
475#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
476pub struct LanguageModelCacheConfiguration {
477 pub max_cache_anchors: usize,
478 pub should_speculate: bool,
479 pub min_total_token: u64,
480}
481
482#[derive(
483 Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom,
484)]
485#[serde(tag = "type", rename_all = "lowercase")]
486pub enum ModelMode {
487 #[default]
488 Default,
489 Thinking {
490 /// The maximum number of tokens to use for reasoning. Must be lower than the model's `max_output_tokens`.
491 budget_tokens: Option<u32>,
492 },
493}