consciousness/src/agent/tools/write.rs
Kent Overstreet dd85a56902 Output tool via Arc<Mutex<Subconscious>> closure — complete
ToolHandler is now Arc<dyn Fn(...)> supporting closures that capture
state. The output tool is created during init_output_tool() as a
closure capturing Arc<Mutex<Subconscious>>, writing directly to
Subconscious.state. No more POC_AGENT_OUTPUT_DIR filesystem hack.

- All tool handlers wrapped in Arc::new()
- Tool is Clone (not Copy) — .copied() → .cloned()
- Subconscious wrapped in Arc<Mutex<>> on Mind
- Dead filesystem-based output() function removed
- memory_tools returns 11 items (output removed from static list)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 20:41:42 -04:00

27 lines
1.1 KiB
Rust

use std::sync::Arc;
// tools/write.rs — Write file contents
use anyhow::{Context, Result};
use serde::Deserialize;
pub fn tool() -> super::Tool {
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"]}"#,
handler: Arc::new(|_a, v| Box::pin(async move { write_file(&v) })),
}
}
#[derive(Deserialize)]
struct Args { file_path: String, content: String }
fn write_file(args: &serde_json::Value) -> Result<String> {
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();
}
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))
}