deepseek/agent/builtin_tools/
cron_list.rs1use 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}