diff --git a/codex-rs/core/src/tools/spec_plan.rs b/codex-rs/core/src/tools/spec_plan.rs index 9d789113ad..5d5d0c7bc9 100644 --- a/codex-rs/core/src/tools/spec_plan.rs +++ b/codex-rs/core/src/tools/spec_plan.rs @@ -1163,6 +1163,14 @@ fn add_core_utility_tools(context: &CoreToolPlanContext<'_>, registry: &mut Tool { registry.add(SleepHandler); } + } else if context + .model_info + .experimental_supported_tools + .iter() + .any(|tool| tool == "clock") + { + registry.add(CurrentTimeHandler); + registry.add(SleepHandler); } if tool_suggest_enabled(turn_context) diff --git a/codex-rs/core/tests/suite/current_time_reminder.rs b/codex-rs/core/tests/suite/current_time_reminder.rs index fa06d98192..400adc0500 100644 --- a/codex-rs/core/tests/suite/current_time_reminder.rs +++ b/codex-rs/core/tests/suite/current_time_reminder.rs @@ -59,6 +59,7 @@ enum ClockSetup { Configured, Persistent, OrdinaryEffort, + ModelTools, ExplicitlyDisabled, RequiredOff, } @@ -338,6 +339,7 @@ async fn current_time_reminders_can_follow_only_user_or_tool_outputs() -> Result #[test_case(ClockSetup::Configured; "configured")] #[test_case(ClockSetup::Persistent; "persistent")] #[test_case(ClockSetup::OrdinaryEffort; "ordinary_effort")] +#[test_case(ClockSetup::ModelTools; "model_tools_without_reminders")] #[test_case(ClockSetup::ExplicitlyDisabled; "explicitly_disabled")] #[test_case(ClockSetup::RequiredOff; "required_off")] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -351,10 +353,17 @@ async fn system_time_source_adds_current_time_reminder(clock_setup: ClockSetup) ) .await; let mut builder = test_codex() + .with_model_info_override("gpt-5.5", move |model_info| { + if matches!(clock_setup, ClockSetup::Configured | ClockSetup::ModelTools) { + model_info + .experimental_supported_tools + .push("clock".to_string()); + } + }) .with_pre_build_hook(move |home| { let config = match clock_setup { ClockSetup::Configured => Some("[features]\ncurrent_time_reminder = true\n"), - ClockSetup::ExplicitlyDisabled => { + ClockSetup::ModelTools | ClockSetup::ExplicitlyDisabled => { Some("[features]\ncurrent_time_reminder = false\n") } ClockSetup::Persistent | ClockSetup::OrdinaryEffort | ClockSetup::RequiredOff => { @@ -369,7 +378,7 @@ async fn system_time_source_adds_current_time_reminder(clock_setup: ClockSetup) .with_config(move |config| { config.include_environment_context = false; config.model_reasoning_effort = Some(match clock_setup { - ClockSetup::OrdinaryEffort => ReasoningEffort::High, + ClockSetup::OrdinaryEffort | ClockSetup::ModelTools => ReasoningEffort::High, ClockSetup::Configured | ClockSetup::Persistent | ClockSetup::ExplicitlyDisabled @@ -392,7 +401,7 @@ async fn system_time_source_adds_current_time_reminder(clock_setup: ClockSetup) ["curr_time", "sleep"].map(|name| request.tool_by_name("clock", name).is_some()), match clock_setup { ClockSetup::Configured => [true, false], - ClockSetup::Persistent => [true, true], + ClockSetup::Persistent | ClockSetup::ModelTools => [true, true], ClockSetup::OrdinaryEffort | ClockSetup::ExplicitlyDisabled | ClockSetup::RequiredOff => [false, false], @@ -400,7 +409,10 @@ async fn system_time_source_adds_current_time_reminder(clock_setup: ClockSetup) ); if matches!( clock_setup, - ClockSetup::OrdinaryEffort | ClockSetup::ExplicitlyDisabled | ClockSetup::RequiredOff + ClockSetup::OrdinaryEffort + | ClockSetup::ModelTools + | ClockSetup::ExplicitlyDisabled + | ClockSetup::RequiredOff ) { assert!(current_time_reminders(&request).is_empty()); return Ok(());