Simplify turn context update plumbing

This commit is contained in:
Eric Traut
2026-05-14 15:34:46 -07:00
parent 3e281977a5
commit 94d47608ac
3 changed files with 29 additions and 95 deletions

View File

@@ -2453,6 +2453,7 @@ mod tests {
fn serialize_thread_turn_context_response_and_notification() -> Result<()> {
let cwd = absolute_path("/tmp");
let turn_context = sample_thread_turn_context(cwd);
let turn_context_json = serde_json::to_value(&turn_context)?;
let response = ClientResponse::ThreadTurnContextUpdate {
request_id: RequestId::Integer(11),
response: v2::ThreadTurnContextUpdateResponse {
@@ -2465,32 +2466,6 @@ mod tests {
turn_context,
},
);
let turn_context_json = json!({
"model": "gpt-5",
"modelProvider": "openai",
"serviceTier": null,
"cwd": absolute_path_string("tmp"),
"approvalPolicy": "on-failure",
"approvalsReviewer": "user",
"sandboxPolicy": {
"type": "dangerFullAccess"
},
"permissionProfile": {
"type": "disabled"
},
"activePermissionProfile": null,
"effort": null,
"summary": null,
"personality": null,
"collaborationMode": {
"mode": "default",
"settings": {
"model": "gpt-5",
"reasoning_effort": null,
"developer_instructions": null
}
}
});
assert_eq!(
json!({

View File

@@ -732,19 +732,11 @@ mod tests {
use codex_app_server_protocol::SessionSource as ApiSessionSource;
use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::ThreadTurnContext;
use codex_app_server_protocol::ThreadTurnContextUpdatedNotification;
use codex_app_server_protocol::Turn;
use codex_app_server_protocol::TurnCompletedNotification;
use codex_app_server_protocol::TurnItemsView;
use codex_app_server_protocol::TurnStatus;
use codex_core::config::ConfigBuilder;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::ModeKind;
use codex_protocol::config_types::Settings;
use codex_protocol::models::PermissionProfile;
use codex_utils_absolute_path::test_support::PathBufExt;
use codex_utils_absolute_path::test_support::test_path_buf;
use pretty_assertions::assert_eq;
use std::path::Path;
use tempfile::TempDir;
@@ -901,32 +893,5 @@ mod tests {
},
})
));
assert!(server_notification_requires_delivery(
&ServerNotification::ThreadTurnContextUpdated(ThreadTurnContextUpdatedNotification {
thread_id: "thread-1".to_string(),
turn_context: ThreadTurnContext {
model: "gpt-5".to_string(),
model_provider: "openai".to_string(),
service_tier: None,
cwd: test_path_buf("/tmp/project").abs(),
approval_policy: codex_app_server_protocol::AskForApproval::Never,
approvals_reviewer: codex_app_server_protocol::ApprovalsReviewer::User,
sandbox_policy: codex_app_server_protocol::SandboxPolicy::DangerFullAccess,
permission_profile: PermissionProfile::read_only().into(),
active_permission_profile: None,
effort: None,
summary: None,
personality: None,
collaboration_mode: CollaborationMode {
mode: ModeKind::Default,
settings: Settings {
model: "gpt-5".to_string(),
reasoning_effort: None,
developer_instructions: None,
},
},
},
})
));
}
}

View File

@@ -47,11 +47,6 @@ impl TurnContextOverrideRequest {
}
}
struct ResolvedTurnContextOverrides {
has_any_overrides: bool,
overrides: CodexThreadTurnContextOverrides,
}
const TURN_STARTED_ACK_TIMEOUT: Duration = Duration::from_secs(5);
impl TurnRequestProcessor {
@@ -364,14 +359,17 @@ impl TurnRequestProcessor {
&self,
base_snapshot: &ThreadConfigSnapshot,
request: TurnContextOverrideRequest,
) -> Result<ResolvedTurnContextOverrides, JSONRPCErrorError> {
) -> Result<Option<CodexThreadTurnContextOverrides>, JSONRPCErrorError> {
if request.sandbox_policy.is_some() && request.permissions.is_some() {
return Err(invalid_request(
"`permissions` cannot be combined with `sandboxPolicy`",
));
}
let has_any_overrides = request.has_any_overrides();
if !request.has_any_overrides() {
return Ok(None);
}
let cwd = request.cwd;
let approval_policy = request.approval_policy.map(AskForApproval::to_core);
let approvals_reviewer = request
@@ -417,26 +415,23 @@ impl TurnRequestProcessor {
(None, None)
};
Ok(ResolvedTurnContextOverrides {
has_any_overrides,
overrides: CodexThreadTurnContextOverrides {
cwd,
approval_policy,
approvals_reviewer,
sandbox_policy,
permission_profile,
active_permission_profile,
windows_sandbox_level: None,
model: request.model,
effort: request.effort,
summary: request.summary,
service_tier: request.service_tier,
collaboration_mode: request
.collaboration_mode
.map(|mode| self.normalize_turn_start_collaboration_mode(mode)),
personality: request.personality,
},
})
Ok(Some(CodexThreadTurnContextOverrides {
cwd,
approval_policy,
approvals_reviewer,
sandbox_policy,
permission_profile,
active_permission_profile,
windows_sandbox_level: None,
model: request.model,
effort: request.effort,
summary: request.summary,
service_tier: request.service_tier,
collaboration_mode: request
.collaboration_mode
.map(|mode| self.normalize_turn_start_collaboration_mode(mode)),
personality: request.personality,
}))
}
async fn maybe_emit_turn_context_updated(
@@ -519,17 +514,16 @@ impl TurnRequestProcessor {
},
)
.await?;
let has_turn_context_overrides = resolved_overrides.has_any_overrides;
if has_turn_context_overrides {
let has_turn_context_overrides = resolved_overrides.is_some();
if let Some(overrides) = resolved_overrides.as_ref() {
thread
.preview_turn_context_overrides(resolved_overrides.overrides.clone())
.preview_turn_context_overrides(overrides.clone())
.await
.map_err(|err| invalid_request(format!("invalid turn context override: {err}")))?;
}
// Start the turn by submitting the user input. Return its submission id as turn_id.
let turn_op = if has_turn_context_overrides {
let overrides = resolved_overrides.overrides;
let turn_op = if let Some(overrides) = resolved_overrides {
Op::UserInputWithTurnContext {
items: mapped_items,
environments: environment_selections,
@@ -656,9 +650,9 @@ impl TurnRequestProcessor {
)
.await?;
let after_snapshot = if resolved_overrides.has_any_overrides {
let after_snapshot = if let Some(overrides) = resolved_overrides {
thread
.update_turn_context_overrides(resolved_overrides.overrides)
.update_turn_context_overrides(overrides)
.await
.map_err(|err| invalid_request(format!("invalid turn context override: {err}")))?
} else {