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}