A coding agent asks its model the same narrow question a few hundred times an hour: which file, which line, what next. We handed that job to a model that stores each of its weights in a little over one bit. Bonsai 27B ships at 3.80 GB in the Bonsai-27B-gguf repository under Apache 2.0, about a fifth the size of the model that does our daily local work, and we wanted to know whether that compression survives contact with an agent loop. It mostly does. What breaks is not the part we expected.
We ran it behind Pi, the terminal coding agent, on a studio work/test stack: an Apple M4 Pro with 48 GB of unified memory, the model served through LM Studio’s OpenAI-compatible endpoint at 32K context. It loaded in 10.21 seconds at 3.54 GiB.
Can a 1-bit model make a tool call?
This was the gate. Before wiring anything into an agent we sent one hand-built request straight at the endpoint: a single read_file schema, a system prompt telling the model to use its tools, and a user question that could only be answered by calling one.
We expected it to fail. Structured tool-call output is the first thing to degrade under aggressive quantization, and at 1.128 bits per weight Bonsai is the most compressed model on the machine. Our own earlier testing of local model tool calling in OpenCode and Hermes found small models dropping tool calls routinely, with one model out of the set working reliably.
Bonsai returned a valid call on the first attempt:
“json
{
"name": "read_file",
"arguments": "{\"path\":\"README.md\"}"
}
`
Correct function name, correct argument shape, valid JSON, and finish_reason: tool_calls. The whole exchange took 5.5 seconds across 316 prompt tokens and 69 completion tokens.
The second surprise was in the token accounting. The 1-bit teardown we published last week recorded a trivial arithmetic prompt spending 1,005 of 1,011 completion tokens inside the thinking block, which would make agent work impractical: every small step would cost a thousand tokens of deliberation before a single useful character. On the tool-call prompt the model spent 41 reasoning tokens. Feeding the tool result back for a second turn cost 63. That earlier figure looks like a property of the arithmetic prompt rather than the model, and it is worth correcting, because the two numbers point at opposite conclusions about whether this model can be used in a loop.
What Bonsai 27B gets wrong in a coding agent
We built a small scratch repository with one seeded fault: an off-by-one in a loop bound, i < items.length - 1, which silently drops the last element from a cart total. The test suite fails on that one case and passes the other two. Then we pointed Pi at it in read-only mode, with only the read, grep, find and list tools enabled.
Bonsai found it. The diagnosis was exact: it quoted the offending loop, explained that the - 1 skips the final item, worked the arithmetic through to 5 against an expected 6, and gave the correct one-line fix. Thirty-two seconds, unattended.

Then it reported the bug as line 14. The bug is on line 17. Line 14 is blank.
That looked like a slip, so we tested the specific capability rather than assuming. We asked for every function in the file with its exact starting line:
| Function | Bonsai reported | Actual | Correct |
|---|---|---|---|
subtotal | 3 | 3 | Yes |
applyDiscount | 10 | 11 | No |
itemCount | 15 | 15 | Yes |
Two out of three, with the miss one line off. Combined with the three-line miss on the bug itself, the pattern is drift rather than random error: the model reads the code correctly, reasons about it correctly, and loses precision on where the code sits.

For a terminal agent that is the expensive failure. Reading and reasoning are what a model is for, and Bonsai does both at a size that fits in the memory a browser uses. But an agent that applies a patch by line number, or hands a line number to a downstream tool, is relying on exactly the thing that drifts. A wrong line number does not announce itself as wrong. It produces an edit in the wrong place, which is worse than a refusal.
We should be clear about the boundary of what we ran. Every result above comes from a read-only agent session. We did not complete a write-enabled run, so we have not measured whether Bonsai's edits land on the correct lines when it is allowed to apply them, which is the question the line-number drift raises most directly. That test is the obvious next one and we have not done it yet.
How to wire Bonsai 27B into Pi
The setup is short, and it is the same shape for any OpenAI-compatible local endpoint.
Pi keeps a provider catalogue at ~/.pi/agent/models.json. An LM Studio provider needs the API style, the base URL and a token that is never checked:
`json
"lmstudio": {
"api": "openai-completions",
"apiKey": "lmstudio",
"baseUrl": "http://localhost:1234/v1",
"models": [ ... ]
}
`
Each model is an entry in that array. Two fields matter for Bonsai. Set reasoning to true, because the model returns its thinking in a separate field and Pi needs to know to expect it. Set maxTokens high enough that the thinking block cannot consume the whole budget, since a completion capped below roughly 1,200 tokens can return an empty content field with finish_reason: "length". We used 8192.
Load the model with an identifier and point Pi at it:
`bash
lms load bonsai-27b --gpu max --context-length 32768 --identifier bonsai-test
pi --provider lmstudio --model bonsai-test --approve
``
The --approve flag clears Pi's trust gate for project-local files in a single run. One note for anyone following our earlier brand voice setup across OpenCode, Hermes and Pi: that piece was tested on Pi v0.79.0 and we ran this one on v0.81.1. The context-file discovery and the trust gate behave the same on both.
When a 1-bit model is worth running behind an agent
The case for Bonsai in this role is memory, and it is a strong case. At 3.54 GiB resident it leaves a 48 GB machine essentially untouched, which matters because that machine runs one large-context model hot at a time. A 1-bit model is the difference between an agent that competes with your main model for memory and one that does not.
The case against is the line drift, and it decides the split cleanly. Tasks where the model reads, reasons and reports in prose are safe: explaining a function, finding a logic error, answering a question about a file, triaging which of several files is relevant. Tasks where a number from the model becomes an instruction to a tool are not, at least until the write path is measured.
That is a narrower recommendation than the speed numbers alone would suggest, and it comes from testing the thing that would actually break rather than the thing that benchmarks well. A model that passes a tool-call test on the first attempt and then quietly misplaces a line by three is exactly the failure a benchmark suite does not catch, because the answer is right and only the coordinate is wrong.
The next measurement is the one we did not take: whether the drift survives into applied edits, or whether Pi's own file handling corrects for it. If it corrects, a 3.8 GB model becomes a genuinely useful agent backend on any Mac. If it does not, the 1-bit build stays a reader rather than a writer, and that is still a job worth having on a machine where memory is the constraint.
