The Quick button did nothing
Our composer offered Quick, Structured and Deep. In a real run, all three changed only the wording of the prompt. This is how we found out and what replaced them.
- Engineering & Data
- Product & UX
- Kind
- Build log
- Min read
- 04
- Sections
- 06
On this page6 sections
When we traced a slow five-word reply (we wrote that run up in an earlier post), the thread had the Quick toggle switched on. It took 30 seconds anyway. So we asked a narrower question: what does Quick change in a real run?
Tracing each control
We followed every composer control from the browser to the provider request. This is what the audit table said on 11 October:
| Control | What it changed in a real run |
|---|---|
| Quick / Structured / Deep | A routing label and some plan text in the prompt. Same model, same token cap, same timeout, same single call. |
| Operator default model | Ignored. The model came from the workspace setting, or a test model from the environment. |
| Output quality, format, approval | One line each in a "Run contract" block of the prompt. |
| Model routes | Nothing. Only the registry panel read them. |
The routing mode did reach the provider, as metadata. Nothing on our side read it to choose a model, a cap or a timer. Every run used one global output cap, and one 60-second timer measured over the whole request.
So the Quick toggle in that slow run could not have made it faster. It changed a few words the model read.
Why the obvious fix was not enough
The tempting fix was to map Quick to a smaller model and move on. The audit found two problems with that.
First, we had no control over how hard a model reasons. Our request body carried the model, messages, a token cap, temperature and metadata. No reasoning effort. Reasoning tokens are paid as output and count against the cap, so on a small cap they can eat the whole reply, and on a large one they cost time.
Second, the owner's direction was different models for different purposes, with a reasoning model only where it pays. That meant giving people the choice directly, by model and by reasoning level, instead of a label that promised speed.
What we built
Three model slots
Settings now has three slots: Fast, Balanced and Deep thinking. Each holds a model and an optional reasoning level. The suggested starting models come from route chains we had already designed and never used, and a heavy reasoner is never the default. If a saved model stops being available, the slot falls back to the workspace default.
"Deep thinking" is named with care: one model given more time to think. We do not run teams of agents yet, and the label should not suggest we do.
A model pill on every message
The composer has a pill to pick the workspace default, a slot, or any selectable model for one message. The server re-checks that choice against the registry, pricing and spend caps. An unknown model is refused with a 409, never quietly swapped for another.
Reasoning effort, sent only where it is accepted
We send a reasoning effort only for models whose OpenRouter listing says they accept one. We never send "off" to a model that always reasons. The effort is bound into the request fingerprints, so a planned run and its dispatch must agree.
Two timers instead of one
A first-response timer, 30 seconds by default, catches a provider that never starts. A total budget grows with effort: at least 120 seconds at medium and 240 at high. Each one fails with its own message and a next step.
The finding that surprised us
Once the registry sync recorded each model's reasoning settings, we could see what models do when we send no effort at all. Sonnet 5.5 and Opus 5.5 reason at high by default. GPT-6 Luna reasons at medium.
That meant a "Fast" slot holding a quick model, with no level set, was not fast. The model's own default was doing the thinking.
So each slot now starts with an explicit level: Fast as light as its model allows (Off where possible), Balanced at Low, Deep thinking at High. The "Model default" option in the menu now says what that default is, for example "Model default (High)", so nobody has to guess.
Feeling fast as well as being fast
Two smaller changes in the same pass:
- The worker's idle poll ceiling dropped from 5 seconds to 1, so a job is picked up sooner after a quiet spell.
- Before the first words arrive, the live run says "Thinking", and after 20 seconds "Still thinking", with an elapsed clock that keeps ticking. Silence no longer looks like a hang.
Where Quick stands now
The Quick and Structured choices are still in the composer, and they still describe the shape of the request (one operator, or an operator plus a playbook). They do not pick the model. Speed comes from the model pill and its reasoning level. Per-mode profiles, where a mode would carry its own cap and model tier, are still on the plan and not built. Nor is a per-slot output cap, because final dispatch still pins one cap for every call. Deep stays hidden until there is a real multi-step runner behind it.
Read next
- 01We had 10,000 lines of multi-agent code. None of it called a model.Our app had a planner, scheduler, worker queue and tool registry for teams of agents. An audit found all of it ran as a local simulation. Here is what we kept and what we fixed first.
- 02Every run said 'Passed'. Nothing had been checked.Real runs in our app were stamped 'Passed' by a hard-coded line. Here is how we found it, what the app shows now, and what it still does not check.
- 03Five words, 5,325 tokens: how our app turned 'say hello' into a product specA five-word greeting took about 30 seconds and 5,325 tokens in our closed test. We traced why, and most of the cause was our own defaults.
Newsletter
The next note, by email.
Guides, analysis and build log entries as they are published, plus new Library records. Occasional, practical, easy to leave.