sgr_agent_tools/
delete.rs1use std::sync::Arc;
4
5use schemars::JsonSchema;
6use serde::Deserialize;
7use serde_json::Value;
8use sgr_agent_core::agent_tool::{Tool, ToolError, ToolOutput, parse_args};
9use sgr_agent_core::context::AgentContext;
10use sgr_agent_core::schema::json_schema_for;
11
12use crate::backend::FileBackend;
13
14pub struct DeleteTool<B: FileBackend>(pub Arc<B>);
15
16#[derive(Deserialize, JsonSchema)]
17struct DeleteArgs {
18 #[serde(default)]
20 path: Option<String>,
21 #[serde(default)]
23 paths: Option<Vec<String>>,
24}
25
26#[async_trait::async_trait]
27impl<B: FileBackend> Tool for DeleteTool<B> {
28 fn name(&self) -> &str {
29 "delete"
30 }
31 fn description(&self) -> &str {
32 "Delete one or more files. Pass `path` for a single file, or `paths` (array) to delete many files at once."
33 }
34 fn parameters_schema(&self) -> Value {
35 json_schema_for::<DeleteArgs>()
36 }
37 async fn execute(&self, args: Value, _ctx: &mut AgentContext) -> Result<ToolOutput, ToolError> {
38 let a: DeleteArgs = parse_args(&args)?;
39
40 let targets: Vec<String> = match (a.path, a.paths) {
41 (_, Some(ps)) if !ps.is_empty() => ps,
42 (Some(p), _) => vec![p],
43 _ => {
44 return Err(ToolError::InvalidArgs(
45 "provide `path` (string) or `paths` (array)".into(),
46 ));
47 }
48 };
49
50 let mut results: Vec<String> = Vec::with_capacity(targets.len());
51 let mut errors: Vec<String> = Vec::new();
52
53 for path in &targets {
54 match self.0.delete(path).await {
55 Ok(()) => results.push(format!("Deleted {}", path)),
56 Err(e) => errors.push(format!("FAILED {}: {}", path, e)),
57 }
58 }
59
60 let mut out = results.join("\n");
61 if !errors.is_empty() {
62 if !out.is_empty() {
63 out.push('\n');
64 }
65 out.push_str(&errors.join("\n"));
66 }
67 if out.is_empty() {
68 out = "No files deleted".to_string();
69 }
70 Ok(ToolOutput::text(out))
71 }
72}