feat(local-model): "Use the local model" works on a buyer's Mac - #347
Merged
Conversation
… the connect screen Checkpoint before the build verifies it; final message on the squash. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Scanning built output reports the repo's own bundled copies and every third-party server (mlx_vlm, transformers) as offenders the moment someone builds the app locally and runs pytest. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…2 gates corrected The bundled server listened and then failed every completion: 'apply_chat_template requires jinja2'. transformers does not declare it. Found by the e2e gate; confirmed by installing jinja2 into the built bundle and getting READY back. Declared unconditionally (pure Python). G1 dropped mlx_lm (not on the serving path) and now requires jinja2. G2's probe copy ran from /tmp, so the script resolved no bundled interpreter and the gate blamed the script for its own mistake; the probe now runs beside the script. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-independent token Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The connect screen offered a local model that could not exist on a fresh Mac. Three independent reasons, each fatal:
mlx_vlm— nothing to serve a model with.scripts/start_model_server.shwasn't in the bundle, and hardcoded~/codec-qwen38-venv, which only the developer's machine has.first_run.pyranfetch_modelswithout--yes— a dry run. The "bundled" 4.3 GB LLM was never downloaded.Operator decision (2026-09-04): accept the bundle growing for the best first-run experience. It landed at 900 MB notarized, vs the 1.2 GB estimate.
What changed
requirements.txt:mlx-vlmgated todarwin/arm64so Linux CI never tries to resolve it;jinja2unconditionally (see below).start_model_server.shresolves, in order:CODEC_MODEL_VENV→ the app's ownResources/python→ the dev venv → system. SetsPYTHONDONTWRITEBYTECODEso it can't corrupt the signed bundle.build_app.shships the script intoResources/app/scripts/, whereservices.jsonalready expects it./api/setup/download_local,/api/setup/download_status). Refuses a duplicate, refuses re-downloading present weights, reports failure honestly — including a fetch that "succeeds" without writing weights.What the gates caught
jinja2was missing. The bundled server started, listened, and then failed every completion:apply_chat_template requires jinja2.transformersdoes not declare it. Only the end-to-end gate — which asks the bundled interpreter for a real completion on a port PM2 doesn't own — found it. Confirmed by installing jinja2 into the built bundle and gettingREADYback, then rebuilt properly.A download-ordering bug.
start_downloadchecked for existing weights before checking for a running download, so a half-finished download (≥500 MB on disk) would have been refused as "already downloaded". The G4 test's realistic fixture caught it.Three of my own gates were wrong and were corrected rather than the code: G1 required
mlx_lm(not on the serving path); G2's probe copy ran from/tmpand blamed the script for its own relocation; G2 then failed the correct answer on an un-normalised path string.A pre-existing test bug:
test_a12_invariantscanneddist/and reported the bundled copies of the repo plus every third-party server as offenders the moment anyone builds locally. Walker now skips build output.Evidence
G3: bundled server answered: READY— fromContents/Resources/python/bin/python3, asserted by process path. Seven gates; G7 (DMG notarized + bundles the MLX-capable app) is added on the follow-up commit once the DMG returns from Apple.🤖 Generated with Claude Code