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}