Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
30f6ab2
Consolidate core input ops
etraut-openai May 16, 2026
e1b60da
Fix clippy field shorthand in core tests
etraut-openai May 16, 2026
3b1b54a
Add turn context to UserInput
etraut-openai May 16, 2026
cb528ad
Remove UserInputWithTurnContext op
etraut-openai May 16, 2026
1c10a91
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 16, 2026
f5943e0
Merge remote-tracking branch 'origin/main' into etraut/next-turn-stat…
etraut-openai May 17, 2026
c6fe81d
Simplify turn context update handling
etraut-openai May 17, 2026
73ad0c2
Merge branch 'etraut/next-turn-state-user-input-context' into etraut/…
etraut-openai May 17, 2026
8f6825e
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 17, 2026
9d5a0e2
Trim redundant turn context defaults
etraut-openai May 17, 2026
cd69441
Simplify turn start context overrides
etraut-openai May 17, 2026
db6e9bf
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 17, 2026
14284fe
Rename input settings override terminology
etraut-openai May 18, 2026
5946878
Merge branch 'etraut/next-turn-state-user-input-context' into etraut/…
etraut-openai May 18, 2026
5043555
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 18, 2026
9ad7f64
Clarify thread settings model updates
etraut-openai May 18, 2026
d3052c6
Merge branch 'etraut/next-turn-state-user-input-context' into etraut/…
etraut-openai May 18, 2026
dea732b
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 18, 2026
2836662
Fix thread settings field rename
etraut-openai May 18, 2026
4939645
Simplify thread settings test overrides
etraut-openai May 18, 2026
d58faa2
Keep thread settings stack placeholder
etraut-openai May 18, 2026
e3fe029
Remove UserInputWithTurnContext op
etraut-openai May 16, 2026
6927359
Simplify turn start context overrides
etraut-openai May 17, 2026
45fe8ff
Merge branch 'etraut/next-turn-state-remove-user-input-with-context' …
etraut-openai May 19, 2026
154ef81
Merge branch 'etraut/next-turn-state-input-op-consolidation' into etr…
etraut-openai May 19, 2026
e940365
Remove UserTurn op
etraut-openai May 19, 2026
981399d
Merge branch 'etraut/next-turn-state-input-op-consolidation' into etr…
etraut-openai May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions codex-rs/core/src/guardian/review_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,22 +706,29 @@ async fn run_review_on_session(
let submit_result = run_before_review_deadline(
deadline,
params.external_cancel.as_ref(),
Box::pin(review_session.codex.submit(Op::UserTurn {
environments: None,
Box::pin(review_session.codex.submit(Op::UserInput {
items: prompt_items.items,
#[allow(deprecated)]
cwd: params.parent_turn.cwd.to_path_buf(),
approval_policy: AskForApproval::Never,
approvals_reviewer: None,
sandbox_policy: legacy_sandbox_policy,
permission_profile: Some(guardian_permission_profile),
model: params.model.clone(),
effort: params.reasoning_effort,
summary: Some(params.reasoning_summary),
service_tier: None,
environments: None,
final_output_json_schema: Some(params.schema.clone()),
collaboration_mode: None,
personality: params.personality,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
#[allow(deprecated)]
cwd: Some(params.parent_turn.cwd.to_path_buf()),
approval_policy: Some(AskForApproval::Never),
sandbox_policy: Some(legacy_sandbox_policy),
permission_profile: Some(guardian_permission_profile),
summary: Some(params.reasoning_summary),
personality: params.personality,
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: params.model.clone(),
reasoning_effort: params.reasoning_effort,
developer_instructions: None,
},
}),
..Default::default()
},
})),
)
.await;
Expand Down
55 changes: 1 addition & 54 deletions codex-rs/core/src/session/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ use codex_protocol::request_permissions::RequestPermissionsResponse;
use codex_protocol::request_user_input::RequestUserInputResponse;

