settings.rs

  1use anyhow::Result;
  2use gpui::App;
  3use schemars::JsonSchema;
  4use serde::{Deserialize, Serialize};
  5use settings::{Settings, SettingsSources};
  6
  7use crate::provider::{
  8    self,
  9    anthropic::AnthropicSettings,
 10    bedrock::AmazonBedrockSettings,
 11    cloud::{self, ZedDotDevSettings},
 12    deepseek::DeepSeekSettings,
 13    google::GoogleSettings,
 14    lmstudio::LmStudioSettings,
 15    mistral::MistralSettings,
 16    ollama::OllamaSettings,
 17    open_ai::OpenAiSettings,
 18    open_router::OpenRouterSettings,
 19    vercel::VercelSettings,
 20};
 21
 22/// Initializes the language model settings.
 23pub fn init(cx: &mut App) {
 24    AllLanguageModelSettings::register(cx);
 25}
 26
 27#[derive(Default)]
 28pub struct AllLanguageModelSettings {
 29    pub anthropic: AnthropicSettings,
 30    pub bedrock: AmazonBedrockSettings,
 31    pub ollama: OllamaSettings,
 32    pub openai: OpenAiSettings,
 33    pub open_router: OpenRouterSettings,
 34    pub zed_dot_dev: ZedDotDevSettings,
 35    pub google: GoogleSettings,
 36    pub vercel: VercelSettings,
 37
 38    pub lmstudio: LmStudioSettings,
 39    pub deepseek: DeepSeekSettings,
 40    pub mistral: MistralSettings,
 41}
 42
 43#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 44pub struct AllLanguageModelSettingsContent {
 45    pub anthropic: Option<AnthropicSettingsContent>,
 46    pub bedrock: Option<AmazonBedrockSettingsContent>,
 47    pub ollama: Option<OllamaSettingsContent>,
 48    pub lmstudio: Option<LmStudioSettingsContent>,
 49    pub openai: Option<OpenAiSettingsContent>,
 50    pub open_router: Option<OpenRouterSettingsContent>,
 51    #[serde(rename = "zed.dev")]
 52    pub zed_dot_dev: Option<ZedDotDevSettingsContent>,
 53    pub google: Option<GoogleSettingsContent>,
 54    pub deepseek: Option<DeepseekSettingsContent>,
 55    pub vercel: Option<VercelSettingsContent>,
 56
 57    pub mistral: Option<MistralSettingsContent>,
 58}
 59
 60#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 61pub struct AnthropicSettingsContent {
 62    pub api_url: Option<String>,
 63    pub available_models: Option<Vec<provider::anthropic::AvailableModel>>,
 64}
 65
 66#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 67pub struct AmazonBedrockSettingsContent {
 68    available_models: Option<Vec<provider::bedrock::AvailableModel>>,
 69    endpoint_url: Option<String>,
 70    region: Option<String>,
 71    profile: Option<String>,
 72    authentication_method: Option<provider::bedrock::BedrockAuthMethod>,
 73}
 74
 75#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 76pub struct OllamaSettingsContent {
 77    pub api_url: Option<String>,
 78    pub available_models: Option<Vec<provider::ollama::AvailableModel>>,
 79}
 80
 81#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 82pub struct LmStudioSettingsContent {
 83    pub api_url: Option<String>,
 84    pub available_models: Option<Vec<provider::lmstudio::AvailableModel>>,
 85}
 86
 87#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 88pub struct DeepseekSettingsContent {
 89    pub api_url: Option<String>,
 90    pub available_models: Option<Vec<provider::deepseek::AvailableModel>>,
 91}
 92
 93#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 94pub struct MistralSettingsContent {
 95    pub api_url: Option<String>,
 96    pub available_models: Option<Vec<provider::mistral::AvailableModel>>,
 97}
 98
 99#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
