From 11b4da4a583a6b98b763e3595974dd6d239ec722 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 12:40:37 -0700 Subject: [PATCH] Fix TUI turn context permissions merge --- codex-rs/tui/src/app/tests.rs | 17 ++++---------- codex-rs/tui/src/app/thread_routing.rs | 14 ++---------- codex-rs/tui/src/app_server_session.rs | 18 ++------------- codex-rs/tui/src/chatwidget/protocol.rs | 22 +++++++++++++------ .../tui/src/chatwidget/tests/app_server.rs | 2 +- 5 files changed, 24 insertions(+), 49 deletions(-) diff --git a/codex-rs/tui/src/app/tests.rs b/codex-rs/tui/src/app/tests.rs index 751bb639f8..44c619c66c 100644 --- a/codex-rs/tui/src/app/tests.rs +++ b/codex-rs/tui/src/app/tests.rs @@ -5387,21 +5387,12 @@ fn override_turn_context_updates_app_server_next_turn_state() { .expect("override should update app-server turn context"); assert_eq!(handled, true); - let current_cwd = app.chat_widget.config_ref().cwd.to_path_buf(); let response = app_server .thread_turn_context_update( - thread_id, - /*cwd*/ None, - /*approval_policy*/ None, - /*approvals_reviewer*/ None, - /*permission_profile*/ None, - /*active_permission_profile*/ None, - current_cwd.as_path(), - /*model*/ None, - /*effort*/ None, - /*summary*/ None, - /*service_tier*/ None, - /*collaboration_mode*/ None, + thread_id, /*cwd*/ None, /*approval_policy*/ None, + /*approvals_reviewer*/ None, /*active_permission_profile*/ None, + /*model*/ None, /*effort*/ None, /*summary*/ None, + /*service_tier*/ None, /*collaboration_mode*/ None, /*personality*/ None, ) .await diff --git a/codex-rs/tui/src/app/thread_routing.rs b/codex-rs/tui/src/app/thread_routing.rs index 19b4ec06c3..be1704af59 100644 --- a/codex-rs/tui/src/app/thread_routing.rs +++ b/codex-rs/tui/src/app/thread_routing.rs @@ -689,7 +689,7 @@ impl App { cwd, approval_policy, approvals_reviewer, - permission_profile, + active_permission_profile, windows_sandbox_level: _, model, effort, @@ -698,23 +698,13 @@ impl App { collaboration_mode, personality, } => { - let config = self.chat_widget.config_ref(); - let current_cwd = config.cwd.to_path_buf(); - let active_permission_profile = - permission_profile.as_ref().and_then(|permission_profile| { - (config.permissions.permission_profile() == permission_profile.clone()) - .then(|| config.permissions.active_permission_profile()) - .flatten() - }); app_server .thread_turn_context_update( thread_id, cwd.clone(), *approval_policy, *approvals_reviewer, - permission_profile.clone(), - active_permission_profile, - current_cwd.as_path(), + active_permission_profile.clone(), model.clone(), *effort, *summary, diff --git a/codex-rs/tui/src/app_server_session.rs b/codex-rs/tui/src/app_server_session.rs index 127d7b702b..4e8ed97081 100644 --- a/codex-rs/tui/src/app_server_session.rs +++ b/codex-rs/tui/src/app_server_session.rs @@ -121,7 +121,6 @@ use color_eyre::eyre::ContextCompat; use color_eyre::eyre::Result; use color_eyre::eyre::WrapErr; use std::collections::HashMap; -use std::path::Path; use std::path::PathBuf; fn bootstrap_request_error(context: &'static str, err: TypedRequestError) -> color_eyre::Report { @@ -613,9 +612,7 @@ impl AppServerSession { cwd: Option, approval_policy: Option, approvals_reviewer: Option, - permission_profile: Option, active_permission_profile: Option, - current_cwd: &Path, model: Option, effort: Option>, summary: Option, @@ -624,18 +621,7 @@ impl AppServerSession { personality: Option, ) -> Result { let request_id = self.next_request_id(); - let (sandbox_policy, permissions) = permission_profile - .as_ref() - .map(|permission_profile| { - let permission_cwd = cwd.as_deref().unwrap_or(current_cwd); - turn_permissions_overrides( - permission_profile, - active_permission_profile, - permission_cwd, - self.thread_params_mode(), - ) - }) - .unwrap_or((None, None)); + let permissions = active_permission_profile.map(permissions_selection_from_active_profile); self.client .request_typed(ClientRequest::ThreadTurnContextUpdate { request_id, @@ -644,7 +630,7 @@ impl AppServerSession { cwd, approval_policy, approvals_reviewer: approvals_reviewer.map(Into::into), - sandbox_policy, + sandbox_policy: None, permissions, model, service_tier, diff --git a/codex-rs/tui/src/chatwidget/protocol.rs b/codex-rs/tui/src/chatwidget/protocol.rs index 1939823578..98a2788724 100644 --- a/codex-rs/tui/src/chatwidget/protocol.rs +++ b/codex-rs/tui/src/chatwidget/protocol.rs @@ -268,18 +268,26 @@ impl ChatWidget { let active_permission_profile = turn_context .active_permission_profile .map(codex_protocol::models::ActivePermissionProfile::from); + let permission_snapshot = PermissionProfileSnapshot::from_session_snapshot( + permission_profile, + active_permission_profile, + ); if let Err(err) = self .config .permissions - .set_permission_profile_with_active_profile( - permission_profile.clone(), - active_permission_profile.clone(), - ) + .set_permission_profile_from_session_snapshot(permission_snapshot.clone()) { tracing::warn!(%err, "failed to sync permissions from turn context update"); - self.config.permissions.permission_profile = - Constrained::allow_only(permission_profile); - self.config.permissions.active_permission_profile = active_permission_profile; + if let Err(replace_err) = self + .config + .permissions + .replace_permission_profile_from_session_snapshot(permission_snapshot) + { + tracing::warn!( + %replace_err, + "failed to replace permissions from turn context update" + ); + } } self.config.approvals_reviewer = turn_context.approvals_reviewer.to_core(); self.current_collaboration_mode = turn_context.collaboration_mode; diff --git a/codex-rs/tui/src/chatwidget/tests/app_server.rs b/codex-rs/tui/src/chatwidget/tests/app_server.rs index 2876ccfa25..fc28e6257d 100644 --- a/codex-rs/tui/src/chatwidget/tests/app_server.rs +++ b/codex-rs/tui/src/chatwidget/tests/app_server.rs @@ -55,7 +55,7 @@ async fn turn_context_updated_notification_refreshes_active_ui_state_without_his ); assert_eq!( chat.config_ref().permissions.permission_profile(), - permission_profile + &permission_profile ); assert_eq!( chat.config_ref().model_reasoning_summary,