Skip to main content

pi_agent/tools/
write.rs

1use async_trait::async_trait;
2use serde_json::{json, Value};
3use tokio::fs;
4
5use crate::types::{AgentTool, AgentToolResult};
6
7pub struct WriteTool;
8
9#[async_trait]
10impl AgentTool for WriteTool {
11    fn name(&self) -> &str {
12        "write"
13    }
14    fn requires_permission(&self) -> bool {
15        true
16    }
17    fn description(&self) -> &str {
18        "Write the given content to the path, replacing any existing file. Creates parent directories as needed."
19    }
20    fn parameters(&self) -> Value {
21        json!({
22            "type": "object",
23            "properties": {
24                "path": {"type": "string"},
25                "content": {"type": "string"}
26            },
27            "required": ["path", "content"]
28        })
29    }
30    async fn execute(&self, _id: &str, args: Value) -> Result<AgentToolResult, String> {
31        let path = args
32            .get("path")
33            .and_then(|v| v.as_str())
34            .ok_or("missing 'path'")?;
35        let content = args
36            .get("content")
37            .and_then(|v| v.as_str())
38            .ok_or("missing 'content'")?;
39        if let Some(parent) = std::path::Path::new(path).parent() {
40            if !parent.as_os_str().is_empty() {
41                fs::create_dir_all(parent).await.ok();
42            }
43        }
44        fs::write(path, content)
45            .await
46            .map_err(|e| format!("write {path}: {e}"))?;
47        Ok(AgentToolResult::text(format!(
48            "wrote {} bytes to {}",
49            content.len(),
50            path
51        )))
52    }
53}