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