mirror of
https://github.com/openai/codex.git
synced 2026-11-13 22:47:20 +00:00
Switch runtime to cloud config bundle (#24622)
## Summary - Adapts the moved `codex-cloud-config` crate from the legacy cloud requirements endpoint to the new config bundle endpoint. - Switches runtime consumers from `CloudRequirementsLoader` to `CloudConfigBundleLoader` so one shared bundle supplies cloud-delivered config and requirements. - Removes the legacy cloud requirements domain loader path. ## Details This intentionally keeps `codex-cloud-config` monolithic for review lineage: the previous PR establishes the crate move, and this PR shows the behavior change against that moved implementation. A follow-up PR splits the module back into focused files. The new bundle path preserves the important cloud requirements loader semantics where intended: account-scoped signed cache, 30 minute TTL, 5 minute refresh cadence, retry/backoff, auth recovery, and fail-closed startup loading. The cached payload changes from a single requirements TOML string to the backend-delivered bundle, and validation rejects malformed config or requirements fragments before cache write/use.
This commit is contained in:
1 parent
b794182ea7
commit
d45cd26248
60 files changed
+2614
-2339
No files matched your search
@@ -586,7 +586,7 @@ impl AccountRequestProcessor {
|
||||
)
|
||||
.map_err(|err| internal_error(format!("failed to set external auth: {err}")))?;
|
||||
self.auth_manager.reload().await;
|
||||
self.config_manager.replace_cloud_requirements_loader(
|
||||
self.config_manager.replace_cloud_config_bundle_loader(
|
||||
self.auth_manager.clone(),
|
||||
self.config.chatgpt_base_url.clone(),
|
||||
);
|
||||
@@ -645,7 +645,7 @@ impl AccountRequestProcessor {
|
||||
let auth_manager = thread_manager.auth_manager();
|
||||
auth_manager.reload().await;
|
||||
config_manager
|
||||
.replace_cloud_requirements_loader(auth_manager.clone(), chatgpt_base_url);
|
||||
.replace_cloud_config_bundle_loader(auth_manager.clone(), chatgpt_base_url);
|
||||
config_manager
|
||||
.sync_default_client_residency_requirement()
|
||||
.await;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::*;
|
||||
|
||||
fn cloud_requirements_load_error(err: &std::io::Error) -> Option<&CloudRequirementsLoadError> {
|
||||
fn cloud_config_bundle_load_error(err: &std::io::Error) -> Option<&CloudConfigBundleLoadError> {
|
||||
let mut current: Option<&(dyn std::error::Error + 'static)> = err
|
||||
.get_ref()
|
||||
.map(|source| source as &(dyn std::error::Error + 'static));
|
||||
while let Some(source) = current {
|
||||
if let Some(cloud_error) = source.downcast_ref::<CloudRequirementsLoadError>() {
|
||||
if let Some(cloud_error) = source.downcast_ref::<CloudConfigBundleLoadError>() {
|
||||
return Some(cloud_error);
|
||||
}
|
||||
current = source.source();
|
||||
@@ -14,16 +14,16 @@ fn cloud_requirements_load_error(err: &std::io::Error) -> Option<&CloudRequireme
|
||||
}
|
||||
|
||||
pub(super) fn config_load_error(err: &std::io::Error) -> JSONRPCErrorError {
|
||||
let data = cloud_requirements_load_error(err).map(|cloud_error| {
|
||||
let data = cloud_config_bundle_load_error(err).map(|cloud_error| {
|
||||
let mut data = serde_json::json!({
|
||||
"reason": "cloudRequirements",
|
||||
"reason": "cloudConfigBundle",
|
||||
"errorCode": format!("{:?}", cloud_error.code()),
|
||||
"detail": cloud_error.to_string(),
|
||||
});
|
||||
if let Some(status_code) = cloud_error.status_code() {
|
||||
data["statusCode"] = serde_json::json!(status_code);
|
||||
}
|
||||
if cloud_error.code() == CloudRequirementsLoadErrorCode::Auth {
|
||||
if cloud_error.code() == CloudConfigBundleLoadErrorCode::Auth {
|
||||
data["action"] = serde_json::json!("relogin");
|
||||
}
|
||||
data
|
||||
|
||||
@@ -54,7 +54,7 @@ mod thread_processor_behavior_tests {
|
||||
use codex_app_server_protocol::ServerRequestPayload;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ToolRequestUserInputParams;
|
||||
use codex_config::CloudRequirementsLoader;
|
||||
use codex_config::CloudConfigBundleLoader;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_config::SessionThreadConfig;
|
||||
use codex_config::StaticThreadConfigLoader;
|
||||
@@ -508,9 +508,9 @@ mod thread_processor_behavior_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_load_error_marks_cloud_requirements_failures_for_relogin() {
|
||||
let err = std::io::Error::other(CloudRequirementsLoadError::new(
|
||||
CloudRequirementsLoadErrorCode::Auth,
|
||||
fn config_load_error_marks_cloud_config_bundle_failures_for_relogin() {
|
||||
let err = std::io::Error::other(CloudConfigBundleLoadError::new(
|
||||
CloudConfigBundleLoadErrorCode::Auth,
|
||||
Some(401),
|
||||
"Your authentication session could not be refreshed automatically. Please log out and sign in again.",
|
||||
));
|
||||
@@ -520,7 +520,7 @@ mod thread_processor_behavior_tests {
|
||||
assert_eq!(
|
||||
error.data,
|
||||
Some(json!({
|
||||
"reason": "cloudRequirements",
|
||||
"reason": "cloudConfigBundle",
|
||||
"errorCode": "Auth",
|
||||
"action": "relogin",
|
||||
"statusCode": 401,
|
||||
@@ -535,7 +535,7 @@ mod thread_processor_behavior_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_load_error_leaves_non_cloud_requirements_failures_unmarked() {
|
||||
fn config_load_error_leaves_non_cloud_config_bundle_failures_unmarked() {
|
||||
let err = std::io::Error::other("required MCP servers failed to initialize");
|
||||
|
||||
let error = config_load_error(&err);
|
||||
@@ -549,11 +549,11 @@ mod thread_processor_behavior_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_load_error_marks_non_auth_cloud_requirements_failures_without_relogin() {
|
||||
let err = std::io::Error::other(CloudRequirementsLoadError::new(
|
||||
CloudRequirementsLoadErrorCode::RequestFailed,
|
||||
fn config_load_error_marks_non_auth_cloud_config_bundle_failures_without_relogin() {
|
||||
let err = std::io::Error::other(CloudConfigBundleLoadError::new(
|
||||
CloudConfigBundleLoadErrorCode::RequestFailed,
|
||||
/*status_code*/ None,
|
||||
"Failed to load cloud requirements (workspace-managed policies).",
|
||||
"Failed to load cloud config bundle (workspace-managed policies).",
|
||||
));
|
||||
|
||||
let error = config_load_error(&err);
|
||||
@@ -561,9 +561,29 @@ mod thread_processor_behavior_tests {
|
||||
assert_eq!(
|
||||
error.data,
|
||||
Some(json!({
|
||||
"reason": "cloudRequirements",
|
||||
"reason": "cloudConfigBundle",
|
||||
"errorCode": "RequestFailed",
|
||||
"detail": "Failed to load cloud requirements (workspace-managed policies).",
|
||||
"detail": "Failed to load cloud config bundle (workspace-managed policies).",
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_load_error_marks_invalid_cloud_config_bundle_failures_without_relogin() {
|
||||
let err = std::io::Error::other(CloudConfigBundleLoadError::new(
|
||||
CloudConfigBundleLoadErrorCode::InvalidBundle,
|
||||
/*status_code*/ None,
|
||||
"invalid cloud config bundle: invalid cloud config fragment Base policy (cfg_123)",
|
||||
));
|
||||
|
||||
let error = config_load_error(&err);
|
||||
|
||||
assert_eq!(
|
||||
error.data,
|
||||
Some(json!({
|
||||
"reason": "cloudConfigBundle",
|
||||
"errorCode": "InvalidBundle",
|
||||
"detail": "invalid cloud config bundle: invalid cloud config fragment Base policy (cfg_123)",
|
||||
}))
|
||||
);
|
||||
}
|
||||
@@ -595,7 +615,7 @@ mod thread_processor_behavior_tests {
|
||||
Vec::new(),
|
||||
LoaderOverrides::default(),
|
||||
/*strict_config*/ false,
|
||||
CloudRequirementsLoader::default(),
|
||||
CloudConfigBundleLoader::default(),
|
||||
Arg0DispatchPaths::default(),
|
||||
Arc::new(StaticThreadConfigLoader::new(vec![
|
||||
ThreadConfigSource::Session(SessionThreadConfig {
|
||||
|
||||
Reference in new issue
Block a user