use crate::context_manager::is_user_turn_boundary;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::ModeKind;
use codex_protocol::config_types::Settings;
use codex_protocol::dynamic_tools::DynamicToolResponse;
use codex_protocol::items::UserMessageItem;
use codex_protocol::mcp::RequestId as ProtocolRequestId;
Expand Down Expand Up @@ -114,56 +111,6 @@ pub(super) async fn user_input_or_turn_inner(
mirror_user_text_to_realtime: Option<()>,
) {
let (items, updates, responsesapi_client_metadata) = match op {
Op::UserTurn {
cwd,
approval_policy,
approvals_reviewer,
sandbox_policy,
permission_profile,
model,
effort,
summary,
service_tier,
final_output_json_schema,
items,
collaboration_mode,
personality,
environments,
} => {
let collaboration_mode = collaboration_mode.or_else(|| {
Some(CollaborationMode {
mode: ModeKind::Default,
settings: Settings {
model: model.clone(),
reasoning_effort: effort,
developer_instructions: None,
},
})
});
(
items,
SessionSettingsUpdate {
cwd: Some(cwd),
approval_policy: Some(approval_policy),
approvals_reviewer,
sandbox_policy: Some(sandbox_policy),
workspace_roots: None,
profile_workspace_roots: None,
permission_profile,
active_permission_profile: None,
windows_sandbox_level: None,
collaboration_mode,
reasoning_summary: summary,
service_tier,
final_output_json_schema: Some(final_output_json_schema),
environments,
personality,
app_server_client_name: None,
app_server_client_version: None,
},
None,
)
}
Op::UserInput {
items,
environments,
Expand Down Expand Up @@ -826,7 +773,7 @@ pub(super) async fn submission_loop(
.await;
false
}
Op::UserInput { .. } | Op::UserTurn { .. } => {
Op::UserInput { .. } => {
user_input_or_turn(&sess, sub.id.clone(), sub.op).await;
false
}
Expand Down
35 changes: 21 additions & 14 deletions codex-rs/core/src/session/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5197,7 +5197,7 @@ fn submission_dispatch_span_uses_debug_for_realtime_audio() {
}

#[test]
fn op_kind_distinguishes_turn_ops() {
fn op_kind_for_input_and_context_ops() {
assert_eq!(
Op::OverrideTurnContext {
cwd: None,
Expand Down Expand Up @@ -5237,24 +5237,31 @@ async fn user_turn_updates_approvals_reviewer() {
handlers::user_input_or_turn(
&session,
"sub-1".to_string(),
Op::UserTurn {
environments: None,
Op::UserInput {
items: vec![UserInput::Text {
text: "hello".to_string(),
text_elements: Vec::new(),
}],
cwd: config.cwd.to_path_buf(),
approval_policy: config.permissions.approval_policy.value(),
approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview),
sandbox_policy: config.legacy_sandbox_policy(),
permission_profile: None,
model: turn_context.model_info.slug.clone(),
effort: config.model_reasoning_effort,
summary: config.model_reasoning_summary,
service_tier: None,
environments: None,
final_output_json_schema: None,
collaboration_mode: None,
personality: config.personality,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
cwd: Some(config.cwd.to_path_buf()),
approval_policy: Some(config.permissions.approval_policy.value()),
approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview),
sandbox_policy: Some(config.legacy_sandbox_policy()),
summary: config.model_reasoning_summary,
personality: config.personality,
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: turn_context.model_info.slug.clone(),
reasoning_effort: config.model_reasoning_effort,
developer_instructions: None,
},
}),
..Default::default()
},
},
)
.await;
Expand Down
42 changes: 27 additions & 15 deletions codex-rs/core/tests/common/test_codex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,14 @@ pub enum ApplyPatchModelOutput {
ShellCommandViaHeredoc,
}

/// Returns the permission fields required by `Op::UserTurn` for tests that
/// construct the op directly.
/// A collection of different ways the model can output an apply_patch call
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ShellModelOutput {
ShellCommand,
// UnifiedExec has its own set of tests
}

/// Returns the permission fields required by test thread-settings overrides.
pub fn turn_permission_fields(
permission_profile: PermissionProfile,
cwd: &Path,
Expand Down Expand Up @@ -754,24 +760,30 @@ impl TestCodex {
turn_permission_fields(permission_profile, self.config.cwd.as_path());
let session_model = self.session_configured.model.clone();
self.codex
.submit(Op::UserTurn {
environments,
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: prompt.into(),
text_elements: Vec::new(),
}],
environments,
final_output_json_schema: None,
cwd: self.config.cwd.to_path_buf(),
approval_policy,
approvals_reviewer: None,
sandbox_policy,
permission_profile,
model: session_model,
effort: None,
summary: None,
service_tier,
collaboration_mode: None,
personality: None,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
cwd: Some(self.config.cwd.to_path_buf()),
approval_policy: Some(approval_policy),
sandbox_policy: Some(sandbox_policy),
permission_profile,
service_tier,
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: session_model,
reasoning_effort: None,
developer_instructions: None,
},
}),
..Default::default()
},
})
.await?;

