Rustagent#
It's a pun on rustacean.
Rustagent is an AI agent framework for autonomous task execution in Rust. It uses a two-phase approach: a Planning Agent that breaks down high-level goals into executable tasks, and the Ralph Loop that executes those tasks iteratively with tool access.
The canonical repository for this project is on tangled.org. It is mirrored on GitHub for discoverability.
Features#
- Interactive TUI: Terminal user interface built with ratatui for managing specs and monitoring agent execution
- Planning Agent: Converts high-level specifications into structured execution plans
- Ralph Loop: Autonomous execution agent with Read-Act-Learn-Plan-Help cycle
- Multiple LLM Support: Works with Anthropic (Claude), OpenAI (GPT), and Ollama (local models)
- Tool System: Extensible tools for file operations and shell commands with security validation
- Permission System: CLI prompts for sensitive operations with path and command validation
- Structured Specs: JSON-based specification format with tasks, acceptance criteria, and learnings
Installation#
Prerequisites#
- Rust 1.85.0 or later (for Rust edition 2024 support)
- An API key for your chosen LLM provider (or Ollama running locally)
Build from Source#
# Clone the repository
git clone https://github.com/yourusername/rustagent.git
cd rustagent
# Build the project
cargo build --release
# The binary will be available at target/release/rustagent
Install Locally#
cargo install --path .
Configuration#
Rustagent looks for configuration files in the following locations (in order):
./rustagent.toml(current directory)~/.config/rustagent/config.toml(XDG config directory)~/.rustagent/config.toml(home directory)
Create Configuration File#
Copy the example configuration and customize it:
cp rustagent.toml.example rustagent.toml
Configuration Format#
# LLM Configuration (required)
[llm]
provider = "anthropic" # Options: "anthropic", "openai", "ollama"
model = "claude-sonnet-4-20250514"
max_tokens = 8192 # Maximum tokens per response
# Provider-specific configuration
[anthropic]
api_key = "${ANTHROPIC_API_KEY}" # Environment variable substitution
# Agent settings (required)
[rustagent]
spec_dir = "specs" # Directory for specification files
max_iterations = 100 # Optional: limit execution iterations
# Security settings (optional, has safe defaults)
[security]
shell_policy = "allowlist" # "allowlist", "blocklist", or "unrestricted"
allowed_commands = ["git", "cargo", "npm", "ls", "cat", "grep", "find"]
max_file_size_mb = 10
allowed_paths = ["."]
Environment Variables#
The config system supports environment variable substitution using ${VAR_NAME} syntax:
# Set your API key
export ANTHROPIC_API_KEY="your-api-key-here"
# Or for OpenAI
export OPENAI_API_KEY="your-api-key-here"
Provider Options#
Anthropic (Claude)
[llm]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
[anthropic]
api_key = "${ANTHROPIC_API_KEY}"
OpenAI (GPT)
[llm]
provider = "openai"
model = "gpt-4"
[openai]
api_key = "${OPENAI_API_KEY}"
Ollama (Local)
[llm]
provider = "ollama"
model = "llama2"
[ollama]
base_url = "http://localhost:11434"
Mode-Specific LLM Overrides#
Use different models for planning vs execution:
# Default LLM
[llm]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
# Use a more capable model for planning
[planning.llm]
provider = "anthropic"
model = "claude-opus-4-20250514"
max_tokens = 16384
# Use a faster model for Ralph execution
[ralph.llm]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
max_tokens = 4096
Security Configuration#
Control what operations the agent can perform:
[security]
# Shell policy options:
# "allowlist" - Only listed commands can run (default, safest)
# "blocklist" - All except blocked patterns can run
# "unrestricted" - All commands can run
shell_policy = "allowlist"
# Commands allowed when using allowlist policy
allowed_commands = ["git", "cargo", "npm", "ls", "cat", "grep", "find", "echo", "pwd", "mkdir", "touch"]
# Regex patterns to block when using blocklist policy
blocked_patterns = ["rm\\s+-rf", "sudo"]
# Maximum file size the agent can write (MB)
max_file_size_mb = 10
# Paths the agent can access (relative or absolute)
allowed_paths = ["."]
Usage#
Rustagent provides four commands: init, plan, run, and tui. Running rustagent without a command launches the TUI by default.
Interactive TUI#
Launch the terminal user interface:
rustagent tui
# or simply
rustagent
The TUI provides:
- Spec browsing and management
- Real-time agent execution monitoring
- Interactive spec creation and editing
1. Initialize a Specification#
Create a new agent specification interactively:
rustagent init --spec-dir ./specs
This command (when implemented) will help you create the initial spec structure.
2. Plan: Generate Execution Tasks#
Convert your specification into an execution plan using the Planning Agent:
rustagent plan --spec-dir ./specs
The Planning Agent will:
- Read your high-level specification
- Break it down into concrete, executable tasks
- Add acceptance criteria for each task
- Save the plan as
spec.jsonin your spec directory
3. Run: Execute the Plan#
Execute the generated plan using the Ralph Loop:
rustagent run specs/spec.json
With iteration limit:
rustagent run specs/spec.json --max-iterations 10
The Ralph Loop will:
- Read the next pending task
- Act using available tools to complete the task
- Learn from the results and update the spec
- Plan the next action based on learnings
- Ask for help if blocked (human intervention required)
- Continue until all tasks are complete or max iterations reached
How It Works#
Planning Agent#
The Planning Agent transforms high-level goals into structured execution plans:
- Input: A specification directory containing your requirements
- Process: LLM-powered analysis and task decomposition
- Output: A
spec.jsonfile with structured tasks
Example flow:
User Spec → Planning Agent → Structured Tasks → spec.json
Ralph Loop (Read-Act-Learn-Plan-Help)#
The Ralph Loop is the core execution engine:
- Read: Load the spec and find the next pending task
- Act: Use tools (file operations, shell commands) to work on the task
- Learn: Analyze results and update learnings in the spec
- Plan: Determine the next action based on context
- Help: Ask for human intervention when blocked
The loop continues until:
- All tasks are complete
- A task is blocked (requires human help)
- Maximum iterations reached (if configured)
Specification Format#
Rustagent uses a JSON-based specification format:
{
"name": "implement-user-auth",
"description": "Implement user authentication system with JWT",
"branch_name": "feature/user-auth",
"created_at": "2026-01-20T10:30:00Z",
"tasks": [
{
"id": "task-1",
"title": "Create User model",
"description": "Define User struct with fields for authentication",
"acceptance_criteria": [
"User struct has email, password_hash, and created_at fields",
"Implements proper serialization/deserialization",
"Includes validation for email format"
],
"status": "pending",
"blocked_reason": null,
"completed_at": null
}
],
"learnings": []
}
Task Statuses#
pending: Task is ready to be worked onin_progress: Task is currently being executedcomplete: Task has been successfully completedblocked: Task cannot proceed without human intervention
Available Tools#
Rustagent provides the following tools to agents:
File Operations#
-
read_file: Read contents of a file
{ "name": "read_file", "arguments": { "path": "src/main.rs" } } -
write_file: Write or overwrite file contents
{ "name": "write_file", "arguments": { "path": "src/config.rs", "content": "// File contents here" } } -
list_files: List files in a directory
{ "name": "list_files", "arguments": { "path": "src", "recursive": false } }
Shell Commands#
- run_command: Execute shell commands
{ "name": "run_command", "arguments": { "command": "cargo test", "working_dir": "." } }
Task Completion#
-
signal_completion: Signal task completion or blocked status
{ "name": "signal_completion", "arguments": { "signal": "complete", "message": "Task finished successfully" } }Or to signal blocked:
{ "name": "signal_completion", "arguments": { "signal": "blocked", "reason": "Missing required dependency" } }
Development#
Building#
# Debug build
cargo build
# Release build with optimizations
cargo build --release
# Quick compile check
cargo check
Code Quality#
# Format code
cargo fmt
# Run linter
cargo clippy
Testing#
# Run all tests
cargo test
# Run with logging
RUST_LOG=debug cargo test
# Run specific test
cargo test test_name
Logging#
Rustagent uses tracing for file-based logging. Logs are stored in:
$XDG_STATE_HOME/rustagent/logs/(if XDG_STATE_HOME is set)~/.local/share/rustagent/logs/(macOS/Linux)~/.local/state/rustagent/logs/(fallback)
Logs are rotated daily. To adjust the log level, set the RUST_LOG environment variable:
RUST_LOG=rustagent=debug cargo run -- plan
Documentation#
# Generate and view documentation
cargo doc --open
Project Structure#
rustagent/
├── src/
│ ├── main.rs # CLI entry point with init/plan/run/tui commands
│ ├── lib.rs # Library exports
│ ├── config.rs # Configuration loading with env var substitution
│ ├── logging.rs # File-based tracing with daily rotation
│ ├── spec.rs # Specification data structures
│ ├── llm/
│ │ ├── mod.rs # LlmClient trait and Message types
│ │ ├── anthropic.rs # Anthropic (Claude) client
│ │ ├── openai.rs # OpenAI (GPT) client
│ │ ├── ollama.rs # Ollama (local models) client
│ │ ├── mock.rs # Mock client for testing
│ │ └── factory.rs # Client factory based on config
│ ├── planning/
│ │ └── mod.rs # Planning Agent implementation
│ ├── ralph/
│ │ └── mod.rs # Ralph Loop execution engine
│ ├── security/
│ │ ├── mod.rs # Security validator for paths/commands
│ │ └── permission.rs # Permission handling (CLI prompts)
│ ├── tools/
│ │ ├── mod.rs # Tool trait and registry
│ │ ├── file.rs # read_file, write_file, list_files tools
│ │ ├── shell.rs # run_command tool
│ │ ├── signal.rs # signal_completion tool
│ │ ├── factory.rs # Tool registry factory
│ │ └── permission_check.rs # File permission checking
│ └── tui/
│ ├── mod.rs # TUI module exports and terminal setup
│ ├── app.rs # Application state and event handling
│ ├── ui.rs # UI rendering logic
│ ├── messages.rs # Agent-TUI message channel
│ ├── views/ # View components (spec list, detail, etc.)
│ └── widgets/ # Reusable TUI widgets
├── specs/ # Default directory for specifications
├── tests/ # Integration tests
├── Cargo.toml # Package manifest
└── rustagent.toml # Configuration file (create from example)
Architecture#
Rustagent follows a modular architecture:
- Config System: Multi-provider LLM configuration with environment variable support
- LLM Clients: Abstracted clients for different LLM providers (streaming support)
- Tool System: Trait-based tool implementation with dynamic registry (
Arc<RwLock>for thread safety) - Security Layer: Path and command validation with interactive permission prompts
- Spec Management: JSON persistence layer for task tracking and learning
- TUI: ratatui-based terminal interface with async agent communication via channels
- Agents: Planning Agent and Ralph Loop for two-phase execution
Examples#
Example 1: Create a New Feature#
- Create a specification:
mkdir -p specs/add-logging
echo '{"description": "Add structured logging to the application"}' > specs/add-logging/description.txt
- Generate execution plan:
rustagent plan --spec-dir specs/add-logging
- Execute the plan:
rustagent run specs/add-logging/spec.json
Example 2: Limited Iteration Run#
Run with a safety limit on iterations:
rustagent run specs/spec.json --max-iterations 5
This will stop after 5 iterations, even if tasks remain pending.
References#
- Rust Edition 2024: This project uses Rust edition 2024, stable since Rust 1.85.0
- Version Control: Compatible with both Git and Jujutsu
- Anthropic API: https://docs.anthropic.com/
- OpenAI API: https://platform.openai.com/docs/
- Ollama: https://ollama.ai/
Contributing#
Contributions are welcome! This is an exploration project for implementing AI agents in Rust.
License#
See LICENSE file for details.