language_model.rs

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