0.49.3 — six surfaces that said more than they knew
这是原样发布的 release 说明,不是它的改写版。 release 说明按其撰写时所用的语言发布。
Six defects found by using the app rather than reading it — a day of building three real projects with it — plus the model defaults, which had drifted a generation behind.
Every one of these is a surface that stated something true beside something it had no way to know, in a shape where the reader could not tell which was which.
Reading data over MCP stopped a run from writing files, and nothing said so
The sharpest one, because of what it cost. Four runs of the same task: US$ 5.11, not one file written. The identical task reading the same catalogue with the built-in tools instead delivered on the first pass, in 236 seconds, for US$ 0.37.
Every step of the mechanism was right. MCP output is untrusted content, so reading it taints the run; a tainted write needs human approval; and over HTTP there is nobody who can give it — whoever is looking at the console did not make the request and cannot consent for whoever did.
What was wrong is that the refusal said only "the tool did NOT run and nobody approved it". That is true when a person declined, true when the owner configured deny, and true when no approver could exist at all — three situations, three different fixes, and the only action it suggests is retrying, which is precisely the one thing that cannot work in the third case. A three-attempt budget bought three identical refusals and a bill.
Each case now gets its own sentence. The unattended one says nobody could be asked, says retrying will be refused identically, and names both ways out: the pause-for-approval switch that parks the run for your verdict, and keeping untrusted content out of the run in the first place.
The MCP Test button proved the server and said nothing about the agent
A server was registered, Test connected, answered ok and listed all four of its tools. The next run made twenty-two tool calls over nineteen minutes and not one was from that server — loading MCP servers at start is off by default. Nothing on the screen said so.
"It works" and "the agent can use it" are different facts. Test now reports the second one too, with a different message per cause, because turning the toggle on and restarting the app fix different halves of it.
"Verified" described an instant and was read as the delivery
A run reported verified: True with the verifier's own Ran 20 tests ... OK stored beside it. The same command against the tree it left behind: 20 failures out of 20 runs, deterministic. Something wrote after the moment the verdict describes.
Runs now carry delivered_matches_verified, and the Runs list shows a badge when the files on disk are no longer the ones the verdict was about. The verdict stays — it was true when it was given — and the caveat sits beside it.
Installing a skill failed and blamed the wrong limit
"GitHub refused — most likely its hourly limit for anonymous downloads. Try again later, or set GITHUB_TOKEN." Measured at that moment: 55 of the 60 anonymous calls were still unspent. The refusal came from a different host, and the token was never sent to that host — so the printed remedy could not affect the request that failed.
The token now reaches both hosts, 429 is retried with the wait the server asks for, and the message names which host refused.
Writing a file was refused by a message naming a folder the file was inside
Declaring an absolute path as the write-region refused every write, with a message that read as a directory comparison. The agent retried the same write four ways, spent its whole budget and reported an environment fault. The refusal now names the path as compared, says the region is a list of workspace-relative globs, and points at the pattern that can never match.
The model defaults were a generation behind, and one could vanish
| role | was | is |
|---|---|---|
| default model | deepseek-chat-v3.1 0.25/0.95 |
deepseek-v4-flash-0731 0.065/0.18 |
| top tier | deepseek-r1 |
z-ai/glm-5.3 |
| fusion judge | deepseek-r1 |
deepseek-v4-flash-0731 |
| fusion panel, Google seat | gemini-3.1-pro-preview |
gemini-3.8-flash |
deepseek-r1 held two roles with a 64k context window in a tier that asks for 100k. And a -preview slug sat in a default — a model the vendor may withdraw without notice, in the one setting a user never chose. A test now holds that rule across every default.
Nothing was removed from the catalogue: what changed is which entry is the default. .env.example also set a default 20× dearer than the code's and named two withdrawn models; four catalogue prices were stale.
The probe meant to decide the swap did not decide it, and that is worth saying. Eight candidates were asked to write a file; 8 of 8 wrote it. So it rules out catastrophic tool-calling failure and separates nothing. The swap rests on price, context window, a third-party index and latency — all measured. Output quality was not measured and is not claimed.
Also: litellm moves to 1.99 (upstream shipped Windows and macOS wheels again), and Dependabot no longer batches majors with patches — a weekly PR that could neither be merged nor split is one nobody reads.
Full notes: CHANGELOG.md