feat(provider): vMLX local inference for Apple Silicon airgap mode - #21832
Closed
maurice-jobst wants to merge 2 commits into
Closed
feat(provider): vMLX local inference for Apple Silicon airgap mode#21832maurice-jobst wants to merge 2 commits into
maurice-jobst wants to merge 2 commits into
Conversation
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.
Summary
Adds a first-class vMLX model-provider plugin (v0.1.0) for fully airgapped
Hermes operation on Apple Silicon, plus an official setup guide.
The plugin is self-contained under
plugins/model-providers/vmlx/and builtagainst the v0.13.0
ProviderProfilecontract introduced in#20324 and
documented in
#20749. It is gated
to macOS via an
ImportErrorguard in__init__.py, so it has zero impacton Linux, Windows, or non-Apple-Silicon contributors — the discovery loop in
providers/__init__.pyskips the directory on non-Darwin.Motivation
CONTRIBUTING.md ranks cross-platform compatibility as the #2 contribution
priority. macOS is currently the weakest production target for Hermes because
the bundled
custom/Ollama profile is the only local-server precedent inplugins/model-providers/, and it requires the user to know they should setbase_url=http://localhost:…/v1and discover their own auxiliary-routingpattern. On Apple Silicon, MLX is the native, Metal-accelerated path — there
is no first-class provider for it.
This PR closes that gap with the airgap profile real users on regulated or
offline workloads need today: $0 token cost, zero outbound network during
inference, and a clean primary/janitor split so auxiliary work
(compression, summarization, memory writes, skill curation) does not steal
context window from the main agent loop.
Related issues / community context:
community fork with local MLX inference; this brings the pattern upstream
cleanly.
for a local model setup skill / guide; the new airgap doc partially
addresses this.
community tip on faster local inference on Mac via MLX.
#3498
(mlx_whisper STT) and
#5350
(parakeet-mlx STT) — same Apple Silicon / MLX direction, complementary scope.
Compatibility
ProviderProfileplugin contract).default base URLs, aliases) is open to change in response to maintainer
feedback during review; once merged, the plugin will graduate to 1.0 and
semver applies. See
plugins/model-providers/vmlx/CHANGELOG.md.Changes
plugins/model-providers/vmlx/plugin.yaml— manifest,kind: model-provider,v0.1.0. Following the canonical schema documented in docs: pluggable surfaces coverage — model-provider guide, full plugin map, opt-in fix #20749.
plugins/model-providers/vmlx/__init__.py— module-levelregister_provider()calls for twoProviderProfileinstances:vmlx— primary,http://localhost:8000/v1, aliasesmlx,mlx-server,apple-mlx,vmlx-primary.vmlx-janitor— auxiliary,http://localhost:8001/v1, aliasesvmlx-aux,mlx-janitor.Both profiles use
env_vars=()andfallback_models=()— no API key,no cloud fallback. Apple Silicon platform gate via
ImportErroronnon-Darwin so the plugin is invisible elsewhere.
plugins/model-providers/vmlx/README.md— provider-level docs coveringhardware sizing, model acquisition (
mlx-community), serving primary on:8000and janitor on:8001, the matching Hermes config, and a 5-rowtroubleshooting table.
plugins/model-providers/vmlx/CHANGELOG.md— release history with thepre-1.0 stability note and references to feat(providers): ProviderProfile ABC + plugins/model-providers/ (salvage of #14424 + pluggable migration) #20324 / docs: pluggable surfaces coverage — model-provider guide, full plugin map, opt-in fix #20749.
website/docs/guides/macos-airgap.md— new Docusaurus guide underguides/with full setup walkthrough, copy-pasteableconfig.yaml,two
launchdplists for auto-start (with absolute-path discipline sothe plists survive on Apple Silicon Homebrew, pip-user, and venv
installs), verification commands, and a 7-row troubleshooting table.
tests/test_vmlx_provider.py— pytest suite covering both profileregistrations, the default base URLs, and the non-Darwin import guard.
Uses
unittest.mockonly (no new test deps) and skips properly onnon-Darwin runners.
No core files modified.
agent/,hermes_cli/,providers/,gateway/,run_agent.py, andcli.pyare untouched — the v0.13.0discovery loop in
providers/__init__.pyauto-picks up plugins underplugins/model-providers/<name>/, so no resolver branch is needed.Out of scope
adds CUDA/ROCm).
ProviderProfilefor vMLX-specific quirks (extra_body fields,non-standard auth, etc.) — none observed in current
vmlx serve; if anyemerge in review, they ship in a follow-up.
provider_health_checkhook — the v0.13.0 doctor automaticallyprobes
{base_url}/modelsfor anyauth_type="api_key"profile, so aplugin-side hook would be redundant.
Testing
Automated:
uv pip install -e ".[all,dev]" pytest tests/test_vmlx_provider.py -vManual end-to-end on M5 Max, 48 GB unified memory:
pip install vmlxvmlx serve --model ~/models/primary --port 8000 --ctx-size 65536vmlx serve --model ~/models/janitor --port 8001 --ctx-size 16384hermes doctorreports both profiles registered and both/modelsprobes
[ok]hermes runcompletes a tool loop with no outbound network traffic(verified via
sudo tcpdump -i any -nn 'host not 127.0.0.1 and host not ::1')log warnings via the existing doctor probe instead of crashing
pytest tests/ -vpasses on darwinpytest tests/test_vmlx_provider.py -vskips (does not fail) on aLinux CI runner
Reviewer checklist
plugin.yamlschema (name,kind: model-provider,version,description,author) matches the canonical form in docs: pluggable surfaces coverage — model-provider guide, full plugin map, opt-in fix #20749plugins/,website/docs/,tests/)ProviderProfilefields used:name,aliases,display_name,description,env_vars,base_url,fallback_modelsProviderProfilehooks — vMLX matches the defaultOpenAI-compatible chat-completions wire protocol
Suggested labels
comp/provider,platform/macos,type/feature,P2Author
maurice-jobst — developed and validated on M5 Max / 48 GB unified
memory in production use before opening this PR.