Consumer view of the release wave
Five labs shipped frontier LLMs in a fortnight. Our Mac app’s picker added zero new rows.
Every other writeup of April 2026 is a scorecard: who shipped, when, at what price, against which benchmark. This one is a consumer story. It walks through what happened inside a shipping Mac app when Claude Opus 4.7, GPT-5.5, DeepSeek V4, Gemini 2.5 Pro, and Llama 4 variants all landed within two weeks, and why the picker users see has three labels instead of fifteen.
The April 2026 release wave, at a glance
Anthropic made Claude Opus 4.7 generally available on April 22, at the same $5 input / $25 output per million tokens as Opus 4.6. Sonnet 4.6 had already settled in as the everyday default. OpenAI introduced GPT-5.5 and GPT-5.5 Pro in the API on April 24. DeepSeek dropped V4-Pro and V4-Flash the same day under an open license, using a mixture-of-experts architecture. Google pushed Gemini 2.5 Pro forward. Meta announced Spark Muse around Llama 4 movement. A third Anthropic model, codename Capybara (Claude Mythos), remains gated behind Project Glasswing.
The more interesting question, for anyone sitting on the consumer side rather than the provider side, is not which lab had the better benchmark. It is: when five providers ship in fourteen days, what does the picker in my Mac app do? Does it grow by five rows? Does it ask me to pick a winner? Does it ask me to learn five new version numbers?
Claude Opus 4.7
Anthropic GA on April 22, 2026 at $5 input / $25 output per million tokens. Inside Fazm it became the backing for the Smart button the next session/new after it appeared in the SDK. No Fazm build, no migration step visible to users.
Claude Sonnet 4.6
The everyday default, already in place for most of April. Backs the Fast button. The floating bar, the main chat, and the observer all run against Sonnet 4.6 unless the user switches per-turn.
GPT-5.5 / GPT-5.5 Pro
OpenAI shipped these to the API on April 24, 2026. Not routed through Fazm today because the picker is fed by the Claude agent SDK. The architecture to add them is a second bridge, not a picker change.
DeepSeek V4 (Pro + Flash)
Open-source mixture-of-experts family released April 24, 2026 with price-performance pressure on closed models. Same story as GPT for Fazm routing: open channel for a future bridge.
Gemini 2.5 Pro, Llama 4, Spark Muse
Google pushed Gemini 2.5 Pro forward. Meta announced Spark Muse around Llama 4 movement. The density of simultaneous releases is the point, not any single launch.
The anchor fact
The picker has 0 labels. The table behind it has 0 rows.
The picker Fazm users see has exactly three buttons: Scary, Fast, Smart. It is rendered at SettingsPage.swift line 2025 as a ForEach(shortcutSettings.availableModels). The array it iterates is not a Swift enum. It is populated at runtime from whatever the Claude agent SDK reports, translated through a 4-row substring table (modelFamilyMap at ShortcutSettings.swift line 159). That table is the entire model catalog. April’s release wave did not make it bigger.
How other apps grew. How this one did not.
Two ways to respond to a release wave of this density. Most developer-facing tools took the scorecard approach: every new model is a new picker row, labeled with the full API name, with version numbers surfaced so expert users can benchmark-pick. Fazm took the opposite approach on April 20 with version 2.4.0: three usage labels, model IDs hidden behind them, no version numbers anywhere in the primary UI. Flip to see what each approach feels like during a release fortnight.
Two pickers, same release wave
Typical for developer-facing tools. Every new model becomes a new row. Users scroll through Opus 4.7, Opus 4.6, Sonnet 4.6, Haiku 4.5, GPT-5.5, GPT-5, DeepSeek V4-Pro, and so on, and pick the one they read about on Twitter this morning.
- Picker grew by 5 rows across April 2026
- Version numbers surfaced in the primary UI
- Users expected to benchmark-pick per task
- Every provider release ships a new build
The substring table that does the renaming
Four rows. That is the whole catalog. It lives at Desktop/Sources/FloatingControlBar/ShortcutSettings.swift line 159. Every model ID the agent reports is matched by substring against these rows, and the first match wins. There are only four rows because there are only four interesting families this month: Haiku, Sonnet, Opus, and the default pseudo-model that Anthropic’s SDK uses as a server-side alias.
The trick is that the left column is a substring, not an exact match. That is what absorbs the April release wave without code edits: claude-opus-4-7 contains opus, so it routes to Smart. claude-sonnet-4-6 contains sonnet, so it routes to Fast. Anthropic can ship claude-opus-5 next month and it routes to Smart with zero work on our side.
How a new model ID reaches the picker
Three inputs fan in to the one function that owns the model catalog, and three UI surfaces fan out from the one @Published array it writes to. That is the entire graph.
From the SDK to every picker surface
What the substring match produces in practice
Tail the dev log at /tmp/fazm-dev.log during an app launch and you see the exchange play out. The raw list from the SDK includes an ID literally named default; the bridge drops it before the IPC; the Swift side receives three real models and substring-matches them into three labels. Nothing here is invented. These log lines come from logErr calls in the bridge and log calls in updateModels.
Notice what the user actually sees in the picker: not claude-opus-4-7, but Smart (Opus, latest). The version part of the label is fixed; only the backing ID rotates. Users who were on Opus 4.6 two days before the GA launched do not experience a migration. They just keep clicking Smart, and Smart now routes to 4.7.
The April 2026 timeline, played through this architecture
Four events that matter to a Fazm user during the month. Only one of them is a Fazm release. The other three are provider-side launches that the architecture absorbs without a build.
From 2.4.0 through the release wave
April 20: Fazm 2.4.0 ships
The model picker stops hard-coding IDs. availableModels is now a @Published array fed at runtime by the Claude agent SDK through a bundled subprocess. The Swift enum of model IDs is gone. The defaultModels fallback stays, but only to cover the split second before the SDK responds.
April 22: Claude Opus 4.7 GA
Anthropic pushes the new Opus ID into the agent SDK. No announcement is needed for Fazm users. Next app launch, the bridge sees it inside session/new's models.availableModels field, and the Swift side substring-matches opus to the Smart label.
April 24: GPT-5.5, DeepSeek V4 land at other labs
Outside Anthropic, the release pressure goes up sharply. Inside Fazm nothing changes because the bridge talks to Claude. The picker remains three labels. The user's experience of the wider release wave is invisible unless they read the news.
Every session/new throughout the month
preWarmSession runs on every app boot. Every session/new response carries models.availableModels. emitModelsIfChanged diffs, fires one IPC on change. The picker stays current without any user action and without any support ticket traffic.
Three labels, many providers orbiting them
The picker is ready for providers Fazm does not route to today. The 4-row substring table has an explicit else branch at ShortcutSettings.swift line 189 that catches anything it has never seen, falls through to the raw API name, and assigns sort order 99 so the model drops to the bottom of the picker without blocking selection. The architecture, visualised as an orbit rather than a table.
Two approaches to the release wave, compared
A cleaner side-by-side of the decisions each approach is making, at every layer from the catalog to the user. The scorecard approach is internally consistent; it just optimizes for a different user than the one who downloads a consumer Mac app.
| Feature | Scorecard picker (typical) | Fazm (three-label picker) |
|---|---|---|
| Model catalog source | Swift enum or JSON inside the app binary | Agent SDK response at runtime |
| Picker rows visible to user | One row per version number | 3 (Scary / Fast / Smart) |
| Reaction to a new Claude model | New build, App Store review, user restart | Next launch, substring match, zero build |
| Reaction to a non-Claude model | New build required to expose it in the UI | Unknown family falls to sort order 99, still selectable |
| User mental model | Pick by benchmark / price per million tokens | Pick by task difficulty |
| Version numbers in primary UI | Surfaced prominently | None |
| Migration on SDK rename | Custom code per release | normalizeModelId handles it at ShortcutSettings.swift line 170 |
“Available AI models now populate dynamically from the agent, so newly released Claude models appear without an app update.”
CHANGELOG.json, Fazm version 2.4.0, dated 2026-04-20
What the user sees, frame by frame
The same events, reframed from the user’s seat rather than the architecture diagram. The notable thing is how little there is to see.
April 20, launch Fazm
The short version of all of this
April 2026 was the densest LLM release fortnight in years. Most apps treated it as a shipping problem and grew their pickers by five rows. Fazm treated it as a naming problem. Three labels, a 4-row substring table, and a subprocess that talks to the Claude agent SDK at runtime. The picker survived the wave at zero builds and zero rows added. The only thing users had to do was relaunch Fazm once, on April 20, to pick up version 2.4.0.
Want to see the three-label picker during a release wave?
Book 20 minutes. I will screenshare the dev log and the picker side by side during a Fazm restart so you can watch the model ID change while the label stays the same.
Questions readers actually ask
Which large language models actually shipped in April 2026?
Anthropic made Claude Opus 4.7 generally available on April 22, 2026 at the same $5 input / $25 output per million tokens as Opus 4.6, with Claude Sonnet 4.6 already the everyday default. OpenAI introduced GPT-5.5 and GPT-5.5 Pro in the API. DeepSeek released its V4 family (V4-Pro and V4-Flash, mixture-of-experts) as open source. Google pushed Gemini 2.5 Pro forward. Meta announced Spark Muse alongside movement around Llama 4. A third Anthropic model, codename Capybara (Claude Mythos), remains gated behind Project Glasswing. In aggregate this is the densest release fortnight since the original GPT-4 launch, and the real cost of "good enough" inference fell roughly 50 percent from January levels.
What makes Fazm's reaction to that release wave different from most Mac AI apps?
Most apps react to a new model by adding a row to a Swift enum and shipping a build. Fazm does not own a model catalog. The UI reads a @Published array called availableModels, and that array is filled at runtime by a bundled subprocess that talks to the Claude agent SDK. The picker renders ForEach(shortcutSettings.availableModels) at SettingsPage.swift line 2025, which means adding a new model is a server-side event for us, not a release event. For the user the visible change is: the label behind the Smart button now routes to Opus 4.7 instead of Opus 4.6. Same button. Same keyboard shortcut. No app to update.
Why does the picker only show three labels when April 2026 released more than three models?
Because the labels are not model names. They are usage profiles. Scary = Haiku-class (fastest, cheapest), Fast = Sonnet-class (everyday default), Smart = Opus-class (heaviest reasoning). The Swift map that does the translation has exactly four rows, living at ShortcutSettings.swift line 159: (haiku, Scary, 0), (sonnet, Fast, 1), (opus, Smart, 2), (default, Smart, 2). Any model ID whose string contains one of those substrings collapses to the right label. Opus 4.6 and Opus 4.7 both map to Smart. They are not competing picker rows; they are the same row with a freshened backing.
What happens to the picker when a non-Anthropic model shows up in the agent's available list?
The else branch at ShortcutSettings.swift line 189 kicks in. If the incoming model ID does not contain haiku, sonnet, opus, or default, the Swift map falls through to the model's raw API name and assigns sort order 99. The model becomes selectable in the picker the same day, just pushed to the bottom with its unfamiliar name. A later build can add a row to the family map to give it a prettier label and a nicer sort position, but the selectability is day zero. This is how the architecture stays open to providers that Fazm does not talk to today.
Does Fazm actually route queries through GPT-5.5 or DeepSeek V4?
Not today. The bridge that populates availableModels is the Claude agent SDK's ACP bridge, so the model list you get is whatever Anthropic is exposing through that protocol. For most of April 2026 that was Haiku 4.5, Sonnet 4.6, and Opus 4.7. Adding a non-Anthropic provider is a second bridge with its own emitModelsIfChanged, not a UI change. The UI side of the abstraction is ready for that future without any edit to the picker code. The bridge side is not written yet.
Where exactly in the Fazm source does the three-label picker live?
Three files. The picker itself is rendered at Desktop/Sources/MainWindow/Pages/SettingsPage.swift line 2025, inside a ForEach over shortcutSettings.availableModels. The same @Published array is read by AIResponseView.swift line 1131 for the floating bar picker. The population logic is at Desktop/Sources/FloatingControlBar/ShortcutSettings.swift lines 151 through 216, which holds defaultModels (the fallback list shown before the ACP response arrives), modelFamilyMap (the 4-row substring table), and updateModels (the function that runs the substring match and overwrites the @Published array). Every other part of the app reads this state; nothing writes to it except updateModels.
How quickly does a new model from Anthropic become selectable for an end user?
Next app launch. When Fazm starts, the ACP bridge calls session/new for each of the main, floating, and observer sessions. Each session/new response carries the current models.availableModels array. The bridge filters out the default pseudo-model at index.ts line 1274, diffs against lastEmittedModelsJson, and emits one IPC message if the list changed. Swift decodes the message, runs updateModels, and re-publishes availableModels. The keyboard-shortcut list, the floating bar's model dropdown, and the Settings preference pane all re-render in the same tick. Round trip on a warm machine is under a second.
Why label Opus as Smart and Sonnet as Fast instead of just showing the model names?
Because the audience that downloads Fazm does not know or care what Opus is. They know that they want something smart for a hard question and something fast for a short one. The version number behind the label is irrelevant to them; by the time they have learned that Opus 4.6 exists, it is already Opus 4.7. The naming choice comes from actual onboarding sessions: when the picker showed real model names, users asked which one to pick; when the picker shows Scary, Fast, Smart, they stop asking. The tradeoff is that experienced users lose per-version control, which is why the full API name is still in the Settings detail view and in the underlying selectedModel string.
Was this architecture in place before April 2026, or did the release wave force it?
Both, a little. The single-source-of-truth picker existed before April. The dynamic population from the agent SDK shipped in Fazm 2.4.0 on April 20, 2026. The changelog line reads, verbatim, "Available AI models now populate dynamically from the agent, so newly released Claude models appear without an app update." That release was two days before Anthropic's own Opus 4.7 GA on April 22. The ordering is not coincidence; the release wave was visible, and the move to delegate the catalog to the SDK was calibrated for it.
What happens if the SDK returns an empty models array?
updateModels bails at its first line with guard !acpModels.isEmpty else { return }. The @Published availableModels stays whatever it was before, which is either the previous SDK list or the defaultModels fallback defined at ShortcutSettings.swift line 151 (Scary, Fast, Smart pointing at canonical aliases). The user never sees an empty picker. The same holds if the SDK only returns one model (say because the user is rate-limited out of the others): the picker contracts, the saved selectedModel survives the shortLabel fallback chain at line 222, and the visible label stays Fast even if Sonnet is temporarily unavailable.
Adjacent pieces of the release month, written from inside a shipping Mac app
More on April 2026
LLM release news, April 2026
The 10-line bridge function that turns a new Claude model ID in the SDK into a rerendered picker on your Mac.
Anthropic April 2026 news
One substring table, one normalize function, zero app updates. A month of Anthropic releases as code paths.
Local LLM releases, April 2026
The other half of the release wave: what moved on-device this month and why it still funnels through the same bridge pattern.