Right-size every turn
Most coding sessions pay the same headline rate for every turn, even though many turns are mechanical and most of the conversation is old. Squeezy reshapes each turn so the cheap, repetitive work stays cheap and your model budget goes to the reasoning that needs it.
contents
contents
Routing: send the mechanical turns to a smaller model
Not every request needs your main model. “Run the test suite,” “check out main,” “rename this symbol in that file,” “grep for TODOs”, these are well-specified, mechanical asks that a smaller, faster model handles correctly for a fraction of the price. Squeezy keeps a ladder of the models you name -- a cheap rung, the main model you chose, and an optional expensive one -- and moves work down that ladder when the work is simple. Each rung is a model you configure, running on whichever provider you gave it. The ladder dispatches to the rung you pointed at and never compares prices, so naming a genuinely smaller model for the cheap rung is what turns that opportunity into a saving.
Left to itself, every turn starts on your main model, so the first answer is never a gamble; pinning a turn with /router cheap or /router expensive is the exception, and runs the very first step on that rung — as far as that rung can carry it. A pinned cheap turn is still checked before its first request: it has to fit that model's context window as the conversation already stands, and to be able to see any image the turn can reach, and it steps up where it cannot. If that answer asks for tools -- and you did not pin the turn, since a pinned one is decided before the first request and never classified at all -- Squeezy sends a short classification request while those tools run, then applies the verdict to the steps that follow. That request goes to the model you named for it, or failing that to your provider's small classification tier, your cheap rung, or your main model — in that order, so it is usually cheap but never guaranteed to be. The classifier answers on a fixed form: which rung the work belongs on, and whether it leans on earlier conversation. With only a cheap rung configured that is a downgrade or nothing; configure an expensive one and the same verdict can move a turn up instead. If the answer is unclear, or says the turn depends on context a fresh cheap model would not have, the turn stays where it is; if it is merely late, the steps already in flight stay put and the verdict lands on the next one, should the turn have another. A turn that finishes without calling a tool never pays for a classification at all. The rest overlap it with the tools they are already running, and at the boundary where its verdict would take effect Squeezy waits about fifty milliseconds for it, then carries on unchanged and folds a late verdict in at the next boundary; a turn that finishes on that step has no next boundary, and the verdict is dropped. Only a turn already pressed against your session cost cap waits longer than that, where the alternative is dispatching two requests it cannot afford together.
Whole categories are held back. Turns carrying an image stay on your main model while the image bypass is on, which is the default, and you can turn it off to let them route -- to a cheap rung or to a more capable one, either of which is checked for vision before it runs, and falls back to your main model when nothing it can climb to is able to see. A non-image attachment counts as large at the byte threshold you set, and set that to zero and none of them do; images never count toward that total, so a big screenshot is held back by the image bypass or not at all; prompts about containers, package managers, or kernel-level work stay put while the sandbox bypass is on, which is also the default and also yours to turn off. Prompts longer than a few thousand characters and any session with no rung configured beside your main model stay put outright. A follow-up stays put too when its earlier context cannot be summarized for the classifier: a short message that leans on work already done reads as trivial exactly when it is not.
All of this is the cheap rung's: a turn on a more capable rung, whether you pinned it there or the classifier sent it, runs to its end on that rung. If a turn on your cheap rung gets in over its head -- too many tool calls, repeated errors, or a give-up phrase in its own answer -- Squeezy moves it up to your main model, gives it a fresh budget, and carries on inside the same turn; it climbs past that model only where the model cannot see an image the turn has picked up along the way. Output that no longer fits, or an error from the provider itself, is a recovery rather than a step: while the step has produced nothing yet, the turn returns to your main model with its history intact. Once it has produced output, or where the failure is your provider being overloaded rather than something another model could get past, the ordinary retry path takes over instead. The conversation goes with it either way: no restart, nothing to repeat. For the next few prompts the router will not drop below the rung the escalation reached, so a follow-up question cannot flap straight back down to a model that already struggled.
Where the cheaper model runs is your choice. A rung is a model you name, and it runs on whichever provider profile you gave that model — usually the one you already configured, so credentials and billing stay put, but another vendor, or a second profile of your own with its own key, if that is what you pointed it at. Nothing routes at all until you name one: with neither a cheaper nor a more capable rung configured, every turn runs on your main model.
Model is not the only dial, and both of these are switches you own. While tier depth is on, which is the default, each rung runs at the thinking depth that rung warrants; while continuation depth is on, also the default, a step whose only new input is the successful results of tools the model itself asked for a moment earlier runs one step shallower than a fresh question would. Turn either off and that rung keeps the depth its model or profile already asks for. Both also ride the routing master switch: turn routing off and neither applies, even though a turn you pin with /router still runs where you pinned it. Hidden reasoning is billed as output, so that step is real money on mechanical follow-ups. Pin a depth yourself and the continuation step backs off entirely, while the rung takes the shallower of your pin and its own default -- so a pin can lower a routed rung's depth but never raise it.
- /router cheap runs the prompt that carries it on the Cheap target, whatever the router would have decided, or on your main model when no Cheap target resolves.
- /router main runs the next turn on the active role's Model profile and skips routing for it.
- /router expensive runs the prompt on the Expensive target, or on your main model when no Expensive target resolves.
- /effort opens a quick window for how hard the model should think about the work in front of you.
- /router with no destination opens Routing configuration, including the master switch for automatic routing.
- The conversation carries over either way -- every message, tool call and result -- except where cache isolation runs the routed work in a separate child, which is given the task alone and none of the history. Credentials follow the provider profile, not the vendor: point a rung at the exact profile your main model uses and its key carries over, and point it anywhere else -- another vendor, or a second profile of your own on the same vendor -- and that turn bills to whatever key that profile names, provided that profile can actually be built. Where it cannot -- a credential that does not resolve is the usual reason -- that rung alone is dropped for the turn. Any other rung you configured still stands and the work can route there instead; it runs on your main model and its key when the dropped rung is the one you asked for, or the only one you named. Either way a misconfigured rung costs you a saving rather than the turn. The model's own hidden reasoning is the exception, and it is tied to the exact route that produced it rather than to the rung: a destination on the same model and provider settings keeps it -- two profiles that differ only in name qualify -- while one that changes either picks the thread up from the transcript instead. OpenAI's sealed reasoning is the looser case, surviving any hop between endpoints that speak the Responses wire.
/router cheap summarize this file # this prompt runs on Cheap
/router main # next turn on the active role's model
/router expensive review this design # this prompt runs on Expensive
/effort # set thinking depth for the work at hand
/router # open routing settings Compaction: stop paying for turns 1-29 on turn 30
A chat-style agent resends the whole conversation on every turn, so a long session's cost grows far faster than the work you did, turn 30 pays for everything said in turns 1 through 29, and old tool outputs (a file you read once, a search result, a build log) usually dominate that weight.
Squeezy folds the older part of a long conversation into a short, structured summary: the goal, the progress so far, the decisions taken, the constraints in force, anything blocked, and what comes next. Recent turns stay verbatim, so the model never loses its grip on the immediate working state, and the files you have read or changed are carried forward by name across each fold.
The result is that a deep session levels off instead of ballooning, and it keeps long sessions from hitting the model's hard context limit and stalling. Full summary folds happen automatically after a turn once the conversation gets large, or reactively after a provider context-window error. Mid-turn pressure is handled by a lighter trim pass that clears old bulky tool-output bodies while keeping the tool-call structure around them intact, so a request near the ceiling can still continue without pretending the whole conversation was summarized mid-turn.
Compaction is a deliberate trade: the model gives up word-for-word recall of old tool output in exchange for a faithful summary plus a record of every file touched. If you ever need the original detail back, /compact undo restores the conversation from before the last fold.
- Goal, progress, decisions, constraints, blocked, next: the six slots every summary keeps, so a decision taken twenty turns ago is still on the record.
- Recent turns stay intact, kept word for word rather than summarized.
- Files carry forward, each with a content fingerprint, so the model can tell which of them are still fresh and re-read only what moved.
- /compact folds the conversation now, /compact history lists the folds, /compact undo puts the last one back.
Shaped tool output: keep the part the model can act on
Tool output is the biggest thing flowing into a coding agent's context, and most of it is noise. A build dumps tens or hundreds of kilobytes of progress chatter around a handful of errors. A test run mixes a pass/fail summary into pages of harness output. A broad search returns thousands of near-identical lines. Left raw, every one of these pushes your context budget toward its limit for no benefit.
Squeezy understands the common tool families and trims each to its signal. A build or compiler run is reduced to the errors and warnings plus the final result. A test run collapses to a pass/fail count, with failing tests and their messages surfaced and tagged so the model can tie a failure back to its source. A search is capped per line and overall, with duplicate file hits folded together. An image is handed to the model as an image instead of being mangled into broken text.
Coverage reaches the toolchains a coding session actually touches: Rust, C and C++, the JVM through Maven and Gradle, .NET, Go, JavaScript and TypeScript, Python, Ruby, PHP, Swift, git, GitHub and GitLab, linters for shell and PowerShell, and cloud tooling including AWS, gcloud, Azure, Docker, kubectl, and Terraform. A git diff comes back as a summary of what changed with hunks capped per file rather than a raw patch. A clean push or pull collapses to a line. Build tools drop their download chatter and per-task banners.
Two guards keep the trimming honest. A line that mentions an error, a warning, a failure, or a result is kept no matter which noise pattern it matched. And a shaped result that would not come out smaller than the raw one is thrown away, so you get the original instead. A command Squeezy does not recognize is passed through untouched.
Nothing is lost. When output is trimmed, the full original is kept for the session and the trimmed block tells the model how to fetch it, so the common path pays for a summary and only the rare call pays for the full bytes. A related control, diff-only reads, restricts a read or a search to the files you have actually changed, which is exactly what the check-my-work loop needs.
Verbosity controls: match the answer to the task
Different tasks want different output budgets. A scripted edit should do the work, say “done,” and stop. A deep review wants the full rationale. Forcing one default across both wastes tokens on the short case and starves the long one, so Squeezy lets you set the dial per session.
Response detail guides how much the model writes back: concise asks for shorter answers and verbose asks for fuller explanations. The model can still choose the length the task needs. A provider verbosity control carries the choice where supported; otherwise Squeezy adds an answer-length instruction. Normal uses the provider’s middle level or adds no extra instruction.
Tool-output verbosity is about your screen, not your bill. It sets how much of a command's output the transcript shows inline, and it starts compact, so a long build does not push a real answer off the top. Opening a result shows the rest. Edits Squeezy makes always render their complete diff; a diff from a command it ran folds like any other output unless you ask for those in full.
- responses.detail guides answer length: concise, normal, or verbose. The default is normal. It does not change transcript rendering.
- tui.tool_output_verbosity sets how much of a command's output shows inline: compact, normal, or verbose. The default is compact.
- Both are editable live from /config.
- Leave response verbosity alone and Squeezy can ease it down when recent answers look over-explained, then put it back the moment one looks too terse. Set it yourself and your value holds.
Subagents: do the wide work somewhere else
Some questions touch a dozen files, “where is auth handled,” “review this whole change.” Done inline, that exploration floods your main conversation with a dozen tool calls and their output, and every later turn re-pays for all of it even though you only needed the conclusion.
Squeezy can push that work into a subagent: a separate run with its own conversation, its own model, and a toolset scoped to the task. That is either a general worker that can edit and run commands under your permission policy, or one of three fixed roles -- explore, plan, review -- whose tools read, search, and verify but never edit. The subagent does the digging and returns a compact summary to your main thread, along with the evidence it leaned on and the files it touched. Its intermediate dumps and its chain of reasoning never enter your main context, so they never get re-sent.
Two savings stack. Your main conversation stays slim, so every later turn re-sends a short summary instead of the whole investigation; and the subagent itself runs lean, advertising only the handful of tools it needs and dropping to a cheaper rung when its work is simple enough. Subagents run in parallel and are kept deliberately flat: one parent, many children, no deeper nesting, so cost stays predictable. The trade-off is clear. Isolation pays off when the inline version would bloat every future turn, not for a single grep.