100pub struct OpenAiSettingsContent {
101    pub api_url: Option<String>,
102    pub available_models: Option<Vec<provider::open_ai::AvailableModel>>,
103}
104
105#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
106pub struct VercelSettingsContent {
107    pub api_url: Option<String>,
108    pub available_models: Option<Vec<provider::vercel::AvailableModel>>,
109}
110
111#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
112pub struct GoogleSettingsContent {
113    pub api_url: Option<String>,
114    pub available_models: Option<Vec<provider::google::AvailableModel>>,
115}
116
117#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
118pub struct ZedDotDevSettingsContent {
119    available_models: Option<Vec<cloud::AvailableModel>>,
120}
121
122#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
123pub struct OpenRouterSettingsContent {
124    pub api_url: Option<String>,
125    pub available_models: Option<Vec<provider::open_router::AvailableModel>>,
126}
127
128impl settings::Settings for AllLanguageModelSettings {
129    const KEY: Option<&'static str> = Some("language_models");
130
131    const PRESERVED_KEYS: Option<&'static [&'static str]> = Some(&["version"]);
132
133    type FileContent = AllLanguageModelSettingsContent;
134
135    fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
136        fn merge<T>(target: &mut T, value: Option<T>) {
137            if let Some(value) = value {
138                *target = value;
139            }
140        }
141
142        let mut settings = AllLanguageModelSettings::default();
143
144        for value in sources.defaults_and_customizations() {
145            // Anthropic
146            let anthropic = value.anthropic.clone();
147            merge(
148                &mut settings.anthropic.api_url,
149                anthropic.as_ref().and_then(|s| s.api_url.clone()),
150            );
151            merge(
152                &mut settings.anthropic.available_models,
153                anthropic.as_ref().and_then(|s| s.available_models.clone()),
154            );
155
156            // Bedrock
157            let bedrock = value.bedrock.clone();
158            merge(
159                &mut settings.bedrock.profile_name,
160                bedrock.as_ref().map(|s| s.profile.clone()),
161            );
162            merge(
163                &mut settings.bedrock.authentication_method,
164                bedrock.as_ref().map(|s| s.authentication_method.clone()),
165            );
166            merge(
167                &mut settings.bedrock.region,
168                bedrock.as_ref().map(|s| s.region.clone()),
169            );
170            merge(
171                &mut settings.bedrock.endpoint,
172                bedrock.as_ref().map(|s| s.endpoint_url.clone()),
173            );
174
175            // Ollama
176            let ollama = value.ollama.clone();
177
178            merge(
179                &mut settings.ollama.api_url,
180                value.ollama.as_ref().and_then(|s| s.api_url.clone()),
181            );
182            merge(
183                &mut settings.ollama.available_models,
184                ollama.as_ref().and_then(|s| s.available_models.clone()),
185            );
186
187            // LM Studio
188            let lmstudio = value.lmstudio.clone();
189
190            merge(
191                &mut settings.lmstudio.api_url,
192                value.lmstudio.as_ref().and_then(|s| s.api_url.clone()),
193            );
194            merge(
195                &mut settings.lmstudio.available_models,
196                lmstudio.as_ref().and_then(|s| s.available_models.clone()),
197            );
198
199            // DeepSeek
200            let deepseek = value.deepseek.clone();
201
202            merge(
203                &mut settings.deepseek.api_url,
204                value.deepseek.as_ref().and_then(|s| s.api_url.clone()),
205            );
206            merge(
207                &mut settings.deepseek.available_models,
208                deepseek.as_ref().and_then(|s| s.available_models.clone()),
209            );
210
211            // OpenAI
212            let openai = value.openai.clone();
213            merge(
214                &mut settings.openai.api_url,
215                openai.as_ref().and_then(|s| s.api_url.clone()),
216            );
217            merge(
218                &mut settings.openai.available_models,
219                openai.as_ref().and_then(|s| s.available_models.clone()),
220            );
221
222            // Vercel
223            let vercel = value.vercel.clone();
224            merge(
225                &mut settings.vercel.api_url,
226                vercel.as_ref().and_then(|s| s.api_url.clone()),
227            );
228            merge(
229                &mut settings.vercel.available_models,
230                vercel.as_ref().and_then(|s| s.available_models.clone()),
231            );
232
233            merge(
234                &mut settings.zed_dot_dev.available_models,
235                value
236                    .zed_dot_dev
237                    .as_ref()
238                    .and_then(|s| s.available_models.clone()),
239            );
240            merge(
241                &mut settings.google.api_url,
242                value.google.as_ref().and_then(|s| s.api_url.clone()),
243            );
244            merge(
245                &mut settings.google.available_models,
246                value
247                    .google
248                    .as_ref()
249                    .and_then(|s| s.available_models.clone()),
250            );
251
252            // Mistral
253            let mistral = value.mistral.clone();
254            merge(
255                &mut settings.mistral.api_url,
256                mistral.as_ref().and_then(|s| s.api_url.clone()),
257            );
258            merge(
259                &mut settings.mistral.available_models,
260                mistral.as_ref().and_then(|s| s.available_models.clone()),
261            );
262
263            // OpenRouter
264            let open_router = value.open_router.clone();
265            merge(
266                &mut settings.open_router.api_url,
267                open_router.as_ref().and_then(|s| s.api_url.clone()),
268            );
269            merge(
270                &mut settings.open_router.available_models,
271                open_router
272                    .as_ref()
273                    .and_then(|s| s.available_models.clone()),
274            );
275        }
276
277        Ok(settings)
278    }
279
280    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
281}