mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
session: convert legacy sandbox updates before settings apply
This commit is contained in:
@@ -234,14 +234,26 @@ impl CodexThread {
|
||||
.await
|
||||
.with_updates(model, effort, /*developer_instructions*/ None)
|
||||
};
|
||||
let clear_active_permission_profile =
|
||||
permission_profile.is_none() && sandbox_policy.is_some();
|
||||
let permission_profile = match (permission_profile, sandbox_policy.as_ref()) {
|
||||
(Some(permission_profile), _) => Some(permission_profile),
|
||||
(None, Some(sandbox_policy)) => Some(
|
||||
self.codex
|
||||
.session
|
||||
.permission_profile_from_legacy_sandbox_update(sandbox_policy, cwd.as_deref())
|
||||
.await,
|
||||
),
|
||||
(None, None) => None,
|
||||
};
|
||||
|
||||
let updates = SessionSettingsUpdate {
|
||||
cwd,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox_policy,
|
||||
permission_profile,
|
||||
active_permission_profile,
|
||||
clear_active_permission_profile,
|
||||
windows_sandbox_level,
|
||||
collaboration_mode: Some(collaboration_mode),
|
||||
reasoning_summary: summary,
|
||||
|
||||
@@ -34,6 +34,7 @@ use crate::tasks::execute_user_shell_command;
|
||||
use codex_mcp::collect_mcp_snapshot_from_manager;
|
||||
use codex_mcp::compute_auth_statuses;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::ErrorEvent;
|
||||
@@ -50,6 +51,7 @@ use codex_protocol::protocol::RealtimeVoicesList;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use codex_protocol::protocol::ReviewRequest;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::protocol::SkillErrorInfo;
|
||||
use codex_protocol::protocol::SkillsListEntry;
|
||||
use codex_protocol::protocol::ThreadMemoryMode;
|
||||
@@ -71,6 +73,7 @@ use codex_protocol::user_input::UserInput;
|
||||
use codex_rmcp_client::ElicitationAction;
|
||||
use codex_rmcp_client::ElicitationResponse;
|
||||
use serde_json::Value;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tracing::debug;
|
||||
@@ -153,15 +156,23 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
},
|
||||
})
|
||||
});
|
||||
let clear_active_permission_profile = permission_profile.is_none();
|
||||
let permission_profile = permission_profile_with_legacy_fallback(
|
||||
sess,
|
||||
Some(&sandbox_policy),
|
||||
permission_profile,
|
||||
Some(cwd.as_path()),
|
||||
)
|
||||
.await;
|
||||
(
|
||||
items,
|
||||
SessionSettingsUpdate {
|
||||
cwd: Some(cwd),
|
||||
approval_policy: Some(approval_policy),
|
||||
approvals_reviewer,
|
||||
sandbox_policy: Some(sandbox_policy),
|
||||
permission_profile,
|
||||
active_permission_profile: None,
|
||||
clear_active_permission_profile,
|
||||
windows_sandbox_level: None,
|
||||
collaboration_mode,
|
||||
reasoning_summary: summary,
|
||||
@@ -205,15 +216,24 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
.with_updates(model, effort, /*developer_instructions*/ None),
|
||||
)
|
||||
};
|
||||
let clear_active_permission_profile =
|
||||
permission_profile.is_none() && sandbox_policy.is_some();
|
||||
let permission_profile = permission_profile_with_legacy_fallback(
|
||||
sess,
|
||||
sandbox_policy.as_ref(),
|
||||
permission_profile,
|
||||
cwd.as_deref(),
|
||||
)
|
||||
.await;
|
||||
(
|
||||
items,
|
||||
SessionSettingsUpdate {
|
||||
cwd,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox_policy,
|
||||
permission_profile,
|
||||
active_permission_profile,
|
||||
clear_active_permission_profile,
|
||||
windows_sandbox_level,
|
||||
collaboration_mode,
|
||||
reasoning_summary: summary,
|
||||
@@ -294,6 +314,22 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
}
|
||||
}
|
||||
|
||||
async fn permission_profile_with_legacy_fallback(
|
||||
sess: &Session,
|
||||
sandbox_policy: Option<&SandboxPolicy>,
|
||||
permission_profile: Option<PermissionProfile>,
|
||||
cwd: Option<&Path>,
|
||||
) -> Option<PermissionProfile> {
|
||||
match (permission_profile, sandbox_policy) {
|
||||
(Some(permission_profile), _) => Some(permission_profile),
|
||||
(None, Some(sandbox_policy)) => Some(
|
||||
sess.permission_profile_from_legacy_sandbox_update(sandbox_policy, cwd)
|
||||
.await,
|
||||
),
|
||||
(None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
async fn mirror_user_text_to_realtime(sess: &Arc<Session>, items: &[UserInput]) {
|
||||
let text = UserMessageItem::new(items).message();
|
||||
if text.is_empty() {
|
||||
@@ -1039,6 +1075,15 @@ pub(super) async fn submission_loop(
|
||||
/*developer_instructions*/ None,
|
||||
)
|
||||
};
|
||||
let clear_active_permission_profile =
|
||||
permission_profile.is_none() && sandbox_policy.is_some();
|
||||
let permission_profile = permission_profile_with_legacy_fallback(
|
||||
&sess,
|
||||
sandbox_policy.as_ref(),
|
||||
permission_profile,
|
||||
cwd.as_deref(),
|
||||
)
|
||||
.await;
|
||||
override_turn_context(
|
||||
&sess,
|
||||
sub.id.clone(),
|
||||
@@ -1046,8 +1091,8 @@ pub(super) async fn submission_loop(
|
||||
cwd,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox_policy,
|
||||
permission_profile,
|
||||
clear_active_permission_profile,
|
||||
windows_sandbox_level,
|
||||
collaboration_mode: Some(collaboration_mode),
|
||||
reasoning_summary: summary,
|
||||
|
||||
@@ -1354,6 +1354,17 @@ impl Session {
|
||||
state.session_configuration.apply(updates).map(|_| ())
|
||||
}
|
||||
|
||||
pub(crate) async fn permission_profile_from_legacy_sandbox_update(
|
||||
&self,
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
cwd: Option<&Path>,
|
||||
) -> PermissionProfile {
|
||||
let state = self.state.lock().await;
|
||||
state
|
||||
.session_configuration
|
||||
.permission_profile_from_legacy_sandbox_update(sandbox_policy, cwd)
|
||||
}
|
||||
|
||||
pub(crate) async fn set_session_startup_prewarm(
|
||||
&self,
|
||||
startup_prewarm: SessionStartupPrewarmHandle,
|
||||
|
||||
@@ -126,6 +126,24 @@ impl SessionConfiguration {
|
||||
self.permission_profile.get().network_sandbox_policy()
|
||||
}
|
||||
|
||||
pub(super) fn permission_profile_from_legacy_sandbox_update(
|
||||
&self,
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
cwd: Option<&Path>,
|
||||
) -> PermissionProfile {
|
||||
let file_system_sandbox_policy =
|
||||
FileSystemSandboxPolicy::from_legacy_sandbox_policy_preserving_deny_entries(
|
||||
sandbox_policy,
|
||||
self.resolved_update_cwd(cwd).as_path(),
|
||||
&self.file_system_sandbox_policy(),
|
||||
);
|
||||
PermissionProfile::from_runtime_permissions_with_enforcement(
|
||||
SandboxEnforcement::from_legacy_sandbox_policy(sandbox_policy),
|
||||
&file_system_sandbox_policy,
|
||||
NetworkSandboxPolicy::from(sandbox_policy),
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn thread_config_snapshot(&self) -> ThreadConfigSnapshot {
|
||||
ThreadConfigSnapshot {
|
||||
model: self.collaboration_mode.model().to_string(),
|
||||
@@ -191,19 +209,7 @@ impl SessionConfiguration {
|
||||
next_configuration.windows_sandbox_level = windows_sandbox_level;
|
||||
}
|
||||
|
||||
let absolute_cwd = updates
|
||||
.cwd
|
||||
.as_ref()
|
||||
.map(|cwd| {
|
||||
AbsolutePathBuf::relative_to_current_dir(normalize_for_native_workdir(
|
||||
cwd.as_path(),
|
||||
))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("failed to normalize update cwd: {cwd:?}: {e}");
|
||||
self.cwd.clone()
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| self.cwd.clone());
|
||||
let absolute_cwd = self.resolved_update_cwd(updates.cwd.as_deref());
|
||||
|
||||
let cwd_changed = absolute_cwd.as_path() != self.cwd.as_path();
|
||||
next_configuration.cwd = absolute_cwd.clone();
|
||||
@@ -214,35 +220,22 @@ impl SessionConfiguration {
|
||||
}
|
||||
|
||||
if let Some(permission_profile) = updates.permission_profile.clone() {
|
||||
let active_permission_profile =
|
||||
let active_permission_profile = if updates.clear_active_permission_profile {
|
||||
None
|
||||
} else {
|
||||
updates.active_permission_profile.clone().or_else(|| {
|
||||
if permission_profile == self.permission_profile() {
|
||||
self.active_permission_profile.clone()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
next_configuration.set_permission_profile_projection(
|
||||
permission_profile,
|
||||
Some(¤t_file_system_sandbox_policy),
|
||||
)?;
|
||||
next_configuration.active_permission_profile = active_permission_profile;
|
||||
} else if let Some(sandbox_policy) = updates.sandbox_policy.clone() {
|
||||
let file_system_sandbox_policy =
|
||||
FileSystemSandboxPolicy::from_legacy_sandbox_policy_preserving_deny_entries(
|
||||
&sandbox_policy,
|
||||
&next_configuration.cwd,
|
||||
¤t_file_system_sandbox_policy,
|
||||
);
|
||||
let network_sandbox_policy = NetworkSandboxPolicy::from(&sandbox_policy);
|
||||
next_configuration.permission_profile.set(
|
||||
PermissionProfile::from_runtime_permissions_with_enforcement(
|
||||
SandboxEnforcement::from_legacy_sandbox_policy(&sandbox_policy),
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
),
|
||||
)?;
|
||||
next_configuration.active_permission_profile = None;
|
||||
} else if cwd_changed
|
||||
&& file_system_policy_matches_legacy
|
||||
&& file_system_policy_has_rebindable_project_root_write
|
||||
@@ -273,6 +266,17 @@ impl SessionConfiguration {
|
||||
Ok(next_configuration)
|
||||
}
|
||||
|
||||
fn resolved_update_cwd(&self, cwd: Option<&Path>) -> AbsolutePathBuf {
|
||||
cwd.map(|cwd| {
|
||||
AbsolutePathBuf::relative_to_current_dir(normalize_for_native_workdir(cwd))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("failed to normalize update cwd: {cwd:?}: {e}");
|
||||
self.cwd.clone()
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| self.cwd.clone())
|
||||
}
|
||||
|
||||
fn set_permission_profile_projection(
|
||||
&mut self,
|
||||
permission_profile: PermissionProfile,
|
||||
@@ -301,9 +305,11 @@ pub(crate) struct SessionSettingsUpdate {
|
||||
pub(crate) cwd: Option<PathBuf>,
|
||||
pub(crate) approval_policy: Option<AskForApproval>,
|
||||
pub(crate) approvals_reviewer: Option<ApprovalsReviewer>,
|
||||
pub(crate) sandbox_policy: Option<SandboxPolicy>,
|
||||
pub(crate) permission_profile: Option<PermissionProfile>,
|
||||
pub(crate) active_permission_profile: Option<ActivePermissionProfile>,
|
||||
/// Legacy sandbox updates are represented as permission profiles before
|
||||
/// reaching this layer, but they should still clear any named profile.
|
||||
pub(crate) clear_active_permission_profile: bool,
|
||||
pub(crate) windows_sandbox_level: Option<WindowsSandboxLevel>,
|
||||
pub(crate) collaboration_mode: Option<CollaborationMode>,
|
||||
pub(crate) reasoning_summary: Option<ReasoningSummaryConfig>,
|
||||
|
||||
Reference in New Issue
Block a user