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 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}