stateful_ralph
Leave one agent on a task it has to remember. One session holds the whole run and is sent the task again every round, so the agent keeps every approach it has already ruled out.
Nothing to install: it is in hmz from the first run, with chat and the other loops, and its code is humanize's flows/builtin/stateful_ralph.
❯ $stateful_ralph find why the parser leaks memory, and fix ithmz exec -f stateful_ralph -a agent=kimi/kimi-code/k3:high \
-p budget.duration=6h "$(cat TASK.md)"The whole run, at rest. Step through it with the buttons, or drag the bar.
One session is one conversation, so its context grows with every round — the thread thickens — and that is the other limit a long run of this reaches.
The run, turn by turn
- agent — the task; a session opened for this turn
- agent — the task, again; another turn of the session it already had
- agent — the task, again; another turn of the session it already had
- agent — the task, again; another turn of the session it already had
Then round again: the same conversation, one round longer.
It ends when the budget runs out, or 3 rounds in a row answer nothing.
When to use it
Reach for it when the work is exploratory, and what has already been tried is the expensive thing to find out again. The opposite trade is ralph_loop, which is the better choice when the work is simply long.
What grows is the conversation. Six hours in, the backend is compacting or summarising it, or refusing to take more. That limit is the backend's, not the budget's.
Roles and params
| Role | What it is | How it is filled | |
|---|---|---|---|
agent | agent, required | -a agent=… | Takes every round, in the one session the run holds. |
workspace | environment, local | the directory you start in; no -e | Where every round works. |
Each agent role takes one -a role=CLI[@PROVIDER]/MODEL[:EFFORT]; several roles may share one -a, comma-separated. There is no -e to give: workspace is a local environment, the directory you start the run in, and an -e naming it is refused. See Command-line specs.
No params. The loop pauses 5 seconds between rounds.
What ends it
- The budget. Whichever of its limits runs out first.
- Three rounds in a row that answer nothing. A round whose turn fails counts as one that answered nothing, as in ralph_loop.
Picking it up
--resume carries on the round count, and nothing else: the session is not picked up. The resumed run opens a new conversation that starts from the task and the repository, with none of the earlier rounds in it. A loop stopped on round 40 says round 41 when it starts again, and remembers nothing of the forty. See Picking a run up.
See also
- continue_loop: one session too, told "continue" instead of the task
- ralph_loop: a fresh session every round