settings.rs

  1use std::sync::Arc;
  2
  3use collections::HashMap;
  4use gpui::App;
  5use settings::Settings;
  6use util::MergeFrom;
  7
  8use crate::provider::{
  9    anthropic::AnthropicSettings, bedrock::AmazonBedrockSettings, cloud::ZedDotDevSettings,
 10    deepseek::DeepSeekSettings, google::GoogleSettings, lmstudio::LmStudioSettings,
 11    mistral::MistralSettings, ollama::OllamaSettings, open_ai::OpenAiSettings,
 12    open_ai_compatible::OpenAiCompatibleSettings, open_router::OpenRouterSettings,
 13    vercel::VercelSettings, x_ai::XAiSettings,
 14};
 15
 16/// Initializes the language model settings.
 17pub fn init_settings(cx: &mut App) {
 18    AllLanguageModelSettings::register(cx);
 19}
 20
 21pub struct AllLanguageModelSettings {
 22    pub anthropic: AnthropicSettings,
 23    pub bedrock: AmazonBedrockSettings,
 24    pub deepseek: DeepSeekSettings,
 25    pub google: GoogleSettings,
 26    pub lmstudio: LmStudioSettings,
 27    pub mistral: MistralSettings,
 28    pub ollama: OllamaSettings,
 29    pub open_router: OpenRouterSettings,
 30    pub openai: OpenAiSettings,
 31    pub openai_compatible: HashMap<Arc<str>, OpenAiCompatibleSettings>,
 32    pub vercel: VercelSettings,
 33    pub x_ai: XAiSettings,
 34    pub zed_dot_dev: ZedDotDevSettings,
 35}
 36
 37impl settings::Settings for AllLanguageModelSettings {
 38    const PRESERVED_KEYS: Option<&'static [&'static str]> = Some(&["version"]);
 39
 40    fn from_defaults(content: &settings::SettingsContent, _cx: &mut App) -> Self {
 41        let language_models = content.language_models.clone().unwrap();
 42        let anthropic = language_models.anthropic.unwrap();
 43        let bedrock = language_models.bedrock.unwrap();
 44        let deepseek = language_models.deepseek.unwrap();
 45        let google = language_models.google.unwrap();
 46        let lmstudio = language_models.lmstudio.unwrap();
 47        let mistral = language_models.mistral.unwrap();
 48        let ollama = language_models.ollama.unwrap();
 49        let open_router = language_models.open_router.unwrap();
 50        let openai = language_models.openai.unwrap();
 51        let openai_compatible = language_models.openai_compatible.unwrap();
 52        let vercel = language_models.vercel.unwrap();
 53        let x_ai = language_models.x_ai.unwrap();
 54        let zed_dot_dev = language_models.zed_dot_dev.unwrap();
 55        Self {
 56            anthropic: AnthropicSettings {
 57                api_url: anthropic.api_url.unwrap(),
 58                available_models: anthropic.available_models.unwrap_or_default(),
 59            },
 60            bedrock: AmazonBedrockSettings {
 61                available_models: bedrock.available_models.unwrap_or_default(),
 62                region: bedrock.region,
 63                endpoint: bedrock.endpoint_url, // todo(should be api_url)
 64                profile_name: bedrock.profile,
 65                role_arn: None, // todo(was never a setting for this...)
 66                authentication_method: bedrock.authentication_method.map(Into::into),
 67            },
 68            deepseek: DeepSeekSettings {
 69                api_url: deepseek.api_url.unwrap(),
 70                available_models: deepseek.available_models.unwrap_or_default(),
 71            },
 72            google: GoogleSettings {
 73                api_url: google.api_url.unwrap(),
 74                available_models: google.available_models.unwrap_or_default(),
 75            },
 76            lmstudio: LmStudioSettings {
 77                api_url: lmstudio.api_url.unwrap(),
 78                available_models: lmstudio.available_models.unwrap_or_default(),
 79            },
 80            mistral: MistralSettings {
 81                api_url: mistral.api_url.unwrap(),
 82                available_models: mistral.available_models.unwrap_or_default(),
 83            },
 84            ollama: OllamaSettings {
 85                api_url: ollama.api_url.unwrap(),
 86                available_models: ollama.available_models.unwrap_or_default(),
 87            },
 88            open_router: OpenRouterSettings {
 89                api_url: open_router.api_url.unwrap(),
 90                available_models: open_router.available_models.unwrap_or_default(),
 91            },
 92            openai: OpenAiSettings {
 93                api_url: openai.api_url.unwrap(),
 94                available_models: openai.available_models.unwrap_or_default(),
 95            },
 96            openai_compatible: openai_compatible
 97                .into_iter()
 98                .map(|(key, value)| {
 99                    (
100                        key,
101                        OpenAiCompatibleSettings {
102                            api_url: value.api_url,
103                            available_models: value.available_models,
104                        },
105                    )
106                })
107                .collect(),
108            vercel: VercelSettings {
109                api_url: vercel.api_url.unwrap(),
110                available_models: vercel.available_models.unwrap_or_default(),
111            },
112            x_ai: XAiSettings {
113                api_url: x_ai.api_url.unwrap(),
114                available_models: x_ai.available_models.unwrap_or_default(),
115            },
116            zed_dot_dev: ZedDotDevSettings {
117                available_models: zed_dot_dev.available_models.unwrap_or_default(),
118            },
119        }
120    }
121
122    fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut App) {
123        let Some(models) = content.language_models.as_ref() else {
124            return;
125        };
126
127        if let Some(anthropic) = models.anthropic.as_ref() {
128            self.anthropic
129                .available_models
130                .merge_from(&anthropic.available_models);
131            self.anthropic.api_url.merge_from(&anthropic.api_url);
132        }
133
134        if let Some(bedrock) = models.bedrock.clone() {
135            self.bedrock
136                .available_models
137                .merge_from(&bedrock.available_models);
138
139            if let Some(endpoint_url) = bedrock.endpoint_url {
140                self.bedrock.endpoint = Some(endpoint_url)
141            }
142
143            if let Some(region) = bedrock.region {
144                self.bedrock.region = Some(region)
145            }
146
147            if let Some(profile_name) = bedrock.profile {
148                self.bedrock.profile_name = Some(profile_name);
149            }
150
151            if let Some(auth_method) = bedrock.authentication_method {
152                self.bedrock.authentication_method = Some(auth_method.into());
153            }
154        }
155
156        if let Some(deepseek) = models.deepseek.as_ref() {
157            self.deepseek
158                .available_models
159                .merge_from(&deepseek.available_models);
160            self.deepseek.api_url.merge_from(&deepseek.api_url);
161        }
162
163        if let Some(google) = models.google.as_ref() {
164            self.google
165                .available_models
166                .merge_from(&google.available_models);
167            self.google.api_url.merge_from(&google.api_url);
168        }
169
170        if let Some(lmstudio) = models.lmstudio.as_ref() {
171            self.lmstudio
172                .available_models
173                .merge_from(&lmstudio.available_models);
174            self.lmstudio.api_url.merge_from(&lmstudio.api_url);
175        }
176
177        if let Some(mistral) = models.mistral.as_ref() {
178            self.mistral
179                .available_models
180                .merge_from(&mistral.available_models);
181            self.mistral.api_url.merge_from(&mistral.api_url);
182        }
183        if let Some(ollama) = models.ollama.as_ref() {
184            self.ollama
185                .available_models
186                .merge_from(&ollama.available_models);
187            self.ollama.api_url.merge_from(&ollama.api_url);
188        }
189        if let Some(open_router) = models.open_router.as_ref() {
190            self.open_router
191                .available_models
192                .merge_from(&open_router.available_models);
193            self.open_router.api_url.merge_from(&open_router.api_url);
194        }
195        if let Some(openai) = models.openai.as_ref() {
196            self.openai
197                .available_models
198                .merge_from(&openai.available_models);
199            self.openai.api_url.merge_from(&openai.api_url);
200        }
201        if let Some(openai_compatible) = models.openai_compatible.clone() {
202            for (name, value) in openai_compatible {
203                self.openai_compatible.insert(
204                    name,
205                    OpenAiCompatibleSettings {
206                        api_url: value.api_url,
207                        available_models: value.available_models,
208                    },
209                );
210            }
211        }
212        if let Some(vercel) = models.vercel.as_ref() {
213            self.vercel
214                .available_models
215                .merge_from(&vercel.available_models);
216            self.vercel.api_url.merge_from(&vercel.api_url);
217        }
218        if let Some(x_ai) = models.x_ai.as_ref() {
219            self.x_ai
220                .available_models
221                .merge_from(&x_ai.available_models);
222            self.x_ai.api_url.merge_from(&x_ai.api_url);
223        }
224        if let Some(zed_dot_dev) = models.zed_dot_dev.as_ref() {
225            self.zed_dot_dev
226                .available_models
227                .merge_from(&zed_dot_dev.available_models);
228        }
229    }
230}