New AI models releases, April 2026, from the runtime side of a consumer Mac app
Every April 2026 roundup lists the same names. Claude Opus 4.6 topping Arena. Gemini 2.5 Pro at 2M context. GPT-5 Turbo natively multimodal. Llama 4 Scout at 10M tokens. GLM-5.1 under MIT. Those are the press releases. The runtime question no roundup answers is: how does a shipping consumer macOS app pick up a brand-new model the same day it ships, without an App Store build? Fazm does it by not hardcoding the list at all. The Anthropic ACP SDK owns the list. The Mac app is a view of that list, rendered into a picker.
“emitModelsIfChanged de-dupes the SDK's availableModels array, writes models_available to stdout, and Swift renders whatever comes back. No Claude model ID is hardcoded in the macOS UI layer.”
acp-bridge/src/index.ts lines 1271-1281
The anchor fact: eleven lines that make every new model release a no-op for the app binary
The ACP SDK returns an availableModels array on every session/new. The bridge filters, de-dupes, and forwards it. If the SDK knows about claude-opus-4-7 tomorrow, the Mac picker shows claude-opus-4-7 tomorrow. The code below is the entire pivot point.
On the Swift side, the list is reshaped into UI-friendly labels with a three-row substring table. Any new model whose ID contains haiku, sonnet, or opus gets a Scary / Fast / Smart label automatically. Any new family falls back to the API name and sorts last.
What happens on release day
Five-frame timeline of a new Claude release reaching a user's floating bar. This is not a marketing animation. Each frame matches a real event in the bridge.
Before: hardcoded picker
The four-hop path from SDK to picker
Top SERP results for this keyword stop at the first box. Everything after "SDK owns the list" is Fazm's contribution to the runtime.
availableModels, SDK to picker
SDK owns the list
Anthropic ships a new model ID in @agentclientprotocol/claude-agent-acp availableModels.
Bridge forwards it
acp-bridge/src/index.ts:1271-1281 emits {type:'models_available',models:[...]} to stdout.
Swift receives and labels
ShortcutSettings.updateModels substring-matches haiku, sonnet, opus; falls back to name.
Picker row appears
Floating bar @Published availableModels updates. No app relaunch, no new build, no release.
The SDK is the hub, the models orbit it
The Mac app does not talk to each model provider. It talks to one ACP SDK, which talks to whichever model IDs Anthropic publishes. New IDs slot into this orbit as the SDK ships them.
How each April 2026 model maps through Fazm's pipeline
The substring family map decides the label. The bootstrap default decides the warmup seed. Unknown families still make it through. Non-Anthropic models route through a separate account key.
Claude Opus 4.6
Arena #1 through April. Fazm renders it as 'Smart (Opus, latest)' via substring match on opus in ShortcutSettings.swift:161-162. No label change when Opus 4.7 lands.
Claude Sonnet 4.6
Bootstrap default for the 'main', 'floating', and 'observer' warmup sessions at ChatProvider.swift:1047-1050. Pre-warmed cwd = homedir() so memory persists.
Claude Haiku 4.5
Labeled 'Scary (Haiku, latest)'. Substring match on 'haiku' assigns order 0, so it sorts first in the picker.
Unknown family
A model whose ID does not contain haiku, sonnet, or opus gets order 99 and the ACP 'name' field as its display label. Picker still lists it. Lines 187-189.
GPT-5 Turbo, Gemini 2.5 Pro, Llama 4, GLM-5.1
The April 2026 non-Anthropic releases sit outside the ACP availableModels stream. Fazm uses gemini-2.5-pro separately for screen observation, billed under 'observer_gemini'.
Tomorrow's model
Ships with the next SDK version bump. No code change in Fazm. The picker grows a new row automatically on the next session/new.
What a single session/new actually does
Six steps inside about 100ms on a warm ACP connection. The bridge and the Swift picker exchange one JSON line.
- 1
session/new
Bridge sends a JSON-RPC request with cwd, mcpServers, meta.
- 2
SDK returns availableModels
Response carries {sessionId, models:{availableModels:[...]}}.
- 3
emitModelsIfChanged
index.ts:1271 filters out 'default' and de-dupes against last JSON.
- 4
models_available JSON line
index.ts:1279 writes {type:'models_available',models:[...]} to stdout.
- 5
Swift decodes and calls updateModels
ChatProvider.swift:1018 hands the array to ShortcutSettings.
- 6
Picker renders
Floating bar shows Scary / Fast / Smart + any unknown families.
The discovery pipeline, by the numbers
Zero hardcoded IDs means no Swift edit on a new release. 1271 is the exact line where the bridge emits models_available. Three is the full size of the family map: every Anthropic tier fits in three substrings. 99 is the bucket that catches new families like Claude Kestrel before a code change even happens.
Verify the pipeline with four greps
If you distrust any of the file and line claims above, run these against the Fazm desktop source tree. Each grep hits the exact line cited in this guide.
Press-release view vs runtime view of April 2026 releases
The press-release view is what every SERP result for this keyword is built on: feature comparisons, benchmarks, context windows, pricing. The runtime view is what determines whether a Mac user ever gets to click on any of it.
| Feature | Press-release view (top SERP articles) | Runtime view (Fazm source tree) |
|---|---|---|
| Model list source of truth | The blog post itself | Anthropic ACP SDK availableModels response |
| How a new release reaches the UI | An updated bullet in next month's roundup | emitModelsIfChanged -> models_available JSON line -> updateModels |
| Label for claude-opus-4-7 on day 1 | Not rendered anywhere (it's an article, not a UI) | 'Smart (Opus, latest)' via substring match |
| What happens when the family is brand new | New section in the next article | Falls back to API name, order 99, picker still works |
| Unknown non-Anthropic providers | Discussed qualitatively in the roundup | Gemini routed via observer_gemini account key |
| Requires an app release to add a model | Not applicable | No. SDK version bump only |
| Per-window model persistence | Not applicable | UserDefaults 'shortcut_selectedModel', per detached window |
| Verifiable from | Linked official release notes | File:line pins across four files |
The April 2026 slate, as the SERP lists it
Every Anthropic entry below flows through availableModels. The non-Anthropic ones show up through their own paths (Gemini via observer_gemini, Llama / GLM / Mistral via their own CLI-side launches).
Three reasons dynamic discovery matters more than the specs
Not instead of benchmarks. Beside them. A 10M context window only helps the user if they can reach the model. Dynamic discovery is the reach mechanism.
Shipping cadence decouples
Anthropic's release cadence is weekly. Fazm's App Store review cycle is not. Moving the model list into the SDK means those cadences no longer need to align. Users get new models when they ship, not when the next binary clears review.
The picker stops lying
A hardcoded picker drifts the moment Anthropic deprecates a model ID. Fazm's picker cannot drift because it holds no state the SDK does not already hold. If the SDK drops an ID, the picker drops it on the next session/new.
Unknown families still render
Order-99 fallback at ShortcutSettings.swift:189 means a new Claude family name renders under its API label without a code change. The label is not pretty, but the user can select and route to it on day one.
Get the next April 2026 model on your Mac the day it ships
Fazm runs the Anthropic Agent Client Protocol SDK as a patched Node subprocess. When a new Claude model ID hits availableModels, the floating control bar picker grows a new row on the next session/new. The April 2026 release cycle reaches your Mac through that pipe, not through a forced app update.
Download Fazm →Frequently asked questions
Which AI models actually shipped in April 2026?
The April 2026 cycle brought Claude Opus 4.6 (current Arena leader), Claude Sonnet 4.6, Claude Haiku 4.5, GPT-5 Turbo with native multimodal input, Gemini 2.5 Pro with a 2M token context on Vertex, Gemini 2.5 Flash, Llama 4 Scout at 10M context, Llama 4 Maverick, GLM-5.1 (MIT license, 744B MoE), Mistral Large 3, DeepSeek R2, and Qwen 3.5. This guide is not a roundup of those names. It is about the plumbing that turns any of them into a picker row inside a shipping macOS agent without a new app build.
Does Fazm ship a new app version every time Anthropic releases a Claude model?
No. The desktop app at no point maintains a hardcoded list of current Claude model IDs in Swift. The source of truth is the Anthropic Agent Client Protocol SDK, which returns an availableModels array in the result of every session/new JSON-RPC call. The bridge at acp-bridge/src/index.ts:1345-1361 forwards that array up to the Swift UI as a models_available JSON line. If the SDK is installed at the right version, a new model ID appears automatically.
How does Fazm label a brand-new model in the picker?
ShortcutSettings.swift line 183 runs modelId.contains($0.substring) against a three-row family map at lines 159-163: ('haiku','Scary',0), ('sonnet','Fast',1), ('opus','Smart',2). Any new model whose ID contains one of those substrings renders as '{short} ({family}, latest)', so claude-opus-4-7 becomes 'Smart (Opus, latest)' on first sight. If the substring does not match, line 188 falls back to the ACP name field directly. No label table to edit.
What is the models_available event and where does it go?
It is a JSON line of the form {type: 'models_available', models: [{modelId, name, description}, ...]} emitted by acp-bridge/src/index.ts:1279 inside the emitModelsIfChanged function at lines 1271-1281. It is typed in acp-bridge/src/protocol.ts:276. The Swift side receives it, decodes it into a list of ModelOption structs, and calls ShortcutSettings.shared.updateModels at Providers/ChatProvider.swift:1018. That call reorders the list by family, picks up unknown families via their API name, and pushes the result into the SwiftUI @Published availableModels array.
Does Fazm hardcode ANY model default?
Only the session warmup seed. ChatProvider.swift lines 1047-1050 pre-warms three ACP sessions ('main', 'floating', 'observer') with model: 'claude-sonnet-4-6'. This is the bootstrap default the app uses before the ACP SDK has returned availableModels for the first session. As soon as session/new responds, emitModelsIfChanged fires and the picker reflects whatever the SDK actually offers. If Anthropic deprecates claude-sonnet-4-6 tomorrow the seed fails over via session/set_model at index.ts:1341.
Why not just hardcode the model list like every other macOS AI app?
Two reasons. First, hardcoded lists drift: the day Claude Opus 4.7 or Haiku 5 ships, every app in the App Store that froze its picker on Opus 4.6 is now out of date until its next review cycle. Second, the ACP SDK already maintains the canonical list, so copying it into Swift is pure duplication that cannot be kept in sync. The only correct place to own the list is the SDK. Fazm treats the SDK as ground truth and the UI as a rendered view of that truth.
What about per-window model persistence?
DetachedChatWindow.swift stores selectedModel per-window in UserDefaults under 'shortcut_selectedModel' at line 355 of that file. Each popped-out chat remembers its own model choice across app restarts. That lets you keep one window on Opus for hard reasoning and another window on Haiku for cheap tool loops. The normalizeModelId helper at ShortcutSettings.swift:169-175 reconciles legacy saved IDs against whatever fresh IDs the SDK returns today.
Does any non-Claude provider show up through the same pipeline?
The ACP SDK's availableModels currently enumerates Anthropic models. Fazm uses Google gemini-2.5-pro for the screen observer pipeline under account 'observer_gemini' (GeminiAnalysisService.swift:260-269). That is tracked and billed separately, not through the Ask Fazm picker, since it runs as a background analyzer not a conversational model. The separation keeps the picker consistent with what ACP actually drives.
What happens if the SDK returns an unknown model family, for example 'claude-kestrel-1'?
ShortcutSettings.swift lines 187-189 handle the miss. The modelId fails every substring check on haiku, sonnet, opus, so the code falls back to `model.name.isEmpty ? modelId : model.name` and assigns order 99, which sorts it after known families. The picker still shows it, under its raw API label. No crash, no hidden model. The user can select it and the SDK gets set_model with that exact ID.
How do I verify this on my own machine?
If you have the Fazm desktop source, run rg -n emitModelsIfChanged acp-bridge/src/index.ts and you should hit line 1271. rg -n modelFamilyMap Desktop/Sources/FloatingControlBar/ShortcutSettings.swift hits line 159. rg -n models_available acp-bridge/src/protocol.ts hits line 276. The combination proves the SDK-to-UI flow. In a running app, watching the stderr log on a fresh session/new shows a line prefixed 'Emitted models_available:' listing the exact IDs the ACP SDK returned that day.
How is this different from a model router?
Model routers pick which model to send a prompt to. Fazm's pipeline is upstream of that: it discovers what models exist at all. Routing logic, if any, runs in the Swift picker and in per-window selection, not in the discovery path. The distinction matters because a router that knows only three models will never route to a new one, no matter how smart. Discovery first, route second.
Does compact_boundary, usage tracking, or Anthropic's context management API affect this flow?
Not directly. compact_boundary is a separate runtime signal covered in the Fazm 'latest LLM news, April 2026' guide. Discovery and labeling happen once per session start and do not interact with context compaction, prompt caching, or rate_limit_event. They are complementary signals wired into the same bridge process.
Why this matters more than the benchmarks this month
Every article you can read about the April 2026 AI model releases ends in the same place: a table of context windows, benchmark scores, and prices per million tokens. The table is stale on publication. By next week there is a new row. By next quarter the model IDs are different.
A shipping consumer Mac app cannot afford to be stale. So Fazm moved the source of truth out of the Swift layer entirely. availableModels lives in the Anthropic ACP SDK. models_available moves it across the subprocess boundary. updateModels renders it into a picker row with a three-line substring rule. On the day Opus 4.7 or Haiku 5 lands, the picker grows a new row, the user clicks it, and the app behaves exactly as if Anthropic had built that model into Fazm from day one.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.