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:
pakrym-oai
2026-10-06 22:39:06 +00:00
committed by copyberry
parent b3b83ace17
commit 28cd3e2501
20 changed files with 46 additions and 317 deletions
@@ -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),
}
}
-1
View File
@@ -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
}
+1 -7
View File
@@ -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
+1 -76
View File
@@ -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