mirror of
https://github.com/openai/codex.git
synced 2026-10-20 00:18:49 +00:00
Remove obsolete fields from persisted turn context (#51492)
## What changed Remove `workspace_roots`, `current_date`, `timezone`, `network`, `personality`, and `multi_agent_mode` from `TurnContextItem` and stop recording them in rollouts. Update the precomputed protocol schema accordingly. Make `summary` optional when reading turn context and write `"none"` as a compatibility placeholder for older readers, rather than persisting the active reasoning-summary setting. ## Testing Update protocol tests to cover omitted `summary` fields and compatibility-placeholder serialization. Extend compaction tests to verify that model requests retain the updated reasoning-summary setting after compaction while the rollout checkpoint records the placeholder. GitOrigin-RevId: d49eabaa1b340be1d79f7f09115281a307ea8a64
This commit is contained in:
BIN
Binary file not shown.
@@ -763,26 +763,20 @@ mod tests {
|
||||
disabled_plugin_ids: None,
|
||||
cwd: AbsolutePathBuf::from_absolute_path(tempdir.path())
|
||||
.expect("absolute feedback rollout directory"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: codex_protocol::protocol::AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: codex_protocol::protocol::SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: (*model).to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: effort.clone(),
|
||||
summary: ReasoningSummary::Auto,
|
||||
summary: Some(ReasoningSummary::Auto),
|
||||
}),
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -67,26 +67,20 @@ fn turn_context_item(
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: cwd(),
|
||||
workspace_roots: Some(vec![cwd()]),
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: Some(PermissionProfile::read_only()),
|
||||
active_permission_profile,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -714,26 +714,20 @@ fn reference_context_item() -> TurnContextItem {
|
||||
.join("reference-cwd"),
|
||||
)
|
||||
.expect("absolute reference cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: Some("2026-03-23".to_string()),
|
||||
timezone: Some("America/Los_Angeles".to_string()),
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-test".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(false),
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,6 @@ use codex_protocol::protocol::ThreadSettingsSnapshot;
|
||||
use codex_protocol::protocol::ThreadSource;
|
||||
use codex_protocol::protocol::TurnAbortReason;
|
||||
use codex_protocol::protocol::TurnContextItem;
|
||||
use codex_protocol::protocol::TurnContextNetworkItem;
|
||||
use codex_protocol::protocol::TurnEnvironmentRequest;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelection;
|
||||
use codex_protocol::protocol::TurnStartedEvent;
|
||||
|
||||
@@ -444,26 +444,20 @@ async fn record_initial_history_resumed_bare_turn_context_does_not_hydrate_previ
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let rollout_items = vec![RolloutItem::TurnContext(previous_context_item)];
|
||||
|
||||
@@ -496,26 +490,20 @@ async fn record_initial_history_resumed_hydrates_previous_turn_settings_from_lif
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: Some("comp-hash-a".to_string()),
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let turn_id = previous_context_item
|
||||
.turn_id
|
||||
@@ -2140,26 +2128,20 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let previous_turn_id = previous_context_item
|
||||
.turn_id
|
||||
@@ -2244,26 +2226,20 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}))
|
||||
.expect("serialize expected reference context item")
|
||||
);
|
||||
@@ -2280,26 +2256,20 @@ async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_tu
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let previous_turn_id = previous_context_item
|
||||
.turn_id
|
||||
@@ -2429,26 +2399,20 @@ async fn record_initial_history_resumed_unmatched_abort_preserves_active_turn_fo
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: current_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
|
||||
let rollout_items = vec![
|
||||
@@ -2570,26 +2534,20 @@ async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clea
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let previous_turn_id = previous_context_item
|
||||
.turn_id
|
||||
@@ -2761,26 +2719,20 @@ async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clear
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let previous_turn_id = previous_context_item
|
||||
.turn_id
|
||||
|
||||
@@ -668,33 +668,6 @@ async fn submitted_sparse_updates_preserve_captured_steps_and_ordering() {
|
||||
]
|
||||
);
|
||||
assert!(Arc::ptr_eq(&before.turn, &after.turn));
|
||||
assert_eq!(
|
||||
turn.to_turn_context_item().summary,
|
||||
ReasoningSummary::Concise
|
||||
);
|
||||
// Even after the live update, an already-captured request retains its own
|
||||
// summary setting in the durable context.
|
||||
for step in [&before, &during, &after] {
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(step)
|
||||
.await
|
||||
.expect("record captured settings");
|
||||
assert_eq!(
|
||||
session.reference_context_item().await.unwrap().summary,
|
||||
step.settings.reasoning_summary,
|
||||
);
|
||||
let world_state = Arc::new(
|
||||
session
|
||||
.build_world_state_for_step(step, /*new_window*/ true)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
session.start_new_context_window(step, world_state).await;
|
||||
assert_eq!(
|
||||
session.reference_context_item().await.unwrap().summary,
|
||||
step.settings.reasoning_summary,
|
||||
);
|
||||
}
|
||||
assert_eq!(after.settings.model_info.as_ref(), &expected_destination);
|
||||
let initial_budget = turn
|
||||
.config
|
||||
|
||||
@@ -76,7 +76,6 @@ impl StepContext {
|
||||
pub(crate) fn to_turn_context_item(&self) -> TurnContextItem {
|
||||
let mut item = self.turn.to_turn_context_item();
|
||||
item.realtime_active = Some(self.realtime.active);
|
||||
item.summary = self.settings.reasoning_summary;
|
||||
item
|
||||
}
|
||||
|
||||
|
||||
@@ -4326,26 +4326,20 @@ async fn record_initial_history_forked_hydrates_previous_turn_settings() {
|
||||
disabled_plugin_ids: None,
|
||||
#[allow(deprecated)]
|
||||
cwd: turn_context.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: turn_context.current_date.clone(),
|
||||
timezone: turn_context.timezone.clone(),
|
||||
approval_policy: turn_context.approval_policy(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: turn_context.personality(),
|
||||
collaboration_mode: Some(turn_context.collaboration_mode()),
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
cyber_access_program: None,
|
||||
effort: turn_context.reasoning_effort().cloned(),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
};
|
||||
let turn_id = previous_context_item
|
||||
.turn_id
|
||||
|
||||
@@ -737,29 +737,6 @@ impl TurnContext {
|
||||
)
|
||||
}
|
||||
|
||||
/// Combines the selected environment's workspace roots with its permission profile roots.
|
||||
pub(crate) fn effective_workspace_roots(&self) -> Vec<PathUri> {
|
||||
let Some(environment) = self.initial_environments.primary() else {
|
||||
return self.config.effective_workspace_roots();
|
||||
};
|
||||
|
||||
let mut workspace_roots = environment.workspace_roots().to_vec();
|
||||
for root in environment
|
||||
.config()
|
||||
.permission_profile
|
||||
.profile_workspace_roots()
|
||||
{
|
||||
let root = root.as_uri();
|
||||
if !workspace_roots
|
||||
.iter()
|
||||
.any(|existing| existing.to_string() == root.to_string())
|
||||
{
|
||||
workspace_roots.push(root.clone());
|
||||
}
|
||||
}
|
||||
workspace_roots
|
||||
}
|
||||
|
||||
/// Legacy: returns the frozen initial-turn reasoning effort, including the initial model default.
|
||||
/// Step-scoped consumers should use their captured `StepContext::settings`.
|
||||
pub(crate) fn effective_reasoning_effort(&self) -> Option<ReasoningEffortConfig> {
|
||||
@@ -913,31 +890,6 @@ impl TurnContext {
|
||||
}
|
||||
|
||||
pub(crate) fn to_turn_context_item(&self) -> TurnContextItem {
|
||||
// The legacy rollout field still stores host-native paths. Keep its
|
||||
// runtime-root filtering and omit it for unrepresentable profile roots;
|
||||
// the authoritative permission profile retains its concrete entries.
|
||||
let profile_roots = self.initial_environments.primary().map_or_else(
|
||||
|| self.config.permissions.profile_workspace_roots(),
|
||||
|environment| {
|
||||
environment
|
||||
.config()
|
||||
.permission_profile
|
||||
.profile_workspace_roots()
|
||||
},
|
||||
);
|
||||
let workspace_roots = if profile_roots
|
||||
.iter()
|
||||
.all(|root| root.as_uri().to_abs_path().is_ok())
|
||||
{
|
||||
let roots = self
|
||||
.effective_workspace_roots()
|
||||
.iter()
|
||||
.filter_map(|root| root.to_abs_path().ok())
|
||||
.collect::<Vec<_>>();
|
||||
(!roots.is_empty()).then_some(roots)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
#[allow(deprecated)]
|
||||
let cwd = self.cwd.clone();
|
||||
TurnContextItem {
|
||||
@@ -945,9 +897,6 @@ impl TurnContext {
|
||||
root_turn_id: self.turn_metadata_state.root_turn_id(),
|
||||
disabled_plugin_ids: Some(self.disabled_plugin_ids.clone()),
|
||||
cwd,
|
||||
workspace_roots,
|
||||
current_date: self.current_date.clone(),
|
||||
timezone: self.timezone.clone(),
|
||||
approval_policy: self.approval_policy(),
|
||||
approvals_reviewer: Some(self.config.approvals_reviewer),
|
||||
sandbox_policy: self.sandbox_policy(),
|
||||
@@ -956,41 +905,17 @@ impl TurnContext {
|
||||
|| self.config.permissions.active_permission_profile(),
|
||||
TurnEnvironment::active_permission_profile,
|
||||
),
|
||||
network: self.turn_context_network_item(),
|
||||
file_system_sandbox_policy: self.non_legacy_file_system_sandbox_policy(),
|
||||
model: self.model_info().slug.clone(),
|
||||
comp_hash: self.model_info().comp_hash.clone(),
|
||||
personality: self.personality(),
|
||||
collaboration_mode: Some(self.collaboration_mode()),
|
||||
multi_agent_version: Some(self.multi_agent_version),
|
||||
multi_agent_mode: None,
|
||||
realtime_active: Some(self.realtime_active),
|
||||
cyber_access_program: self.cyber_access_program,
|
||||
effort: self.reasoning_effort().cloned(),
|
||||
summary: self.reasoning_summary(),
|
||||
summary: Some(ReasoningSummaryConfig::None),
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_context_network_item(&self) -> Option<TurnContextNetworkItem> {
|
||||
let network = self
|
||||
.config
|
||||
.config_layer_stack
|
||||
.requirements()
|
||||
.network
|
||||
.as_ref()?;
|
||||
Some(TurnContextNetworkItem {
|
||||
allowed_domains: network
|
||||
.domains
|
||||
.as_ref()
|
||||
.and_then(codex_config::NetworkDomainPermissionsToml::allowed_domains)
|
||||
.unwrap_or_default(),
|
||||
denied_domains: network
|
||||
.domains
|
||||
.as_ref()
|
||||
.and_then(codex_config::NetworkDomainPermissionsToml::denied_domains)
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Grants and their review requirement share a lock so readers cannot see a new grant before
|
||||
|
||||
@@ -701,12 +701,6 @@ async fn environment_permissions_follow_configuration_ownership() -> Result<()>
|
||||
_ => None,
|
||||
})
|
||||
.context("owner turn context")?;
|
||||
assert!(
|
||||
turn_context
|
||||
.workspace_roots
|
||||
.as_ref()
|
||||
.is_some_and(|roots| roots.contains(&owner_profile_workspace_root))
|
||||
);
|
||||
assert_eq!(
|
||||
(
|
||||
turn_context.permission_profile,
|
||||
@@ -807,14 +801,13 @@ async fn executor_profile_roots_survive_settings_restore_and_turn_recording() ->
|
||||
_ => None,
|
||||
})
|
||||
.context("recorded turn context")?;
|
||||
// The rollout retains compiled permissions, not the unprojectable root list.
|
||||
// The rollout retains compiled permissions.
|
||||
assert_eq!(
|
||||
(
|
||||
context.permission_profile,
|
||||
context.active_permission_profile,
|
||||
context.workspace_roots
|
||||
),
|
||||
(Some(expected_profile), Some(active_profile), None)
|
||||
(Some(expected_profile), Some(active_profile))
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -33,28 +33,24 @@ fn resume_history(
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: config.cwd.clone(),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: config.permissions.approval_policy.value(),
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: config.legacy_sandbox_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: previous_model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: config.model_reasoning_effort.clone(),
|
||||
summary: config
|
||||
.model_reasoning_summary
|
||||
.unwrap_or(ReasoningSummary::Auto),
|
||||
summary: Some(
|
||||
config
|
||||
.model_reasoning_summary
|
||||
.unwrap_or(ReasoningSummary::Auto),
|
||||
),
|
||||
};
|
||||
|
||||
InitialHistory::Resumed(ResumedHistory {
|
||||
|
||||
@@ -833,7 +833,6 @@ async fn review_uses_updated_turn_permissions_and_approval_policy() {
|
||||
review_context.approvals_reviewer,
|
||||
Some(ApprovalsReviewer::User)
|
||||
);
|
||||
assert_eq!(review_context.personality, Some(Personality::Friendly));
|
||||
// The review delegate still starts in its own default mode, not the parent's Plan mode.
|
||||
assert_eq!(
|
||||
review_context.collaboration_mode,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Compaction checkpoints retain the summary captured after a mid-turn settings update.
|
||||
//! Model requests retain the summary captured after a mid-turn settings update and compaction.
|
||||
|
||||
use super::*;
|
||||
use codex_history::RolloutItem;
|
||||
@@ -79,12 +79,14 @@ async fn compaction_preserves_updated_summary(mode: CompactionMode) -> Result<()
|
||||
test.codex.shutdown_and_wait().await?;
|
||||
|
||||
let requests = responses.requests();
|
||||
assert_eq!(requests.len(), 4);
|
||||
assert_eq!(
|
||||
[
|
||||
requests[0].body_json()["reasoning"]["summary"].clone(),
|
||||
requests[1].body_json()["reasoning"]["summary"].clone()
|
||||
requests[1].body_json()["reasoning"]["summary"].clone(),
|
||||
requests[3].body_json()["reasoning"]["summary"].clone(),
|
||||
],
|
||||
[json!("concise"), json!("detailed")]
|
||||
[json!("concise"), json!("detailed"), json!("detailed")]
|
||||
);
|
||||
let rollout =
|
||||
std::fs::read_to_string(test.session_configured.rollout_path.expect("rollout path"))?;
|
||||
@@ -101,6 +103,6 @@ async fn compaction_preserves_updated_summary(mode: CompactionMode) -> Result<()
|
||||
RolloutItem::TurnContext(context) => Some(context.summary),
|
||||
_ => None,
|
||||
});
|
||||
assert_eq!(checkpoint, Some(ReasoningSummary::Detailed));
|
||||
assert_eq!(checkpoint, Some(Some(ReasoningSummary::None)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ use crate::capabilities::SelectedCapabilityRoot;
|
||||
use crate::config_types::ApprovalsReviewer;
|
||||
use crate::config_types::CollaborationMode;
|
||||
use crate::config_types::ModeKind;
|
||||
use crate::config_types::MultiAgentMode;
|
||||
use crate::config_types::Personality;
|
||||
use crate::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||
use crate::config_types::WindowsSandboxLevel;
|
||||
@@ -3317,12 +3316,6 @@ impl WorldStateItem {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct TurnContextNetworkItem {
|
||||
pub allowed_domains: Vec<String>,
|
||||
pub denied_domains: Vec<String>,
|
||||
}
|
||||
|
||||
/// Persist once per real user turn after computing that turn's model-visible
|
||||
/// context updates, and again after mid-turn compaction when replacement
|
||||
/// history re-establishes full context, so resume/fork replay can recover the
|
||||
@@ -3339,14 +3332,6 @@ pub struct TurnContextItem {
|
||||
#[ts(optional)]
|
||||
pub disabled_plugin_ids: Option<Vec<String>>,
|
||||
pub cwd: AbsolutePathBuf,
|
||||
/// Effective workspace roots used to materialize symbolic
|
||||
/// `:workspace_roots` filesystem permissions in `permission_profile`.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub workspace_roots: Option<Vec<AbsolutePathBuf>>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub current_date: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub timezone: Option<String>,
|
||||
pub approval_policy: AskForApproval,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub approvals_reviewer: Option<ApprovalsReviewer>,
|
||||
@@ -3357,33 +3342,25 @@ pub struct TurnContextItem {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub active_permission_profile: Option<ActivePermissionProfile>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub network: Option<TurnContextNetworkItem>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub file_system_sandbox_policy: Option<RawFileSystemSandboxPolicy>,
|
||||
pub model: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub comp_hash: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub personality: Option<Personality>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub collaboration_mode: Option<CollaborationMode>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||
/// Legacy effective model-visible mode retained to deserialize older rollouts.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub multi_agent_mode: Option<MultiAgentMode>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub realtime_active: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cyber_access_program: Option<CyberAccessProgram>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub effort: Option<ReasoningEffortConfig>,
|
||||
// Compatibility-only field written with a default value so older Codex
|
||||
// versions can deserialize turn-context rollout items. It is no longer
|
||||
// read by context reconstruction and should be removed in a future schema
|
||||
// cleanup.
|
||||
pub summary: ReasoningSummaryConfig,
|
||||
/// Legacy placeholder written as `Some(ReasoningSummaryConfig::None)` for older readers.
|
||||
/// Optional so newer readers also accept its future removal.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub summary: Option<ReasoningSummaryConfig>,
|
||||
}
|
||||
|
||||
impl TurnContextItem {
|
||||
@@ -6197,18 +6174,18 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_context_item_deserializes_without_network() -> Result<()> {
|
||||
fn turn_context_item_deserializes_without_summary() -> Result<()> {
|
||||
let item: TurnContextItem = serde_json::from_value(json!({
|
||||
"cwd": test_path_buf("/tmp"),
|
||||
"approval_policy": "never",
|
||||
"sandbox_policy": { "type": "danger-full-access" },
|
||||
"model": "gpt-5",
|
||||
"summary": "auto",
|
||||
}))?;
|
||||
|
||||
assert_eq!(item.network, None);
|
||||
assert_eq!(item.summary, None);
|
||||
assert_eq!(item.file_system_sandbox_policy, None);
|
||||
assert_eq!(item.comp_hash, None);
|
||||
assert_eq!(serde_json::to_value(item)?.get("summary"), None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6227,24 +6204,17 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_context_item_serializes_network_when_present() -> Result<()> {
|
||||
fn turn_context_item_serializes_split_policy_and_summary() -> Result<()> {
|
||||
let item = TurnContextItem {
|
||||
turn_id: None,
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::DangerFullAccess,
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: Some(TurnContextNetworkItem {
|
||||
allowed_domains: vec!["api.example.com".to_string()],
|
||||
denied_domains: vec!["blocked.example.com".to_string()],
|
||||
}),
|
||||
file_system_sandbox_policy: Some(
|
||||
FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::GlobPattern {
|
||||
@@ -6258,24 +6228,15 @@ mod tests {
|
||||
),
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: ReasoningSummaryConfig::Auto,
|
||||
summary: Some(ReasoningSummaryConfig::None),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(item)?;
|
||||
assert_eq!(
|
||||
value["network"],
|
||||
json!({
|
||||
"allowed_domains": ["api.example.com"],
|
||||
"denied_domains": ["blocked.example.com"],
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
value["file_system_sandbox_policy"],
|
||||
json!({
|
||||
@@ -6289,7 +6250,9 @@ mod tests {
|
||||
}]
|
||||
})
|
||||
);
|
||||
assert_eq!(value["summary"], json!("auto"));
|
||||
let legacy_summary: ReasoningSummaryConfig =
|
||||
serde_json::from_value(value["summary"].clone())?;
|
||||
assert_eq!(legacy_summary, ReasoningSummaryConfig::None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1933,26 +1933,20 @@ async fn resume_candidate_matches_cwd_reads_latest_turn_context() -> std::io::Re
|
||||
disabled_plugin_ids: None,
|
||||
cwd: serde_json::from_value(serde_json::json!(&latest_cwd))
|
||||
.expect("absolute latest cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "test-model".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}),
|
||||
};
|
||||
writeln!(file, "{}", serde_json::to_string(&turn_context)?)?;
|
||||
|
||||
@@ -571,26 +571,20 @@ mod tests {
|
||||
.join("parent/workspace")
|
||||
))
|
||||
.expect("absolute parent cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::DangerFullAccess,
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}),
|
||||
"test-provider",
|
||||
);
|
||||
@@ -621,26 +615,20 @@ mod tests {
|
||||
.join("workspace")
|
||||
))
|
||||
.expect("absolute workspace cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(permission_profile.clone()),
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}),
|
||||
"test-provider",
|
||||
);
|
||||
@@ -667,26 +655,20 @@ mod tests {
|
||||
disabled_plugin_ids: None,
|
||||
cwd: serde_json::from_value(serde_json::json!(&fallback_cwd))
|
||||
.expect("absolute fallback cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}),
|
||||
"test-provider",
|
||||
);
|
||||
@@ -710,26 +692,20 @@ mod tests {
|
||||
.join("fallback/workspace")
|
||||
))
|
||||
.expect("absolute fallback cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "gpt-5".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: codex_protocol::config_types::ReasoningSummary::Auto,
|
||||
summary: Some(codex_protocol::config_types::ReasoningSummary::Auto),
|
||||
}),
|
||||
"test-provider",
|
||||
);
|
||||
|
||||
@@ -1077,26 +1077,20 @@ mod tests {
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: serde_json::from_value(serde_json::json!(cwd)).expect("absolute cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::DangerFullAccess,
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: model.to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
summary: Some(ReasoningSummary::Auto),
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -683,26 +683,20 @@ fn turn_context(root: &Path, turn_id: &str) -> RolloutItem {
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: serde_json::from_value(serde_json::json!(root)).expect("absolute cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "test-model".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
summary: Some(ReasoningSummary::Auto),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -2102,26 +2102,20 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
|
||||
root_turn_id: None,
|
||||
disabled_plugin_ids: None,
|
||||
cwd: serde_json::from_value(json!(home.path())).expect("absolute cwd"),
|
||||
workspace_roots: None,
|
||||
current_date: None,
|
||||
timezone: None,
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: None,
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
network: None,
|
||||
file_system_sandbox_policy: None,
|
||||
model: "test-model".to_string(),
|
||||
comp_hash: None,
|
||||
personality: None,
|
||||
collaboration_mode: None,
|
||||
multi_agent_version: None,
|
||||
multi_agent_mode: None,
|
||||
realtime_active: None,
|
||||
cyber_access_program: None,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
summary: Some(ReasoningSummary::Auto),
|
||||
}),
|
||||
user_message("child question"),
|
||||
agent_message("child answer"),
|
||||
|
||||
Reference in New Issue
Block a user