Releases: gorillanobakaa-dot/Gorilla.Opencode
Release list
Gorilla OpenCode 0.1.134 — Windows
Gorilla OpenCode 0.1.134 — Windows
A two-sentence fix to the AI's rulebook, and the audit that found it.
Previous Windows release: 0.1.133, published yesterday. If you are running it,
this replaces it. Nothing else changed — same features, same tools, same install.
What was wrong
Version 0.1.133 shipped five new rules telling the AI to stay on the job it was
given: don't wander into nearby files, don't read through whole folders uninvited,
don't delete things, assume the machine you actually have.
They were switched on, and the release page said plainly that they had never been
measured. This release is what happened when they were.
Two of them were broken. Not subtly.
It could not read the file with the answer in it
One rule said a file being nearby, imported, or already open does not make it part
of your task. Sensible. But it did not distinguish looking from touching.
You say "fix the build error in
src/parser.c". The compiler complains that
FOO_MAXis undefined.parser.cincludeslimits_config.h, which is where
FOO_MAXlives.The rule marked that header as out of scope. So the AI could not open the file
containing the answer.
Another shape of the same fault:
You say "the build is broken, fix
render.cpp". The first real error is a
missing semicolon ingeometry.h, cascading into forty errors inrender.cpp.
The rule marked the actual fix site as off-limits.
This program is built for large C and C++ codebases where the fault is almost never
in the file you named. The restraint landed squarely on the thing it exists to do.
It could not delete, and could not do the alternative either
A second rule said: don't delete things, move them to a clearly labelled holding
folder instead.
An older rule, which outranks it, says: don't create files nobody asked for.
So the AI could not delete, and could not create the approved holding folder. It
would simply stall.
What changed
Two sentences. No rule was switched off.
Looking is not touching. The first rule now restrains changing — editing,
deleting, moving, running — and says outright that reading along an include or call
chain to find the fault is part of the job, not a scope violation.
The holding folder is part of the delete. No longer a forbidden extra file.
That is the entire code change: four lines in one text file.
How this was found, and how much to trust it
Forty-four AI agents examined the rulebook from three angles at once: one group
classifying every rule, one hunting for conflicts, one predicting behaviour on
realistic tasks. Then ten more whose only job was to prove the first lot wrong.
Three of those groups independently landed on the same rule without being
pointed at it. That convergence is why these two fixes were made and the other
three rules were left alone.
Now the honest part, because it cuts the other way.
The suspicion that started the audit was that the rulebook had become lopsided —
too many "stop" rules against too few "go" rules, roughly 15 to 6. That figure was
a hand-count and it was wrong. Counted properly: 20 restraint, 18 completion,
20 honesty, 16 neutral. Balanced. The real defect was two sentences, not a ratio.
Every one of the ten demolition agents succeeded in refuting the finding it was
given. They were instructed to assume a finding was wrong unless proven, so a high
strike rate is partly built into the method — and only about a tenth of the serious
findings were ever checked before the audit ran out of budget. So the findings are
softer than they look, and are not disproved either.
Eight of thirteen test scenarios changed behaviour with no harm at all. The
rules were never broadly breaking things. Two specific sentences were.
And no agent ran a real task. Every scenario is one AI predicting what another
would do. That is careful reasoning, not measurement, and it should not be read as
measurement.
Still not measured, still shipped on
The other three restraint rules are unchanged and still switched on. One of them,
"no scanning or stockpiling", drew twenty-six findings in the audit with eight
rated serious, and barely any were checked.
They stay on for the same reason as before: a rule nobody runs produces no
evidence. If the AI starts asking permission for things it used to simply do, that
is them, and one keypress removes all five — open /context, find Scope
restraint, press space. You get 212 tokens per message back.
Install
- Close Gorilla OpenCode if it is running.
- Download
gorilla-opencode.exebelow. - In a terminal, from wherever you saved it:
.\gorilla-opencode.exe install
Then check it:
gorilla-opencode --version
You should see v0.1.134.
To go back: gorilla-opencode uninstall, then install your previous .exe the
same way. Conversations, settings and API keys live elsewhere and are untouched by
either step.
Verify the download (optional):
certutil -hashfile gorilla-opencode.exe SHA256
9c3bd04f8ea8c06c8de1ec781be2e7d70bca94939bfd1ed970e0045dac3b4840
Everything else from 0.1.133 is unchanged
Including the parts most worth knowing about if you are arriving here first:
The command list uses the whole window. Two columns, all 31 commands visible at
once, instead of about a dozen in a narrow panel.
Low-bandwidth mode says it is on, for as long as it is on, instead of
announcing itself once and fading.
The research tool refuses rather than overspending. Ask for more helpers than
your limit allows and the run does not start — and the AI reports the refusal
instead of inventing a result. Note the spend at the bottom of that screen.
Known issues
| What you see | Why | What to do |
|---|---|---|
| The AI asks permission for things it used to just do | The three remaining restraint rules, overreaching | /context, find Scope restraint, press space |
| The AI says a tool does not exist | Something switched it off, usually the low-bandwidth preset | /context, press u to undo the preset |
/review refuses and lists missing analysers |
Those analysers are separate programs and are not installed. An empty result would look exactly like a clean report | Read the list — it names each one and how to install it |
| A patch reports applied WITH FUZZ | It did not fit where it claimed; surrounding lines were used to place it | Read the diff. If those lines appear twice, it can land in the wrong place |
Not done, and said rather than implied
- macOS. Never built, never run.
- Linux. The last Linux build is 0.1.132 and does not contain this fix.
- The remaining three restraint rules are unmeasured, and one of them has
serious unchecked findings against it. - Deferred tool loading still ships off. Tested over 26 runs against a small
AI, it silently cost two of four specialist tools without saying so.
Privacy
No telemetry was added and none exists. Nothing is sent anywhere except to the AI
provider you configured.
Full notes
v0.1.134-release-notes.layman.md— plain Englishv0.1.134-release-notes.developer.md— the audit method, evidence weights, and what it cost
Gorilla OpenCode 0.1.133 — Windows
Gorilla OpenCode 0.1.133 — Windows
This is the Windows build. Previous Windows release: 0.1.130, seventeen
commits ago.
0.1.132 existed and you could not use it. It shipped a .deb, an Arch package
and a Linux binary, and no .exe — so anyone on Windows landing on the latest
release found three things they could not install and left. Everything fixed in
that release had been compiled for Linux only. This closes that gap.
Why this release exists
Two reasons, and the first is an apology.
The Windows build was three fixes behind and nothing said so. The work
below was written, tested and released for Linux on 3 September. On Windows the
program carried on showing a command list in a narrow panel and a cost screen
cut off mid-sentence, because nobody had built it here.
Then a run on Linux found six broken tests, and three of them had been
passing for weeks while testing nothing at all. No product code needed
changing. The tests were asserting things that could only ever be true on
Windows. That is worth a release on its own: a test that cannot fail is not
protecting anything.
What you will see
The command list uses the whole window
Before: a panel about 84 columns wide showing roughly a dozen of the 31
commands, with nothing to say the rest existed. If you did not already know the
list scrolled, the bottom row looked like the end of what this program can do.
After: two balanced columns across the whole terminal, with a count at the top.
On an ordinary screen every command is visible at once.
Low-bandwidth mode now says it is on
Pressing l switches seven things off. Six of them sat below the visible part
of the list, so nothing on screen changed and it looked exactly like a key that
did nothing. A red line now stays at the top for as long as the mode is on,
saying how many things are off and which key puts them back.
This is the same failure that produced 0.1.130: a switch that silently removed
capability and never mentioned it again.
The cost screen finishes its sentences
/context was capped at a fixed size, so on a wide screen the column explaining
what switching a tool off would cost you was cut off mid-sentence. That column
is the one thing on that screen you actually need before deciding. It now uses
the whole window, and the footer rows are reserved so the banner and title stop
scrolling away.
Patch porting still tells you HOW a patch landed
Unchanged in behaviour, verified on a second platform. /port asks permission
before it touches a git tree, and asks for nothing when only inspecting.
The AI's rulebook grew, and part of it is an experiment
The instructions sent to the AI on every message gained eleven lines. Six are
about honesty and are not negotiable. Five are about restraint and are new,
unmeasured, and switched on.
The six that stay on
First, a word you will see a lot below. A token is roughly three-quarters
of a word — it is the unit AI services count and charge by, and the unit your
data allowance disappears in. Everything the AI is told gets re-sent on every
single message, so a line added to its instructions is not a one-off cost. It is
a standing charge, on every message, forever. That is why this page prices each
change instead of just listing it.
Three of the six concern what the AI writes down about you: open a file before
claiming not to have the answer; never record its own guess as though you had
said it; one passing mention of something is not a preference.
One concerns what happens when you push back: correct a real error and move on,
rather than folding and abandoning a correct answer because you sounded annoyed.
Two concern verification, and both name a bug this program has actually shipped:
- Check the thing itself, not the message about it. When you run a command
and feed its output through a second command, the "did it work?" answer you
get back belongs to the second one. So a build can fail while the terminal
cheerfully reports success. That has printed "BUILD OK" over a failed
build in this repository more than once. The AI was already told to verify
its work; it was never told where to look. Now it is: open the file and see
if the thing is actually there. - Missing means missing. If something the AI expected is not there, it must
say so — never quietly write an empty stand-in file so the job can carry on.
That converts a problem you would have noticed into one you would not.
Cost: 84 tokens per message for the verification pair, 161 for the rest.
The five that are an experiment
/context has a new row, Scope restraint, costing 212 tokens on every
message. In plain terms, it tells the AI to stay on the job you gave it:
- A file being nearby, or already open, or mentioned by the file you asked
about, does not make it part of the task. - "It would save time later" is not permission.
- Do not go reading through a whole folder tree nobody asked about.
- Move something to a clearly labelled holding place rather than deleting it.
- Assume the machine you actually have — its speed, its screen, its connection —
rather than an imagined average one.
Read this part carefully, because it is the honest bit.
These five lines have never been tested. Not once. We have no evidence that
an AI reads around less with them than without them — only a reasonable belief
that it should.
They are switched on anyway, for one reason: a rule nobody ever runs can never
be proven or disproven, so leaving it off would have kept it a guess forever.
212 tokens on top of roughly 2,250 was judged a fair price for one release in
exchange for finding out.
If it goes wrong, it will go wrong by being too careful — not too reckless.
Watch for the AI:
- asking permission for things it used to simply do,
- running commands one at a time that it used to send together, making it
slower and costing you more, - or telling you it is stuck when it could have looked in the next folder along.
Any of those, and it is probably these five lines.
It is one keypress to switch off. Open /context, find Scope restraint,
press space. Nothing else changes, and you get the 212 tokens back on every
message from then on.
That is the same deal deferred tool loading got in 0.1.130, and it is the deal
anything unmeasured should get: shipped where it can be observed, priced in
public, and removable by one key.
Install
- Close Gorilla OpenCode if it is running.
- Download
gorilla-opencode.exebelow. - In a terminal, from wherever you saved it:
.\gorilla-opencode.exe install
It copies itself into your programs folder and adds Desktop and Start menu
shortcuts. Then check it:
gorilla-opencode --version
You should see v0.1.133.
To go back: gorilla-opencode uninstall, then install your previous .exe
the same way. Your conversations, settings and API keys live elsewhere and are
untouched by either step.
Verify the download (optional):
certutil -hashfile gorilla-opencode.exe SHA256
2513f4ccfd8c8143fc2523f3d35eddef067541291c65c5a0da0b0fac4d199eeb
Known issues
| What you see | Why | What to do |
|---|---|---|
| The AI asks permission for things it used to just do | The new Scope restraint rules, overreaching | /context, find Scope restraint, press space |
| The AI says a tool does not exist | Something switched it off, usually the low-bandwidth preset | /context, press u to undo the preset |
/review refuses to run and lists missing analysers |
The analysers are separate programs and are not installed. An empty result would look exactly like a clean report | Read the list — it names each one and how to install it |
| A patch reports applied WITH FUZZ | It did not fit where it claimed; ... |
Gorilla OpenCode 0.1.132 — the Linux build
Gorilla OpenCode 0.1.132 — the Linux build
0.1.130 was the Windows build. It compiled for Linux and passed the static
checks there, and that was the entire extent of the evidence. Nobody had run it.
This is that same work, executed on Linux for the first time, plus what the first
run turned up. Previous Linux release: 0.1.119.
Why this release exists
A branch that cross-compiles is not a branch that works. GOOS=linux go build
succeeding tells you the types line up. It tells you nothing about whether a
shell wrapper written against PowerShell can report an exit code through bash,
or whether a test that passed on a bare Windows box passes on a laptop that
already has the tools installed.
So the first thing that happened on Linux was the test suite, and it failed in
six places.
Not one of them was a bug in the program. Every failure was a test or a test
harness asserting something that could only ever be true on Windows. The product
code needed no changes at all. That is a good result, but it is only knowable by
running it, which is the point.
Three of the six are worse than a plain failure: they were passing for the wrong
reason, and had been for weeks.
What the first Linux run found
A shell test that could not have passed here. It ran exit 7 and expected
the exit code back. But the shell is persistent, so exit ends the session
rather than a subshell, the status file is never written, and the program
deliberately returns 1 with an explanation. The Windows half of the test never
hit this because cmd /c "exit 7" is already a subprocess. The POSIX equivalent
is (exit 7), a subshell, and the round trip works.
A path test that asserted a Windows fact. ~\Documents\my-project must
expand on Windows. On Linux a backslash is an ordinary character in a filename,
so that string is one segment genuinely named \Documents\my-project, and
resolving it any other way would break anyone who has a backslash in a name. The
program was already right; the test was asserting for both platforms what is
true of one.
Two /arsenal tests that assumed a bare machine. The helper picked the first
package the system could install without asking whether it was already
installed. Selecting an installed package is deliberately a no-op, so on a
machine that already had the tool the test selected nothing, the install plan
correctly refused to open for an empty selection, and the failure described the
symptom. It would have failed the same way on a Windows box with the tools
already present.
Three smoke checks that were grading an error message. This is the one worth
reading twice. The checks invoked the program as:
env -i HOME=... PATH=... TERM=dumb runbin "$BIN" -p hi -qenv executes a program. runbin is a shell function, so env could not
see it. Every one of those runs started nothing at all and exited 127, and the
checks graded env's own complaint: "did it exit non-zero?" passed on 127, "is
the cryptic error gone?" and "is there no usage dump?" both passed because
env: 'runbin': No such file or directory contains neither. Only the one check
asserting that expected text was present failed, and that is what exposed it.
It stayed hidden on Windows because a local model server was listening, which
made the enclosing block skip. The fix is to nest the other way round, so the
timeout wrapper is outermost. The same check now reports the program's real exit
status of 1.
A packaging check demanding the return of a bug. It searched
build-deb.sh for an inlined desktop-entry line. That inlined copy is exactly
what v0.1.44 deleted, because keeping the launcher in three places is how the
package once shipped without its plain-mode action. The check now resolves the
tracked .desktop file the script actually installs and asserts on that.
The low-bandwidth mode line
Pressing l in /context applies the low-bandwidth preset. It was reported as
doing nothing.
It was doing exactly what it promises: seven components switched off, written to
disk, undo recorded. But of those seven, six sat below the visible window of a
forty-two row list, so nothing on the screen being watched changed. The only
acknowledgement was a message that appears once and fades.
A message that has already gone cannot tell you what state you are still in.
/context now carries a persistent line, in the theme's error colour, for as
long as the preset is applied:
LOW-BANDWIDTH MODE: 7 components switched off. Press u to put them back.
It names the count and the way out. It costs a row only while the preset is
applied, and it deliberately survives on a short terminal, where the
explanatory header lines are dropped first: a cramped screen shows fewer rows,
so that is precisely where the least of the change is visible.
This is the third instance of one mistake in this part of the program, after two
fixes in August. Stated generally, so the fourth is recognised: when the effect
of a key can land off-screen, say what happened, do not merely do it.
The permission gate in front of your git tree
patch_port rewrites git trees. One line decides whether it asks first:
if op != "inspect" {inspect is read-only. It reaches the tree through exactly one call,
git apply --check, which asks git whether a patch would apply and writes
nothing. Everything else, forward-port, backport, rebase, refresh and
port-series, can rewrite a checkout, and each one asks first and names the
tree and the operation in the prompt.
That was all correct, and nothing tested any of it. The file had no tests at
all. Refactor that condition the wrong way and the whole suite still passes while
five operations start rewriting trees unannounced.
Six tests now pin it: inspect does not ask, an omitted operation defaults to
the safe side, all five modifying operations ask exactly once with the tree named,
denying actually aborts, the operation approved is the operation that runs, and
an unrecognised operation is refused without asking about something that will
never happen.
The set of modifying operations is declared in the test, so adding a seventh
operation without gating it fails the suite until somebody gates it.
On proving a negative. Two of those tests assert that permission was not
requested, and the permission check sits after two steps that can return early.
So "nobody asked" is also true if the tool died before reaching the gate, and
both tests would pass having exercised nothing. Neutering the gate proves only
that the positive tests work. The mutation that matters is the opposite one:
force the gate to fire when it should not, and confirm the negative tests go red.
They did.
The command reference uses the window now
/help capped itself at 84 columns. On a 200-column terminal that is a narrow
panel floating in the middle of the display, showing about a dozen of
thirty-one commands, with nothing to say the list continued. Reported plainly:
someone who does not already know a reference is scrollable reads the bottom row
as the end of what the program can do.
The answer is to show the commands rather than announce them. Full width, two
columns, and on a normal-sized terminal every command is on screen at once
with no scrolling at all.
- tab, and the left and right arrows, move between the columns, the way the
old Slackware installer moved between panes. - Columns are balanced while everything fits, and only fill top-to-bottom once
there is more than a screenful. Filling in order first put every row in the
left column and left the right half empty, which is the same wasted window
moved to the other side of the screen. - The header now counts what exists, so the size of the list is a fact on the
page rather than something you discover by scrolling. - The border is gone. It drew a rounded box around the whole screen, spending
two rows and two columns of a fixed budget to put a line just inside an edge
the terminal already has. Those are also box-drawing characters, which are
East Asian Ambiguous and measure two columns instead of one on a terminal
configured for CJK: the one piece of decoration here that could change width
on somebody else's machine.
Screenshots
Every command in the program, on one screen. The header counts them, so the size of
the list is a fact you can read rather than something you find out by scrolling. This
replaces an 84-column panel that showed about a dozen of them and said nothing about
the rest.
The red line is the whole point. Pressing l switches seven things off, and six of
them sit below the visible part of a 42-row list, so the screen you are looking at
does not change. The state now says so for as long as it lasts, and names the key
that undoes it, instead of a message that appears once a...
Gorilla OpenCode 0.1.130 - Windows
Gorilla OpenCode 0.1.130 — Windows
This is the Windows build. It has not been run on Linux or macOS. It compiles
for Linux and passes the static checks there, but nobody has executed it, and we
are not going to pretend otherwise.
Previous Windows release: 0.1.120. Thirty-five commits since.
Why this release exists
Someone typed /review and the model answered:
I do not have access to a tool named review.
It was telling the truth. Months earlier, one press of the low-bandwidth
button in /context had switched off seven tools at once, written that to
disk, and provided no way back. The connection recovered. The tools did not.
Nothing anywhere said so, and the only visible symptom was an AI that appeared
to have forgotten how to work.
Fixing it properly took three changes, and then the release kept growing.
What changed
The review tool works again — and cannot vanish silently.
The low-bandwidth preset now has an undo (press u in /context). It restores
exactly what the button took and leaves alone anything you switched off
yourself. Every command now checks its own tool is switched on before asking the
AI to use it, so you get an explanation instead of a confused model.
Patch porting is new. /port forward-ports, backports, rebases and
refreshes patches, and reports how each one landed: cleanly, by merge, or
relocated by fuzz. That last one can be silently wrong, so it is reported
separately instead of being called success.
Eleven scientific databases. bio_lookup reads UniProt, Ensembl, PDB,
AlphaFold, PubChem, ChEMBL, InterPro, ClinVar, openFDA, STRING and Reactome
directly. No API key, no account. Ships off; arm it in /context.
The program is politer to free services. Every host gets a request budget
and callers wait their turn, using published limits where a service states one.
This exists because a model, cornered by rate-limit refusals, once invented a
table of citations instead of reporting the failure.
/context tells the truth about cost again. It had started adding up tools
the program no longer sends, so the number could be thousands of tokens too
high. It now reports what actually goes over the wire.
Nine recorded tool costs were wrong by up to 182% and have been
re-measured.
What ships switched OFF, and why
Deferred tool loading holds back specialised tool descriptions until the AI
asks for them. It saves roughly 2,900 tokens per session — real money on a
metered connection or a free tier.
It ships off, because we measured it over 26 runs against a small local
model and it silently cost the AI two of its four specialised tools. When that
happens the AI does not stop and say so. It answers by hand, from whatever it
can read, and sounds confident.
If you use a larger model it may well be worth switching on. It cannot cost
you more than leaving it off — that is guaranteed and tested at every point.
Turn it on in /context and watch how your own model copes.
Install
- Close Gorilla OpenCode if it is running.
- Download
gorilla-opencode.exebelow. - In a terminal, from wherever you saved it:
.\gorilla-opencode.exe install
It copies itself into your programs folder and adds Desktop and Start menu
shortcuts. Then check it:
gorilla-opencode --version
You should see v0.1.130.
To go back: gorilla-opencode uninstall, then install your previous .exe
the same way. Your conversations, settings and API keys live elsewhere and are
untouched by either step.
Verify the download (optional):
certutil -hashfile gorilla-opencode.exe SHA256
8ec6607400d6442e5961dc5c0fabc6dd6d062a13516e35b0686b2c18730ab7dc
Known issues
| What you see | Why | What to do |
|---|---|---|
| The AI says a tool does not exist | Something switched it off, usually the low-bandwidth preset | /context, press u to undo the preset, or space on the row |
/review refuses to run and lists missing analysers |
The analysers are separate programs and are not installed. An empty result would look exactly like a clean report | Read the list — it names each one and the command that installs it |
| A patch reports applied WITH FUZZ | It did not fit where it claimed; the lines around it were used to place it | Read the diff. If those lines appear twice in the file, it can land in the wrong place |
| Deferred loading on, and a tool stops being used | Small models do not always realise they should search for it first | Switch it back off in /context |
Privacy
No telemetry was added and none exists. Nothing is sent anywhere except to the
AI provider you configured. The eleven scientific databases are public and are
queried without any key. The code-review tools run entirely on your machine.
Full notes
Two versions, same release, both in the repository:
v0.1.130-release-notes.layman.md— plain Englishv0.1.130-release-notes.developer.md— architecture, measurements, file-by-file
The developer notes include something worth reading if you maintain anything
like this: one change in here was written, measured across five runs, found to
change nothing at all, and removed. It cost 63 tokens on every turn. A cost
that buys nothing is a leak, and this program is built for people for whom that
is not a rounding error.
v0.1.119: a reply with nothing in it should cost a turn, not the session
A reply with nothing in it should cost a turn, not the session
One crash, fixed. That is the whole release.
What was wrong
Sometimes an AI service answers your question with nothing at all. Not an
error, not a refusal, just a technically valid reply that contains no words. A
safety filter removed the answer, a quota ran out mid-sentence, or a proxy in
the middle timed out and handed back an empty envelope.
Gorilla OpenCode did not know that was allowed. It reached for the first
sentence of the reply, found there wasn't one, and crashed: not the answer, not
the question, the whole program, closing the window and taking the conversation
with it.
panic: runtime error: index out of range [0] with length 0
provider.(*openaiClient).stream.func1() internal/llm/provider/openai.go:478
If a run has ever died on you for no visible reason just as an answer was about
to appear, this may well have been why. It looked like a network fault. It was
not one. The reply arrived perfectly. The program could not cope with it being
empty.
What changes for you
That turn now fails with a message and your session survives.
If part of the answer had already reached your screen, it is kept. It arrived,
and you paid for it, so discarding it to be tidy would be its own kind of loss.
How it was found, which is the interesting part
We spent the morning checking whether Gorilla OpenCode could be built for
Windows. It can: there is no cgo anywhere in the tree and the SQLite driver is
pure Go, so GOOS=windows go build produces a working executable with no
source change. Under Wine on a Debian laptop, that build printed its version,
parsed its CLI, refused correctly with no provider configured, created its
database, ran its migrations and wrote a real session row.
To drive it without spending money on a real AI service, we stood up a fake one
on localhost. The fake was slightly wrong: it answered a streaming request with
an ordinary JSON body.
That mistake is what triggered the crash, and the crash turned out to have been
in the normal Linux build the whole time, reachable from every
OpenAI-compatible service this program supports.
An experiment on a platform we do not ship to paid for itself before producing
anything shippable. Unfamiliar ground hands a program inputs its usual
surroundings never do.
Under the hood
internal/llm/provider/openai.go read Choices[0] without checking the list
was non-empty, on both the streaming and the non-streaming paths. An empty
list arrives three ways: an explicit "choices": [], a stream that ends before
the first chunk, and an HTTP 200 whose body is actually an error page. An
unrecovered panic in a goroutine terminates the process, so there was no
degraded mode.
ErrEmptyCompletion now names the condition once in provider.go. The
streaming repair splits the two situations that the empty list was conflating:
- Nothing streamed: the turn produced nothing, so report the error and let the
caller decide. - Tokens streamed and only the closing bookkeeping chunk is missing: the answer
is on screen and billed, so keep it and report a normal end of turn.
The default-then-override shape is copied from gemini.go:262, which already
handled the equivalent case. Every [0] index on a wire-derived list in the
provider package was enumerated before writing the fix: gemini.go,
antigravity.go and code_assist.go all guard every Candidates[0] read.
Only the OpenAI client was exposed.
Cover is three end-to-end httptest cases in empty_completion_test.go, not
unit tests on the guard, because the bug was never in the arithmetic. It was in
what the wire is allowed to contain, so the test has to put those things on a
wire. Verified non-vacuous by reinstating both reads and confirming the
original panic returns. Full suite exit 0.
Evidence
The Windows build of this release, running here under Wine against a local stub.
The line Error: agent processing failed: the provider returned a response with no content in it is the fix doing its job: that is the precise input that used
to end the process. Below it, the SQLite database the Windows binary created,
with its migrations run and a real session row in it.
A test that cannot fail proves nothing, so here it is failing. The guards are
removed from openai.go in a throwaway worktree, the same test command
reproduces the original panic on demand, and the fix is restored.
Verification
All four artifacts were extracted and their inner binary hashed against the
binary that passed the test suite:
repo build 815a54e7204944ad
deb inner 815a54e7204944ad
arch pkg inner 815a54e7204944ad
raw binary 815a54e7204944ad
Identical, and all four report v0.1.119.
Install
Debian, Ubuntu and derivatives:
sudo apt install ./gorilla-opencode_0.1.119_amd64.deb
Arch, CachyOS and derivatives:
sudo pacman -U gorilla-opencode-0.1.119-1-x86_64.pkg.tar.zst
Anything else: take the raw binary, chmod +x, put it on your PATH.
Checksums for all artifacts are in SHA256SUMS-v0.1.119.txt.
v0.1.118: stop asking about the string, start asking about the outcome
Gorilla OpenCode v0.1.118: stop asking about the string, start asking about the outcome
Everything about this release is printed in full on this page.
Six fixes, one theme. Every one of them was a number or a question put in
front of you that you could not act on.
The prompt you clicked twenty times
Every web search asked permission, and the approval covered only that exact
search. Nobody runs the same search twice, so "Allow for session" covered
nothing useful, and clicking Allow every single time was the only thing that
worked. A ten-helper research run asked ten times, and answering did not help,
because the eleventh search was a different question again.
"This is getting ridiculous. In order to get a web search either I have to
click ten or twenty times if the search has to restart or what?"
Now it asks once. Allow covers this search. Allow for session covers
searching for the rest of the session. The two things people actually want are
on the two buttons, which they were not before: "allow every future search with
this exact wording" is a grant nobody has ever needed.
Why the old prompt was useless, and not just annoying
It showed you the search words.
Search SearXNG for: ath9k rfkill regression
You cannot tell from that whether allowing it is wise. Reading it more carefully
does not help. It is the equivalent of a surgeon showing you their choice of
incision and asking you to approve it: the honest question was never about the
technique, it was about the risk.
So the prompt now says the things you can actually decide about:
- what leaves the machine: search terms, to one search service
- what it can reach: the open web, and nothing on your computer. No files,
no commands, no keys, no history - what cannot be taken back: a term that has left has left, and terms are
written from what you were discussing - that there is no list to show you, because the model writes each search as
it works
That last point is the one most tools leave out. If permission is being asked
over words nobody can read in advance, the dialog should say so plainly instead
of showing one example and implying that is the deal.
Opening pages is separate and still asks, once per site. Sending words out
is one thing; choosing which server answers you is another, and the second is
what a poisoned search result would want to change.
Research runs ask once, before they start
A single question covering searching and fetching for the whole run, showing how
many helpers are about to start.
Deny does not cancel the run. It falls back to asking separately for each
search and page, and the dialog says so, because Deny on a permission prompt
otherwise reads as a cancel button. The approval ends when the run ends.
Nine questions you never saw were recorded as refusals
Nobody had noticed this one, and it is worse than the clicking.
The dialog holds exactly one question. When ten helpers asked at the same
moment, each question painted over the last, and only the tenth was ever
shown. The other nine waited for an answer that could no longer arrive, timed
out after ten minutes, and were recorded as denied.
Nothing unsafe happened: an unanswered request is refused, which is the safe
direction. The problem is honesty. A question you never saw was filed as one you
refused, and while it happened the run looked frozen for ten minutes and then
blamed the network.
Reproduced by putting the bug back:
showed 1 of 10 queued requests: [j]
Questions now queue. Answer one, the next appears, and anything your answer
already settled is approved quietly instead of asked again.
/tasks: tab and escape work
Reported twice. With the task list open, tab and escape did nothing, and only
began working once enough helpers finished for the list to shrink.
The permission prompt was underneath the task list. It was taking the
keystrokes, because a blocking question outranks everything else, but it was
drawn first, so every other dialog painted over it. You were typing at a dialog
you could not see.
Finished helpers also used to vanish from /tasks the instant they were marked
DONE. They now stay until the run is over.
The cost screen was roughly double, and left your own model out
Three errors, all in the direction of a wrong number stated confidently.
The money was nearly double. Helper steps were priced at the main model's
context. A helper does not run that: it carries four tools, the main model
carries thirteen.
helper 5,246 tokens
main model (was used) 10,380 tokens 1.98x
"Worth about N ordinary questions" had no token in its arithmetic. It was a
step count wearing a label naming a unit it never touched. At ten helpers it
said 30. The real token model gives about 16.
"This run" left out your own model. The launch turn and the write-up turn run
on the main model, and the write-up turn carries everything the helpers sent
back. On a cheap-helper, expensive-main-model setup that single turn can cost
more than the whole fleet. It now has its own line, in its own model's name.
The per-minute figures are measured now
Every per-minute and per-hour figure rested on an invented constant: fifteen
seconds per step. It was labelled ASSUMED on screen, which was honest, and is
not the same as knowing.
Helper durations are now recorded, and the figure comes from your machine, your
model and your connection. Until there are three samples the screen still says
ASSUMED, and it always says which of the two it is showing.
The median is used rather than the average, so one helper stuck on retries
does not drag the forecast above anything you will ever see.
Smaller
- The research modes said "up to 4 at a time". The real cap is 11 and had
been for a while. It reads the cap now instead of repeating a number. - A research run had no label of its own, so the longest operation in the
program said "Working...".
The run that found half of this release
One question, put through the research tool: who is pete holmes? Ten
helpers, supervised, on a free-tier model.
| cost | $7.64 |
| wall clock | 27m 57s |
| helper sessions | 18 |
| tool calls | 195 |
| tokens processed | 11,935,525 |
| tokens written | 56,923 |
| ratio | 210 : 1 |
It answered correctly, and it found seven separate bugs on the way, every
one of them spotted by a person watching his own screen. That beat every audit,
analyser and test suite in this project on the same afternoon.
What the run got right, which is why it is worth the money
It verified a load-bearing claim itself instead of trusting the helpers,
grepping CREDITS, .mailmap and the source tree, and reporting that the vault
is a tarball extract with no git history to search.
It refused to repeat an unverified claim. Eighteen helpers reported a
Facebook connection; the searches behind it were degraded, so it tagged the
claim single_claim, not verified and kept it out of the answer.
It listed what nobody had established, including whether a contributor might
have used the name as a pseudonym, which nothing available could rule out.
Seven of ten helpers agreed and the synthesis overruled them, on a primary source. That is the whole argument for tiers in one line.
And the gap it exposed
Its bottom line said "Pete Holmes is the comedian" with no source and no tier.
A helper really had fetched the Wikipedia page, so the claim was well founded.
The report just never said so.
If you did not already know the answer, you could not tell a checked claim from
a remembered one. Fixed in this release: every answer must now name its
strongest evidence and its tier, there is a new weakest tier unsourced for
claims resting only on the model's memory, and every report ends by telling the
synthesiser that helpers agreeing is not corroboration, because they all run
the same model.
Every figure in that receipt was checked against the session database afterwards: 1,467,867 tokens in, 16,476 out, 76 tool calls (47 searches, 13 finds, 11 fetches, 5 reads), 18 sessions. Four for four, nothing rounded.
The 210 to 1
Almost twelve million tokens in, fifty-seven thousand out.
An agent re-sends its entire conversation on every turn, so a helper wo...
v0.1.117: a window of nothing but a zero is not a window
Gorilla OpenCode v0.1.117: a window of nothing but a zero is not a window
Everything about this release is printed in full on this page, including the
pictures.
One fix. The usage panel was drawing a full green bar for an allowance that
does not exist.
The bar that was measuring nothing
Sign in with a ChatGPT account, type /usage, and you got two bars: a monthly
limit reading 16% left, and underneath it a "Secondary usage limit" at 100%,
three bananas, full green.
There is no secondary limit on a free plan. That bar was measuring nothing.
OpenAI's own client, on the same account, minutes apart, shows only the
monthly limit. That disagreement is what exposed it:
Where it came from
OpenAI's server does send a "secondary" figure on every reply. On a free account
it sends a bare zero, with no window length and no reset time attached. That
is the server's way of saying not applicable here.
The reading taken off the account above, exactly as stored:
primary : used 84%, window 30 days, resets 15 September <- a real limit
secondary: used 0%, no window, no reset time <- nothing at all
Our code took that zero at face value. Zero used means a hundred left, so it drew
a hundred left.
OpenAI's own program throws that reading away. It counts a limit as real only
if at least one of the three things says something:
let has_data = used_percent != 0.0
|| window_minutes.is_some_and(|minutes| minutes != 0)
|| resets_at.is_some();A bare zero fails all three. That is why the two screens disagreed.
Why this is worse than showing nothing
A blank would have been honest. A confident full green bar is not.
This project has a rule written into the file that reads balances: unknown and
plenty-left must never look alike. A full bar for an allowance that does not
exist is the bad half of exactly that pair. Somebody could look at that screen
and believe they had a second pot of credit held in reserve.
Fixed, using their guard rather than one of ours
A limit is now real if it has been used at all, or declares how long its
window is, or says when it resets. A bare zero is discarded.
Ported rather than invented, on the same principle as the window labels before
it: this backend is undocumented, and OpenAI's own client is the only authority
on what its headers mean.
Both directions are tested, because getting it wrong the other way is just as
bad. A limit reading zero used that does carry a window or a reset time is a
genuine untouched allowance, and it still shows.
| test | asserts |
|---|---|
TestAWindowOfNothingButZeroIsNotAWindow |
the bare-zero secondary is dropped, the real monthly one kept |
TestAnUntouchedButRealWindowSurvives |
zero used WITH a window, or WITH a reset, still renders |
TestOnlyAnEmptySecondaryMeansNoReading |
a reply carrying only the empty secondary parses to nothing, so "no meter" stays distinct from "meter reads full" |
Checked non-vacuously: removing the guard reproduces v0.1.116 and fails two of
the three, quoting the phantom window.
If you had the old version, the phantom bar disappears on your next request,
when the cached reading is rewritten from fresh headers. Nothing to do.
Fixed, on the installed build. Same account, same panel, no second bar:
The version in frame reads v0.1.117, so the picture carries its own proof of
which build produced it. That one image is pinned to a commit rather than to the
tag, because it was taken after the tag was cut: a commit hash is immutable, so
the picture on this page can never change under it.
A note on the two numbers disagreeing
Our panel said 16% and Codex said 18% at the same moment. That one is not a
fault. Both read the same monthly pot, but each updates from its own replies,
and about 2% had been spent through this program since Codex last looked. Ours
was the fresher figure.
What was checked, and what was not
Verified: full test suite green; the new guard checked non-vacuously by
reinstating the bug; the packaged binary's SHA-256 equal to the built binary and
to the installed copy.
Not verified, said plainly:
- Any paid ChatGPT plan. A paid account reports a genuine second window,
which by the guard's own rule is kept, but nobody here has one to check
against. - That the 16% vs 18% gap is purely freshness. It is the obvious explanation
and both figures move on their own client's traffic, but it was not proven by
forcing a request and re-reading both.
Install
Debian / Ubuntu:
sudo apt install ./gorilla-opencode_0.1.117_amd64.debapt rather than dpkg -i, because the package depends on lynx, python3
and ripgrep, and dpkg resolves nothing.
Arch / CachyOS, pre-built, no Go toolchain needed:
sudo pacman -U gorilla-opencode-0.1.117-1-x86_64.pkg.tar.zstOr build from source: git clone, cd packaging, makepkg -si. The PKGBUILD
carries a real checksum, not SKIP, so makepkg verifies what it fetched.
Verify your download first, in the same directory as the files:
sha256sum -c SHA256SUMS-v0.1.117.txtv0.1.116: what every message costs, counted rather than guessed
Gorilla OpenCode v0.1.116: what every message costs, counted rather than guessed
Everything about this release is printed in full on this page, including the
pictures.
No new features. This one makes the program cheaper to run and removes three
things that were quietly untrue: a token figure reached by subtraction, an
economy setting that had stopped covering everything, and a bug fix that was a
runtime check where it should have been a type.
Every message carries a price, and we had it wrong
Every time you send a message, the program also sends a description of every
tool the model can use. Every message, not once at the start.
That cost was written down as about 5,000 tokens, and the document said
plainly that the number came from subtraction rather than counting: measure a
total, take away the parts you know, call the rest tool descriptions.
Counted directly, it is 8,462. Nearly double.
tool schemas, default ON 8,462 81%
base system prompt 1,791 17%
prompt blocks, default ON 133 1%
per-turn total, no CLAUDE.md 10,386
find 1,322 · research 1,007 · bash 962 · fetch 789 · edit 759 · review 759 · websearch 749
The subtraction had been done against a total measured on one machine with
several tools switched off, so the leftover described those settings rather than
what a new user pays.
The part worth remembering: the real number was already on screen. The
/context screen has been showing the cost of each tool, individually and
correctly, the whole time. Nothing was missing except somebody adding the rows
up.
It is now pinned by a test that prints the whole breakdown, so the documented
figure can be regenerated rather than trusted, and fails if it drifts by more
than 500 tokens.
You can see the per-tool prices yourself, and the running total in the status
bar:
The economy setting had a hole in it
/context has a key (l) that switches off everything not needed for
ordinary editing and building. It exists for people on slow or metered links.
That list was written on 14 August. The code-review tool arrived on
18 August, switched on by default, costing 759 tokens per message, and
nobody went back to add it. So the setting built for somebody on a satellite link
was still shipping a thirty-analyser review tool with every single message.
Nothing looked broken. It still ran, still switched things off, still showed a
smaller number. It was simply leaving 759 tokens behind, and only counting the
schemas directly made it visible.
From default settings it now saves 43%, from 10,386 tokens per message down
to 5,921.
And the key itself was wrong
l was written as a preset, not a subtraction. It did two things: switch off
everything on its list, and switch everything else back to the factory
default. The second half undid your own economies.
Here it is on a hand-trimmed setup, before, at ~8,802:
After, at ~8,138. Only about 8%, because the web tools went away but bash, the
edit tool, environment info and four language servers all came back:
Run against the old code from a more trimmed starting point, the test says it
plainly:
the low-bandwidth key RAISED the per-turn cost: 6125 -> 7020
tool.bash was switched off by hand and the low-bandwidth key turned it back ON
tool.edit was switched off by hand and the low-bandwidth key turned it back ON
895 tokens more per message, from a button labelled low bandwidth. It only
shows if you have already trimmed harder than the defaults, which is exactly what
somebody on a bad connection does. Anywhere else it looked like it worked.
Fixed. l now only ever subtracts. It switches off its list and leaves every
other choice alone, so it can never raise your bill. r already existed for
restoring the shipped defaults. Pinned by a test that fails if the cost goes up,
or if a component you disabled by hand comes back.
The ambiguity is gone either way
A tool missing from that drop-list used to mean either "we decided to keep it" or
"nobody looked", and from outside those are the same thing. There are now two
lists: things dropped, and things deliberately kept with the reason written
down. A tool in neither fails the build.
Files stopped being sent over and over
Read a file at ten in the morning, and the program was still paying to send it at
eleven, in every message in between.
An old read is now replaced with a short note saying the content was dropped and
where to find it.
The note matters more than the saving. A model that simply cannot see
something fills the gap from memory. Being told plainly that content was removed,
and that it should look again, is the difference between a re-read and an
invention.
Only things cheap to fetch again are dropped: reading a file, searching, checking
diagnostics. Nothing from the web is touched, because re-downloading costs
you bandwidth and may not return the same page. Nothing recent is touched at all.
The petrol gauge cannot read the wrong tank any more
v0.1.115 fixed the symptom: /usage on a ChatGPT session used to show a
different service's allowance, and a check now stops that.
A check is something somebody has to remember to write.
This release makes it impossible instead. A reading now carries the account it
belongs to as one thing rather than two, so it cannot be shown under another
name, and the screen that draws the bars no longer knows anything about sign-ins.
The same fault turned out to exist in the low-quota warnings, and nobody had
noticed: they were filed under the name of the limit, so two accounts both
reporting a "Weekly Limit" would have warned about each other.
One of ours, written down
The file-dropping feature shipped in its first draft with a safety rule that read
as sensible and was really an off switch.
The rule was "always keep the most recent read of each file". A file read once
is trivially the most recent read of itself, so it could never be dropped, and a
file read once then forgotten is exactly what the feature was built for. It did
nothing at all.
It passed every test asking "did we break anything". It failed the one asking
"did it actually work".
A guard that makes a feature safe by making it inert is not a safe feature, it
is a disabled one.
What was checked, and what was not
Verified: full test suite green; every new guard checked non-vacuously by
reinstating the real bug and confirming it fails; the panel layout compared
against a rendered sample with all 14 existing panel tests passing; the packaged
binary's SHA-256 equal to the built binary and to the installed copy.
Not verified, said plainly:
- How much context the file-dropping actually saves in a real session. The
mechanism is tested. The saving is not measured. That claim is a mechanism, not
a number, and it was the same gap in v0.1.115. - The 8-turn window before a read counts as idle. Chosen because evicting too
early is worse than evicting too late, not tuned against real sessions. - Any paid provider. The meter work still runs only against a free plan and
the free Antigravity tier. - Whether anyone relied on the old reset behaviour.
lno longer restores
defaults;rdoes, and always did.
Install
Debian / Ubuntu:
sudo apt install ./gorilla-opencode_0.1.116_amd64.debapt rather than dpkg -i, because the package depends on lynx, python3
and ripgrep, and dpkg resolves nothing.
Arch / CachyOS, pre-built, no Go toolchain needed:
sudo pacman -U gorilla-opencode-0.1.116-1-x86_64.pkg.tar.zstOr build from source: git clone, cd packaging, makepkg -si. The PKGBUILD
carries a real checksum, not SKIP, so makepkg verifies what it fetched.
Verify your download first, in the same directory as the files:
sha256sum -c SHA256SUMS-v0.1.116.txtv0.1.115: the meter, and the list that had stopped being true
Gorilla OpenCode v0.1.115: the meter, and the list that had stopped being true
Everything about this release is printed in full on this page, including the
pictures.
Two things here were wrong in the same way, and neither of them looked wrong. A
usage meter showed a number belonging to a different account. A model list
showed models that were not the ones on offer. Both failed silently, both looked
healthy, and both were caught the same way: the owner noticed that another
program on the same machine disagreed.
The meter was reading the wrong barrel
Sign in with a ChatGPT account, type /usage, and you were shown a weekly
allowance and a Google email address. Neither belonged to the account you were
using. They were the numbers for Antigravity, a different free tier
entirely, printed under a ChatGPT session because nothing checked which one you
were actually on.
That is worse than showing nothing. A meter that reads full when your tank is
nearly empty is not broken, it is misleading, and you would find out when the
program stopped answering.
Here is the state that started it. Our panel on the left with nothing to say;
OpenAI's own Codex on the right, same account, reporting a real number:
The number plainly existed. We just were not reading it.
Where it was hiding, and why reading it is free
There is no page to ask. OpenAI publishes no "how much have I used" endpoint for
this sign-in. The figures ride along on the replies to requests you were
already making, in the response headers.
That is the right answer for anyone on a metered connection: reading your usage
costs nothing at all. No extra request, no polling, no background check.
The catch, stated plainly because it is a real limitation: there is nothing to
show until your first reply comes back. On a fresh session the meter is blank
until you have asked something.
And the same panel beside Codex, so you are not taking our arithmetic on trust.
Both read 18%. Codex prints "resets 19:01 on 15 Sep"; the value we stored is
reset_at=1789495295, which is 2026-09-15 19:01:35 BST, and we render it as
"resets in 23d":
A rounding error that would have panicked you
A test caught this before release, and it is worth spelling out.
The program stores how much you have used and shows how much you have
left. That conversion is a subtraction, and the obvious way to write it is
slightly wrong. Ask a computer for 1 - 80/100 and you do not get 0.2. You
get 0.19999999999999996.
One part in fifty thousand billion, and it matters at exactly one place: the
colour scale changes at 20%. Somebody with exactly a fifth of their allowance
left would have been shown "Banana emergency! Scraping the peel" instead of
the calm amber they had earned. Every warning level (20, 15, 10 and 5 percent)
sat one step too alarming.
Written (100 - 80) / 100 it lands on exactly 0.2. The test now pins all four
boundaries to exact values, with != rather than a tolerance, so it cannot
drift back.
Nothing else lost its meter
The gate removes the wrong reading, not the right one. Antigravity still shows
both model groups, the account line and the OpenRouter balance:
The model list had quietly stopped being true
The ChatGPT model list was typed out by hand six days earlier, from a reading of
what OpenAI was serving that day.
By this week it was wrong. OpenAI was offering four models. We showed
two, and one of those two, GPT-5.4-Mini, is switched off by OpenAI on
31 August 2026, eight days after this release. That list was about to have a
single working entry on it.
Caught from the outside again: Codex was running GPT-5.6-Luna on the owner's
account while this program told him it was not available.
Why the good models were missing, and why that reason was wrong
This is the part worth reading, because it is a mistake about how to know
things, not a mistake in the code.
The two GPT-5.6 models were not missing by accident. They were deliberately
excluded, with a confident comment in the source explaining why: those models
carry a code_mode_only flag, which supposedly meant they wanted their tools
presented as a code sandbox, so offering them would put two entries in the menu
that "sign in fine and then fail on the first tool call".
Every part of that was reasoned from the name of the flag. Nobody had sent a
single request to check. A guess, written in the voice of a finding, and it cost
six days of a better model being unavailable.
OpenAI publishes the source of their own client. It says the flag means
"Restrict model-visible tools to code mode entrypoints": a decision their
program makes about what to hand the model. Not a wire format. Not a rule the
server enforces. Nothing stops another client doing it the ordinary way.
So we stopped reasoning and asked the server. One ordinary request each, one
ordinary tool:
gpt-5.5 HTTP 200 get_weather({"city":"Bucharest"})
gpt-5.6-luna HTTP 200 get_weather({"city":"Bucharest"})
gpt-5.6-terra HTTP 200 get_weather({"city":"Bucharest"})
Then in the shipped binary, on the free plan, off one throwaway question. Not
one tool call. Two, chained:
The wrong paragraph has been left in the source with the correction printed
underneath it, rather than quietly deleted, so anyone reading later can see
what changed and why.
So the list is asked for now, not typed
What the live list actually says, on a free plan:
| model | OpenAI's rank | shown? |
|---|---|---|
| GPT-5.6-Terra | 2 | yes |
| GPT-5.6-Luna | 3 | yes |
| GPT-5.5 | 7 | yes |
| GPT-5.4-Mini | 23 | yes, until OpenAI retires it |
| codex-auto-review | 43 | no, OpenAI marks it hidden and it is not a chat model |
- The order is OpenAI's own, not ours.
- When next week's retirement lands, the model disappears on its own.
- It costs no extra request: the program already asked that same question to
check your sign-in worked.
Signing in no longer picks your models by name either. It used to hard-code
"coder on GPT-5.5, background jobs on 5.4-Mini", a decision made once that then
governed your whole session and pinned your background jobs to the model that
dies next week. It now asks the list which is best and which is cheapest.
The cheap one still writes your conversation titles, deliberately: on a free
plan what you run out of is the cooldown, not money, so the good model
should not be spent naming chats.
Three smaller things
Your files stop being sent twice. When the agent reads a file and later
reads the same file again, the first copy used to be re-sent with every
following message for the rest o...
v0.1.114 — the switch reaches the model
Gorilla Opencode v0.1.114 — the switch reaches the model
Everything is on this page, in full. Nothing here says "see the docs".
The bug: the menu changed the label, not the model
You pick a provider. The bar at the bottom says the new model immediately. Your
next message goes to the old one.
Picking a provider wrote your choice into a settings file. The bottom bar reads
that file, so it updated at once — but the part of the program that actually
sends the request was never told, and kept using whatever it was built with when
the session started.
Nothing errored. Nothing looked wrong. You could work for an hour believing you
were on a free model while every message came off a different account's
allowance.
It was caught by behaviour, not by a test. The owner switched to Claude,
typed "hm", and got back an unrequested attempt to fetch a website:
"I have a feeling this is not Claude, only Llama does that."
He was right. The small label under the reply read Llama 3.3 70B, under a
bottom bar reading Claude Sonnet 4.6 (Antigravity free).
Fixed — and it says which model is answering
Two paths change the model and only one of them told the agent:
| Path | Behaviour |
|---|---|
/model |
builds the new provider, updates the config, swaps the live provider |
/providers |
updated the config and stopped |
The portal now routes through the same atomic path — not a second copy of it
— and reports the result. If the switch fails it says the session is still on
the old model and names it, because silence there is what created the bug.
The old wording, "Provider updated — use /models if you want a different model
from it", is gone too: it implied the switch was still pending while the footer
already claimed it was done.
Verified in the database, not just on screen
| Session | Bottom bar said | model column of the saved reply |
|---|---|---|
| Before | Claude Sonnet 4.6 (Antigravity free) | local.meta/llama-3.3-70b-instruct |
| After | Claude Sonnet 4.6 (Antigravity free) | antigravity.claude-sonnet-4-6 |
And the invented tool call is gone. Before, from the word "hm":
TOOL CALL: web_fetch -> {"format":"markdown","url":"https://www.debian.org/"}
finish: permission_denied
After, a real question and a clean answer — parts are ['text', 'finish'],
finish reason end_turn, no tool calls:
Tools still reach the Antigravity path — "list all the files in your working
folder" produces a real Find call with a tree view and a correct summary:
Two smaller repairs
Sign-in could wait forever. Every call in the auth package used a connection
with no time limit at all, from a context with no deadline — five call sites
across Antigravity, Google Code Assist and ChatGPT. One request that never came
back would leave "Setting up your free tier..." on screen indefinitely, which is
indistinguishable from "working, please wait". They now give up after 45 seconds
and say so; the saved sign-in is kept either way and retries on first use.
"Provider busy" now names the provider. It used to name nobody, which let an
NVIDIA rate-limit be mistaken for a Google one — including by me, in writing, to
the owner, about an account he had used for months. It now reads:
Gorilla.FREE.NVIDIA.NIM busy (rate-limit/5xx) on meta/llama-3.3-70b-instruct, retrying 2/5 in 4.8s
For a local endpoint it uses your name for it. "local busy" identifies
nothing when several endpoints are configured.
That line was also the evidence: it exists only in the OpenAI-compatible client,
and Antigravity has its own client and cannot emit it — which is how the
throttling was proven to be NVIDIA rather than Google. The code path, not a
hunch.
What was NOT verified
- The new timeout has not been seen to fire against a real provider. It is proven
against a stub server that accepts the connection and never answers. - The renamed "busy" line has not been photographed against a live rate-limit.
- 45 seconds is a judgement, not a measurement: generous for small JSON calls,
short enough that nobody concludes the program has died.
Install
sudo apt install ./gorilla-opencode_0.1.114_amd64.debapt, not dpkg -i — the package depends on lynx, which is what makes web
search work with no setup, and dpkg resolves nothing.
Full detail, both tracks, in Changelogs/v0.1.114-release-notes.md inside the
package and the repository.




























