Implement cron job management tools and types

- Added `JobType`, `SessionTarget`, `Schedule`, `DeliveryConfig`, `CronJob`, `CronRun`, and `CronJobPatch` types in `src/cron/types.rs` for cron job configuration and management.
- Introduced `CronAddTool`, `CronListTool`, `CronRemoveTool`, `CronRunTool`, `CronRunsTool`, and `CronUpdateTool` in `src/tools` for adding, listing, removing, running, and updating cron jobs.
- Updated the `run` function in `src/daemon/mod.rs` to conditionally start the scheduler based on the cron configuration.
- Modified command-line argument parsing in `src/lib.rs` and `src/main.rs` to support new cron job commands.
- Enhanced the onboarding wizard in `src/onboard/wizard.rs` to include cron configuration.
- Added tests for cron job tools to ensure functionality and error handling.
This commit is contained in:
mai1015 2026-02-16 20:35:20 -05:00 committed by Chummy
parent 0ec46ac3d1
commit fb2d1cea0b
24 changed files with 2682 additions and 638 deletions

View file

@ -47,6 +47,9 @@ pub struct Config {
#[serde(default)]
pub heartbeat: HeartbeatConfig,
#[serde(default)]
pub cron: CronConfig,
#[serde(default)]
pub channels_config: ChannelsConfig,
@ -1172,6 +1175,29 @@ impl Default for HeartbeatConfig {
}
}
// ── Cron ────────────────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CronConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_max_run_history")]
pub max_run_history: u32,
}
fn default_max_run_history() -> u32 {
50
}
impl Default for CronConfig {
fn default() -> Self {
Self {
enabled: true,
max_run_history: default_max_run_history(),
}
}
}
// ── Tunnel ──────────────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -1579,6 +1605,7 @@ impl Default for Config {
agent: AgentConfig::default(),
model_routes: Vec::new(),
heartbeat: HeartbeatConfig::default(),
cron: CronConfig::default(),
channels_config: ChannelsConfig::default(),
memory: MemoryConfig::default(),
tunnel: TunnelConfig::default(),
@ -1863,6 +1890,38 @@ mod tests {
assert_eq!(h.interval_minutes, 30);
}
#[test]
fn cron_config_default() {
let c = CronConfig::default();
assert!(c.enabled);
assert_eq!(c.max_run_history, 50);
}
#[test]
fn cron_config_serde_roundtrip() {
let c = CronConfig {
enabled: false,
max_run_history: 100,
};
let json = serde_json::to_string(&c).unwrap();
let parsed: CronConfig = serde_json::from_str(&json).unwrap();
assert!(!parsed.enabled);
assert_eq!(parsed.max_run_history, 100);
}
#[test]
fn config_defaults_cron_when_section_missing() {
let toml_str = r#"
workspace_dir = "/tmp/workspace"
config_path = "/tmp/config.toml"
default_temperature = 0.7
"#;
let parsed: Config = toml::from_str(toml_str).unwrap();
assert!(parsed.cron.enabled);
assert_eq!(parsed.cron.max_run_history, 50);
}
#[test]
fn memory_config_default_hygiene_settings() {
let m = MemoryConfig::default();
@ -1918,6 +1977,7 @@ mod tests {
enabled: true,
interval_minutes: 15,
},
cron: CronConfig::default(),
channels_config: ChannelsConfig {
cli: true,
telegram: Some(TelegramConfig {
@ -2041,6 +2101,7 @@ tool_dispatcher = "xml"
scheduler: SchedulerConfig::default(),
model_routes: Vec::new(),
heartbeat: HeartbeatConfig::default(),
cron: CronConfig::default(),
channels_config: ChannelsConfig::default(),
memory: MemoryConfig::default(),
tunnel: TunnelConfig::default(),