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