Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion codex-rs/app-server/tests/suite/v2/sleep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
"#
),
Expand Down
10 changes: 4 additions & 6 deletions codex-rs/core/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,6 @@
"skill_mcp_dependency_install": {
"type": "boolean"
},
"sleep_tool": {
"type": "boolean"
},
"sqlite": {
"type": "boolean"
},
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -4951,9 +4952,6 @@
"skill_mcp_dependency_install": {
"type": "boolean"
},
"sleep_tool": {
"type": "boolean"
},
"sqlite": {
"type": "boolean"
},
Expand Down
2 changes: 2 additions & 0 deletions codex-rs/core/src/config/config_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
),
] {
Expand Down
8 changes: 7 additions & 1 deletion codex-rs/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -1117,13 +1117,16 @@ 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 {
fn default() -> Self {
Self {
reminder_interval_seconds: 1,
clock_source: CurrentTimeSource::System,
sleep_tool: false,
}
}
}
Expand Down Expand Up @@ -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),
}))
}

Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/src/session/config_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}))
);

Expand Down
12 changes: 8 additions & 4 deletions codex-rs/core/src/tools/spec_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 15 additions & 6 deletions codex-rs/core/src/tools/spec_plan_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]
Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/tests/suite/code_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
});
},
)
Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/tests/suite/current_time_reminder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fn enable_current_time_reminder(
config.current_time_reminder = Some(CurrentTimeReminderConfig {
reminder_interval_seconds: interval,
clock_source,
..CurrentTimeReminderConfig::default()
});
}

Expand Down
9 changes: 7 additions & 2 deletions codex-rs/core/tests/suite/pending_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions codex-rs/features/src/feature_configs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 0 additions & 8 deletions codex-rs/features/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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",
Expand Down
Loading