Skip to content
OSOKORO

Capping what an AI agent can spend on one task

Why a daily budget arrives too late, how a reservation has to be taken before the price is known, and what a cap should do when it binds.

Published Aug 22, 20265 minutes to read

Most spend controls on AI tooling are monthly budgets with an email at 80%. That is an accounting control wearing the costume of an engineering one, and the difference shows up on the afternoon a single task goes wrong.

A daily cap tells you about yesterday

The failure that costs money is not a month of steady overuse. It is one task that loops: the agent proposes an edit, the test fails, it reads more files to understand why, the context grows, it tries again, the test fails differently.

Every pass costs more than the last, because each one re-sends the accumulated conversation as input. Turn twelve carries turns one through eleven. That is a curve, not a line, and a daily budget notices it after it has finished.

A cap is useful in proportion to how quickly it interrupts. Codoro's defaults:

CapDefaultWho sets it
Per run$2.00The developer, per task
Per developer per day$25.00The team owner
Markup on your own API key0%Not applicable

The per-run cap is the one that changes behaviour, because it binds while you are still in the room and still remember what you asked for. The daily cap is a backstop against a bad afternoon, which is a different and lesser job.

The hard part: you have to commit before you know the price

This is the part I would not have anticipated before building it.

A model's published price is frequently not one number. The same model can carry a different rate in the US and the EU. Some price by whichever provider endpoint serves the request. Some have tiered long-context rates where crossing an input threshold reprices the entire request, not the excess above the threshold.

And the region and the endpoint are not ours to choose. The gateway decides, after the request is sent.

So a cap has to hold an amount before the thing that determines the amount has happened. There is no way around that ordering, only ways to be honest about it.

Reserve at the worst price, settle at the real one

Two operations, two prices, deliberately kept apart.

The reservation is taken before the first token, at the dearest price the request could possibly attract — the maximum across regional variants and, where a model prices per provider, across the endpoints currently up. In Codoro's generated catalogue that is a distinct field, reserveRates, present only when it differs from the headline price, which for most models it does not.

The settlement is the vendor's actual published rate for what actually happened.

The two errors are both real and they are not symmetric:

  • Reserving at the headline price under-reserves, and under-reserving defeats the whole point. The reservation is the mechanism that stops a run.
  • Settling at the dearest price overcharges, and charges every developer a regional premium their request may never have attracted — on an invoice, where they can see it.

A hold is not a charge. Conflating them is the most expensive small mistake available in this codebase, and keeping them apart is the reason there are two rate tables rather than one.

The same pessimism does not carry over to context and output limits, which are the gateway's published numbers rather than a maximum. Reserving money conservatively protects the customer; truncating a request conservatively just breaks it.

What a cap should do when it binds

Hitting the cap pauses the run and offers a cheaper model. It does not silently downgrade.

That distinction is worth more than it sounds. A run that switched models mid-task would hand you a diff you would review under assumptions that stopped being true partway through — half the work reasoned about by one model and half by another, with nothing in the output saying where the seam is. Pausing is worse ergonomics and better engineering.

It also does not silently continue, which is the other tempting behaviour. A cap that can be exceeded "just this once" is a suggestion.

Setting a number that does something

Set it at something you would be annoyed to hit. A cap above your worst case is decoration. If your typical task costs 30 cents and your worst is $1.80, a $2 cap has never once fired and is not protecting you. Set it at 60 cents and find out how often you are wrong about your typical task.

Raise it deliberately, per task, when you know the task is large. The per-run cap is editable at the point of use precisely so that "this one is a big refactor" is an explicit decision rather than a permanent loosening.

Treat a firing cap as information. The useful question is not "why did it stop" but "why did this cost four times what I expected". Usually the answer is turns: the task was underspecified and the agent spent the budget discovering what you meant.

Bring your own key and the cap still works

With your own API key the markup is zero — the provider bills you directly, the key lives in the macOS keychain and is transmitted only to the vendor that issued it. The caps still apply. They are a property of the runner, not of the billing relationship.

That is the configuration I would pick if you already have provider accounts. The zero-markup path is not a loss-leader with a catch; it is the honest price of a product whose value is the interface rather than the tokens. Hosted credits carry a 40% default markup on cost with published per-model overrides, which after Stripe's 2.9% plus 30 cents nets somewhere near 25% of revenue — that is what you are paying for one bill and no key management.

Where this is

There is no public download. The macOS build is in preview, the download page is a waitlist until a signed release manifest says otherwise, and the numbers above describe the launch model rather than a checkout you can reach today.

The catalogue is real — roughly 216 models synced from Vercel AI Gateway, with a CI check that fails when our committed rates drift from the published ones. That check is the only reason I am willing to put rates in an article that will still be here in a year.

Read next

All writing