Skip to content

goal

Ralph, with the task set as the agent's own goal: a turn that would have ended starts another instead, until the model itself says the objective is met. The loop is only what starts it over where it stopped without having met it.

sh
hmz exec -f goal -a claude/claude-opus-5:max "$(cat TASK.md)"
goal
the agentrun under a goalpursue(task)pursue(task)started over only where it stopped without meeting itbudget0.00M of 10M output tokens

The ticks inside one box are turns the backend started itself: a turn that would have ended starts another, until the model says the objective is met.

Two things decide, and only one of them is your code

The ticks inside one box above are turns the backend started. agent.pursue(task) hands the objective to the backend's own goal feature; what comes back is one call, with as many turns of the model inside it as it thought the objective needed.

That is why you reach for this rather than ralph_loop: "is this done?" is asked by something that has just read the work, every turn, rather than by a while True that cannot tell. The cost is that it is asked by the same thing that did the work, which rlar fixes by asking somebody else.

A backend without a goal feature cannot run this flow, and says so before the first turn rather than an hour in. Which backends have one.

What ends it

The run's allowance — hours, millions of output tokens, dollars. It counts every turn of the model the goal took, not one per round: the backend started them, and the agent counted them all. The flow itself takes no settings; it declares ten million output tokens as what a run of it is worth by default, and -c budget.yaml with a budget: mapping in it, or the budget row in /flow, says otherwise.

An allowance is read at the edges of the session a goal runs in rather than inside it, so a goal that burns for an hour inside one call is not cut off mid-call. It stops at the next round.

What it keeps

rounds. A goal is pursued in a session of its own and nothing of it carries into the next, so a round begun by a run picked up starts from the task and the repository exactly as the first round did.

See also

Released under the Apache-2.0 licence.