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