recursive-agent 0.6.0

A minimal, orthogonal, self-improving coding agent kernel in Rust
Documentation
# Custom Tools

Implement the `Tool` trait to add new capabilities to the agent.

## The Tool trait

```rust
#[async_trait]
pub trait Tool: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn parameters(&self) -> serde_json::Value;    // JSON Schema object
    async fn call(&self, args: serde_json::Value) -> ToolResult;
}
```

## Minimal example

```rust
use recursive::tools::{Tool, ToolResult};
use serde_json::{json, Value};
use async_trait::async_trait;

pub struct GetCurrentTime;

#[async_trait]
impl Tool for GetCurrentTime {
    fn name(&self) -> &str { "get_current_time" }

    fn description(&self) -> &str {
        "Returns the current UTC time in ISO 8601 format."
    }

    fn parameters(&self) -> Value {
        json!({
            "type": "object",
            "properties": {},
            "required": []
        })
    }

    async fn call(&self, _args: Value) -> ToolResult {
        let now = chrono::Utc::now().to_rfc3339();
        ToolResult::success(now)
    }
}
```

Then register it:

```rust
let tools = ToolRegistry::local()
    .register(Arc::new(GetCurrentTime));
```

## ToolResult

```rust
pub struct ToolResult {
    pub content: String,
    pub is_error: bool,
}

impl ToolResult {
    pub fn success(content: impl Into<String>) -> Self { ... }
    pub fn error(content: impl Into<String>) -> Self { ... }
}
```

## Built-in tools reference

| Tool name | Struct | Description |
|---|---|---|
| `read_file` | `ReadFile` | Read file contents (sandboxed) |
| `write_file` | `WriteFile` | Write or create a file |
| `apply_patch` | `ApplyPatch` | Apply a V4A patch |
| `list_dir` | `ListDir` | List directory contents |
| `run_shell` | `RunShell` | Execute a shell command |
| `search_files` | `SearchFiles` | Regex search across files |
| `web_fetch` | `WebFetch` | HTTP GET (requires `web_fetch` feature) |
| `remember` | `Remember` | Store a value in memory |
| `recall` | `Recall` | Retrieve a value from memory |
| `forget` | `Forget` | Delete a memory entry |

## Sandbox safety

All built-in filesystem tools resolve paths through `tools::resolve_within(workspace, path)`, which rejects paths that escape the workspace root (via `..`, symlinks, absolute paths, etc.).

When building custom tools that access the filesystem, use the same helper:

```rust
use recursive::tools::resolve_within;

let safe_path = resolve_within(&self.workspace, &user_provided_path)?;
```