Streaming that doesn't freeze, bounce, or vomit
If long answers ever made the app freeze for a beat and then dump a wall of text, or made the streaming bubble visibly bounce while it grew , this release is for you. None of it was the engine (decode was flat the whole time); all of it was the app's render path, and each cause is now fixed rather than papered over:
- Old finalized lines fold into multi-line segments as they scroll past, so a long answer no longer accumulates hundreds of live text views. The measured failure mode, UI updates sinking from ~10 to ~6 per second with 250 to 800 ms stalls on a perfectly healthy engine, is gone.
- The bottom-pin scroll correction now runs in the same display cycle as the layout pass that grew the content. The ±34 px bounce some of you could see six times a second can no longer be presented on screen.
- A per-display-cycle window-sizing walk that put a flat ~50 ms floor
under every update has been switched off (
MTPLX_APP_SIZING_TUNER=0restores the old behavior if you ever need it). - New text reveals with typewriter pacing: a few characters per frame at
steady state, geometric catch-up after a stall, and a hard drain bound
so it can never fall behind (
MTPLX_STREAM_TYPEWRITER=0restores reveal-everything-at-once). - The live tok/s chip now reports a sliding ~5-second window instead of a cumulative average that read high once a long answer slowed down.
Markdown grew up
- Code blocks get real syntax coloring, twelve languages plus a generic fallback, from a freeze-time lexer that colors each line exactly once, when it stops changing. Streaming cost is O(new text), never O(document).
- A code block that is still streaming now renders as a live code card with colored lines, and flips once to its exact settled form when the fence closes.
- Pipe tables render as actual tables.
- Math renders as actual notation:
x^2becomes x², matrices stack as real grids between tall delimiters, fractions stack numerator over denominator, and inline expressions like$(0,0,0)$convert instead of leaking literal dollar signs. Currency stays text. - Performance mode is now a true kill switch: enabling it turns off markdown, cards, and coloring through both the streaming and settled paths, for people who want maximum-throughput plain text.
Fixes
- 2.4.0 short-turn regression: the compiled-verify path could reserve KV budget above the configured ceiling, which taxed short requests with setup work they never used. The reserve is now clamped to the env ceiling. If short turns felt slower on 2.4.0 than 2.3.0, this was why.
- Warming prefills now yield to real traffic within one small chunk, so a background warm-up can no longer delay the request you just sent.
- A derivative model artifact whose folder name extends a first-party
name (say, a local fine-tune ending in
-Speed-something) is now served under its own id instead of the flagship's. The health payload, the OpenAImodelfield, and the app's model chip all tell the truth about what is actually loaded.
For the debugging-inclined
All off by default, all opt-in via env:
MTPLX_REQUEST_CAPTURE_DIR=<dir>persists every request's exact reproduction envelope (post-encoding token ids, sampler, seed, mode, session identity) at dispatch time, so a turn that hangs or dies still leaves everything needed to replay it bit-exactly. This is the third layer of the #196/#197 work.MTPLX_UI_PERF=1(withMTPLX_UI_PERF_HUD=1for an on-screen HUD) turns on the frontend stream-performance probe: main-thread stall census, per-flush ledger, and a per-turn JSONL trace joinable to engine stats by request id.--adaptive-policy costadds a cost-model speculative-depth policy, andMTPLX_GDN_BLOCKED_PREFILL=1enables an experimental blocked-sequential GDN prefill route. Both are experiments; defaults are unchanged.
Upgrading
- App: Sparkle will offer 2.4.1 (build 24100), or grab the DMG.
- CLI:
pip install -U mtplxorbrew upgrade mtplx.
Get it. Download the current DMG, or
brew upgrade mtplx / pip install -U mtplx. Every published speed
number with its conditions is on the benchmarks page; the archive of every version is
on the releases page.