Changelog / release
0.12.5 — Tool calling tells the truth
Released 2026-08-07 · full changelog · GitHub releases
Ten defects across the parsers, the streaming path and the prompt builder, all the same shape: what the model meant to call was not what got called, or not what you saw.
- Every streamed string argument could come back wrapped in quotes. On the streaming path only, formatting whitespace arriving before a JSON value’s opening quote made the Qwen3-Coder XML parser read the wrapper quotes as argument bytes.
browsegot"https://example.com"— quotes included — and rejected it as not a URL; a file read got"/path/to/file"and was told it does not exist. Non-streaming was unaffected, which is exactly what made it read as a weak model rather than a parser bug: same model, same prompt, onlystreamdiffering — 4/4 correct without it, 5/5 corrupt with it. Found from the other end, as five stable failures in the Hermes agent suite (PR #1600). agents codex --setupno longer deletes your Codex config. It rewrote~/.codex/config.tomlfrom a template instead of merging, so anyone who had customised Codex lost it the first time they pointed it at Rapid-MLX. It now deep-merges, backs the original up first, and copies metadata through the destination descriptor rather than by pathname — so the backup cannot be diverted by a symlink swapped in mid-write (PR #1539).- Tool-call arguments survive the round trip. Seven defects, one shape — a value the model emitted did not reach the tool: values mangled converting between wire formats (#1518), XML delimiters stripped out of string arguments (#1552), undeclared parameters accepted ambiguously (#1551), Qwen truncating its own arguments at the length cutoff (#1574), streamed arguments unvalidated on some parsers (#1559), Nemotron dropping the declared-tool gate while streaming (#1540), and forced-stream tool wire leaking into the response (#1546).
- LFM models no longer print their tool calls at you. On the streaming path LFM2.5 emitted raw markup into the visible answer while the call itself parsed fine, so it looked like a display glitch. It was not: for parsers without native tool-format support the engine serialises prior calls into the prompt as
[Calling tool: name({args})], the model imitates its own transcript, and the parser only knew the pythonic dialect. 10/10 before, 0/10 after (PR #1592). - Concurrent chat and tool calls no longer kill the engine loop. With both in flight,
PromptProcessingBatch.extendwroteNoneinto mlx-lm’s per-slot logits-processor list and took the scheduler down — reproducibly, in 3 of 5 runs (PR #1526). rapid-mlx lswas reporting cached sizes at roughly double reality. It walked the Hugging Face cache following symlinks, counting each blob once underblobs/and again through everysnapshots/link. Every “reclaim space” figure inherited the error, including the ones the Mac app renders — Ternary Bonsai 27B read 15.87 GiB against a true 7.9 GiB (PR #1584).- Ministral 3 is withdrawn. It could return no reply at all on some Macs; the alias is gone rather than left in the picker. Model count is now 215.