synaptic_lark/tools/
task.rs1use async_trait::async_trait;
2use serde_json::{json, Value};
3use synaptic_core::{SynapticError, Tool};
4
5use crate::{api::task::TaskApi, LarkConfig};
6
7pub struct LarkTaskTool {
20 api: TaskApi,
21}
22
23impl LarkTaskTool {
24 pub fn new(config: LarkConfig) -> Self {
26 Self {
27 api: TaskApi::new(config),
28 }
29 }
30}
31
32#[async_trait]
33impl Tool for LarkTaskTool {
34 fn name(&self) -> &'static str {
35 "lark_task"
36 }
37
38 fn description(&self) -> &'static str {
39 "Create and manage Feishu/Lark Tasks. \
40 Use action='list' to list tasks; \
41 action='get' to get a task by GUID; \
42 action='create' to create a new task; \
43 action='update' to update task fields; \
44 action='complete' to mark a task as complete; \
45 action='delete' to delete a task."
46 }
47
48 fn parameters(&self) -> Option<Value> {
49 Some(json!({
50 "type": "object",
51 "properties": {
52 "action": {
53 "type": "string",
54 "description": "Operation: list | get | create | update | complete | delete",
55 "enum": ["list", "get", "create", "update", "complete", "delete"]
56 },
57 "task_guid": {
58 "type": "string",
59 "description": "Task GUID — required for get, update, complete, delete"
60 },
61 "summary": {
62 "type": "string",
63 "description": "For 'create': task title (required); for 'update': new title"
64 },
65 "description": {
66 "type": "string",
67 "description": "For 'create'/'update': task description"
68 },
69 "due_timestamp": {
70 "type": "string",
71 "description": "For 'create'/'update': due date as Unix timestamp string (seconds)"
72 },
73 "page_token": {
74 "type": "string",
75 "description": "For 'list': pagination token from previous response"
76 }
77 },
78 "required": ["action"]
79 }))
80 }
81
82 async fn call(&self, args: Value) -> Result<Value, SynapticError> {
83 let action = args["action"]
84 .as_str()
85 .ok_or_else(|| SynapticError::Tool("missing 'action'".to_string()))?;
86
87 match action {
88 "list" => {
89 let page_token = args["page_token"].as_str();
90 let (tasks, next_token) = self.api.list_tasks(page_token).await?;
91 let mut result = json!({ "tasks": tasks });
92 if let Some(t) = next_token {
93 result["next_page_token"] = json!(t);
94 }
95 Ok(result)
96 }
97
98 "get" => {
99 let task_guid = args["task_guid"]
100 .as_str()
101 .ok_or_else(|| SynapticError::Tool("missing 'task_guid'".to_string()))?;
102 let task = self.api.get_task(task_guid).await?;
103 Ok(json!({ "task": task }))
104 }
105
106 "create" => {
107 let summary = args["summary"]
108 .as_str()
109 .ok_or_else(|| SynapticError::Tool("missing 'summary'".to_string()))?;
110 let due_timestamp = args["due_timestamp"].as_str();
111 let description = args["description"].as_str();
112 let task_guid = self
113 .api
114 .create_task(summary, due_timestamp, description)
115 .await?;
116 Ok(json!({ "task_guid": task_guid }))
117 }
118
119 "update" => {
120 let task_guid = args["task_guid"]
121 .as_str()
122 .ok_or_else(|| SynapticError::Tool("missing 'task_guid'".to_string()))?;
123 let mut fields = json!({});
124 let mut update_fields: Vec<String> = Vec::new();
125 if let Some(s) = args["summary"].as_str() {
126 fields["summary"] = json!(s);
127 update_fields.push("summary".to_string());
128 }
129 if let Some(d) = args["description"].as_str() {
130 fields["description"] = json!(d);
131 update_fields.push("description".to_string());
132 }
133 if let Some(ts) = args["due_timestamp"].as_str() {
134 fields["due"] = json!({ "timestamp": ts });
135 update_fields.push("due".to_string());
136 }
137 self.api
138 .update_task(task_guid, fields, update_fields)
139 .await?;
140 Ok(json!({ "task_guid": task_guid, "status": "updated" }))
141 }
142
143 "complete" => {
144 let task_guid = args["task_guid"]
145 .as_str()
146 .ok_or_else(|| SynapticError::Tool("missing 'task_guid'".to_string()))?;
147 self.api.complete_task(task_guid).await?;
148 Ok(json!({ "task_guid": task_guid, "status": "completed" }))
149 }
150
151 "delete" => {
152 let task_guid = args["task_guid"]
153 .as_str()
154 .ok_or_else(|| SynapticError::Tool("missing 'task_guid'".to_string()))?;
155 self.api.delete_task(task_guid).await?;
156 Ok(json!({ "task_guid": task_guid, "status": "deleted" }))
157 }
158
159 other => Err(SynapticError::Tool(format!(
160 "unknown action '{other}': expected list | get | create | update | complete | delete"
161 ))),
162 }
163 }
164}