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