Skip to content

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.

ships with humanize

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.

text
❯ $stateful_ralph find why the parser leaks memory, and fix it
sh
hmz exec -f stateful_ralph -a agent=kimi/kimi-code/k3:high \
    -p budget.duration=6h "$(cat TASK.md)"
stateful_ralphsimulated

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
  1. agent — the task; a session opened for this turn
  2. agent — the task, again; another turn of the session it already had
  3. agent — the task, again; another turn of the session it already had
  4. 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 ​

RoleWhat it isHow it is filled
agentagent, required-a agent=…Takes every round, in the one session the run holds.
workspaceenvironment, localthe directory you start in; no -eWhere 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 ​