Releases: scouzi1966/maclocal-api
afm 0.9.12
afm 0.9.12
Apple Foundation Models + MLX local models — OpenAI-compatible API, WebUI, all Swift.
Changes since v0.9.11
- fix: resolve executable path via _NSGetExecutablePath, not argv[0] (
4bd0ec6) - Add nightly test results for 2026-05-02 (7af438e) (
4cbbe06) - Update nightly release link to 20260502-a589c50 (
7af438e) - feat(embeddings): add /v1/embeddings backed by Apple NaturalLanguage (#119) (
a589c50) - Feature: Expand vision API with barcode, classify, and saliency modes (#114) (
b7ffe18) - Add on-device speech transcription and TTS (#113) (
34001ec) - fix: afm -w falls back to ephemeral port when 9999 is busy (#116) (
1e9f22c) - README: surface "What's new in afm-next" above Install (
779e89e) - skill(promote-nightly): validate on staging tap before touching production (
53e58fa) - README: remove staging tap from public docs (
87c105e) - README: document installing previous versions of afm (
3dae2dd) - Bump version to 0.9.12 for next dev cycle (
7a23874) - Release v0.9.11: promote nightly to stable (
94fdc35) - skill(promote-nightly): verify Apple framework links and bundle id in Step 5h (
2717cdd) - Credit @jesserobbins for Vision OCR and Speech transcription (
36e0194) - Fix publish-next.sh tap-staging: use full ${VERSION} not ${DATE} (
90fd1d3) - Update nightly release link to 20260418-9c3225e (
a08f840)
Install / Upgrade via Homebrew
Fresh install:
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm
Upgrade:
brew upgrade afm
Install via PyPI
pip install macafm==0.9.12
afm-next (20260502 · a589c50)
Nightly build from main branch.
- Commit: a589c50
- Date: 20260502
- Version: 0.9.12-next.a589c50.20260502
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
Changes since last build (9c3225e)
- feat(embeddings): add /v1/embeddings backed by Apple NaturalLanguage (#119) (
a589c50) - Feature: Expand vision API with barcode, classify, and saliency modes (#114) (
b7ffe18) - Add on-device speech transcription and TTS (#113) (
34001ec) - fix: afm -w falls back to ephemeral port when 9999 is busy (#116) (
1e9f22c) - README: surface "What's new in afm-next" above Install (
779e89e) - skill(promote-nightly): validate on staging tap before touching production (
53e58fa) - README: remove staging tap from public docs (
87c105e) - README: document installing previous versions of afm (
3dae2dd) - Bump version to 0.9.12 for next dev cycle (
7a23874) - Release v0.9.11: promote nightly to stable (
94fdc35) - skill(promote-nightly): verify Apple framework links and bundle id in Step 5h (
2717cdd) - Credit @jesserobbins for Vision OCR and Speech transcription (
36e0194) - Fix publish-next.sh tap-staging: use full ${VERSION} not ${DATE} (
90fd1d3) - Update nightly release link to 20260418-9c3225e (
a08f840)
Install / Upgrade
Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade existing
brew reinstall afm-next # force reinstall (same version, new build)pip
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-nextSwitching between stable and nightly
# Homebrew
brew unlink afm && brew install scouzi1966/afm/afm-next # switch to nightly
brew unlink afm-next && brew link afm # switch back to stable
# pip
pip install macafm # stable
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next # nightlyafm 0.9.11
afm 0.9.11
Apple Foundation Models + MLX local models — OpenAI-compatible API, WebUI, all Swift.
Changes since v0.9.10
- Bump version baseline to 0.9.11 (post-v0.9.10 stable) (
9b3f3bf) - Fix macOS 26 Speech Recognition SIGABRT: embed Info.plist via linker (
b39cd60) - Resolve merge conflicts for PR #107 (
e139985) - Address second round of Vision OCR review feedback (
9039eb5) - Close taskRef/onCancel race window (
8c10027) - Fix recognition task cancellation leak and lock race (
4f19247) - Fix data race in speech recognition timeout (
34406fd) - Address speech transcription review feedback (
8b3a3f0) - Add on-device audio transcription via Apple Speech framework (
7e18c90) - Address Vision OCR review feedback (
38b16c5) - Fix Vision OCR in webui: bypass Foundation Model 4096 token limit (
0292f3c) - Address Vision OCR review feedback (
5159ea2) - Document Vision OCR API (
b1d0f9c) - Add Vision OCR API and stabilize tests (
7ab80b6) - Release v0.9.10: promote nightly to stable (
332c8c2) - feat: versioned Homebrew formulae for afm and afm-next (#102) (
7cff3df) - fix: handle 1D logits in TopPSampler (#100) (#101) (
36ee874) - chore: bump wheel version to 0.9.10.dev20260408 (
212d945) - Add nightly test results for 2026-04-07 (4f24281) (
272cc13) - Update nightly release link to 20260408-628c2bb (
4f24281)
Install / Upgrade via Homebrew
Fresh install:
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm
Upgrade:
brew upgrade afm
Install via PyPI
pip install macafm==0.9.11
afm-next (20260418 · 9c3225e)
Nightly build from main branch.
- Commit: 9c3225e
- Date: 20260418
- Version: 0.9.11-next.9c3225e.20260418
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
🙏 Acknowledgement
Huge thanks to first-time contributor @jesserobbins — this cycle landed two substantial features from him: the Apple Vision OCR HTTP API (#104) and Apple Speech transcription (#107). Both lift afm's Apple-native capabilities from CLI-only into first-class HTTP APIs compatible with the OpenAI-style surface that third-party clients already speak. Contributions of this size and quality from a new contributor are rare and appreciated.
Highlights
- Apple Vision OCR HTTP API —
POST /v1/vision/ocrfor files, multipart uploads, base64, data URLs, and OpenAI-style image content parts. Multi-page PDF support, structured document/page/block/table output, Foundation chat auto-OCR integration. Contributed by @jesserobbins (#104). - Apple Speech transcription — on-device audio transcription via the Speech framework. New
afm speech -f <file>CLI,POST /v1/audio/transcriptionsAPI, chatinput_audiocontent parts. Supports WAV/MP3/M4A/CAF/AIFF. Contributed by @jesserobbins (#107). - macOS 26 privacy fix — binary now embeds
NSSpeechRecognitionUsageDescriptionvia-sectcreate __TEXT __info_plist, so Speech Recognition actually works instead of SIGABRT'ing the process. First invocation from Terminal prompts for permission as expected (no Developer ID required). (#108) - Versioned Homebrew formulae — pinned nightly formulae
afm-next@<full-version>.rbgenerated alongside the rollingafm-next.rbso users canbrew installa specific nightly build. (#102) - TopPSampler 1D-logits crash fix — no longer crashes when concurrent batching meets
top_p<1. (#100 / #101)
Changes since last build (628c2bb)
- Fix publish-next.sh tap-staging: use full ${VERSION} not ${DATE} (
90fd1d3) - Update nightly release link to 20260418-9c3225e (
a08f840) - Bump version baseline to 0.9.11 (post-v0.9.10 stable) (
9b3f3bf) - Fix macOS 26 Speech Recognition SIGABRT: embed Info.plist via linker (
b39cd60) - Merge PR #107 (
b7ecdbd,e139985) — speech transcription - Speech transcription hardening (
8c10027,4f19247,34406fd,8b3a3f0,7e18c90) - Vision OCR + webui bypass (
a3b60a5,9039eb5,38b16c5,0292f3c,a1dda2b,5159ea2,b1d0f9c,7ab80b6) - feat: versioned Homebrew formulae for afm and afm-next (#102) (
7cff3df) - fix: handle 1D logits in TopPSampler (#100) (#101) (
36ee874)
Install / Upgrade
Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade existing
brew reinstall afm-next # force reinstall (same version, new build)
# Pinned to this exact nightly:
brew install scouzi1966/afm/afm-next@0.9.11-next.9c3225e.20260418pip
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-nextSwitching between stable and nightly
# Homebrew
brew unlink afm && brew install scouzi1966/afm/afm-next # switch to nightly
brew unlink afm-next && brew link afm # switch back to stable
# pip
pip install macafm # stable
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next # nightlyafm 0.9.10
afm 0.9.10
Apple Foundation Models + MLX local models — OpenAI-compatible API, WebUI, all Swift.
Highlights
- Gemma 4 support — text, vision-language, and MoE variants with tool calling
- Gemma 4 concurrent batch mode — ~10x throughput via new
BatchRotatingKVCachefor sliding-window attention - Server-level
--guided-jsonnow actually constrains MLX requests (#97) - Concurrent / prefix-cache stability — resolved radix cache SIGTRAP on wrapped
RotatingKVCache(#94), batched prefill lazy-graph overflow, and Metal buffer lifecycle issues under long runs (#88) - Performance — removed
container.performlock and actor serialization bottlenecks, raised SSE multiplex batch limit to 200, pipeline timing instrumentation viaAFM_DEBUG=1 - Request correlation IDs for end-to-end tracing across the server → scheduler → MLX path
Fixes since v0.9.9
--guided-jsonserver flag now applied to every request (fixed in #97)- Gemma 4 batch mode, structured tool history, and Metal buffer lifecycle (#88)
- Gemma 4 streaming + non-streaming tool call type coercion (array/object/int) (#87)
- Radix cache SIGTRAP for wrapped
RotatingKVCache(#94) - Root-cause batched prefill crash caused by MLX lazy graph overflow
- Snapshot prefill state to prevent decode mutation corruption
BatchRotatingKVCachemasktotalLenafter circular buffer wrap- Flatten
anyOf/oneOfnullable schemas for Jinja template safety - Structured output streaming regression
- Queue requests instead of rejecting with
server_busy - Homebrew libexec search path for metallib
- Test harness: timestamped logs, format validation, Codex ARG_MAX, baseline tagging, spec extraction (#98)
Known issues
- TopPSampler + concurrent mode crash: on this exact commit, requests with
0 < top_p < 1hitting theBatchScheduler(concurrent mode, llama.cpp WebUI default) abort with[squeeze] axis 0fatal error. Fix is on main (PR #101) and will ship in v0.9.11 or the next nightly. Workaround: usetop_p=1.0ortemperature=0in concurrent mode for now, or use the WebUI against the non-concurrent single-sequence server path.
Install / Upgrade via Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm
Upgrade:
brew upgrade afm
Pin to this version specifically:
brew install scouzi1966/afm/afm@0.9.10
Install via PyPI
pip install macafm==0.9.10
afm-next (20260408 · 628c2bb)
Nightly build from main branch.
- Commit: 628c2bb
- Date: 20260408
- Version: 0.9.10-next.628c2bb.20260408
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
Changes since last build (2b647b2)
- fix: --guided-json server flag and per-test spec extraction (#97, #98) (
628c2bb) - fix: generate-report.py reads from RESULTS_FILE env var, not hardcoded path (
6b36714) - fix: timestamp all temp files to prevent overwrites between runs (
f10f72b) - fix: codex per-test scoring — local outside function, unbound var (
5142185) - fix: handle unset AFM_BIN with set -u (
e48e0f5) - fix: mlx-model-test.sh defaults to local build over PATH (
2f88460) - fix: smart analysis reporting — codex ARG_MAX, format validation, baseline tagging (
f582ac5) - refactor: address PR #95 review — extract helper, improve readability (
2c7d205) - fix: skip radix save for wrapped RotatingKVCache to prevent SIGTRAP (#94) (
48f88a8) - fix: Gemma 4 batch mode, structured tool history, and Metal buffer lifecycle (#88) (
d5573d1) - Add nightly test results for 2026-04-04 (4 models) (
44c048e) - fix: Gemma 4 tool call type coercion (array/object/int) (
2aa2abd) - fix: flatten anyOf/oneOf nullable schemas for Jinja template safety (
ce66763) - Merge feature/gemma4-batch-kvcache: 10x throughput for Gemma 4 (
bc9de80) - Fix structured output streaming regression (
4afb1ff) - fix: address PR review — empty cache merge safety, slot wait cancellation (
731ca38) - refactor: raise SSE multiplex batch limit to 200, extract as constant (
55ea028) - fix: root-cause batched prefill crash — MLX lazy graph overflow (
329b114) - refactor: improve updateConcat alloc pattern, keep individual prefill (
3d5f9e1) - feat: add request correlation ID for end-to-end tracing (
ea12c89) - perf: add pipeline timing instrumentation (AFM_DEBUG=1) (
65c093c) - perf: remove container.perform lock and actor serialization bottlenecks (
a289c42) - fix: snapshot prefill state to prevent decode mutation corruption (
6e16a21) - fix: BatchRotatingKVCache mask totalLen after circular buffer wrap (
f650d65) - fix: updateConcat alloc size, debug prefillBatch B>=3 crash (
38159f0) - debug: add SDPA shape logging and BatchRotatingKV tracing (
22461ac) - Bypass adaptive XML for Gemma 4 tool calls (
45910d7) - feat: BatchRotatingKVCache — Gemma 4 concurrent batch mode working (
4006a11) - WIP: BatchRotatingKVCache — B=1 works, B>=2 segfaults in SDPA (
c04eafc) - WIP: BatchRotatingKVCache for Gemma 4 batch mode (
0f94cca) - refactor: extract magic numbers to named constants, add coding rule (
4e9edf3) - fix: queue requests instead of rejecting with server_busy (
a73b820) - fix: patch pin check matched wrong line (swift-docc-plugin) (
16cf3da) - Fix Gemma 4 handling and consolidate repo skills (
f0bd9c7) - chore: bump wheel version to 0.9.10.dev20260403, add test reports (
7c38a5a) - Update nightly release link to 20260403-2b647b2 (
9098e31)
Install / Upgrade
Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade existing
brew reinstall afm-next # force reinstall (same version, new build)pip
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-nextSwitching between stable and nightly
# Homebrew
brew unlink afm && brew install scouzi1966/afm/afm-next # switch to nightly
brew unlink afm-next && brew link afm # switch back to stable
# pip
pip install macafm # stable
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next # nightlyafm-next (20260403 · 2b647b2)
Nightly build from main branch.
- Commit: 2b647b2
- Date: 20260403
- Version: 0.9.10-next.2b647b2.20260403
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
Changes since last build (7f15ed5)
- fix: add Homebrew libexec search path for metallib (
2b647b2) - Add nightly test results for 2026-04-03 (be55f89) (
cb29c5e) - Update nightly release link to 20260403-be55f89 (
e379ec1) - feat: add Gemma 4 tool call parser (new tag format) (
be55f89)
Install / Upgrade
Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade existing
brew reinstall afm-next # force reinstall (same version, new build)pip
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-nextSwitching between stable and nightly
# Homebrew
brew unlink afm && brew install scouzi1966/afm/afm-next # switch to nightly
brew unlink afm-next && brew link afm # switch back to stable
# pip
pip install macafm # stable
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next # nightlyafm-next (20260402 · 64de72f)
afm-next 0.9.10
- Commit: 64de72f
- Date: 2026-04-02
- Version: 0.9.10-next.64de72f.20260402
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
Bug Fixes
- #67 — Chat.Message missing
namefield causes Jinja template failure on Gemma tool responses. Addedname: String?to vendorChat.Messagevia patch. (eb10bc9,5cf4336) - #68 — Mistral3/sliding-window models produce degenerate output in batch mode. RotatingKVCache models now fall back to serial generation via
runSerialGeneration(). (cdf87ab) - #72 — Batch logit processor crashes (top_k, presence_penalty, repetition_penalty). Added ndim-safe 1D/2D handling, fixed first-token dispatch, grammar JSON opening brace. (
b36b953) - #74 — Prioritize AFM cache for model loading, enable CacheList models in concurrent batch mode. (
d36fb10) - #75 — Relative model paths broken by metallib CWD change. Now resolves against original shell
$PWD. (7bbb47c) - #76 — Single-prompt mode (
-s) pollutes terminal with loading/cache/GPU logs. All output suppressed unless--verbose; only the response prints. (a150479,64de72f) - #80 (partial) —
afm_adaptive_xmlparser appends</functionto zero-parameter tool names. Safety-net stripping added in 3 code paths; intermittent vendor parser root cause filed for follow-up. (aab6449,0585f06)
Testing & Infrastructure
- Dimension tags (
// dimensions:) added to all 14 Swift unit test files (f51991b) - Section 16: 6 pairwise smoke tests for high-risk interactions (
f51991b) - 5 unit tests for Chat.Message name field patch guard (
4f1736a) - Improved 7 opencode promptfoo test prompts (ambiguous → actionable), fixed workspace_symbol regex
- Nightly results: 392/395 assertions (99%), 350/388 promptfoo (90%)
Install / Upgrade
Homebrew:
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade
pip:
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next
afm 0.9.9
afm 0.9.9
Apple Foundation Models + MLX local models — OpenAI-compatible API, WebUI, all Swift.
Changes since v0.9.8
- fix: HF-style cache for model downloads, avoid iCloud eviction — downloads now go to
~/.cache/huggingface/hub/(Python-compatible HF layout) instead of~/Documents/huggingface/which was iCloud-synced on macOS, causing timeouts and crashes from disk eviction - fix: partial download resume — interrupted downloads are automatically resumed on next launch via
swift-huggingfaceHubClient - dep: swift-transformers 1.3.0 + swift-huggingface 0.8.1 — Python-compatible HF cache with blob/snapshot/symlink layout
- fix: metallib available for swift test after clean builds
- fix: eliminated fatalError crash when binary is relocated (pip/Homebrew install)
Known Issue
- Batch logit processors (
top_k,presence_penalty) crash in--concurrentmode (#72)
Install / Upgrade via Homebrew
Fresh install:
```
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm
```
Upgrade:
```
brew upgrade afm
```
Install via PyPI
```
pip install macafm==0.9.9
```
afm-next (20260331 · 74dbbe2)
Nightly build from main branch.
- Commit: 74dbbe2
- Date: 20260331
- Version: 0.9.9-next.74dbbe2.20260331
This is an unstable development build. For the latest stable release, use
brew install scouzi1966/afm/afm.
Changes since last build (392de4a)
- fix: ensure metallib available for swift test after clean release build (
74dbbe2) - fix: use HF-style cache for model downloads, avoid iCloud eviction (#71) (
6c1eec9) - Bump version to v0.9.9 (
0b9d25f) - Release v0.9.8: promote nightly to stable (
85e914c) - feat: add test-afm-binary skill for standalone binary validation (
49bcbc8) - Add promptfoo agentic evals to build and test skills (
226b3c4) - fix: add mandatory relocated-binary checks to nightly AND stable skills (
ed52fed) - fix: eliminate fatalError crash when binary is relocated (pip install) (
6b58bf9) - Update nightly release link to 20260327-62395ab (
7093997)
Install / Upgrade
Homebrew
brew tap scouzi1966/afm
brew install scouzi1966/afm/afm-next # fresh install
brew upgrade afm-next # upgrade existing
brew reinstall afm-next # force reinstall (same version, new build)pip
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-nextSwitching between stable and nightly
# Homebrew
brew unlink afm && brew install scouzi1966/afm/afm-next # switch to nightly
brew unlink afm-next && brew link afm # switch back to stable
# pip
pip install macafm # stable
pip install --extra-index-url https://kruks.ai/afm/wheels/simple/ macafm-next # nightly