Expand Down
31 changes: 18 additions & 13 deletions codex-rs/core/tests/suite/apply_patch_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,29 @@ async fn submit_without_wait_with_turn_permissions(
let test = harness.test();
let session_model = test.session_configured.model.clone();
test.codex
.submit(Op::UserTurn {
environments: None,
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: prompt.into(),
text_elements: Vec::new(),
}],
environments: None,
final_output_json_schema: None,
cwd: harness.cwd().to_path_buf(),
approval_policy: AskForApproval::Never,
approvals_reviewer: None,
sandbox_policy,
permission_profile,
model: session_model,
effort: None,
summary: None,
service_tier: None,
collaboration_mode: None,
personality: None,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
cwd: Some(harness.cwd().to_path_buf()),
approval_policy: Some(AskForApproval::Never),
sandbox_policy: Some(sandbox_policy),
permission_profile,
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: session_model,
reasoning_effort: None,
developer_instructions: None,
},
}),
..Default::default()
},
})
.await?;
Ok(())
Expand Down
63 changes: 37 additions & 26 deletions codex-rs/core/tests/suite/approvals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,24 +644,29 @@ async fn submit_turn(
let session_model = test.session_configured.model.clone();

test.codex
.submit(Op::UserTurn {
environments: None,
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: prompt.into(),
text_elements: Vec::new(),
}],
environments: None,
final_output_json_schema: None,
cwd: test.cwd.path().to_path_buf(),
approval_policy,
approvals_reviewer: Some(ApprovalsReviewer::User),
sandbox_policy,
permission_profile: None,
model: session_model,
effort: None,
summary: None,
service_tier: None,
collaboration_mode: None,
personality: None,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
cwd: Some(test.cwd.path().to_path_buf()),
approval_policy: Some(approval_policy),
approvals_reviewer: Some(ApprovalsReviewer::User),
sandbox_policy: Some(sandbox_policy),
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: session_model,
reasoning_effort: None,
developer_instructions: None,
},
}),
..Default::default()
},
})
.await?;

Expand Down Expand Up @@ -2578,24 +2583,30 @@ async fn matched_prefix_rule_runs_unsandboxed_under_zsh_fork() -> Result<()> {
let (sandbox_policy, permission_profile) =
turn_permission_fields(permission_profile, test.cwd.path());
test.codex
.submit(Op::UserTurn {
environments: None,
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: "run allowed touch under zsh fork".into(),
text_elements: Vec::new(),
}],
environments: None,
final_output_json_schema: None,
cwd: test.cwd.path().to_path_buf(),
approval_policy,
approvals_reviewer: Some(ApprovalsReviewer::User),
sandbox_policy,
permission_profile,
model: session_model,
effort: None,
summary: None,
service_tier: None,
collaboration_mode: None,
personality: None,
responsesapi_client_metadata: None,
thread_settings: codex_protocol::protocol::ThreadSettingsOverrides {
cwd: Some(test.cwd.path().to_path_buf()),
approval_policy: Some(approval_policy),
approvals_reviewer: Some(ApprovalsReviewer::User),
sandbox_policy: Some(sandbox_policy),
permission_profile,
collaboration_mode: Some(codex_protocol::config_types::CollaborationMode {
mode: codex_protocol::config_types::ModeKind::Default,
settings: codex_protocol::config_types::Settings {
model: session_model,
reasoning_effort: None,
developer_instructions: None,
},
}),
..Default::default()
},
})
.await?;

Expand Down
Loading
Loading