Download codex-rs/app-server/src/config_manager.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 15.8 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/app-server/src/config_manager.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/app-server/src/config_manager.rs
-
curl -L -o config_manager.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/app-server/src/config_manager.rs
15.8 kB
| use codex_arg0::Arg0DispatchPaths; | |
| use codex_cloud_config::cloud_config_bundle_loader; | |
| use codex_config::CloudConfigBundleLoader; | |
| use codex_config::ConfigLayerStack; | |
| use codex_config::LoaderOverrides; | |
| use codex_config::ThreadConfigLoader; | |
| use codex_config::loader::load_config_layers_state; | |
| use codex_config::loader::load_managed_requirements_state; | |
| use codex_core::config::Config; | |
| use codex_core::config::ConfigBuilder; | |
| use codex_core::config::ConfigOverrides; | |
| use codex_exec_server::LOCAL_FS; | |
| use codex_features::feature_for_key; | |
| use codex_login::AuthManager; | |
| use codex_login::default_client::set_default_client_residency_requirement; | |
| use codex_model_provider_info::AMAZON_BEDROCK_PROVIDER_ID; | |
| use codex_model_provider_info::AMAZON_BEDROCK_RUNTIME_PROVIDER_ID; | |
| use codex_model_provider_info::built_in_model_providers; | |
| use codex_model_provider_info::merge_configured_model_providers; | |
| use codex_utils_absolute_path::AbsolutePathBuf; | |
| use codex_utils_json_to_toml::json_to_toml; | |
| use std::collections::BTreeMap; | |
| use std::collections::BTreeSet; | |
| use std::collections::HashMap; | |
| use std::path::Path; | |
| use std::path::PathBuf; | |
| use std::sync::Arc; | |
| use std::sync::RwLock; | |
| use toml::Value as TomlValue; | |
| use tracing::instrument; | |
| use tracing::warn; | |
| pub(crate) struct ModelProviderRequirementsChanged; | |
| /// Shared app-server entry point for loading effective Codex configuration. | |
| pub(crate) struct ConfigManager { | |
| codex_home: PathBuf, | |
| cli_overrides: Arc<RwLock<Vec<(String, TomlValue)>>>, | |
| runtime_feature_enablement: Arc<RwLock<BTreeMap<String, bool>>>, | |
| loader_overrides: LoaderOverrides, | |
| strict_config: bool, | |
| cloud_config_bundle: Arc<RwLock<CloudConfigBundleLoader>>, | |
| arg0_paths: Arg0DispatchPaths, | |
| thread_config_loader: Arc<dyn ThreadConfigLoader>, | |
| } | |
| impl ConfigManager { | |
| pub(crate) fn new( | |
| codex_home: PathBuf, | |
| cli_overrides: Vec<(String, TomlValue)>, | |
| loader_overrides: LoaderOverrides, | |
| strict_config: bool, | |
| cloud_config_bundle: CloudConfigBundleLoader, | |
| arg0_paths: Arg0DispatchPaths, | |
| thread_config_loader: Arc<dyn ThreadConfigLoader>, | |
| ) -> Self { | |
| Self { | |
| codex_home, | |
| cli_overrides: Arc::new(RwLock::new(cli_overrides)), | |
| runtime_feature_enablement: Arc::new(RwLock::new(BTreeMap::new())), | |
| loader_overrides, | |
| strict_config, | |
| cloud_config_bundle: Arc::new(RwLock::new(cloud_config_bundle)), | |
| arg0_paths, | |
| thread_config_loader, | |
| } | |
| } | |
| pub(crate) fn codex_home(&self) -> &Path { | |
| self.codex_home.as_path() | |
| } | |
| pub(crate) fn user_config_path(&self) -> std::io::Result<AbsolutePathBuf> { | |
| self.loader_overrides.user_config_path(self.codex_home()) | |
| } | |
| pub(crate) fn current_cli_overrides(&self) -> Vec<(String, TomlValue)> { | |
| self.cli_overrides | |
| .read() | |
| .map(|guard| guard.clone()) | |
| .unwrap_or_default() | |
| } | |
| pub(crate) fn current_cloud_config_bundle(&self) -> CloudConfigBundleLoader { | |
| self.cloud_config_bundle | |
| .read() | |
| .map(|guard| guard.clone()) | |
| .unwrap_or_default() | |
| } | |
| pub(crate) fn extend_runtime_feature_enablement<I>(&self, enablement: I) -> Result<(), ()> | |
| where | |
| I: IntoIterator<Item = (String, bool)>, | |
| { | |
| let mut runtime_feature_enablement = | |
| self.runtime_feature_enablement.write().map_err(|_| ())?; | |
| runtime_feature_enablement.extend(enablement); | |
| Ok(()) | |
| } | |
| pub(crate) fn replace_cloud_config_bundle_loader( | |
| &self, | |
| auth_manager: Arc<AuthManager>, | |
| chatgpt_base_url: String, | |
| http_client_factory: codex_http_client::HttpClientFactory, | |
| ) { | |
| let loader = cloud_config_bundle_loader( | |
| auth_manager, | |
| chatgpt_base_url, | |
| self.codex_home.clone(), | |
| http_client_factory, | |
| ); | |
| if let Ok(mut guard) = self.cloud_config_bundle.write() { | |
| *guard = loader; | |
| } else { | |
| warn!("failed to update cloud config bundle loader"); | |
| } | |
| } | |
| pub(crate) fn clear_cloud_config_bundle_loader(&self) { | |
| if let Ok(mut guard) = self.cloud_config_bundle.write() { | |
| *guard = CloudConfigBundleLoader::default(); | |
| } else { | |
| warn!("failed to clear cloud config bundle loader"); | |
| } | |
| } | |
| pub(crate) async fn sync_default_client_residency_requirement(&self) { | |
| match self.load_latest_config(/*fallback_cwd*/ None).await { | |
| Ok(config) => { | |
| set_default_client_residency_requirement(config.enforce_residency.value()); | |
| } | |
| Err(err) => warn!( | |
| error = %err, | |
| "failed to sync default client residency requirement after auth refresh" | |
| ), | |
| } | |
| } | |
| pub(crate) async fn load_latest_config( | |
| &self, | |
| fallback_cwd: Option<PathBuf>, | |
| ) -> std::io::Result<Config> { | |
| self.load_with_cli_overrides( | |
| &self.current_cli_overrides(), | |
| /*request_overrides*/ None, | |
| ConfigOverrides::default(), | |
| fallback_cwd, | |
| ) | |
| .await | |
| } | |
| /// Loads system, user, and runtime settings without discovering a project | |
| /// from the app-server process's working directory. | |
| pub(crate) async fn load_non_project_config(&self) -> std::io::Result<Config> { | |
| let mut manager = self.clone(); | |
| manager.loader_overrides.ignore_project_config = true; | |
| manager.load_latest_config(/*fallback_cwd*/ None).await | |
| } | |
| pub(crate) async fn load_latest_config_with_session_layers( | |
| &self, | |
| session_layers: &ConfigLayerStack, | |
| cwd: &Path, | |
| ) -> std::io::Result<Config> { | |
| let refreshed_config = self.load_latest_config(Some(cwd.to_path_buf())).await?; | |
| let mut config = Config::rebuild_with_session_layers( | |
| session_layers, | |
| cwd.to_path_buf(), | |
| &refreshed_config, | |
| ) | |
| .await?; | |
| self.apply_runtime_feature_enablement(&mut config); | |
| self.apply_arg0_paths(&mut config); | |
| Ok(config) | |
| } | |
| /// Checks the retained session route against current managed provider requirements. | |
| pub(crate) async fn check_thread_model_provider( | |
| &self, | |
| current: &Config, | |
| ) -> std::io::Result<()> { | |
| // Existing threads retain their session route; only managed | |
| // requirements can invalidate it. | |
| let requirements = load_managed_requirements_state( | |
| LOCAL_FS.as_ref(), | |
| &self.codex_home, | |
| codex_config::ConfigLoadOptions { | |
| loader_overrides: self.loader_overrides.clone(), | |
| strict_config: self.strict_config, | |
| cloud_config_bundle: self.current_cloud_config_bundle(), | |
| }, | |
| ) | |
| .await?; | |
| let selection_changed = requirements | |
| .model_provider | |
| .as_ref() | |
| .is_some_and(|provider_id| provider_id != ¤t.model_provider_id); | |
| let required_provider = requirements | |
| .model_providers | |
| .as_ref() | |
| .and_then(|providers| providers.get(¤t.model_provider_id)) | |
| .cloned(); | |
| let required_provider = match required_provider { | |
| Some(provider) | |
| if matches!( | |
| current.model_provider_id.as_str(), | |
| AMAZON_BEDROCK_PROVIDER_ID | AMAZON_BEDROCK_RUNTIME_PROVIDER_ID | |
| ) => | |
| { | |
| // Bedrock requirements contain overrides of the built-in provider. | |
| merge_configured_model_providers( | |
| built_in_model_providers(/*openai_base_url*/ None), | |
| HashMap::from([(current.model_provider_id.clone(), provider)]), | |
| ) | |
| .map_err(|message| std::io::Error::new(std::io::ErrorKind::InvalidData, message))? | |
| .remove(¤t.model_provider_id) | |
| } | |
| Some(provider) => Some(provider), | |
| None => None, | |
| }; | |
| let definition_changed = required_provider | |
| .as_ref() | |
| .is_some_and(|provider| provider != ¤t.model_provider); | |
| if selection_changed || definition_changed { | |
| return Err(std::io::Error::new( | |
| std::io::ErrorKind::PermissionDenied, | |
| ModelProviderRequirementsChanged, | |
| )); | |
| } | |
| Ok(()) | |
| } | |
| pub(crate) async fn load_default_config(&self) -> std::io::Result<Config> { | |
| let mut loader_overrides = self.loader_overrides.clone(); | |
| loader_overrides.ignore_user_config = true; | |
| let mut config = ConfigBuilder::default() | |
| .codex_home(self.codex_home.clone()) | |
| .cli_overrides(self.current_cli_overrides()) | |
| .loader_overrides(loader_overrides) | |
| .fallback_cwd(Some(self.codex_home.clone())) | |
| .cloud_config_bundle(CloudConfigBundleLoader::default()) | |
| .build() | |
| .await?; | |
| self.apply_runtime_feature_enablement(&mut config); | |
| self.apply_arg0_paths(&mut config); | |
| Ok(config) | |
| } | |
| pub(crate) async fn load_with_overrides( | |
| &self, | |
| request_overrides: Option<HashMap<String, serde_json::Value>>, | |
| typesafe_overrides: ConfigOverrides, | |
| ) -> std::io::Result<Config> { | |
| self.load_with_cli_overrides( | |
| &self.current_cli_overrides(), | |
| request_overrides, | |
| typesafe_overrides, | |
| /*fallback_cwd*/ None, | |
| ) | |
| .await | |
| } | |
| pub(crate) async fn load_for_cwd( | |
| &self, | |
| request_overrides: Option<HashMap<String, serde_json::Value>>, | |
| typesafe_overrides: ConfigOverrides, | |
| cwd: Option<PathBuf>, | |
| ) -> std::io::Result<Config> { | |
| self.load_with_cli_overrides( | |
| &self.current_cli_overrides(), | |
| request_overrides, | |
| typesafe_overrides, | |
| cwd, | |
| ) | |
| .await | |
| } | |
| pub(crate) async fn load_with_cli_overrides( | |
| &self, | |
| cli_overrides: &[(String, TomlValue)], | |
| request_overrides: Option<HashMap<String, serde_json::Value>>, | |
| mut typesafe_overrides: ConfigOverrides, | |
| fallback_cwd: Option<PathBuf>, | |
| ) -> std::io::Result<Config> { | |
| let mut request_overrides = request_overrides.unwrap_or_default(); | |
| if let Some(value) = request_overrides.remove("bypass_hook_trust") { | |
| typesafe_overrides.bypass_hook_trust = Some(value.as_bool().ok_or_else(|| { | |
| std::io::Error::new( | |
| std::io::ErrorKind::InvalidData, | |
| "`bypass_hook_trust` override must be a boolean", | |
| ) | |
| })?); | |
| } | |
| let merged_cli_overrides = cli_overrides | |
| .iter() | |
| .cloned() | |
| .chain( | |
| request_overrides | |
| .into_iter() | |
| .map(|(key, value)| (key, json_to_toml(value))), | |
| ) | |
| .collect::<Vec<_>>(); | |
| let mut config = codex_core::config::ConfigBuilder::default() | |
| .codex_home(self.codex_home.clone()) | |
| .cli_overrides(merged_cli_overrides) | |
| .loader_overrides(self.loader_overrides.clone()) | |
| .strict_config(self.strict_config) | |
| .harness_overrides(typesafe_overrides) | |
| .fallback_cwd(fallback_cwd) | |
| .cloud_config_bundle(self.current_cloud_config_bundle()) | |
| .thread_config_loader(Arc::clone(&self.thread_config_loader)) | |
| .build() | |
| .await?; | |
| self.apply_runtime_feature_enablement(&mut config); | |
| self.apply_arg0_paths(&mut config); | |
| Ok(config) | |
| } | |
| pub(crate) async fn load_config_layers_for_cwd( | |
| &self, | |
| cwd: AbsolutePathBuf, | |
| ) -> std::io::Result<ConfigLayerStack> { | |
| self.load_config_layers(Some(cwd)).await | |
| } | |
| pub(crate) async fn load_config_layers( | |
| &self, | |
| cwd: Option<AbsolutePathBuf>, | |
| ) -> std::io::Result<ConfigLayerStack> { | |
| load_config_layers_state( | |
| LOCAL_FS.as_ref(), | |
| &self.codex_home, | |
| cwd, | |
| &self.current_cli_overrides(), | |
| codex_config::ConfigLoadOptions { | |
| loader_overrides: self.loader_overrides.clone(), | |
| strict_config: self.strict_config, | |
| cloud_config_bundle: self.current_cloud_config_bundle(), | |
| }, | |
| self.thread_config_loader.as_ref(), | |
| ) | |
| .await | |
| } | |
| fn apply_runtime_feature_enablement(&self, config: &mut Config) { | |
| apply_runtime_feature_enablement(config, &self.current_runtime_feature_enablement()); | |
| } | |
| fn current_runtime_feature_enablement(&self) -> BTreeMap<String, bool> { | |
| self.runtime_feature_enablement | |
| .read() | |
| .map(|guard| guard.clone()) | |
| .unwrap_or_default() | |
| } | |
| fn apply_arg0_paths(&self, config: &mut Config) { | |
| config.codex_self_exe = self.arg0_paths.codex_self_exe.clone(); | |
| config.codex_linux_sandbox_exe = self.arg0_paths.codex_linux_sandbox_exe.clone(); | |
| config.main_execve_wrapper_exe = self.arg0_paths.main_execve_wrapper_exe.clone(); | |
| } | |
| pub(crate) fn new_for_tests( | |
| codex_home: PathBuf, | |
| cli_overrides: Vec<(String, TomlValue)>, | |
| loader_overrides: LoaderOverrides, | |
| cloud_config_bundle: CloudConfigBundleLoader, | |
| ) -> Self { | |
| Self::new( | |
| codex_home, | |
| cli_overrides, | |
| loader_overrides, | |
| /*strict_config*/ false, | |
| cloud_config_bundle, | |
| Arg0DispatchPaths::default(), | |
| Arc::new(codex_config::NoopThreadConfigLoader), | |
| ) | |
| } | |
| pub(crate) fn without_managed_config_for_tests(codex_home: PathBuf) -> Self { | |
| Self::new_for_tests( | |
| codex_home, | |
| Vec::new(), | |
| LoaderOverrides::without_managed_config_for_tests(), | |
| CloudConfigBundleLoader::default(), | |
| ) | |
| } | |
| } | |
| mod provider_tests; | |
| pub(crate) fn protected_feature_keys(config_layer_stack: &ConfigLayerStack) -> BTreeSet<String> { | |
| let mut protected_features = config_layer_stack | |
| .effective_config() | |
| .get("features") | |
| .and_then(toml::Value::as_table) | |
| .map(|features| features.keys().cloned().collect::<BTreeSet<_>>()) | |
| .unwrap_or_default(); | |
| if let Some(feature_requirements) = config_layer_stack | |
| .requirements_toml() | |
| .feature_requirements | |
| .as_ref() | |
| { | |
| protected_features.extend(feature_requirements.entries.keys().cloned()); | |
| } | |
| protected_features | |
| } | |
| pub(crate) fn apply_runtime_feature_enablement( | |
| config: &mut Config, | |
| runtime_feature_enablement: &BTreeMap<String, bool>, | |
| ) { | |
| let protected_features = protected_feature_keys(&config.config_layer_stack); | |
| for (name, enabled) in runtime_feature_enablement { | |
| if protected_features.contains(name) { | |
| continue; | |
| } | |
| let Some(feature) = feature_for_key(name) else { | |
| continue; | |
| }; | |
| if let Err(err) = config.features.set_enabled(feature, *enabled) { | |
| warn!( | |
| feature = name, | |
| error = %err, | |
| "failed to apply runtime feature enablement" | |
| ); | |
| } | |
| } | |
| } | |