Skip to content

The third most cited requirement, 18 of 26 clients

Anyone can make a model
call a function.

What clients ask about is never that. It is “what made it reliable, and what broke along the way”, and “how do you design gates to stop an agent doing the wrong thing”. Both questions are about the moment a step fails, so that is what this page is built to show.

Give it a goal, or press the second button and watch it fail and recover. Every model turn, tool call, retry and refusal is printed as it happens.

The checkbox changes the prompt and nothing else. The gate, the retry rules and the budget are the same either way, which is the whole point of offering it.

What building this actually taught me

Asked to repeat a write, the model read the rule in the prompt and refused on its own. The gate never fired. That looked like proof the prompt was doing the work.

On the next run, same prompt, same goal, it tried anyway and the gate refused it. The same instruction produced both behaviours on two runs a minute apart.

That is the argument for the gate, and it is not one I had before building it. A prompt rule usually works, which is exactly what makes it dangerous: it will hold for every test you run and fail on the one you did not.

Five decisions, and why each one is there

01

The gate is code, not a sentence in the prompt

A rule in a prompt is a request. The model can be argued out of it, and one that has been still reports success. The gate runs inside the loop, before any tool does, so nothing routes around it. The checkbox above proves that: take the rules out of the prompt and the same calls are refused.

02

A failed write is never retried

A read that fails can be repeated at no cost. A write that fails may well have succeeded on the far side before the answer got lost, and retrying it is how one intention becomes two records. The loop refuses and says so, rather than guessing. That is the idempotency question every client asks and the honest answer is that the code will not gamble.

03

A failure is handed back, not thrown

When a tool fails for good the model is told what happened and asked to carry on without it. An agent that cannot be told a step failed cannot recover from one, and recovering is the whole thing worth demonstrating. Try the second button: the site does not exist, it is retried with backoff, and the agent then says so instead of inventing what the tool would have returned.

04

Two budgets, because one is not enough

Six model turns and forty eight seconds, whichever runs out first. A step budget will not save you from one slow tool, and a clock will not save you from a model circling quickly. When a budget stops a run, the page says so.

05

The tools are the rest of this site

The audit engine, the GitHub client and the Python PDF service are all things you can operate on their own from other pages here, so an agent composing them is not a demonstration standing on nothing. The one tool that writes goes through the same scoped session and audit log as everything else.

How it is tested without a model

The loop takes the model and the tools as arguments, so all 42 tests run without a key and without touching the network. That matters because the interesting cases are the ones that are hard to produce against a real model on purpose: a tool that fails once then works, a tool that never works, a model that invents a tool name, a model that emits broken JSON, and a model that will not stop.

npx tsx lib/agent/loop.test.ts     42 tests, none of which call a model

What this is not

One agent, six tools, no delegation. There are no subagents and no planner separate from the executor, so anything about coordinating several agents is not shown here and is not claimed.

Memory lasts one run. The note it writes survives, and the agent starts the next run knowing nothing, so this says nothing about learning across sessions.

A tool result is text from somewhere else, which is a route for prompt injection. The gate limits the damage because it does not read the tool output, and that is a bound rather than a defence. Nothing here has been red teamed.

Every run costs money and makes real outbound requests, so it is rationed to four a minute.

The tools it calls are the audit engine, the GitHub client and the Python PDF service, each of which you can operate on its own. The whole list is 41 requirements from 114 job posts.