2026-03-27 15:22:48 -04:00
|
|
|
// tools/write.rs — Write file contents
|
|
|
|
|
|
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
2026-04-04 15:34:07 -04:00
|
|
|
pub fn tool() -> super::Tool {
|
2026-04-04 15:50:14 -04:00
|
|
|
super::Tool {
|
|
|
|
|
name: "write_file",
|
|
|
|
|
description: "Create or overwrite a file with the given content.",
|
|
|
|
|
parameters_json: r#"{"type":"object","properties":{"file_path":{"type":"string","description":"Absolute path to write"},"content":{"type":"string","description":"File content"}},"required":["file_path","content"]}"#,
|
2026-04-08 20:38:42 -04:00
|
|
|
handler: Arc::new(|_a, v| Box::pin(async move { write_file(&v) })),
|
2026-04-04 15:50:14 -04:00
|
|
|
}
|
2026-04-04 15:34:07 -04:00
|
|
|
}
|
|
|
|
|
|
2026-04-04 15:50:14 -04:00
|
|
|
#[derive(Deserialize)]
|
|
|
|
|
struct Args { file_path: String, content: String }
|
2026-03-27 15:22:48 -04:00
|
|
|
|
2026-04-04 15:34:07 -04:00
|
|
|
fn write_file(args: &serde_json::Value) -> Result<String> {
|
2026-04-04 15:50:14 -04:00
|
|
|
let a: Args = serde_json::from_value(args.clone()).context("invalid write_file arguments")?;
|
|
|
|
|
if let Some(parent) = std::path::Path::new(&a.file_path).parent() {
|
|
|
|
|
std::fs::create_dir_all(parent).ok();
|
2026-03-27 15:22:48 -04:00
|
|
|
}
|
2026-04-04 15:50:14 -04:00
|
|
|
std::fs::write(&a.file_path, &a.content)
|
|
|
|
|
.with_context(|| format!("Failed to write {}", a.file_path))?;
|
|
|
|
|
Ok(format!("Wrote {} bytes to {}", a.content.len(), a.file_path))
|
2026-03-27 15:22:48 -04:00
|
|
|
}
|