llama-cpp-v3-agent-sdk 0.1.7

Agentic tool-use loop on top of llama-cpp-v3 — local LLM agents with built-in tools
Documentation
use crate::error::AgentError;
use crate::tool::{Tool, ToolResult};
use std::fs;
use std::path::Path;

/// Create or overwrite files.
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);

        // Create parent directories if needed
        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
    }
}