Your warm session stops getting evicted mid-run
The session bank protects the state that makes follow-up turns fast. Two failure modes are closed:
- Cross-session pressure could evict the session you were actively
using. A long coding session's warm entry was LRU-evicted mid-run,
forcing an 85.6k-token full re-prefill on the very next turn.
Sessions that touched the bank within the last
MTPLX_SESSION_BANK_ACTIVE_PIN_TTL_Sseconds (default 600) are now eviction-last: cross-session pressure prefers idle victims. It is an activity window, not a pin, so a crashed request can never leak a reservation. - Per-turn sibling snapshots accumulated without bound. Agent
turns can produce near-duplicate divergent snapshots (~1.7 GB each on
a 27B session) that prefix-superseding could never reclaim. The bank
now keeps the newest
MTPLX_SESSION_BANK_PER_SESSION_MAX_ENTRIES(default 3) per session; live and protected entries are exempt.
/health now reports active sessions, the pin TTL, and recent
evictions, so "what did the bank just do" has an answer.
Tool-turn commits stop being ghosts
Two background-commit pathologies made agent loops pay a cache tax on every tool turn:
- The tool-rewrite async commit rendered a "canonical" history that
matched neither what was generated nor what the client sent next. It
could burn a full-history re-forward (26.8 s observed at 27-29k
context) and never store a usable entry. It is now disabled pending a
byte-proven canonical render (
MTPLX_IDLE_POSTCOMMIT_TOOL_REWRITEre-enables it); store-on-prefill and block salvage already cover the lane. - Fast agent loops (next request arriving in under half a second)
preempted every background commit before it landed, so the
generation tail never got banked. A bounded foreground grace
(
MTPLX_POSTCOMMIT_FOREGROUND_GRACE_S, default 2 s) lets a nearly-finished commit land; the request that arrives after the window still wins immediately.
And an identity fix that multiplies both: the server now honors the
x-session-affinity / x-session-id headers OpenCode sends on every
request, so consecutive turns from the same session stop being treated
as strangers.
Every serve keeps a durable trail, diagnosis stops being archaeology
2.4.1 added opt-in bit-exact request capture. 2.4.2 turns on the
always-on companion: every serve writes per-request telemetry ,
timings, token counts, prefill/restore behavior, request ids, to
~/.mtplx/logs/request-log-<port>.jsonl (64 MB × 4 rotation). No
prompt or completion content is recorded, and MTPLX_REQUEST_LOG_JSONL=off
disables it. When an agent session goes wrong at 2 a.m., the evidence
now exists by default.
Three helpers ship alongside: scripts/gauntlet_scoreboard.py
summarizes a session against product bars (decode floor, TTFT,
re-prefill hygiene); scripts/oc_tap.py is a transparent recording
proxy for content-level wire truth (it also forces
Connection: close toward the client, because keep-alive pools were
observed silently dropping the first request after a server restart);
scripts/oc_tap_diff.py shows exactly what a client rewrote between
consecutive requests.
One contract fix caught on a live gauntlet: the bridge's convergence guard could be read by the model as a session-wide tool ban ("the system explicitly forbids additional tool calls"), stalling the session. The guard now states that editing and verification tools remain allowed and that it scopes to the current reply only.
Experimental: DeepSeek-V4-Flash
A from-scratch native backend for model_type: deepseek_v4
(Hyper-Connections, compressed sparse attention with learned gated
pooling, hash-routed MoE layers, grouped output-LoRA), loading the
published mlx-community checkpoints directly, plus an optional
single-block MTP speculative lane when the checkpoint carries
mtp.0.* draft weights. The speculative lane is gated on committed-
sequence identity with AR and measured up to 2.28x at K=3 on the
2bit-DQ build. Checkpoints that declare MTP but ship no draft weights
(the current mlx-community conversions) degrade cleanly to AR. The
backend is labeled experimental; treat throughput as unoptimized.
Contributed by @davidtai (#216).
The documentation now tells the truth
Seeded by #215 (a README workflow pointing at a script that never existed, removed in #218 by @PhilipJohnBasile), a three-sweep audit verified ~450 documentation claims against the code and fixed every confirmed drift across 27 files. The ones you might have hit:
- INSTALL.md pointed
performance-coldusers at an MLX fork that was removed in v2.0.0. MTPLX runs on stock PyPI MLX, full stop. - turbo-verify.md called the turbo lane "experimental, off by default" , it has been the shipped default for the quantized 27B flagships since 2.0.0 and the 9B tier since 2.0.1, and wrongly excluded the 6-bit lane that ships.
- The Anthropic client instructions (docs and the canonical example)
pointed
base_urlat/v1, which 404s once the SDK appends/v1/messages. Use the server root. /metricswas documented as offering "Prometheus-style text". It never did; it returns a JSON snapshot.- The README modes table hid Turbo entirely, so third-party benchmarks following it measured the wrong profile.
- The Laguna memory requirement claimed 96 GiB with no code basis; the real preflight gate is ~85.3 GiB of unified memory.
- Four diagnostic subcommands (
profile thermal,profile eval-attribution,profile dispatch --trace,thermal fanmax-run) invoked scripts that do not exist in the distribution, and--dry-runprinted the phantom paths. They now say honestly when the research-workspace tooling isn't present. mtplx doctorcertified Python 3.10 on a package that requires 3.11, and several of its remediation texts were unactionable.- Historical release notes that documented commands which never worked keep their record but gain bracketed corrections naming the working path.
Upgrade
- App: Sparkle offers 2.4.2 (build 24200); the app re-provisions its runtime from the bundled wheel on next Start.
- pip:
pip install -U mtplx - Homebrew:
brew upgrade mtplx
No defaults changed for non-agent workloads. The new session-bank and
postcommit behaviors ship with conservative defaults and are fully
env-tunable; set MTPLX_REQUEST_LOG_JSONL=off if you want no on-disk
request trail.