saorsa-agent 0.1.0

AI coding agent runtime with tool execution
Documentation
# saorsa-agent

Agent runtime for the Saorsa AI framework, providing a complete environment for AI agents to execute tools and interact with the system.

## Overview

The `saorsa-agent` crate implements the core agent loop that enables AI models to:
- Execute tools in a controlled environment
- Manage tool sessions and state
- Handle tool execution errors and recoveries
- Provide a unified interface for multiple LLM providers

## Features

### Agent Core
- **Tool Registry**: Manages available tools and their schemas
- **Session Management**: Maintains context across tool calls
- **Error Recovery**: Handles tool failures gracefully
- **Streaming Support**: Processes streaming responses from LLM providers

### Tool Suite

The agent comes with a comprehensive suite of built-in tools:

#### File Operations Tools

##### Read Tool (`read`)
Read file contents with optional line range filtering.

**Usage:**
```json
{
  "file_path": "/path/to/file.txt"
}
```

**With line range:**
```json
{
  "file_path": "/path/to/file.txt",
  "line_range": "10-20"
}
```

**Examples:**
- Read entire file: `{"file_path": "src/main.rs"}`
- Read lines 5-10: `{"file_path": "src/main.rs", "line_range": "5-10"}`
- Read from line 20 onwards: `{"file_path": "src/main.rs", "line_range": "20-"}`

##### Write Tool (`write`)
Write content to files with automatic directory creation.

**Usage:**
```json
{
  "file_path": "/path/to/file.txt",
  "content": "File content here"
}
```

##### Edit Tool (`edit`)
Perform surgical text replacements in files.

**Usage:**
```json
{
  "file_path": "/path/to/file.txt",
  "old_text": "old text",
  "new_text": "new text",
  "replace_all": false
}
```

##### Grep Tool (`grep`)
Search file contents using regex patterns.

**Usage:**
```json
{
  "pattern": "fn main",
  "path": "/path/to/search",
  "case_insensitive": false
}
```

##### Find Tool (`find`)
Locate files by name patterns.

**Usage:**
```json
{
  "pattern": "*.rs",
  "path": "/path/to/search"
}
```

##### Ls Tool (`ls`)
List directory contents with metadata.

**Usage:**
```json
{
  "path": "/path/to/directory",
  "recursive": false
}
```

#### System Operations Tools

##### Bash Tool (`bash`)
Execute bash commands in a controlled environment.

**Usage:**
```json
{
  "command": "echo 'Hello, World!'"
}
```

**With working directory:**
```json
{
  "command": "ls -la",
  "working_directory": "/tmp"
}
```

**With timeout:**
```json
{
  "command": "sleep 2",
  "timeout_ms": 1000
}
```

## Quick Start

### Basic Agent Usage

```rust
use saorsa_agent::{Agent, ToolRegistry};
use saorsa_ai::AnthropicProvider;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create an agent
    let agent = Agent::new();
    
    // Add your LLM provider
    let anthropic = AnthropicProvider::new()?;
    agent.add_provider("anthropic", Box::new(anthropic));
    
    // Start an agent session
    let mut session = agent.start_session(
        "You are a helpful assistant that can use tools.",
        "anthropic",
    )?;
    
    // Process user messages
    let response = session.process_message(
        "List the files in the current directory",
    ).await?;
    
    println!("Response: {}", response);
    
    Ok(())
}
```

### Using Specific Tools

```rust
use saorsa_agent::tools::{ReadTool, BashTool};

// Read a file
let read_tool = ReadTool;
let result = read_tool.execute(
    &serde_json::json!({
        "file_path": "Cargo.toml"
    }),
    std::env::current_dir()?,
    None,
)?;

println!("File content: {}", result);

// Execute a bash command
let bash_tool = BashTool;
let result = bash_tool.execute(
    "ls -la src/",
    std::env::current_dir()?,
    None,
)?;

println!("Command output: {}", result);
```

## Agent Configuration

### Tool Registry

The agent maintains a registry of available tools:

```rust
use saorsa_agent::Agent;

let agent = Agent::new();
let registry = agent.tool_registry();

// List all available tools
for name in registry.tool_names() {
    println!("Tool: {}", name);
}

// Get a specific tool
if let Some(tool) = registry.get_tool("read") {
    println!("Tool schema: {}", tool.schema());
}
```

### Custom Tools

You can add custom tools to the registry:

```rust
use saorsa_agent::{Tool, ToolRegistry};

struct CustomTool;

impl Tool for CustomTool {
    fn name(&self) -> &'static str {
        "custom"
    }
    
    fn description(&self) -> &'static str {
        "A custom tool implementation"
    }
    
    fn schema(&self) -> &str {
        r#"
        {
          "type": "object",
          "properties": {
            "input": {"type": "string"}
          }
        }
        "#
    }
    
    fn execute(&self, input: &serde_json::Value, _context: ToolContext) -> Result<String, ToolError> {
        // Your tool implementation here
        Ok("Custom tool result".to_string())
    }
}

// Add to registry
let mut registry = ToolRegistry::new();
registry.register_tool(Box::new(CustomTool));
```

## Error Handling

All tool operations return a `Result`:

```rust
use saorsa_agent::ToolError;

match read_tool.execute(input, context, timeout) {
    Ok(output) => println!("Success: {}", output),
    Err(ToolError::FileNotFound(path)) => eprintln!("File not found: {}", path),
    Err(ToolError::PermissionDenied(path)) => eprintln!("Permission denied: {}", path),
    Err(e) => eprintln!("Error: {}", e),
}
```

## Security Considerations

- **File Operations**: Restricted to the working directory tree
- **Command Execution**: Runs in a sandboxed environment with timeout limits
- **Input Validation**: All tool inputs are validated against JSON schema
- **Logging**: All tool executions are logged for auditability

## Development

### Running Tests

```bash
cargo test --all-features
```

### Integration Tests

Run the tool suite integration tests:

```bash
cargo test tool_integration -- --nocapture
```

## License

This project is licensed under either of:

- Apache License, Version 2.0, ([LICENSE-APACHE]LICENSE-APACHE or
  https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or
  https://opensource.org/licenses/MIT)

at your option.