Skip to content

TASK: merge upstream v0.33.0 (ebf200f9) — mlxrunner prefix-cache robustness, Claude Desktop subsystem; pins unchanged - #217

Merged
glennneuber merged 23 commits into
mainfrom
task/upstream-sync-2026-08-26
Aug 26, 2026
Merged

TASK: merge upstream v0.33.0 (ebf200f9) — mlxrunner prefix-cache robustness, Claude Desktop subsystem; pins unchanged#217
glennneuber merged 23 commits into
mainfrom
task/upstream-sync-2026-08-26

Conversation

@glennneuber

Copy link
Copy Markdown

The merge is done on this branch — zero conflicts — with the local test gates green; what remains before deploy is the Metal-host gates and the (deliberately deferred) image build + preflight. Full assessment: docs/maxusai/tasks/upstream-sync-2026-08-26.md.

Scope

Merge upstream release tag v0.33.0 (ebf200f9) into main. Merge-base 8f912415 (v0.32.15+6); exactly 20 upstream commits (2026-08-21 → 08-25). Dry-run and actual merge both clean — zero conflicts, including against the freshly merged qwen25vl cuBLAS gate (#215) and the preflight poison_probe.

Why this fold is nearly free

Both payload pins are unchanged: LLAMA_CPP_VERSION stays b10488 / 9d77fa172, MLX stays 27fec909…. Every llama/compat/ patch carries unmodified (clean-room validated against this exact pin on 2026-08-26; 903 still required — llama.cpp#27044 remains open), every preflight expectation stays valid with zero re-measurement, and the fork-tag version lineage keeps matching the cuda-dynres-903 profile.

What's in it

  • 5 mlxrunner prefix-cache robustness commits (the substance): prefill snapshots survive mid-prompt cancels, captures clipped to trie-node edges, generated-token page-out, whole-child-node trie growth, draft-cache settling on cancelled prefills — directly relevant to long-prompt / speculative MLX campaigns. Textual overlap with fork work is confined to x/mlxrunner/pipeline.go + prefix_cache.go (auto-merged).
  • Claude Desktop subsystem (~15 commits, internal/proxy/claude_desktop* + app//cmd/launch/): new self-contained files, inert to the serving image.
  • Two small fixes (proxy image fallback, cmd editor guard).

Stock 0.33.0 still carries the qwen2.5vl fp16-accumulate class (#216) — the gate stays load-bearing and poison_probe asserts it on every preflight.

Acceptance criteria

  1. ✅ Merge on this branch, zero conflicts.
  2. go test ./server/ ./model/renderers/ ./model/parsers/ ./llm/ — all green (golang:1.26 container).
  3. ☐ mlx suite + 12b/26b/31b vision goldens on the Metal host — the semantic gate for the two overlapping files (single-owner-thread rule).
  4. ☐ Image build (bigdisk builder, GOFLAGS version stamp, expect the ~3 h MLX-stage nvcc cache miss) + full CUDA preflight (poison_probe included) + mlx-metal preflight — deferred until the rebuild is green-lit; vsuite's interim global-f32 workaround retires when this deploys.
  5. ✅ Merge-commit body carries the SPEC H11 server_version comparability note.

Follow-up owed after landing: re-merge fix/mlx-thrash-check-default-off (touches pipeline.go, upstream's delta there is +4 lines).

🤖 Generated with Claude Code

jessegross and others added 22 commits August 21, 2026 09:58
A prefill settles the drafter with the seed token after its last chunk,
leveling the draft caches with the targets; a cancelled prefill
returned before that, leaving the targets one token past the draft
caches and the recorded keys. The next request then had to move every
cache, and models with recurrent layers, which cannot rewind, fell back
to the last snapshot: a retry after a client timeout lost up to a full
snapshot interval of the prompt it had just evaluated.

Settle with the next prompt token on the cancelled path too. The caches
then rest level with the recorded keys, and a retry resumes exactly
where the prefill stopped.
Page-in restores a path node by node and trusts each stored snapshot to
cover its node's whole edge. A capture taken during prefill spans from
the previous capture or the prefill base, which need not line up with
the node it lands on: when a prefill resumes partway into cached
history, a capture can reach back before its node's start, and a
capture landing on a node that already has snapshots replaced them
with a shorter span that page-in then could not serve.

Clip each capture to its node's edge on attach, and keep the snapshots
the node already has instead of replacing them.
When a session closes, every cache rests exactly at the end of the
segment the trie is about to record. That is the one moment the
segment's state can be captured for every layer, so close now pages
the new segment out itself instead of recording it without snapshots
and leaving the capture to a later path switch.

Path switching then has nothing left to capture and only rewinds and
pages in. The whole-state entry taken at close is released when the
next request grows past the segment; sliding-window layers pay the
same window copy a scheduled capture already costs.
…s survive resumed prefills

A prefill that resumes partway into cached history — routine once
client timeouts interrupt long prompts — used to attach its captures
onto a node extended in place, so the stored snapshot spanned only the
tokens the prefill evaluated while the node's edge reached further
back. Restores walk node by node and trust each snapshot to cover its
node's edge; the short snapshot stranded the caches at mismatched
offsets and, on models with recurrent layers, ended up freeing all
cache state — a request matching 46k of a 47k-token prompt reprocessed
from zero.

Growth now never extends a node underneath its snapshots. New tokens
become a child node that carries exactly its own captures, and the
path stays compressed because non-user segments merge back into their
parent through the caches' snapshot Merge. Close already pages out
what it records, so every merge combines adjacent covered snapshots
and every stored snapshot spans exactly its node's edge.
A long prompt records restore points during prefill, but they only
reached the prefix trie when the prefill completed; a cancelled request
closed and released everything it had captured. Agent clients routinely
cancel long prefills — their timeouts are shorter than the minutes a
40k-token prompt takes — so every retry started the whole prompt over
and never got further than the timeout allowed, which presents as the
model hanging forever.

Closing a session now attaches every snapshot the prefill crossed, so a
retry resumes from the last one and makes progress across timeouts.
Scenario tests cover retries resuming exactly where a cancelled attempt
stopped and cancellations on divergent conversation variants.

Fixes ollama#17839
…ama#17918)

Claude Code adds a "tokens left" system message after every tool
result. Since ollama moves system messages to the front of the prompt,
this breaks the KV cache on every request.
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
* app: fix desktop interaction regressions

* app: serialize settings reset updates
* app: improve desktop integration responsiveness

* app: reconcile delayed Claude connection results

* app: preserve delayed Claude action errors
Assessment for merging upstream tag v0.33.0 (ebf200f): 20 commits from
base v0.32.15-6-g8f912415, dry-run merge-tree clean (zero conflicts),
llama.cpp and MLX pins UNCHANGED so compat patches and preflight
expectations carry without re-measurement. Substance is five mlxrunner
prefix-cache robustness commits; semantic gate is the fork's mlx suite +
vision goldens. Build/preflight deferred per operator instruction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…xrunner prefix-cache robustness; pins unchanged

20 commits from v0.32.15-6-g8f912415; zero conflicts, textual or
otherwise, including against the qwen25vl cuBLAS gate and the preflight
poison_probe already on main. LLAMA_CPP_VERSION stays b10488 and the MLX
pin stays 27fec909 — every llama/compat patch and every preflight
expectation (payload_pin 9d77fa172) carries unchanged.

The five mlxrunner commits (prefill snapshots on cancel, trie-edge
capture clipping, generated-token page-out, whole-child-node trie
growth, draft-cache settling) overlap fork work only in pipeline.go and
prefix_cache.go; the mlx suite + 12b/26b/31b vision goldens are the
semantic gate before deploy. Stock 0.33.0 still carries the qwen2.5vl
fp16-accumulate class (#216), so the gate stays load-bearing.

SPEC H11 server_version remains the comparability boundary for
benchmark cells measured on builds from this merge; vsuite's interim
global GGML_CUDA_CUBLAS_COMPUTE_TYPE=f32 workaround retires when a
build from this lineage deploys.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@glennneuber

Copy link
Copy Markdown
Author

Reviewing as consolidator. I ran the check I asked for on #208 rather than asking again — it is clean.

Independently, from a git archive of this branch into a scratch tree (nothing touched in the shared checkout), golang:1.26:

go vet ./x/... ./llm/... ./server/...     VET_EXIT=0
go vet ./x/models/... ./x/mlxrunner/...   VET_EXIT=0
go test ./x/models/...                    TEST_EXIT=0

That matters because the acceptance criteria scope tests to ./server/ ./model/renderers/ ./model/parsers/ ./llm/, and the defect that broke main for fourteen hours on #165 was in x/models/qwen3_5/ — a merge resolution keeping both copies of a test upstream had moved:

vet: x/models/qwen3_5/qwen3_5_test.go:43:6: TestSanitizeConvWeight redeclared in this block

None of the four listed packages would have caught it. This sync does not carry that class, and now there is a record saying so rather than an absence of evidence.

Zero conflicts on +14072/-893 is worth a second look for the same reason — a clean auto-merge is exactly the condition under which a duplicated symbol slips through unexamined, because there is no conflict to draw the eye. The sweep above is the substitute for that attention.

Two process notes

CI is still in flight. test (ubuntu-latest), patches (ubuntu-latest), patches-ggml and both other test legs are unresolved as I write. #165 merged with test (ubuntu-latest): FAILURE on the PR — the job is one of the few not gated behind vars.SELF_HOSTED_RUNNERS, it ran, it reported, and it was overridden. If any of those goes red, it blocks. My local sweep is not a substitute for the matrix legs, particularly macOS.

Criterion 4 is the one not to let slide. The image build plus full CUDA preflight and mlx-metal preflight are deferred, and vsuite's interim global-f32 workaround retires when this deploys — so the deploy is load-bearing for #215's arch-scoped fix replacing a blunt global. --platform mlx-cuda now resolves and passes on the CUDA host, so there is a real gate to fail against.

On the MLX half

mlxrunner prefix-cache robustness upstream is the area three of this month's findings sat in: the cacheSession.close double-panic that masked the thrash throw (#211/#212), and the graph-cache poisoning behind it. Worth confirming after deploy that guardClose still reports the first panic — upstream changes in the same teardown path are exactly what would silently undo it, and the symptom would be a return to cudaGraphAddDependencies in the logs with no thrash line.

…pass)

The targeted semantic gate for the two overlapping files ran on the
merged tree without Metal: 244 x/mlxrunner tests pass incl. upstream's
prefix_cache_scenario_test.go. Remaining Apple-host residue narrowed to
the native-runtime SKIPs (TestDFlash* — the draft-cache-settling paths)
and the vision goldens, bundled with the mlx-metal preflight.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@glennneuber
glennneuber merged commit 2dcf295 into main Aug 26, 2026
11 checks passed
glennneuber added a commit that referenced this pull request Aug 26, 2026
…-off

Picks up the upstream mlxrunner prefix-cache rework alongside this
branch's pipeline.go changes; dry-run and actual merge both clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@glennneuber

Copy link
Copy Markdown
Author

Criterion 4, CUDA half: maxusai/ollama:sync-0.33.0 built and full preflight PASSES — 19/19

Built from main @ 51718870 (bigdisk builder, GOFLAGS-stamped 0.32.14-dynres-112-g5171887; the MLX-stage cache miss cost ~3 h of nvcc as forecast). Full preflight on the Blackwell host, no arch or probe skipped:

  • Gates: version → cuda-dynres-903, payload_pin 9d77fa172, image_tag, go_patch_marker — PASS.
  • poison_probe PASS on a natively-gated build for the first time ("1.06x-ceiling trigger decodes healthily, slot clean after") — the llm: force f32 cuBLAS compute for qwen25vl runners #215 gate working from /bin/ollama as shipped, no binary swap, no env override.
  • nemotron_h_omni full incl. pinned (3328 → 3270), gemma4, qwen35: ladders 5/5, baselines, payload proofs, think+format — all match recorded expectations exactly. endpoint_exclusive clean.
  • PASS=19 SKIP=2 (no pinned expectation recorded for gemma4/qwen35), VERDICT: PASS.

Remaining from criterion 4: the Apple-host session — 12b/26b/31b vision goldens + native TestDFlash* + mlx-metal preflight — then deploy, which retires vsuite's interim global-f32 workaround. The superseded dress-rehearsal image pr215-gate-rc0 has been removed; sync-0.33.0 is the deployable artifact.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants