settings.rs

  1use std::time::Duration;
  2
  3use anyhow::Result;
  4use gpui::AppContext;
  5use schemars::JsonSchema;
  6use serde::{Deserialize, Serialize};
  7use settings::{Settings, SettingsSources};
  8
  9use crate::provider::{
 10    anthropic::AnthropicSettings,
 11    cloud::{self, ZedDotDevSettings},
 12    google::GoogleSettings,
 13    ollama::OllamaSettings,
 14    open_ai::OpenAiSettings,
 15};
 16
 17/// Initializes the language model settings.
 18pub fn init(cx: &mut AppContext) {
 19    AllLanguageModelSettings::register(cx);
 20}
 21
 22#[derive(Default)]
 23pub struct AllLanguageModelSettings {
 24    pub anthropic: AnthropicSettings,
 25    pub ollama: OllamaSettings,
 26    pub openai: OpenAiSettings,
 27    pub zed_dot_dev: ZedDotDevSettings,
 28    pub google: GoogleSettings,
 29}
 30
 31#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 32pub struct AllLanguageModelSettingsContent {
 33    pub anthropic: Option<AnthropicSettingsContent>,
 34    pub ollama: Option<OllamaSettingsContent>,
 35    pub openai: Option<OpenAiSettingsContent>,
 36    #[serde(rename = "zed.dev")]
 37    pub zed_dot_dev: Option<ZedDotDevSettingsContent>,
 38    pub google: Option<GoogleSettingsContent>,
 39}
 40
 41#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 42pub struct AnthropicSettingsContent {
 43    pub api_url: Option<String>,
 44    pub low_speed_timeout_in_seconds: Option<u64>,
 45    pub available_models: Option<Vec<anthropic::Model>>,
 46}
 47
 48#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 49pub struct OllamaSettingsContent {
 50    pub api_url: Option<String>,
 51    pub low_speed_timeout_in_seconds: Option<u64>,
 52}
 53
 54#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 55pub struct OpenAiSettingsContent {
 56    pub api_url: Option<String>,
 57    pub low_speed_timeout_in_seconds: Option<u64>,
 58    pub available_models: Option<Vec<open_ai::Model>>,
 59}
 60
 61#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 62pub struct GoogleSettingsContent {
 63    pub api_url: Option<String>,
 64    pub low_speed_timeout_in_seconds: Option<u64>,
 65    pub available_models: Option<Vec<google_ai::Model>>,
 66}
 67
 68#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 69pub struct ZedDotDevSettingsContent {
 70    available_models: Option<Vec<cloud::AvailableModel>>,
 71}
 72
 73impl settings::Settings for AllLanguageModelSettings {
 74    const KEY: Option<&'static str> = Some("language_models");
 75
 76    type FileContent = AllLanguageModelSettingsContent;
 77
 78    fn load(sources: SettingsSources<Self::FileContent>, _: &mut AppContext) -> Result<Self> {
 79        fn merge<T>(target: &mut T, value: Option<T>) {
 80            if let Some(value) = value {
 81                *target = value;
 82            }
 83        }
 84
 85        let mut settings = AllLanguageModelSettings::default();
 86
 87        for value in sources.defaults_and_customizations() {
 88            merge(
 89                &mut settings.anthropic.api_url,
 90                value.anthropic.as_ref().and_then(|s| s.api_url.clone()),
 91            );
 92            if let Some(low_speed_timeout_in_seconds) = value
 93                .anthropic
 94                .as_ref()
 95                .and_then(|s| s.low_speed_timeout_in_seconds)
 96            {
 97                settings.anthropic.low_speed_timeout =
 98                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
 99            }
100            merge(
101                &mut settings.anthropic.available_models,
102                value
103                    .anthropic
104                    .as_ref()
105                    .and_then(|s| s.available_models.clone()),
106            );
107
108            merge(
109                &mut settings.ollama.api_url,
110                value.ollama.as_ref().and_then(|s| s.api_url.clone()),
111            );
112            if let Some(low_speed_timeout_in_seconds) = value
113                .ollama
114                .as_ref()
115                .and_then(|s| s.low_speed_timeout_in_seconds)
116            {
117                settings.ollama.low_speed_timeout =
118                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
119            }
120
121            merge(
122                &mut settings.openai.api_url,
123                value.openai.as_ref().and_then(|s| s.api_url.clone()),
124            );
125            if let Some(low_speed_timeout_in_seconds) = value
126                .openai
127                .as_ref()
128                .and_then(|s| s.low_speed_timeout_in_seconds)
129            {
130                settings.openai.low_speed_timeout =
131                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
132            }
133            merge(
134                &mut settings.openai.available_models,
135                value
136                    .openai
137                    .as_ref()
138                    .and_then(|s| s.available_models.clone()),
139            );
140
141            merge(
142                &mut settings.zed_dot_dev.available_models,
143                value
144                    .zed_dot_dev
145                    .as_ref()
146                    .and_then(|s| s.available_models.clone()),
147            );
148
149            merge(
150                &mut settings.google.api_url,
151                value.google.as_ref().and_then(|s| s.api_url.clone()),
152            );
153            if let Some(low_speed_timeout_in_seconds) = value
154                .google
155                .as_ref()
156                .and_then(|s| s.low_speed_timeout_in_seconds)
157            {
158                settings.google.low_speed_timeout =
159                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
160            }
161            merge(
162                &mut settings.google.available_models,
163                value
164                    .google
165                    .as_ref()
166                    .and_then(|s| s.available_models.clone()),
167            );
168        }
169
170        Ok(settings)
171    }
172}