[codex] nest sleep config under current time reminder (#29910)

## Summary

- move sleep tool enablement from top-level `[features].sleep_tool` to
`[features.current_time_reminder].sleep_tool`
- remove the standalone `Feature::SleepTool` flag and gate `clock.sleep`
from resolved current-time configuration
- update config schema, config-lock materialization, and existing sleep
coverage

Stacked on #29907.
This commit is contained in:
rka-oai
2026-06-24 17:49:00 -07:00
committed by GitHub
Unverified
parent 800529218a
commit 35f5d02464
12 changed files with 51 additions and 28 deletions
+2 -1
View File
@@ -167,7 +167,8 @@ wire_api = "responses"
request_max_retries = 0
stream_max_retries = 0
[features]
[features.current_time_reminder]
enabled = true
sleep_tool = true
"#
),
+4 -6
View File
@@ -643,9 +643,6 @@
"skill_mcp_dependency_install": {
"type": "boolean"
},
"sleep_tool": {
"type": "boolean"
},
"sqlite": {
"type": "boolean"
},
@@ -820,6 +817,10 @@
"format": "uint64",
"minimum": 1.0,
"type": "integer"
},
"sleep_tool": {
"description": "Expose the input-interruptible `clock.sleep` tool.",
"type": "boolean"
}
},
"type": "object"
@@ -4951,9 +4952,6 @@
"skill_mcp_dependency_install": {
"type": "boolean"
},
"sleep_tool": {
"type": "boolean"
},
"sqlite": {
"type": "boolean"
},
+2
View File
@@ -623,10 +623,12 @@ current_time_reminder = true
enabled = true
reminder_interval_seconds = 4
clock_source = "external"
sleep_tool = true
"#,
CurrentTimeReminderConfig {
reminder_interval_seconds: 4,
clock_source: CurrentTimeSource::External,
sleep_tool: true,
},
),
] {
+7 -1
View File
@@ -1037,7 +1037,7 @@ pub struct Config {
pub token_budget: Option<TokenBudgetConfig>,
/// Shared token budget for the root thread and its sub-agents.
pub rollout_budget: Option<RolloutBudgetConfig>,
/// Current-time reminder configuration, when enabled.
/// Current-time reminder and clock tool configuration, when enabled.
pub current_time_reminder: Option<CurrentTimeReminderConfig>,
/// Centralized feature flags; source of truth for feature gating.
@@ -1117,6 +1117,8 @@ pub struct RolloutBudgetConfig {
pub struct CurrentTimeReminderConfig {
pub reminder_interval_seconds: u64,
pub clock_source: CurrentTimeSource,
/// Whether to expose the input-interruptible `clock.sleep` tool.
pub sleep_tool: bool,
}
impl Default for CurrentTimeReminderConfig {
@@ -1124,6 +1126,7 @@ impl Default for CurrentTimeReminderConfig {
Self {
reminder_interval_seconds: 1,
clock_source: CurrentTimeSource::System,
sleep_tool: false,
}
}
}
@@ -2675,6 +2678,9 @@ fn resolve_current_time_reminder_config(
clock_source: base
.and_then(|config| config.clock_source)
.unwrap_or(default.clock_source),
sleep_tool: base
.and_then(|config| config.sleep_tool)
.unwrap_or(default.sleep_tool),
}))
}
+1
View File
@@ -359,6 +359,7 @@ mod tests {
enabled: Some(true),
reminder_interval_seconds: Some(1),
clock_source: Some(codex_features::CurrentTimeSource::System),
sleep_tool: Some(false),
}))
);
+8 -4
View File
@@ -744,10 +744,14 @@ fn add_core_utility_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut
if features.enabled(Feature::CurrentTimeReminder) {
planned_tools.add(CurrentTimeHandler);
}
if features.enabled(Feature::SleepTool) {
planned_tools.add(SleepHandler);
if turn_context
.config
.current_time_reminder
.as_ref()
.is_some_and(|config| config.sleep_tool)
{
planned_tools.add(SleepHandler);
}
}
if tool_suggest_enabled(turn_context)
+15 -6
View File
@@ -31,6 +31,7 @@ use codex_tools::ToolSpec;
use pretty_assertions::assert_eq;
use serde_json::json;
use crate::config::CurrentTimeReminderConfig;
use crate::session::step_context::StepContext;
use crate::session::tests::make_session_and_context;
use crate::session::turn_context::TurnContext;
@@ -721,19 +722,27 @@ async fn host_context_gates_agent_job_tools() {
}
#[tokio::test]
async fn sleep_tool_follows_feature_gate() {
async fn sleep_tool_follows_current_time_config() {
let disabled = probe(|turn| {
set_feature(turn, Feature::SleepTool, /*enabled*/ false);
set_feature(turn, Feature::CurrentTimeReminder, /*enabled*/ true);
})
.await;
disabled.assert_visible_lacks(&["clock"]);
assert_eq!(disabled.namespace_function_names("clock"), ["curr_time"]);
let enabled = probe(|turn| {
set_feature(turn, Feature::SleepTool, /*enabled*/ true);
set_feature(turn, Feature::CurrentTimeReminder, /*enabled*/ true);
let mut config = (*turn.config).clone();
config.current_time_reminder = Some(CurrentTimeReminderConfig {
sleep_tool: true,
..CurrentTimeReminderConfig::default()
});
turn.config = Arc::new(config);
})
.await;
enabled.assert_visible_contains(&["clock"]);
assert_eq!(enabled.namespace_function_names("clock"), ["sleep"]);
assert_eq!(
enabled.namespace_function_names("clock"),
["curr_time", "sleep"]
);
}
#[tokio::test]
+1
View File
@@ -883,6 +883,7 @@ text(JSON.stringify(result));
config.current_time_reminder = Some(CurrentTimeReminderConfig {
reminder_interval_seconds: 3_000,
clock_source: CurrentTimeSource::System,
..CurrentTimeReminderConfig::default()
});
},
)
@@ -86,6 +86,7 @@ fn enable_current_time_reminder(
config.current_time_reminder = Some(CurrentTimeReminderConfig {
reminder_interval_seconds: interval,
clock_source,
..CurrentTimeReminderConfig::default()
});
}
+7 -2
View File
@@ -2,6 +2,7 @@ use core_test_support::test_codex::local_selections;
use std::sync::Arc;
use codex_core::CodexThread;
use codex_core::config::CurrentTimeReminderConfig;
use codex_features::Feature;
use codex_protocol::AgentPath;
use codex_protocol::items::SleepItem;
@@ -390,8 +391,12 @@ async fn any_new_input_interrupts_sleep() {
.with_config(|config| {
config
.features
.enable(Feature::SleepTool)
.expect("test config should allow feature update");
.enable(Feature::CurrentTimeReminder)
.expect("test config should allow current-time reminders");
config.current_time_reminder = Some(CurrentTimeReminderConfig {
sleep_tool: true,
..CurrentTimeReminderConfig::default()
});
})
.build_with_streaming_server(&server)
.await
+3
View File
@@ -147,6 +147,9 @@ pub struct CurrentTimeReminderConfigToml {
pub reminder_interval_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub clock_source: Option<CurrentTimeSource>,
/// Expose the input-interruptible `clock.sleep` tool.
#[serde(skip_serializing_if = "Option::is_none")]
pub sleep_tool: Option<bool>,
}
impl FeatureConfig for CurrentTimeReminderConfigToml {
-8
View File
@@ -219,8 +219,6 @@ pub enum Feature {
RolloutBudget,
/// Add current-time reminders to model-visible context.
CurrentTimeReminder,
/// Expose an input-interruptible sleep tool.
SleepTool,
/// Route MCP tool approval prompts through the MCP elicitation request path.
ToolCallMcpElicitation,
/// Prompt Codex Apps connector auth failures through MCP URL elicitations.
@@ -1243,12 +1241,6 @@ pub const FEATURES: &[FeatureSpec] = &[
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::SleepTool,
key: "sleep_tool",
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::CollaborationModes,
key: "collaboration_modes",