Skip to main content

deepseek/agent/builtin_tools/
cron_list.rs

1//! `CronList` tool — return all scheduled tasks.
2
3use std::sync::{Arc, Mutex};
4
5use async_trait::async_trait;
6use serde_json::{json, Value};
7
8use crate::agent::scheduler::{Schedule, Scheduler};
9use crate::agent::tool::{Tool, ToolDefinition};
10
11pub struct CronListTool {
12    pub scheduler: Arc<Mutex<Scheduler>>,
13}
14
15impl CronListTool {
16    pub fn new(scheduler: Arc<Mutex<Scheduler>>) -> Self {
17        Self { scheduler }
18    }
19}
20
21#[async_trait]
22impl Tool for CronListTool {
23    fn name(&self) -> &str {
24        "CronList"
25    }
26
27    fn definition(&self) -> ToolDefinition {
28        ToolDefinition {
29            name: self.name().to_string(),
30            description: "List every scheduled task in the current session, with \
31                          schedule, prompt, next fire time (UTC), and expiry."
32                .into(),
33            parameters: json!({
34                "type": "object",
35                "properties": {},
36            }),
37        }
38    }
39
40    fn read_only_hint(&self) -> bool {
41        true
42    }
43
44    async fn call_json(&self, _args: Value) -> Result<String, String> {
45        let sched = self
46            .scheduler
47            .lock()
48            .map_err(|_| "CronList: scheduler lock poisoned".to_string())?;
49
50        let tasks: Vec<_> = sched
51            .list()
52            .into_iter()
53            .map(|t| {
54                let schedule = match &t.schedule {
55                    Schedule::Cron(c) => json!({"kind": "cron", "expr": c.as_str()}),
56                    Schedule::Once(at) => json!({"kind": "once", "at": at}),
57                    Schedule::Dynamic => json!({"kind": "dynamic"}),
58                };
59                json!({
60                    "task_id": t.id.as_str(),
61                    "schedule": schedule,
62                    "prompt": t.prompt,
63                    "recurring": t.recurring,
64                    "next_fire": t.next_fire,
65                    "expires_at": t.expires_at,
66                    "created_at": t.created_at,
67                })
68            })
69            .collect();
70
71        Ok(serde_json::to_string(&json!({
72            "session_id": sched.session_id(),
73            "count": tasks.len(),
74            "cap": sched.cap(),
75            "disabled": sched.is_disabled(),
76            "tasks": tasks,
77        }))
78        .unwrap())
79    }
80}