use crate::error::AgentError;
use crate::tool::{Tool, ToolResult};
use std::fs;
use std::path::Path;
pub struct WriteFileTool;
impl Tool for WriteFileTool {
fn name(&self) -> &str {
"write"
}
fn description(&self) -> &str {
"Create or overwrite a file with the given content. \
Parent directories are created automatically if they don't exist."
}
fn parameters_schema(&self) -> serde_json::Value {
serde_json::json!({
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to create/overwrite"
},
"content": {
"type": "string",
"description": "Content to write to the file"
}
},
"required": ["path", "content"]
})
}
fn execute(&self, args: &serde_json::Value) -> Result<ToolResult, AgentError> {
let path = args["path"].as_str().ok_or_else(|| AgentError::Tool {
tool: "write".to_string(),
message: "Missing 'path' argument".to_string(),
})?;
let content = args["content"].as_str().ok_or_else(|| AgentError::Tool {
tool: "write".to_string(),
message: "Missing 'content' argument".to_string(),
})?;
let file_path = Path::new(path);
if let Some(parent) = file_path.parent() {
if !parent.exists() {
if let Err(e) = fs::create_dir_all(parent) {
return Ok(ToolResult::err(format!(
"Failed to create directories for '{}': {}",
path, e
)));
}
}
}
match fs::write(file_path, content) {
Ok(_) => {
let lines = content.lines().count();
let bytes = content.len();
Ok(ToolResult::ok(format!(
"Wrote {} lines ({} bytes) to '{}'",
lines, bytes, path
)))
}
Err(e) => Ok(ToolResult::err(format!(
"Failed to write '{}': {}",
path, e
))),
}
}
fn requires_permission(&self) -> bool {
true
}
}