Fetch Requirements from cloud (#10167)

Load requirements from Codex Backend. It only does this for enterprise
customers signed in with ChatGPT.

Todo in follow-up PRs:
* Add to app-server and exec too
* Switch from fail-open to fail-closed on failure
This commit is contained in:
gt-oai
2026-01-30 12:03:29 +00:00
committed by GitHub
parent 1ef5455eb6
commit e85d019daa
17 changed files with 673 additions and 17 deletions

View File

@@ -8,6 +8,7 @@ use app::App;
pub use app::AppExitInfo;
pub use app::ExitReason;
use codex_app_server_protocol::AuthMode;
use codex_cloud_requirements::cloud_requirements_loader;
use codex_common::oss::ensure_oss_provider_ready;
use codex_common::oss::get_default_model_for_oss_provider;
use codex_common::oss::ollama_chat_deprecation_notice;
@@ -23,6 +24,7 @@ use codex_core::config::ConfigOverrides;
use codex_core::config::find_codex_home;
use codex_core::config::load_config_as_toml_with_cli_overrides;
use codex_core::config::resolve_oss_provider;
use codex_core::config_loader::CloudRequirementsLoader;
use codex_core::config_loader::ConfigLoadError;
use codex_core::config_loader::format_config_error_with_source;
use codex_core::find_thread_path_by_id_str;
@@ -206,6 +208,17 @@ pub async fn run_main(
}
};
let cloud_auth_manager = AuthManager::shared(
codex_home.to_path_buf(),
false,
config_toml.cli_auth_credentials_store.unwrap_or_default(),
);
let chatgpt_base_url = config_toml
.chatgpt_base_url
.clone()
.unwrap_or_else(|| "https://chatgpt.com/backend-api/".to_string());
let cloud_requirements = cloud_requirements_loader(cloud_auth_manager, chatgpt_base_url);
let model_provider_override = if cli.oss {
let resolved = resolve_oss_provider(
cli.oss_provider.as_deref(),
@@ -257,7 +270,12 @@ pub async fn run_main(
..Default::default()
};
let config = load_config_or_exit(cli_kv_overrides.clone(), overrides.clone()).await;
let config = load_config_or_exit(
cli_kv_overrides.clone(),
overrides.clone(),
cloud_requirements.clone(),
)
.await;
if let Some(warning) = add_dir_warning_message(&cli.add_dir, config.sandbox_policy.get()) {
#[allow(clippy::print_stderr)]
@@ -370,9 +388,16 @@ pub async fn run_main(
.with(otel_tracing_layer)
.try_init();
run_ratatui_app(cli, config, overrides, cli_kv_overrides, feedback)
.await
.map_err(|err| std::io::Error::other(err.to_string()))
run_ratatui_app(
cli,
config,
overrides,
cli_kv_overrides,
cloud_requirements,
feedback,
)
.await
.map_err(|err| std::io::Error::other(err.to_string()))
}
async fn run_ratatui_app(
@@ -380,6 +405,7 @@ async fn run_ratatui_app(
initial_config: Config,
overrides: ConfigOverrides,
cli_kv_overrides: Vec<(String, toml::Value)>,
cloud_requirements: CloudRequirementsLoader,
feedback: codex_feedback::CodexFeedback,
) -> color_eyre::Result<AppExitInfo> {
color_eyre::install()?;
@@ -465,7 +491,12 @@ async fn run_ratatui_app(
.map(|d| d == TrustDirectorySelection::Trust)
.unwrap_or(false)
{
load_config_or_exit(cli_kv_overrides.clone(), overrides.clone()).await
load_config_or_exit(
cli_kv_overrides.clone(),
overrides.clone(),
cloud_requirements.clone(),
)
.await
} else {
initial_config
}
@@ -633,6 +664,7 @@ async fn run_ratatui_app(
load_config_or_exit_with_fallback_cwd(
cli_kv_overrides.clone(),
overrides.clone(),
cloud_requirements.clone(),
fallback_cwd,
)
.await
@@ -816,19 +848,23 @@ fn get_login_status(config: &Config) -> LoginStatus {
async fn load_config_or_exit(
cli_kv_overrides: Vec<(String, toml::Value)>,
overrides: ConfigOverrides,
cloud_requirements: CloudRequirementsLoader,
) -> Config {
load_config_or_exit_with_fallback_cwd(cli_kv_overrides, overrides, None).await
load_config_or_exit_with_fallback_cwd(cli_kv_overrides, overrides, cloud_requirements, None)
.await
}
async fn load_config_or_exit_with_fallback_cwd(
cli_kv_overrides: Vec<(String, toml::Value)>,
overrides: ConfigOverrides,
cloud_requirements: CloudRequirementsLoader,
fallback_cwd: Option<PathBuf>,
) -> Config {
#[allow(clippy::print_stderr)]
match ConfigBuilder::default()
.cli_overrides(cli_kv_overrides)
.harness_overrides(overrides)
.cloud_requirements(cloud_requirements)
.fallback_cwd(fallback_cwd)
.build()
.await