|
| 1 | +# Using with Different Agents |
| 2 | + |
| 3 | +Ralphify works with **any CLI that reads a prompt from stdin and exits when done**. Claude Code is the default, but you can swap in any tool that follows this contract. |
| 4 | + |
| 5 | +This page shows how to configure ralphify for popular agents and how to write your own wrapper. |
| 6 | + |
| 7 | +## What ralphify needs from an agent |
| 8 | + |
| 9 | +Every iteration, ralphify runs your agent like this: |
| 10 | + |
| 11 | +``` |
| 12 | +echo "<assembled prompt>" | <command> <args...> |
| 13 | +``` |
| 14 | + |
| 15 | +Your agent must: |
| 16 | + |
| 17 | +1. **Read a prompt from stdin** — the full assembled prompt (with contexts, instructions, and any check failures) is piped in |
| 18 | +2. **Do work in the current directory** — edit files, run commands, make commits |
| 19 | +3. **Exit when done** — exit code 0 means success, non-zero means failure |
| 20 | + |
| 21 | +That's it. No special protocol, no API — just stdin in, work done, process exits. |
| 22 | + |
| 23 | +## Claude Code |
| 24 | + |
| 25 | +The default configuration. Claude Code's `-p` flag reads from stdin and runs non-interactively. |
| 26 | + |
| 27 | +```toml |
| 28 | +[agent] |
| 29 | +command = "claude" |
| 30 | +args = ["-p", "--dangerously-skip-permissions"] |
| 31 | +prompt = "PROMPT.md" |
| 32 | +``` |
| 33 | + |
| 34 | +| Flag | Purpose | |
| 35 | +|---|---| |
| 36 | +| `-p` | Non-interactive mode — reads prompt from stdin, prints output, exits | |
| 37 | +| `--dangerously-skip-permissions` | Skips approval prompts so the agent can work autonomously | |
| 38 | + |
| 39 | +Install Claude Code: |
| 40 | + |
| 41 | +```bash |
| 42 | +npm install -g @anthropic-ai/claude-code |
| 43 | +``` |
| 44 | + |
| 45 | +!!! info "Why `--dangerously-skip-permissions`?" |
| 46 | + Without this flag, Claude Code pauses to ask for approval before editing files, running commands, or making commits. In an autonomous loop, nobody is there to approve — so the agent would hang forever. Checks act as your guardrails instead. |
| 47 | + |
| 48 | +## Aider |
| 49 | + |
| 50 | +[Aider](https://aider.chat) is an AI pair-programming tool that works with multiple LLM providers. It supports a message flag that accepts the prompt directly. |
| 51 | + |
| 52 | +```toml |
| 53 | +[agent] |
| 54 | +command = "bash" |
| 55 | +args = ["-c", "aider --yes-always --no-auto-commits --message \"$(cat -)\""] |
| 56 | +prompt = "PROMPT.md" |
| 57 | +``` |
| 58 | + |
| 59 | +| Flag | Purpose | |
| 60 | +|---|---| |
| 61 | +| `--yes-always` | Auto-approve all changes (no interactive prompts) | |
| 62 | +| `--no-auto-commits` | Let your prompt control when commits happen | |
| 63 | +| `--message "..."` | Pass the prompt as a message instead of stdin | |
| 64 | + |
| 65 | +!!! note "Why the bash wrapper?" |
| 66 | + Aider doesn't natively read prompts from stdin. The `bash -c` wrapper reads stdin with `cat -` and passes it as a `--message` argument. This is a common pattern for adapting tools that don't support piped input directly. |
| 67 | + |
| 68 | +### Aider with a specific model |
| 69 | + |
| 70 | +```toml |
| 71 | +[agent] |
| 72 | +command = "bash" |
| 73 | +args = ["-c", "aider --yes-always --no-auto-commits --model claude-3-5-sonnet-20241022 --message \"$(cat -)\""] |
| 74 | +prompt = "PROMPT.md" |
| 75 | +``` |
| 76 | + |
| 77 | +## Codex CLI |
| 78 | + |
| 79 | +[OpenAI Codex CLI](https://github.com/openai/codex) can be configured to run non-interactively. |
| 80 | + |
| 81 | +```toml |
| 82 | +[agent] |
| 83 | +command = "bash" |
| 84 | +args = ["-c", "codex --approval-mode full-auto \"$(cat -)\""] |
| 85 | +prompt = "PROMPT.md" |
| 86 | +``` |
| 87 | + |
| 88 | +| Flag | Purpose | |
| 89 | +|---|---| |
| 90 | +| `--approval-mode full-auto` | Skip all approval prompts for autonomous operation | |
| 91 | + |
| 92 | +## Custom wrapper script |
| 93 | + |
| 94 | +For full control, write a wrapper script that reads stdin and calls your agent however it needs to be called. |
| 95 | + |
| 96 | +**`ralph-agent.sh`** |
| 97 | + |
| 98 | +```bash |
| 99 | +#!/bin/bash |
| 100 | +set -e |
| 101 | + |
| 102 | +# Read the prompt from stdin |
| 103 | +PROMPT=$(cat -) |
| 104 | + |
| 105 | +# Call your agent however it works |
| 106 | +# Examples: |
| 107 | +# curl an API, save response, apply changes |
| 108 | +# call a local LLM with the prompt |
| 109 | +# pipe to any tool that accepts text input |
| 110 | + |
| 111 | +my-custom-agent --input "$PROMPT" --auto-approve |
| 112 | +``` |
| 113 | + |
| 114 | +```bash |
| 115 | +chmod +x ralph-agent.sh |
| 116 | +``` |
| 117 | + |
| 118 | +**`ralph.toml`** |
| 119 | + |
| 120 | +```toml |
| 121 | +[agent] |
| 122 | +command = "./ralph-agent.sh" |
| 123 | +args = [] |
| 124 | +prompt = "PROMPT.md" |
| 125 | +``` |
| 126 | + |
| 127 | +### Python wrapper example |
| 128 | + |
| 129 | +**`ralph-agent.py`** |
| 130 | + |
| 131 | +```python |
| 132 | +#!/usr/bin/env python3 |
| 133 | +"""Custom agent wrapper that reads a prompt from stdin.""" |
| 134 | + |
| 135 | +import subprocess |
| 136 | +import sys |
| 137 | + |
| 138 | +prompt = sys.stdin.read() |
| 139 | + |
| 140 | +# Transform the prompt, call APIs, run tools — whatever you need |
| 141 | +result = subprocess.run( |
| 142 | + ["my-tool", "--prompt", prompt], |
| 143 | + check=True, |
| 144 | +) |
| 145 | + |
| 146 | +sys.exit(result.returncode) |
| 147 | +``` |
| 148 | + |
| 149 | +```bash |
| 150 | +chmod +x ralph-agent.py |
| 151 | +``` |
| 152 | + |
| 153 | +```toml |
| 154 | +[agent] |
| 155 | +command = "./ralph-agent.py" |
| 156 | +args = [] |
| 157 | +prompt = "PROMPT.md" |
| 158 | +``` |
| 159 | + |
| 160 | +## Testing your agent setup |
| 161 | + |
| 162 | +Before running the full loop, verify your agent works with a simple prompt: |
| 163 | + |
| 164 | +```bash |
| 165 | +echo "Say hello and create a file called test.txt with the word 'hello' in it." | <your-command> <your-args> |
| 166 | +``` |
| 167 | + |
| 168 | +Then check: |
| 169 | + |
| 170 | +```bash |
| 171 | +cat test.txt # Should contain "hello" |
| 172 | +rm test.txt # Clean up |
| 173 | +``` |
| 174 | + |
| 175 | +If this works, your agent is compatible with ralphify. Run `ralph status` to verify the full setup: |
| 176 | + |
| 177 | +```bash |
| 178 | +ralph status |
| 179 | +``` |
| 180 | + |
| 181 | +You should see a green checkmark next to your command: |
| 182 | + |
| 183 | +``` |
| 184 | +✓ Command '<your-command>' found on PATH |
| 185 | +``` |
| 186 | + |
| 187 | +## Agent compatibility checklist |
| 188 | + |
| 189 | +| Requirement | Why | |
| 190 | +|---|---| |
| 191 | +| Reads prompt from stdin (or via wrapper) | Ralphify pipes the assembled prompt to the agent's stdin | |
| 192 | +| Works non-interactively | No human is present to approve actions during the loop | |
| 193 | +| Exits when done | Ralphify waits for the process to finish before running checks | |
| 194 | +| Returns meaningful exit codes | Exit 0 = success, non-zero = failure (used by `--stop-on-error`) | |
| 195 | +| Operates on files in the current directory | Checks validate the project state after the agent runs | |
| 196 | + |
| 197 | +## Tips for non-Claude-Code agents |
| 198 | + |
| 199 | +**Disable auto-commits if your prompt handles commits.** Most agents have an auto-commit feature. If your `PROMPT.md` includes commit instructions, disable the agent's built-in commits to avoid double-committing or conflicts. |
| 200 | + |
| 201 | +**Test with `-n 1` first.** Run a single iteration to verify the agent receives the prompt correctly and produces useful output: |
| 202 | + |
| 203 | +```bash |
| 204 | +ralph run -n 1 --log-dir ralph_logs |
| 205 | +cat ralph_logs/001_*.log |
| 206 | +``` |
| 207 | + |
| 208 | +**Use `--timeout` as a safety net.** If the agent hangs or enters an interactive mode you didn't expect, the timeout kills it so the loop doesn't stall forever: |
| 209 | + |
| 210 | +```bash |
| 211 | +ralph run --timeout 300 |
| 212 | +``` |
| 213 | + |
| 214 | +**Check that the agent's PATH is correct.** Some agents need specific tools (compilers, linters, package managers) available. Make sure everything the agent might call is on your PATH before starting the loop. |
0 commit comments