models:
Syntax
models: fast <model>, strong <model>
What it does
Name two tiers โ a fast model and a strong one โ and the engine auto-assigns them by phase: plan / reflect / also โ fast and act โ strong. observe is a shell check with no model at all, so it never costs a token. The reasoning is economic: most cycles are cheap thinking (planning the change, digesting a failure, running finishing passes) and only the act phase writes code that has to be right. Paying strong-model rates for every plan and reflect is waste; tiering routes the expensive model to the one phase that needs it and lets a cheap model carry the rest.
You can override any single phase or set them all at once โ models: act fast pulls act down to the cheap tier, models: all strong puts everything on the strong one. Like other config-tier lines it cascades file โ loop โ stage (nearest wins), and a command-line --model flag overrides everything. At the end of a run the engine prints a per-tier cost summary, so the spend is measurable rather than a guess. Pair it with an observe: cost cap to stop a run before it overspends.
Example
models: fast haiku, strong opus # file default
# override: `models: act fast` or `models: all strong`tier the cycle
How it runs
Example โ tier plus a cost cap
models: fast haiku, strong opus
observe:
meter tokens and cost
stop and warn if cost exceeds "$5"cheap thinking, one strong act, a spend ceiling
Common mistakes
- Pulling
actonto the fast tier to save money.actis the phase that writes code โ a weak model here produces changes that fail the check and force more cycles, costing more overall. Keepact strongand economize on plan/reflect. - Expecting
observeto use a model.observeruns yourdone whenshell command; it has no model tier and never appears in the cost summary. Naming a model for it does nothing. - Forgetting the cascade direction. A per-loop or per-stage
models:line overrides the file-level one, and--modeloverrides them all. If a run uses the wrong tier, check the nearest scope, not just the top of the file.