Meet Ralph
An autonomous agent loop that runs continuously until all PRD items are complete. No bash scripts needed β everything runs within ADK-Rust.

Architecture Overview
Built entirely in Rust using ADK-Rust's native loop capabilities
Loop Agent
Main orchestrator that cycles through tasks, delegates work, and tracks overall progress.
Worker Agent
Executes individual tasks with focused context. Implements, tests, and commits changes.
Custom Tools
Native ADK-Rust tools for Git, file operations, quality checks, and PRD management.
Key Capabilities
Ralph showcases the full power of ADK-Rust for autonomous agent development
Autonomous Loop
Continuous execution until all PRD items complete. Native loop tool integration without bash scripts.
Multi-Agent Coordination
Loop Agent orchestrates Worker Agents. Each agent specializes in its role for maximum effectiveness.
Custom Tools
Git, file operations, quality checks, PRD management - all built as native ADK-Rust tools.
PRD-Driven
JSON-based task management with user stories, acceptance criteria, and pass/fail tracking.
Quality Gates
Automated cargo check, test, clippy, and fmt verification before any commit.
State Persistence
Git commits, progress logs, and AGENTS.md updates provide complete memory and auditability.
Implementation Details
Clean, idiomatic Rust code that leverages ADK-Rust's full feature set
use serde::{Deserialize, Serialize};
use std::fs;
use anyhow::Result;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Prd {
pub project: String,
pub branch_name: String,
pub description: String,
pub user_stories: Vec<UserStory>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserStory {
pub id: String,
pub title: String,
pub description: String,
pub acceptance_criteria: Vec<String>,
pub priority: u32,
pub passes: bool,
#[serde(default)]
pub notes: String,
}
impl Prd {
pub fn load(path: &str) -> Result<Self> {
let content = fs::read_to_string(path)?;
let prd: Prd = serde_json::from_str(&content)?;
Ok(prd)
}
pub fn save(&self, path: &str) -> Result<()> {
let content = serde_json::to_string_pretty(self)?;
fs::write(path, content)?;
Ok(())
}
pub fn get_next_task(&self) -> Option<&UserStory> {
self.user_stories
.iter()
.filter(|story| !story.passes)
.min_by_key(|story| story.priority)
}
pub fn mark_complete(&mut self, task_id: &str) -> Result<()> {
if let Some(story) = self.user_stories
.iter_mut()
.find(|s| s.id == task_id)
{
story.passes = true;
}
Ok(())
}
pub fn is_complete(&self) -> bool {
self.user_stories.iter().all(|story| story.passes)
}
pub fn stats(&self) -> (usize, usize) {
let complete = self.user_stories
.iter()
.filter(|s| s.passes)
.count();
let total = self.user_stories.len();
(complete, total)
}
}Project Structure
A clean, modular organization that separates agents, tools, and models for easy maintenance and extension.
ralph/ βββ Cargo.toml # Ralph agent config βββ src/ β βββ main.rs # Entry point β βββ agents/ β β βββ mod.rs β β βββ loop_agent.rs # Main orchestrator β β βββ worker_agent.rs # Task executor β βββ tools/ β β βββ mod.rs β β βββ git_tool.rs # Git operations β β βββ file_tool.rs # File manipulation β β βββ test_tool.rs # Quality checks β β βββ prd_tool.rs # PRD management β βββ models/ β βββ prd.rs # PRD data structures β βββ config.rs # Configuration βββ prd.json # Task list βββ progress.txt # Learnings log
Native vs Bash
Why build autonomous agents natively in Rust instead of orchestrating with shell scripts?
| Aspect | Bash | Native |
|---|---|---|
| Implementation | Shell script + ADK-Rust | Pure Rust |
| Type Safety | Runtime | Compile-time |
| Error Handling | Exit codes | Result<T, E> |
| Concurrency | Sequential | Async/await |
| Tool Integration | Shell commands | Native ADK-Rust tools |
| Debugging | Log files | Tracing + structured logging |
| Performance | Process spawning overhead | Zero-cost abstractions |
| Memory Safety | Manual management | Guaranteed by compiler |
| Testing | Integration tests only | Unit + integration tests |
Ready to Build Your Own Ralph?
Explore the full source code, customize it for your use case, or use it as inspiration for your own autonomous agent systems.