From b138a8a99221da726d287a280cb3ac64a7926092 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Fri, 29 May 2026 00:18:53 -0700 Subject: [PATCH] [codex] Use ToolMode as resolved runtime value --- codex-rs/core/src/lib.rs | 2 +- codex-rs/core/src/session/review.rs | 5 ++- codex-rs/core/src/session/turn_context.rs | 18 ++++---- .../src/{model_runtime.rs => tool_mode.rs} | 43 ++++--------------- codex-rs/core/src/tools/spec_plan_tests.rs | 10 ++--- 5 files changed, 26 insertions(+), 52 deletions(-) rename codex-rs/core/src/{model_runtime.rs => tool_mode.rs} (56%) diff --git a/codex-rs/core/src/lib.rs b/codex-rs/core/src/lib.rs index 06ed86e14b..286c87b226 100644 --- a/codex-rs/core/src/lib.rs +++ b/codex-rs/core/src/lib.rs @@ -60,7 +60,7 @@ pub use codex_mcp::SandboxState; mod mcp_openai_file; mod mcp_tool_call; pub(crate) mod mention_syntax; -mod model_runtime; +mod tool_mode; pub(crate) mod utils; pub use mention_syntax::PLUGIN_TEXT_MENTION_SIGIL; pub use mention_syntax::TOOL_MENTION_SIGIL; diff --git a/codex-rs/core/src/session/review.rs b/codex-rs/core/src/session/review.rs index 1dc78f1ee6..ddd9585eb4 100644 --- a/codex-rs/core/src/session/review.rs +++ b/codex-rs/core/src/session/review.rs @@ -1,4 +1,5 @@ use super::*; +use crate::tool_mode::resolve_tool_mode; use std::sync::atomic::AtomicBool; /// Spawn a review thread using the given prompt. @@ -47,7 +48,7 @@ pub(super) async fn spawn_review_thread( let mut per_turn_config = (*config).clone(); per_turn_config.model = Some(model.clone()); per_turn_config.features = review_features.clone(); - let model_runtime_modes = ModelRuntimeModes::resolve(&model_info, &per_turn_config.features); + let tool_mode = resolve_tool_mode(&model_info, &per_turn_config.features); if let Err(err) = per_turn_config.web_search_mode.set(review_web_search_mode) { let fallback_value = per_turn_config.web_search_mode.value(); tracing::warn!( @@ -97,7 +98,7 @@ pub(super) async fn spawn_review_thread( config: per_turn_config, auth_manager: auth_manager_for_context, model_info: model_info.clone(), - model_runtime_modes, + tool_mode, session_telemetry: session_telemetry_for_context, provider: provider_for_context, reasoning_effort, diff --git a/codex-rs/core/src/session/turn_context.rs b/codex-rs/core/src/session/turn_context.rs index d88ec62081..ee67e915c2 100644 --- a/codex-rs/core/src/session/turn_context.rs +++ b/codex-rs/core/src/session/turn_context.rs @@ -2,11 +2,12 @@ use super::*; use crate::SkillLoadOutcome; use crate::config::GhostSnapshotConfig; use crate::environment_selection::ResolvedTurnEnvironments; -use crate::model_runtime::ModelRuntimeModes; +use crate::tool_mode::resolve_tool_mode; use codex_model_provider::SharedModelProvider; use codex_model_provider::create_model_provider; use codex_protocol::SessionId; use codex_protocol::models::AdditionalPermissionProfile; +use codex_protocol::openai_models::ToolMode; use codex_protocol::protocol::ThreadSource; use codex_protocol::protocol::TurnEnvironmentSelection; use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile; @@ -56,7 +57,7 @@ pub struct TurnContext { pub config: Arc, pub(crate) auth_manager: Option>, pub(crate) model_info: ModelInfo, - pub(crate) model_runtime_modes: ModelRuntimeModes, + pub(crate) tool_mode: ToolMode, pub(crate) session_telemetry: SessionTelemetry, pub(crate) provider: SharedModelProvider, pub(crate) reasoning_effort: Option, @@ -165,11 +166,11 @@ impl TurnContext { } pub(crate) fn code_mode_enabled(&self) -> bool { - self.model_runtime_modes.code_mode_enabled() + matches!(self.tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly) } pub(crate) fn code_mode_only_enabled(&self) -> bool { - self.model_runtime_modes.code_mode_only_enabled() + self.tool_mode == ToolMode::CodeModeOnly } pub(crate) async fn with_model( @@ -182,7 +183,7 @@ impl TurnContext { let model_info = models_manager .get_model_info(model.as_str(), &config.to_models_manager_config()) .await; - let model_runtime_modes = ModelRuntimeModes::resolve(&model_info, &config.features); + let tool_mode = resolve_tool_mode(&model_info, &config.features); let truncation_policy = model_info.truncation_policy.into(); let supported_reasoning_levels = model_info .supported_reasoning_levels @@ -223,7 +224,7 @@ impl TurnContext { config: Arc::new(config), auth_manager: self.auth_manager.clone(), model_info: model_info.clone(), - model_runtime_modes, + tool_mode, session_telemetry: self .session_telemetry .clone() @@ -487,8 +488,7 @@ impl Session { ); let mut per_turn_config = per_turn_config; - let model_runtime_modes = - ModelRuntimeModes::resolve(&model_info, &per_turn_config.features); + let tool_mode = resolve_tool_mode(&model_info, &per_turn_config.features); per_turn_config.service_tier = get_service_tier( per_turn_config.service_tier, per_turn_config.features.enabled(Feature::FastMode), @@ -515,7 +515,7 @@ impl Session { config: per_turn_config.clone(), auth_manager: auth_manager_for_context, model_info: model_info.clone(), - model_runtime_modes, + tool_mode, session_telemetry: session_telemetry_for_context, provider: provider_for_context, reasoning_effort, diff --git a/codex-rs/core/src/model_runtime.rs b/codex-rs/core/src/tool_mode.rs similarity index 56% rename from codex-rs/core/src/model_runtime.rs rename to codex-rs/core/src/tool_mode.rs index 7c1d6c2acf..168cc6e8af 100644 --- a/codex-rs/core/src/model_runtime.rs +++ b/codex-rs/core/src/tool_mode.rs @@ -3,27 +3,10 @@ use codex_features::Feature; use codex_protocol::openai_models::ModelInfo; use codex_protocol::openai_models::ToolMode; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) struct ModelRuntimeModes { - tool_mode: ToolMode, -} - -impl ModelRuntimeModes { - pub(crate) fn resolve(model_info: &ModelInfo, features: &ManagedFeatures) -> Self { - Self { - tool_mode: model_info - .tool_mode - .unwrap_or_else(|| tool_mode_from_features(features)), - } - } - - pub(crate) fn code_mode_enabled(self) -> bool { - matches!(self.tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly) - } - - pub(crate) fn code_mode_only_enabled(self) -> bool { - self.tool_mode == ToolMode::CodeModeOnly - } +pub(crate) fn resolve_tool_mode(model_info: &ModelInfo, features: &ManagedFeatures) -> ToolMode { + model_info + .tool_mode + .unwrap_or_else(|| tool_mode_from_features(features)) } fn tool_mode_from_features(features: &ManagedFeatures) -> ToolMode { @@ -57,31 +40,21 @@ mod tests { #[test] fn omitted_selector_follows_feature_flags() { - let modes = ModelRuntimeModes::resolve( + let tool_mode = resolve_tool_mode( &model_info(/*tool_mode*/ None), &features(&[Feature::CodeModeOnly]), ); - assert_eq!( - modes, - ModelRuntimeModes { - tool_mode: ToolMode::CodeModeOnly, - } - ); + assert_eq!(tool_mode, ToolMode::CodeModeOnly); } #[test] fn explicit_selector_overrides_feature_flags() { - let modes = ModelRuntimeModes::resolve( + let tool_mode = resolve_tool_mode( &model_info(Some(ToolMode::Direct)), &features(&[Feature::CodeModeOnly]), ); - assert_eq!( - modes, - ModelRuntimeModes { - tool_mode: ToolMode::Direct, - } - ); + assert_eq!(tool_mode, ToolMode::Direct); } } diff --git a/codex-rs/core/src/tools/spec_plan_tests.rs b/codex-rs/core/src/tools/spec_plan_tests.rs index 243bec75ee..c2e41b7ad1 100644 --- a/codex-rs/core/src/tools/spec_plan_tests.rs +++ b/codex-rs/core/src/tools/spec_plan_tests.rs @@ -30,9 +30,9 @@ use codex_tools::ToolSpec; use pretty_assertions::assert_eq; use serde_json::json; -use crate::model_runtime::ModelRuntimeModes; use crate::session::tests::make_session_and_context; use crate::session::turn_context::TurnContext; +use crate::tool_mode::resolve_tool_mode; use crate::tools::handlers::multi_agents_spec::MULTI_AGENT_V1_NAMESPACE; use crate::tools::router::ToolRouter; use crate::tools::router::ToolRouterParams; @@ -217,7 +217,7 @@ fn set_feature(turn: &mut TurnContext, feature: Feature, enabled: bool) { .expect("test feature should be disableable in config"); } turn.config = Arc::new(config); - resolve_model_runtime_modes(turn); + resolve_tool_mode_for_turn(turn); } fn set_features(turn: &mut TurnContext, features: &[Feature]) { @@ -232,8 +232,8 @@ fn update_config(turn: &mut TurnContext, update: impl FnOnce(&mut crate::config: turn.config = Arc::new(config); } -fn resolve_model_runtime_modes(turn: &mut TurnContext) { - turn.model_runtime_modes = ModelRuntimeModes::resolve(&turn.model_info, &turn.config.features); +fn resolve_tool_mode_for_turn(turn: &mut TurnContext) { + turn.tool_mode = resolve_tool_mode(&turn.model_info, &turn.config.features); } fn set_web_search_mode(turn: &mut TurnContext, mode: WebSearchMode) { @@ -809,7 +809,7 @@ async fn tool_mode_selector_overrides_feature_flags() { let direct = probe(|turn| { set_features(turn, &[Feature::CodeMode, Feature::CodeModeOnly]); turn.model_info.tool_mode = Some(ToolMode::Direct); - resolve_model_runtime_modes(turn); + resolve_tool_mode_for_turn(turn); }) .await; direct.assert_visible_lacks(&[