settings.rs

  1use std::time::Duration;
  2
  3use anyhow::Result;
  4use gpui::AppContext;
  5use schemars::JsonSchema;
  6use serde::{Deserialize, Serialize};
  7use settings::{Settings, SettingsSources};
  8
  9use crate::provider::{
 10    anthropic::AnthropicSettings,
 11    cloud::{self, ZedDotDevSettings},
 12    copilot_chat::CopilotChatSettings,
 13    google::GoogleSettings,
 14    ollama::OllamaSettings,
 15    open_ai::OpenAiSettings,
 16};
 17
 18/// Initializes the language model settings.
 19pub fn init(cx: &mut AppContext) {
 20    AllLanguageModelSettings::register(cx);
 21}
 22
 23#[derive(Default)]
 24pub struct AllLanguageModelSettings {
 25    pub anthropic: AnthropicSettings,
 26    pub ollama: OllamaSettings,
 27    pub openai: OpenAiSettings,
 28    pub zed_dot_dev: ZedDotDevSettings,
 29    pub google: GoogleSettings,
 30    pub copilot_chat: CopilotChatSettings,
 31}
 32
 33#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 34pub struct AllLanguageModelSettingsContent {
 35    pub anthropic: Option<AnthropicSettingsContent>,
 36    pub ollama: Option<OllamaSettingsContent>,
 37    pub openai: Option<OpenAiSettingsContent>,
 38    #[serde(rename = "zed.dev")]
 39    pub zed_dot_dev: Option<ZedDotDevSettingsContent>,
 40    pub google: Option<GoogleSettingsContent>,
 41    pub copilot_chat: Option<CopilotChatSettingsContent>,
 42}
 43
 44#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 45pub struct AnthropicSettingsContent {
 46    pub api_url: Option<String>,
 47    pub low_speed_timeout_in_seconds: Option<u64>,
 48    pub available_models: Option<Vec<anthropic::Model>>,
 49}
 50
 51#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 52pub struct OllamaSettingsContent {
 53    pub api_url: Option<String>,
 54    pub low_speed_timeout_in_seconds: Option<u64>,
 55}
 56
 57#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 58pub struct OpenAiSettingsContent {
 59    pub api_url: Option<String>,
 60    pub low_speed_timeout_in_seconds: Option<u64>,
 61    pub available_models: Option<Vec<open_ai::Model>>,
 62}
 63
 64#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 65pub struct GoogleSettingsContent {
 66    pub api_url: Option<String>,
 67    pub low_speed_timeout_in_seconds: Option<u64>,
 68    pub available_models: Option<Vec<google_ai::Model>>,
 69}
 70
 71#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 72pub struct ZedDotDevSettingsContent {
 73    available_models: Option<Vec<cloud::AvailableModel>>,
 74}
 75
 76#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
 77pub struct CopilotChatSettingsContent {
 78    low_speed_timeout_in_seconds: Option<u64>,
 79}
 80
 81impl settings::Settings for AllLanguageModelSettings {
 82    const KEY: Option<&'static str> = Some("language_models");
 83
 84    type FileContent = AllLanguageModelSettingsContent;
 85
 86    fn load(sources: SettingsSources<Self::FileContent>, _: &mut AppContext) -> Result<Self> {
 87        fn merge<T>(target: &mut T, value: Option<T>) {
 88            if let Some(value) = value {
 89                *target = value;
 90            }
 91        }
 92
 93        let mut settings = AllLanguageModelSettings::default();
 94
 95        for value in sources.defaults_and_customizations() {
 96            merge(
 97                &mut settings.anthropic.api_url,
 98                value.anthropic.as_ref().and_then(|s| s.api_url.clone()),
 99            );
100            if let Some(low_speed_timeout_in_seconds) = value
101                .anthropic
102                .as_ref()
103                .and_then(|s| s.low_speed_timeout_in_seconds)
104            {
105                settings.anthropic.low_speed_timeout =
106                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
107            }
108            merge(
109                &mut settings.anthropic.available_models,
110                value
111                    .anthropic
112                    .as_ref()
113                    .and_then(|s| s.available_models.clone()),
114            );
115
116            merge(
117                &mut settings.ollama.api_url,
118                value.ollama.as_ref().and_then(|s| s.api_url.clone()),
119            );
120            if let Some(low_speed_timeout_in_seconds) = value
121                .ollama
122                .as_ref()
123                .and_then(|s| s.low_speed_timeout_in_seconds)
124            {
125                settings.ollama.low_speed_timeout =
126                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
127            }
128
129            merge(
130                &mut settings.openai.api_url,
131                value.openai.as_ref().and_then(|s| s.api_url.clone()),
132            );
133            if let Some(low_speed_timeout_in_seconds) = value
134                .openai
135                .as_ref()
136                .and_then(|s| s.low_speed_timeout_in_seconds)
137            {
138                settings.openai.low_speed_timeout =
139                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
140            }
141            merge(
142                &mut settings.openai.available_models,
143                value
144                    .openai
145                    .as_ref()
146                    .and_then(|s| s.available_models.clone()),
147            );
148
149            merge(
150                &mut settings.zed_dot_dev.available_models,
151                value
152                    .zed_dot_dev
153                    .as_ref()
154                    .and_then(|s| s.available_models.clone()),
155            );
156
157            merge(
158                &mut settings.google.api_url,
159                value.google.as_ref().and_then(|s| s.api_url.clone()),
160            );
161            if let Some(low_speed_timeout_in_seconds) = value
162                .google
163                .as_ref()
164                .and_then(|s| s.low_speed_timeout_in_seconds)
165            {
166                settings.google.low_speed_timeout =
167                    Some(Duration::from_secs(low_speed_timeout_in_seconds));
168            }
169            merge(
170                &mut settings.google.available_models,
171                value
172                    .google
173                    .as_ref()
174                    .and_then(|s| s.available_models.clone()),
175            );
176
177            if let Some(low_speed_timeout) = value
178                .copilot_chat
179                .as_ref()
180                .and_then(|s| s.low_speed_timeout_in_seconds)
181            {
182                settings.copilot_chat.low_speed_timeout =
183                    Some(Duration::from_secs(low_speed_timeout));
184            }
185        }
186
187        Ok(settings)
188    }
189}