Skip to main content

deepseek/agent/builtin_tools/
write.rs

1use async_trait::async_trait;
2use serde_json::{json, Value};
3
4use crate::agent::tool::{Tool, ToolDefinition};
5
6
7pub struct WriteTool;
8
9#[async_trait]
10impl Tool for WriteTool {
11    fn name(&self) -> &str {
12        "Write"
13    }
14
15    fn definition(&self) -> ToolDefinition {
16        ToolDefinition {
17            name: self.name().to_string(),
18            description:
19                "Create or overwrite a file. Parent directories are created automatically."
20                    .into(),
21            parameters: json!({
22                "type": "object",
23                "properties": {
24                    "path":    { "type": "string" },
25                    "content": { "type": "string" }
26                },
27                "required": ["path", "content"]
28            }),
29        }
30    }
31
32    async fn call_json(&self, args: Value) -> Result<String, String> {
33        let path = args
34            .get("path")
35            .and_then(Value::as_str)
36            .ok_or_else(|| "Write: missing string `path`".to_string())?;
37        let content = args
38            .get("content")
39            .and_then(Value::as_str)
40            .ok_or_else(|| "Write: missing string `content`".to_string())?;
41
42        if let Some(parent) = std::path::Path::new(path).parent() {
43            if !parent.as_os_str().is_empty() {
44                tokio::fs::create_dir_all(parent)
45                    .await
46                    .map_err(|e| format!("Write({path}): mkdir parent: {e}"))?;
47            }
48        }
49        tokio::fs::write(path, content)
50            .await
51            .map_err(|e| format!("Write({path}): {e}"))?;
52        Ok(format!("Wrote {} bytes to {path}", content.len()))
53    }
54}