1use crate::types::*;
7
8pub struct CronCreateTool;
10
11impl CronCreateTool {
12 pub fn new() -> Self {
13 Self
14 }
15
16 pub fn input_schema(&self) -> ToolInputSchema {
17 ToolInputSchema {
18 schema_type: "object".to_string(),
19 properties: serde_json::json!({
20 "cron": {
21 "type": "string",
22 "description": "Standard 5-field cron expression in local time: 'M H DoM Mon DoW' (e.g., '*/5 * * * *' = every 5 minutes, '0 9 * * 1-5' = weekdays at 9am)"
23 },
24 "prompt": {
25 "type": "string",
26 "description": "The prompt to enqueue at each fire time"
27 },
28 "recurring": {
29 "type": "boolean",
30 "description": "true (default) = fire on every cron match until deleted or auto-expired after 7 days. false = fire once at the next match, then auto-delete"
31 },
32 "durable": {
33 "type": "boolean",
34 "description": "true = persist to .ai/scheduled_tasks.json and survive restarts. false (default) = in-memory only, dies when this Claude session ends"
35 }
36 }),
37 required: Some(vec!["cron".to_string(), "prompt".to_string()]),
38 }
39 }
40
41 pub async fn execute(
42 &self,
43 input: serde_json::Value,
44 _context: &ToolContext,
45 ) -> Result<ToolResult, crate::error::AgentError> {
46 let cron = input["cron"].as_str().unwrap_or("");
47 let prompt = input["prompt"].as_str().unwrap_or("");
48 let recurring = input["recurring"].as_bool().unwrap_or(true);
49 let durable = input["durable"].as_bool().unwrap_or(false);
50
51 let response = format!(
52 "Scheduled task created:\nCron: {}\nPrompt: {}\nRecurring: {}\nDurable: {}\nNote: Full implementation would persist and execute this scheduled task.",
53 cron, prompt, recurring, durable
54 );
55
56 Ok(ToolResult {
57 result_type: "text".to_string(),
58 tool_use_id: "cron_create".to_string(),
59 content: response,
60 is_error: Some(false),
61 })
62 }
63}
64
65impl Default for CronCreateTool {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71pub struct CronDeleteTool;
73
74impl CronDeleteTool {
75 pub fn new() -> Self {
76 Self
77 }
78
79 pub fn input_schema(&self) -> ToolInputSchema {
80 ToolInputSchema {
81 schema_type: "object".to_string(),
82 properties: serde_json::json!({
83 "id": {
84 "type": "string",
85 "description": "Job ID returned by CronCreate"
86 }
87 }),
88 required: Some(vec!["id".to_string()]),
89 }
90 }
91
92 pub async fn execute(
93 &self,
94 input: serde_json::Value,
95 _context: &ToolContext,
96 ) -> Result<ToolResult, crate::error::AgentError> {
97 let id = input["id"].as_str().unwrap_or("");
98
99 let response = format!("Scheduled task '{}' deleted.", id);
100
101 Ok(ToolResult {
102 result_type: "text".to_string(),
103 tool_use_id: "cron_delete".to_string(),
104 content: response,
105 is_error: Some(false),
106 })
107 }
108}
109
110impl Default for CronDeleteTool {
111 fn default() -> Self {
112 Self::new()
113 }
114}
115
116pub struct CronListTool;
118
119impl CronListTool {
120 pub fn new() -> Self {
121 Self
122 }
123
124 pub fn input_schema(&self) -> ToolInputSchema {
125 ToolInputSchema {
126 schema_type: "object".to_string(),
127 properties: serde_json::json!({}),
128 required: None,
129 }
130 }
131
132 pub async fn execute(
133 &self,
134 _input: serde_json::Value,
135 _context: &ToolContext,
136 ) -> Result<ToolResult, crate::error::AgentError> {
137 let response = "Scheduled tasks:\n- (none)".to_string();
138
139 Ok(ToolResult {
140 result_type: "text".to_string(),
141 tool_use_id: "cron_list".to_string(),
142 content: response,
143 is_error: Some(false),
144 })
145 }
146}
147
148impl Default for CronListTool {
149 fn default() -> Self {
150 Self::new()
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn test_cron_create_schema() {
160 let tool = CronCreateTool::new();
161 let schema = tool.input_schema();
162 assert!(schema.properties.get("cron").is_some());
163 assert!(schema.properties.get("prompt").is_some());
164 }
165
166 #[test]
167 fn test_cron_delete_schema() {
168 let tool = CronDeleteTool::new();
169 let schema = tool.input_schema();
170 assert!(schema.properties.get("id").is_some());
171 }
172
173 #[test]
174 fn test_cron_list_schema() {
175 let tool = CronListTool::new();
176 let schema = tool.input_schema();
177 assert_eq!(schema.schema_type, "object");
178 }
179}