# Ralph — Feature Reference
Complete reference for every feature in Ralph v0.1, grouped by area.
---
## Providers
### Multi-provider LLM support
Ralph supports four LLM backends selected at startup via flag. All share the same tool interface and agentic loop.
| `--anthropic` | `ANTHROPIC_API_KEY` | claude-sonnet-4-6 |
| `--openai` | `OPENAI_API_KEY` | gpt-4o |
| `--deepseek` | `DEEPSEEK_API_KEY` | deepseek-chat |
| `--gemini` | `GEMINI_API_KEY` | gemini-1.5-pro |
A default provider can be set in config so no flag is needed:
```toml
[defaults]
provider = "deepseek"
```
Override the model for a single run: `ralph --anthropic --model claude-opus-4-6`.
### Streaming output (OpenAI / DeepSeek)
OpenAI and DeepSeek support server-sent event streaming. When streaming is available, Ralph prints the LLM's reasoning token-by-token as it arrives rather than showing a spinner. Anthropic and Gemini fall back to a spinner while waiting for the complete response.
### Retry with backoff
All providers retry on 429 (rate limit) and 5xx errors with exponential backoff, up to 3 attempts.
---
## The Ralph Loop
Ralph runs an **observe → plan → execute → verify** cycle, repeating until the LLM calls `declare_done` or `declare_failed`, or until `--max-turns` is reached.
- **Observe**: build workspace context (file tree, git status), compact if needed
- **Plan**: call the LLM with tool definitions; receive tool calls
- **Execute**: dispatch each tool call through the tool registry
- **Verify**: feed results back, continue or exit
---
## Tools available to the LLM
### File tools
| `read_file` | Read a single file |
| `write_file` | Create or overwrite a file (confirmation prompt on overwrite) |
| `edit_file` | Replace an exact string in a file |
| `delete_file` | Delete a file (confirmation required) |
| `list_dir` | List directory contents (gitignore-aware, depth 4) |
| `load_files` | Load all files matching a glob pattern (e.g. `src/**/*.rs`) |
| `explain_code` | Analyze project structure: type detection, directory tree, source previews |
### Shell tools
| `run_command` | Execute a shell command (user confirmation once per session) |
| `run_test` | Run the test suite (whitelisted — no confirmation needed) |
| `run_build` | Run the build (whitelisted — no confirmation needed) |
### Search tools
| `search_web` | Requires `BRAVE_API_KEY` or `SERP_API_KEY` | Web search; top-5 snippets with URLs |
| `search_codebase` | Always available | Regex search across workspace files with line numbers |
### Symbol navigation tools
| `find_symbol` | Case-insensitive substring search across the workspace symbol index |
| `read_symbol` | Read the full source body of a named symbol |
| `go_to_definition` | Jump to the definition of the symbol at a file position |
| `find_references` | Find all usages of the symbol at a file position |
| `hover` | Get type/context information for a symbol at a file position |
Navigation tools use LSP when `--lsp <language>` is active; otherwise fall back to regex search.
### Memory tools
| `remember` | Store a persistent key/value fact about this project |
| `recall` | Retrieve stored facts (empty query returns all) |
### Meta tools
| `ask_user` | Pause and ask the user a clarifying question |
| `declare_done` | Signal task complete with a summary |
| `declare_failed` | Signal task cannot be completed with a reason |
---
## Symbol Index
Ralph builds a workspace-wide symbol index on first use of `find_symbol` or `read_symbol`. The index is built from regex patterns and supports: Rust, C/C++, Python, JavaScript/TypeScript, Go, Java/Kotlin, Ruby.
Index entries include: symbol name, kind (fn/struct/class/etc.), file path, and line number. `read_symbol` extracts the full source body by heuristic brace/indent counting.
---
## LSP Integration
Activated per-language via `--lsp <language>` (repeatable). Multiple languages can be active simultaneously:
```bash
ralph --anthropic --lsp rust --lsp ts "refactor the auth module"
```
Supported languages and their servers:
| `rust` | `rust-analyzer` |
| `ts` / `typescript` | `typescript-language-server --stdio` |
| `python` | `pylsp` |
| `go` | `gopls` |
| `java` | `jdtls` |
| `cpp` / `c` | `clangd` |
LSP clients are **lazily initialized** — the server process is only spawned when the first navigation tool call arrives for a matching file extension. Initialization has a 30-second timeout.
When no LSP is configured (default), all three navigation tools (`go_to_definition`, `find_references`, `hover`) fall back to regex-based grep search.
---
## Project Memory
A persistent JSON store at `~/.ralph/memory/<workspace-hash>/memory.json`, shared across all sessions for the same workspace.
**Facts** (`remember` / `recall`): key/value pairs Ralph stores about the project — architecture decisions, conventions, known issues. Facts are injected into the system prompt at session start so Ralph has project context from turn 1.
**Episodes**: brief summaries of completed or failed tasks, written automatically when Ralph calls `declare_done` or `declare_failed`. The 50 most recent episodes are kept.
---
## Web Search
Web search is provider-agnostic and gated on environment variables:
- `BRAVE_API_KEY` — Brave Search API
- `SERP_API_KEY` — SerpAPI
When a key is set, the `search_web` tool is included in the tool list and the system prompt instructs Ralph to search before making assumptions about APIs, library versions, or recent changes. Without a key, Ralph degrades gracefully (no search tool shown).
---
## Auto-test Loop
When configured, Ralph automatically runs the project test suite after any turn that modifies files, and injects failures back as user messages for Ralph to fix.
Config (`.ralph.toml`):
```toml
[testing]
auto_test = true
cmd = "" # empty = auto-detect (cargo test / pytest / npm test / go test)
max_retries = 3 # give up after this many consecutive failures
```
Detection order: `Cargo.toml` → `go.mod` → `pytest.ini` / `pyproject.toml` → `package.json`.
If `run_test` is already in the tool calls for that turn, auto-test is skipped (Ralph already ran tests itself).
---
## Streaming Output
When the active provider supports streaming (OpenAI, DeepSeek), Ralph prints LLM tokens incrementally as they arrive:
```
[plan] ▶ I'll start by reading the existing auth module to understand...
```
Non-streaming providers show a spinner while waiting.
---
## Session Persistence
Sessions are saved to `~/.ralph/sessions/<session-id>/` after every turn.
| `meta.json` | ID, workspace, provider, model, turn count, status |
| `messages.json` | Full conversation history |
| `compacted.json` | Archived messages after compaction |
**Auto-resume**: on startup Ralph checks for an existing session for the workspace and prompts to resume (configurable). `--resume` skips the prompt; `--new-session` ignores any existing session; `--resume <id>` loads a specific session.
**Session subcommands:**
```bash
ralph sessions list
ralph sessions show <session-id>
ralph sessions clean --older-than 30
```
---
## Context Compaction
When the message history approaches the provider's context window limit (default: 80%), Ralph summarises the conversation using the LLM and replaces the history with a compact window (summary + last N turns verbatim). The full history is archived to `compacted.json`.
Config:
```toml
[compaction]
enabled = true
threshold_pct = 80
keep_recent_turns = 3
```
---
## Checkpoints
Named snapshots of workspace files and conversation history. A `before-revert-<timestamp>` safety checkpoint is always created automatically before any revert, making reverts themselves reversible.
### Creating checkpoints
```bash
ralph --anthropic --checkpoint baseline "your task" # checkpoint before starting
ralph checkpoint create my-name # create mid-session
/cp # interactive browser (see below)
```
Auto-checkpoint before destructive operations:
```toml
[checkpoints]
auto_checkpoint_before_destructive = true
```
### Git commits at checkpoints (opt-in)
When `git_commit = true` and the number of modified files exceeds `git_commit_threshold`, Ralph stages those files and commits them on the current branch with message `ralph checkpoint: <name> (turn <n>)`. The commit SHA is stored in `checkpoint.json` and shown in `/cp`.
Ralph never switches branches, force-pushes, or touches `main`/`master` beyond normal commits.
```toml
[checkpoints]
git_commit = true
git_commit_threshold = 5 # only git-commit when > 5 files modified
```
### Reverting
```bash
ralph checkpoint revert before-auth-refactor # revert by name
ralph checkpoint revert 2 # revert by number
ralph checkpoint revert 2 --files-only # restore files, keep conversation
```
### Checkpoint subcommands
```bash
ralph checkpoint list [--session <id>]
ralph checkpoint create <name> [--session <id>]
ralph checkpoint revert <name-or-number> [--session <id>] [--files-only]
ralph checkpoint show <name-or-number> [--session <id>]
```
---
## Guardrails
### Hard blocks
- **Path traversal**: any path resolving outside the workspace root is rejected
- **Blocked commands**: `rm -rf`, `sudo`, `curl | bash`, `wget | sh` (configurable)
- **Secret detection**: `write_file` content scanned for API key patterns (`sk-`, `AKIA`), private key headers
### Soft guards (confirmation prompts)
- `write_file` on an existing file → `[y/N/d/c]` (yes / no / show diff / checkpoint-then-proceed)
- `delete_file` → `[y/N]`
- `run_command` → `[y/N]` once per session; subsequent calls proceed automatically
`--no-confirm` bypasses soft guards for scripted use.
---
## Diff Preview (`/dp`)
A per-session toggle. When on, every `write_file` call shows the old↔new diff and requires explicit confirmation before proceeding — regardless of whether the file already exists.
```
/dp on enable diff preview
/dp off disable diff preview
/dp toggle
```
Default: **off**. A tip is shown at startup.
---
## Interactive Mode
Launch without a prompt to enter a readline chat loop:
```bash
ralph --anthropic
```
Each task runs a full agentic loop. Session context accumulates across tasks. Ctrl+C cancels the current task without exiting Ralph.
### Slash commands
| `/cp` | Browse checkpoints and revert interactively (numbered list → f/h/c) |
| `/dp` | Toggle diff preview on/off |
| `/dp on` | Enable diff preview |
| `/dp off` | Disable diff preview |
| `/clear` | Clear conversation context (system prompt retained) |
| `/h`, `/help` | Show all commands |
| `exit`, `quit` | Exit Ralph |
### `/cp` — interactive checkpoint browser
```
[ralph] Checkpoints — session a3f1bc
# Name Turn Files When
1 before-auth-refactor 12 4 10m ago *git
2 after-tests-green 7 2 32m ago
3 baseline 1 0 1h ago
Enter number to revert, or Enter to cancel: _
```
After selecting a number:
```
Checkpoint #1 "before-auth-refactor" (turn 12, 4 files)
[f] restore files only — conversation continues as-is
[h] restore files + roll back conversation to turn 12
[c] cancel
→ _
```
`*git` marks checkpoints that were also committed to the repository.
---
## Configuration
**Global**: `~/.ralph/config.toml`
**Workspace**: `.ralph.toml` (takes precedence over global)
Full example:
```toml
[defaults]
provider = "deepseek"
confirm_overwrites = true
[providers.deepseek]
model = "deepseek-chat"
[search]
brave_api_key_env = "BRAVE_API_KEY"
serp_api_key_env = "SERP_API_KEY"
[session]
auto_resume = true
clean_after_days = 30
[compaction]
enabled = true
threshold_pct = 80
keep_recent_turns = 3
[checkpoints]
auto_checkpoint_before_destructive = false
git_commit = false
git_commit_threshold = 5
[testing]
auto_test = false
cmd = ""
max_retries = 3
```
---
## CLI Reference
```
ralph [OPTIONS] [PROMPT]
Provider flags (pick one):
--anthropic Use Anthropic Claude
--openai Use OpenAI
--deepseek Use DeepSeek
--gemini Use Google Gemini
Run options:
--model/-m <model> Override default model
--workspace/-w <dir> Target directory (default: current)
--max-turns <n> Turn limit (default: unlimited)
--dry-run Show planned actions, skip execution
--no-confirm Skip all confirmation prompts
--context <file> Inject extra context from a file
LSP:
--lsp <language> Activate LSP for a language (repeatable)
Supported: rust, ts, python, go, java, cpp
Session:
--resume [id] Resume last session (or specific session by ID)
--new-session Force a new session
Checkpoints:
--checkpoint <name> Create a named checkpoint before starting
--auto-checkpoint Auto-checkpoint before destructive operations
Output:
Subcommands:
sessions list
sessions show <id>
sessions clean --older-than <days>
checkpoint list [--session <id>]
checkpoint create <name> [--session <id>]
checkpoint revert <name-or-number> [--session <id>] [--files-only]
checkpoint show <name-or-number> [--session <id>]
```
---
## Data layout
```
~/.ralph/
config.toml
sessions/
<session-id>/
meta.json
messages.json
compacted.json
checkpoints/
<n>_<name>/
checkpoint.json (includes git_sha if committed)
messages.json
files/ (file snapshots)
memory/
<workspace-hash>/
memory.json
logs/
YYYY-MM-DD_<session-id>.log
```