mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[5 of 7] Replace OverrideTurnContext with ThreadSettings (#22508)
**Stack position:** [5 of 7] ## Summary This PR adds `Op::ThreadSettings`, a queued settings-only update mechanism for changing stored thread settings without starting a new turn. It also removes the legacy `Op::OverrideTurnContext` in the same layer, so reviewers can see the replacement and deletion together. ## Changes - Add `Op::ThreadSettings` for settings-only queued updates. - Emit `ThreadSettingsApplied` with the effective thread settings snapshot after core applies an update. - Route settings-only updates through the same submission queue as user input. - Migrate remaining `OverrideTurnContext` tests and callers to the queued `Op::ThreadSettings` path. - Delete `Op::OverrideTurnContext` from the core protocol and submission loop. This stack addresses #20656 and #22090. ## Stack 1. [1 of 7] [Add thread settings to UserInput](https://github.com/openai/codex/pull/23080) 2. [2 of 7] [Remove UserInputWithTurnContext](https://github.com/openai/codex/pull/23081) 3. [3 of 7] [Remove UserTurn](https://github.com/openai/codex/pull/23075) 4. [4 of 7] [Placeholder for OverrideTurnContext cleanup](https://github.com/openai/codex/pull/23087) 5. [5 of 7] [Replace OverrideTurnContext with ThreadSettings](https://github.com/openai/codex/pull/22508) (this PR) 6. [6 of 7] [Add app-server thread settings API](https://github.com/openai/codex/pull/22509) 7. [7 of 7] [Sync TUI thread settings](https://github.com/openai/codex/pull/22510)
This commit is contained in:
@@ -396,7 +396,8 @@ pub struct ConversationTextParams {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// Persistent thread-settings overrides that can be applied before user input.
|
||||
/// Persistent thread-settings overrides that can be applied before user input or
|
||||
/// on their own.
|
||||
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, JsonSchema)]
|
||||
pub struct ThreadSettingsOverrides {
|
||||
/// Updated `cwd` for sandbox/tool calls.
|
||||
@@ -518,76 +519,22 @@ pub enum Op {
|
||||
thread_settings: ThreadSettingsOverrides,
|
||||
},
|
||||
|
||||
/// Apply persistent thread-settings overrides without starting a turn.
|
||||
///
|
||||
/// This uses the same submission queue as turn starts so app-server can
|
||||
/// preserve caller order between both kinds of mutation.
|
||||
ThreadSettings {
|
||||
/// Persistent thread-settings overrides to apply.
|
||||
#[serde(flatten)]
|
||||
thread_settings: ThreadSettingsOverrides,
|
||||
},
|
||||
|
||||
/// Inter-agent communication that should be recorded as assistant history
|
||||
/// while still using the normal thread submission lifecycle.
|
||||
InterAgentCommunication {
|
||||
communication: InterAgentCommunication,
|
||||
},
|
||||
|
||||
/// Override parts of the persistent thread settings for subsequent turns.
|
||||
///
|
||||
/// All fields are optional; when omitted, the existing value is preserved.
|
||||
/// This does not enqueue any input – it only updates defaults used for
|
||||
/// turns that rely on persistent session-level settings (for example,
|
||||
/// [`Op::UserInput`]).
|
||||
OverrideTurnContext {
|
||||
/// Updated `cwd` for sandbox/tool calls.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
cwd: Option<PathBuf>,
|
||||
|
||||
/// Updated command approval policy.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
approval_policy: Option<AskForApproval>,
|
||||
|
||||
/// Updated approval reviewer for future approval prompts.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
approvals_reviewer: Option<ApprovalsReviewer>,
|
||||
|
||||
/// Updated sandbox policy for tool calls.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
sandbox_policy: Option<SandboxPolicy>,
|
||||
|
||||
/// Updated permissions profile for tool calls.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
permission_profile: Option<PermissionProfile>,
|
||||
|
||||
/// Updated Windows sandbox mode for tool execution.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
windows_sandbox_level: Option<WindowsSandboxLevel>,
|
||||
|
||||
/// Updated model slug. When set, the model info is derived
|
||||
/// automatically.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
model: Option<String>,
|
||||
|
||||
/// Updated reasoning effort (honored only for reasoning-capable models).
|
||||
///
|
||||
/// Use `Some(Some(_))` to set a specific effort, `Some(None)` to clear
|
||||
/// the effort, or `None` to leave the existing value unchanged.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
effort: Option<Option<ReasoningEffortConfig>>,
|
||||
|
||||
/// Updated reasoning summary preference (honored only for reasoning-capable models).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
summary: Option<ReasoningSummaryConfig>,
|
||||
|
||||
/// Updated service tier preference for future turns.
|
||||
///
|
||||
/// Use `Some(Some(_))` to set a specific tier, `Some(None)` to clear the
|
||||
/// preference, or `None` to leave the existing value unchanged.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
service_tier: Option<Option<String>>,
|
||||
|
||||
/// EXPERIMENTAL - set a pre-set collaboration mode.
|
||||
/// Takes precedence over model, effort, and developer instructions if set.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
collaboration_mode: Option<CollaborationMode>,
|
||||
|
||||
/// Updated personality preference.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
personality: Option<Personality>,
|
||||
},
|
||||
|
||||
/// Approve a command execution
|
||||
ExecApproval {
|
||||
/// The id of the submission we are approving
|
||||
@@ -775,8 +722,8 @@ impl Op {
|
||||
Self::RealtimeConversationClose => "realtime_conversation_close",
|
||||
Self::RealtimeConversationListVoices => "realtime_conversation_list_voices",
|
||||
Self::UserInput { .. } => "user_input",
|
||||
Self::ThreadSettings { .. } => "thread_settings",
|
||||
Self::InterAgentCommunication { .. } => "inter_agent_communication",
|
||||
Self::OverrideTurnContext { .. } => "override_turn_context",
|
||||
Self::ExecApproval { .. } => "exec_approval",
|
||||
Self::PatchApproval { .. } => "patch_approval",
|
||||
Self::ResolveElicitation { .. } => "resolve_elicitation",
|
||||
@@ -1227,6 +1174,10 @@ pub enum EventMsg {
|
||||
#[serde(rename = "task_started", alias = "turn_started")]
|
||||
TurnStarted(TurnStartedEvent),
|
||||
|
||||
/// Persistent thread-settings overrides from the correlated submission have
|
||||
/// been applied to the session configuration.
|
||||
ThreadSettingsApplied(ThreadSettingsAppliedEvent),
|
||||
|
||||
/// Agent has completed all actions.
|
||||
/// v1 wire format uses `task_complete`; accept `turn_complete` for v2 interop.
|
||||
#[serde(rename = "task_complete", alias = "turn_complete")]
|
||||
@@ -1907,6 +1858,33 @@ pub struct TurnStartedEvent {
|
||||
pub collaboration_mode_kind: ModeKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct ThreadSettingsAppliedEvent {
|
||||
pub thread_settings: ThreadSettingsSnapshot,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct ThreadSettingsSnapshot {
|
||||
pub model: String,
|
||||
pub model_provider_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub service_tier: Option<String>,
|
||||
pub approval_policy: AskForApproval,
|
||||
pub approvals_reviewer: ApprovalsReviewer,
|
||||
pub permission_profile: PermissionProfile,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub active_permission_profile: Option<ActivePermissionProfile>,
|
||||
pub cwd: AbsolutePathBuf,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reasoning_effort: Option<ReasoningEffortConfig>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reasoning_summary: Option<ReasoningSummaryConfig>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub personality: Option<Personality>,
|
||||
pub collaboration_mode: CollaborationMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct TokenUsage {
|
||||
#[ts(type = "number")]
|
||||
|
||||
Reference in New Issue
Block a user