app-server: accept permission profile overrides

This commit is contained in:
Michael Bolin
2026-04-20 23:16:54 -07:00
parent 40397502d5
commit 9d354ba7d9
44 changed files with 1844 additions and 17 deletions
@@ -102,6 +102,7 @@ use codex_app_server_protocol::MockExperimentalMethodParams;
use codex_app_server_protocol::MockExperimentalMethodResponse;
use codex_app_server_protocol::ModelListParams;
use codex_app_server_protocol::ModelListResponse;
use codex_app_server_protocol::PermissionProfile as ApiPermissionProfile;
use codex_app_server_protocol::PluginDetail;
use codex_app_server_protocol::PluginInstallParams;
use codex_app_server_protocol::PluginInstallResponse;
@@ -2399,6 +2400,7 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
config,
service_name,
base_instructions,
@@ -2411,6 +2413,14 @@ impl CodexMessageProcessor {
session_start_source,
persist_extended_history,
} = params;
if sandbox.is_some() && permission_profile.is_some() {
self.send_invalid_request_error(
request_id,
"`permissionProfile` cannot be combined with `sandbox`".to_string(),
)
.await;
return;
}
let mut typesafe_overrides = self.build_thread_config_overrides(
model,
model_provider,
@@ -2419,6 +2429,7 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
base_instructions,
developer_instructions,
personality,
@@ -2836,6 +2847,7 @@ impl CodexMessageProcessor {
approval_policy: Option<codex_app_server_protocol::AskForApproval>,
approvals_reviewer: Option<codex_app_server_protocol::ApprovalsReviewer>,
sandbox: Option<SandboxMode>,
permission_profile: Option<ApiPermissionProfile>,
base_instructions: Option<String>,
developer_instructions: Option<String>,
personality: Option<Personality>,
@@ -2850,6 +2862,7 @@ impl CodexMessageProcessor {
approvals_reviewer: approvals_reviewer
.map(codex_app_server_protocol::ApprovalsReviewer::to_core),
sandbox_mode: sandbox.map(SandboxMode::to_core),
permission_profile: permission_profile.map(Into::into),
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
base_instructions,
@@ -4365,12 +4378,21 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
config: mut request_overrides,
base_instructions,
developer_instructions,
personality,
persist_extended_history,
} = params;
if sandbox.is_some() && permission_profile.is_some() {
self.send_invalid_request_error(
request_id,
"`permissionProfile` cannot be combined with `sandbox`".to_string(),
)
.await;
return;
}
let thread_history = if let Some(history) = history {
let Some(thread_history) = self
@@ -4399,6 +4421,7 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
base_instructions,
developer_instructions,
personality,
@@ -4906,12 +4929,21 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
config: cli_overrides,
base_instructions,
developer_instructions,
ephemeral,
persist_extended_history,
} = params;
if sandbox.is_some() && permission_profile.is_some() {
self.send_invalid_request_error(
request_id,
"`permissionProfile` cannot be combined with `sandbox`".to_string(),
)
.await;
return;
}
let (rollout_path, source_thread_id) = if let Some(path) = path {
(path, None)
@@ -4988,6 +5020,7 @@ impl CodexMessageProcessor {
approval_policy,
approvals_reviewer,
sandbox,
permission_profile,
base_instructions,
developer_instructions,
/*personality*/ None,
@@ -7307,6 +7340,7 @@ impl CodexMessageProcessor {
|| params.approval_policy.is_some()
|| params.approvals_reviewer.is_some()
|| params.sandbox_policy.is_some()
|| params.permission_profile.is_some()
|| params.model.is_some()
|| params.service_tier.is_some()
|| params.effort.is_some()
@@ -7314,6 +7348,15 @@ impl CodexMessageProcessor {
|| collaboration_mode.is_some()
|| params.personality.is_some();
if params.sandbox_policy.is_some() && params.permission_profile.is_some() {
self.send_invalid_request_error(
request_id,
"`permissionProfile` cannot be combined with `sandboxPolicy`".to_string(),
)
.await;
return;
}
// If any overrides are provided, update the session turn context first.
if has_any_overrides {
let _ = self
@@ -7327,6 +7370,7 @@ impl CodexMessageProcessor {
.approvals_reviewer
.map(codex_app_server_protocol::ApprovalsReviewer::to_core),
sandbox_policy: params.sandbox_policy.map(|p| p.to_core()),
permission_profile: params.permission_profile.map(Into::into),
windows_sandbox_level: None,
model: params.model,
effort: params.effort.map(Some),
@@ -9247,6 +9291,16 @@ fn collect_resume_override_mismatches(
));
}
}
if let Some(requested_permission_profile) = request.permission_profile.as_ref() {
let requested_permission_profile =
codex_protocol::models::PermissionProfile::from(requested_permission_profile.clone());
if requested_permission_profile != config_snapshot.permission_profile {
mismatch_details.push(format!(
"permission_profile requested={requested_permission_profile:?} active={:?}",
config_snapshot.permission_profile
));
}
}
if let Some(requested_personality) = request.personality.as_ref()
&& config_snapshot.personality.as_ref() != Some(requested_personality)
{
@@ -10740,6 +10794,7 @@ mod tests {
approval_policy: None,
approvals_reviewer: None,
sandbox: None,
permission_profile: None,
config: None,
base_instructions: None,
developer_instructions: None,