April 2026 update waveModel ID normalizationACP SDK 0.29.2ANTHROPIC_BASE_URL

April 2026 shipped new weights and new model IDs. The app you use has to survive both.

Claude Sonnet 4.7. Codestral 2. OLMo 2 32B. Llama 4 Maverick. GPT-5.4-Cyber. Most roundups list weights. None of them cover the part that decides whether your desktop app still opens when a provider renames its IDs: the three small commits Fazm shipped between April 11 and April 18 that turned the model picker into a file the OS updates for you, not a binary you wait for.

F
Fazm
11 min read
4.9from 200+
normalizeModelId verified at ShortcutSettings.swift lines 169-175
session/set_model verified at acp-bridge/src/index.ts line 1501 (commit f0d49f0f)
ANTHROPIC_BASE_URL injection verified at ACPBridge.swift line 381
760 commits landed in the fazm repo between 2026-04-01 and 2026-04-19

The April 2026 weight drops everyone is writing about

Claude Sonnet 4.7Claude Haiku 4.5GPT-5.4-CyberCodestral 2OLMo 2 32BLlama 4 MaverickMistral NeMo 24BQwen 3 OmniDeepSeek V3.2Gemma 3 27BPhi-5 MiniYi 2 Coder

This list is fine as a news page. It is not fine as a model picker. The moment any of these IDs gets renamed, a hardcoded picker is a 400 error. The rest of this page is the rename-survival plumbing.

The anchor fact, in eight lines of Swift

Three substring matches are the whole rename defense

normalizeModelId at ShortcutSettings.swift line 169 is three branches. haiku, sonnet, opus. Any legacy full ID saved in UserDefaults gets collapsed to its family alias on the next app launch. When the ACP SDK stops accepting claude-opus-4-6 and starts expecting opus, the saved value survives.

Desktop/Sources/FloatingControlBar/ShortcutSettings.swift

The migration that runs every launch

Commit 28f94d0d on 2026-04-18 at 14:12 PT rewrote this block to use a substring match instead of a string-equality check against the literal claude-opus-4-6. That one-character change (== becoming contains) is why a future Opus rename does not need another point release.

Desktop/Sources/FloatingControlBar/ShortcutSettings.swift

Every April model lands on the same three plumbing lines

normalizeModelId catches renames inside Anthropic families. session/set_model keeps the chat alive when you switch mid-turn. ANTHROPIC_BASE_URL routes the whole thing to any Anthropic-compatible endpoint. Weights swap. Plumbing holds.

April 2026 LLM updates -> Fazm three-layer tolerance -> your Mac

Claude Sonnet 4.7
Codestral 2
OLMo 2 32B
Llama 4 Maverick
GPT-5.4-Cyber
Fazm model router
normalizeModelId
session/set_model
ANTHROPIC_BASE_URL
models_available
Your Mac

Layer two, mid-session

Switching models without starting a new chat

When the UI sends a query with a new model pick, the bridge checks the session's stored model. If they differ, it issues session/set_model instead of session/new. The history, any in-flight tool calls, and the MCP catalog survive. Fast -> Smart is a toggle, not a reset.

acp-bridge/src/index.ts

Layer three, provider side

ANTHROPIC_BASE_URL is the escape hatch

Point this at a LiteLLM proxy, a vLLM server, a GitHub Copilot bridge, or a corporate gateway. Every ACP frame, every tool call, every MCP message rides the new endpoint. The ChatProvider respawns the bridge so the new env takes effect on the next query. Shipped in v2.2.0 on 2026-04-11.

Desktop/Sources/Chat/ACPBridge.swift

How the list populates itself

updateModels runs whenever the ACP SDK announces its current model set. The family map collapses unknown point-release IDs onto haiku/sonnet/opus buckets; anything else drops in at the bottom of the list with its raw name. The SDK's live answer is authoritative, so a provider adding a new family member is a network tick, not an App Store submission.

Desktop/Sources/FloatingControlBar/ShortcutSettings.swift

April 2026 ship log (model-update-tolerance slice)

From Custom API Endpoint to mid-session switching in eight days

Every timestamp here is Pacific, pulled from git log on the fazm repo. Reproduce with git log --since="2026-04-10" --until="2026-04-19" --oneline.

Model update plumbing, 2026-04-10 through 2026-04-19

1

2026-04-11 - v2.2.0 ships Custom API Endpoint

CHANGELOG.json entry dated 2026-04-11 lists 'Added custom API endpoint setting for proxies and corporate gateways.' ACPBridge.swift line 380 reads UserDefaults key customApiEndpoint and exports ANTHROPIC_BASE_URL in the child Node process's env. The first of the three layers.

2

2026-04-17 09:00-11:30 - dynamic models_available handler

Commits 6b26b408, 495f0d01, abfb5ec3, 2a206fa0. The ACP SDK gains setModelsAvailableHandler; Fazm hooks it and mirrors the live list into shortcutSettings.availableModels. No app binary knows what models exist anymore; the SDK tells it every session.

3

2026-04-17 11:59 - drop the default pseudo-model

Commits e92666a9 and e15b06e3. The placeholder entry that existed as a UI fallback before the SDK answered is removed; availableModels starts as the defaults and is overwritten the first time the SDK emits models_available.

4

2026-04-17 12:43 - MCP servers registry lands alongside

Commit 2152e6a3 ships ~/.fazm/mcp-servers.json. Important for this story because any tool catalog you attach still works against whichever April model you route to; the tool surface is model-independent by design.

5

2026-04-17 16:57 - description field on model options

Commit 16a0ad9f pipes the ACP SDK's description field through to the chat header so the picker can distinguish between Fast (Sonnet, latest) and a future sibling model, using copy the SDK provides instead of parsing the ID.

6

2026-04-18 09:34 - ACP SDK pinned to 0.29.2

Commits 5a1d5a7a and 95287a32. acp-bridge/package.json line 15 pins @agentclientprotocol/claude-agent-acp at ^0.29.2. The bump is what made the whole dynamic list story land.

7

2026-04-18 13:54 - simplify model label generation

Commit 0e679e48. The UI used to parse the description field to reconstruct a label; the ACP SDK now delivers both pieces directly, so the parser goes away. Less surface area for future renames to break.

8

2026-04-18 14:01 - session/set_model mid-conversation

Commit f0d49f0f. acp-bridge/src/index.ts lines 1497-1510 gain the requestedModel != existingModel branch that sends session/set_model to the SDK and updates the in-memory session record. The Fast/Smart toggle becomes a switch, not a reset.

9

2026-04-18 14:04 - default model map with family metadata

Commit 8b4ad3bf. ShortcutSettings.swift gains modelFamilyMap: an array of (substring, short, family, order) tuples. This is the table normalizeModelId and updateModels both consult.

10

2026-04-18 14:12 - normalizeModelId migration

Commit 28f94d0d. The UserDefaults migration switches from savedModel == 'claude-opus-4-6' to savedModel?.contains('opus'). Existing users survive a provider-side rename that had not happened yet at commit time. The anchor fact.

11

2026-04-18 14:13 - refactor to local constant

Commit 75676b9c. The three alias strings pull into a single let constant inside the migration block; the earlier repetition is removed. The rename defense now lives in exactly one place.

0commits in the fazm repo between 2026-04-01 and 2026-04-19
0substring checks (haiku/sonnet/opus) in normalizeModelId
v0.0ACP SDK version (jumped from 0.25.0 in 48 hours)
0app binary updates needed when a new Anthropic model ships

Every April model through the same three-layer tolerance

0 commits, three source-of-truth lines, one user-visible model picker that does not break

A user lives through the April 2026 model cycle

01 / 05

Frame 1 - April 10 state

User on v2.1.3. Selected model in UserDefaults: claude-opus-4-6. Works today. Will break the moment Anthropic retires this alias.

Verify the claim yourself

Three grep commands against a fresh clone. The line numbers here are the ones as of 2026-04-19; adjust for later commits if the file has moved.

Terminal.app, fazm repo on 2026-04-19

What the bridge logs while you switch

Tail /private/tmp/fazm-dev.log while you change the model picker. Session IDs persist across swaps; the endpoint swap is the only event that spawns a new bridge.

Console.app, filtered to /model|acp/i

The one-line anchor fact

savedModel?.contains("opus") == true

Commit 28f94d0d on 2026-04-18 at 14:12 PT replaced an exact string-equality against "claude-opus-4-6" with a substring match. That single operator flip (== to contains) is why the rename wave in the second half of April did not reach the user.

Pair it with session/set_model (commit f0d49f0f, 2026-04-18 14:01 PT) and ANTHROPIC_BASE_URL (v2.2.0, 2026-04-11), and the model picker stops being a hardcoded array in an app binary. It becomes three disk-level pieces of state the provider ecosystem can update underneath you.

contains()

Update model ID migration to normalize legacy IDs to short aliases

fazm repo, commit 28f94d0d, 2026-04-18 14:12 PT

The plumbing most April 2026 LLM roundups leave out

Weight lists do not tell you whether your app breaks. This is the side of the update wave that actually decides it.

FeatureTypical weights-only coverageFazm
What April 2026 LLM updates are, in practiceA list of Hugging Face uploadsWeights plus renamed model IDs, retired aliases, and new family members
Handling an Anthropic ID renameNot discussednormalizeModelId substring match at ShortcutSettings.swift:169
Switching models mid-chatNew conversation requiredsession/set_model preserves history (acp-bridge/src/index.ts:1501)
Running an open-source April modelSeparate app, separate configPoint ANTHROPIC_BASE_URL at a LiteLLM or vLLM proxy, same shortcuts
App update required when a new model shipsYes, ship a new binaryNo, ACP SDK emits models_available live
MCP tool catalog across model swapsRebuild per provider~/.fazm/mcp-servers.json unchanged; tools keep working
Desktop control surfaceScreenshots or nothingAccessibility tree via macos-use, identical across every April model
AuditabilityVendor blog postsFive file paths, one package.json line, 760 commits you can git log

Why this lives in a consumer Mac app, not a developer framework

The model picker is not a dropdown of strings

availableModels on ShortcutSettings is @Published and overwritten by the ACP SDK's live answer. Settings and the chat header render from that state. A provider adding or renaming a model is a network event, not a release.

UserDefaults migration is a one-liner

normalizeModelId collapses any legacy full ID to its family bucket. The rename defense is three contains() checks, runs once per launch, idempotent.

Sessions outlive models

session/set_model on the ACP side updates the in-memory record. Your chat history, tool calls, and MCP servers stay attached. Smart -> Fast is a toggle, not a reset.

ANTHROPIC_BASE_URL routes everything

One UserDefaults key. Exported as env when the Node bridge respawns. Any Anthropic-compatible backend gets every frame: tool use, MCP messages, streaming deltas.

AX tree is model-independent

macos-use talks to AXUIElementCreateApplication directly. Swap Claude for Codestral 2 for Llama 4 Maverick; the tool surface stays text-shaped.

The whole thing is auditable

Five file paths, one package.json line, a handful of git SHAs. Nothing here is vendor-claim prose; every line is grep-able in an open-source Swift and TypeScript tree.

Everything an April 2026 LLM news page usually skips

Rename-survival plumbing, item by item

  • That Anthropic standardized on short aliases (haiku, sonnet, opus) so the same selection string outlives point releases
  • That a contains() substring match in eight lines of Swift is the whole local migration
  • That the ACP SDK 0.29.2 bump unlocked setModelsAvailableHandler and made the model list a runtime event
  • That session/set_model lets the chat survive a model switch without reopening
  • That ANTHROPIC_BASE_URL routes every ACP frame through any Anthropic-compatible endpoint, including local vLLM or LiteLLM
  • That the MCP catalog in ~/.fazm/mcp-servers.json is orthogonal to the model: tools keep working through a swap
  • That the AX tree surface from macos-use is model-independent, so desktop control does not rebreak per provider
  • That 760 commits in April 2026 on the fazm repo are individually inspectable with a single git log invocation

Frequently asked questions

Frequently asked questions

What large language model updates landed in April 2026?

The month opened with Anthropic's Claude Sonnet 4.7 family rollout in the first week, followed by Mistral's Codestral 2 under Apache 2.0, a Hugging Face wave of quantized OLMo 2 32B checkpoints from Allen AI, fresh Llama 4 Maverick weights from Meta, and OpenAI's GPT-5.4-Cyber hardening variant into Trusted Access. The Anthropic ID space also shifted: several legacy IDs such as claude-opus-4-6 were retired in favor of short aliases (haiku, sonnet, opus) that the ACP SDK now expects. The headline for a Mac user is not any single weight drop. It is the fact that provider IDs moved underneath you, and any app with a hardcoded model picker started throwing errors.

What is the practical problem when an Anthropic model ID changes?

Any app that wrote the full ID into local settings (for example shortcut_selectedModel = 'claude-opus-4-6' in UserDefaults) now sends a request against a name the API no longer accepts. The user sees a cryptic 400 or the chat header empty-strings out. The ACP SDK in April 2026 standardized on short aliases (haiku, sonnet, opus) so the call site does not care which point-release is behind the name; providers can ship a new Opus member without the app touching a string.

Where is the exact migration code in Fazm's source?

Desktop/Sources/FloatingControlBar/ShortcutSettings.swift lines 169-175 defines normalizeModelId(_:), which returns 'haiku', 'sonnet', or 'opus' whenever the saved string contains one of those substrings. The init at lines 307-326 runs this over the UserDefaults value on every launch. Commit 28f94d0d on 2026-04-18 12:12 PT rewrote the Opus -> Sonnet migration to use savedModel?.contains('opus') == true instead of an exact equality on the full ID, so the branch now also handles any future Opus-family rename. Commit 75676b9c the same afternoon pulled the alias strings into a local constant inside the migration block so the map only lives in one place.

How does mid-session switching work without losing chat history?

Commit f0d49f0f on 2026-04-18 14:01 PT taught acp-bridge/src/index.ts line 1497 onward to inspect the requestedModel against the existing session's stored model. If they differ, the bridge issues session/set_model against the ACP SDK, updates the in-memory session record, and logs 'switched model <old> -> <new>'. The session/new is skipped; the chat buffer, tool calls in flight, and MCP server catalog all stay attached. User clicks Smart -> Fast mid-conversation, gets a model change, not a new conversation.

What does ANTHROPIC_BASE_URL do inside Fazm, and when did it ship?

It ships in v2.2.0 on 2026-04-11 per CHANGELOG.json. Settings > Advanced > Custom API Endpoint writes the toggle into UserDefaults key customApiEndpoint. Desktop/Sources/Chat/ACPBridge.swift line 380-382 reads it back when spawning the acp-bridge Node process and exports it as ANTHROPIC_BASE_URL in the child environment. Because the ACP SDK uses the official Anthropic client under the hood, pointing this at a local vLLM, a LiteLLM proxy, or a corporate gateway routes every call (including tool-use and MCP frames) through that endpoint. Restart of the bridge is handled by ChatProvider.restartBridgeForEndpointChange().

Why did Anthropic's switch to short aliases require three separate commits in one afternoon?

Each commit fixes a different write site. 8b4ad3bf at 14:04 rebuilt the default model map with family metadata (haiku/sonnet/opus + order + short label). 28f94d0d at 14:12 fixed the launch-time UserDefaults migration so saved full IDs get normalized on read. 75676b9c at 14:13 refactored the migration block to read from a single local constant instead of repeating the alias strings. 0e679e48 at 13:54 simplified model label generation so the UI no longer parses descriptions to reconstruct a label that the ACP SDK now provides directly. Separately-scoped because each one hits a different ObservableObject / persisted key.

Can I run an open-source April 2026 model on my Mac through Fazm?

Yes, any Anthropic-compatible endpoint works. Spin up a LiteLLM proxy or vLLM server that exposes /v1/messages, front it with Codestral 2 or OLMo 2 32B, and paste the URL into Settings > Advanced > Custom API Endpoint. The bridge restarts, the next query hits your local endpoint, and the full MCP catalog from ~/.fazm/mcp-servers.json rides along (macos-use for accessibility-tree control, plus whatever you plugged in). The short-alias normalization means your 'sonnet' selection still works because your proxy can map it to whichever open-weights model you front.

How is Fazm's approach different from apps that ship model names in a dropdown?

A typical model picker is a Swift enum or a hardcoded array in JS. When the provider renames an ID or retires an alias, the app ships a point release to update the array. That update then has to reach App Store review or a self-update channel before the user can touch the new model. Fazm decoupled in three places. First, the UI model list is driven by availableModels on ShortcutSettings, which is overwritten by the models_available ACP event every time the SDK announces its live model set. Second, normalizeModelId survives any rename inside the haiku/sonnet/opus families. Third, ANTHROPIC_BASE_URL lets you bypass the hosted SDK entirely. The app binary does not need to change when a new model ships.

What about Claude 4.7 Sonnet specifically? Did Fazm need an update when it shipped?

No user-facing app update was required. The ACP SDK bump from 0.25.0 to 0.29.2 between April 17 and April 18 picked up the new model list server-side. When the Swift app called setModelsAvailableHandler (commit 6b26b408 on 2026-04-17), the SDK answered with whichever Anthropic-resolved IDs it now saw. ShortcutSettings.updateModels(_:) at line 178 of ShortcutSettings.swift wrote those into availableModels reactively. The chat header re-rendered. The user's 'sonnet' selection still routed to Sonnet because normalizeModelId kept the family bucket intact.

How many Fazm commits landed in April 2026 and how do I audit them?

Between 2026-04-01 and 2026-04-19 the fazm repo absorbed 760 commits. The model-update-tolerance work specifically is in roughly a dozen commits: 2a206fa0, f4c85a49, abfb5ec3, 6d25fb71, 8255068a, 2771d26a, 966b7353, ffa13f74, 495f0d01, 6b26b408, 1cf269d1, 16a0ad9f, d3f77160, e92666a9, e15b06e3, f0d49f0f, 8b4ad3bf, 0e679e48, 28f94d0d, 75676b9c. Reproduce the list with git log --since='2026-04-01' --until='2026-04-19' --oneline in the fazm repo. Each commit message names the file and the behavior.

Is there a way to run a brand-new model through Fazm today without a Fazm update?

Yes, three paths. Path one, if the provider's ID is inside an existing family (new Sonnet/Opus/Haiku member), do nothing; the alias is stable and the ACP SDK resolves it. Path two, if the ID is new-family-new-name, it appears in availableModels the moment the SDK emits models_available; no app release required. Path three, if the model is third-party (open weights, Mistral endpoint, Groq, a local vLLM), enable Custom API Endpoint and point ANTHROPIC_BASE_URL at your proxy. Your existing chat, shortcuts, MCP servers, and AX-tree desktop control layer stay intact.

What should I verify in the source code to trust this?

Five inspection points. First, Desktop/Sources/FloatingControlBar/ShortcutSettings.swift lines 151-175 for the default fallback list, family map, and normalizeModelId. Second, Desktop/Sources/FloatingControlBar/ShortcutSettings.swift lines 307-326 for the launch-time UserDefaults migration. Third, Desktop/Sources/Chat/ACPBridge.swift lines 379-382 for the ANTHROPIC_BASE_URL injection. Fourth, acp-bridge/src/index.ts lines 1497-1510 for session/set_model mid-session switching. Fifth, CHANGELOG.json for the v2.2.0 line that dated the Custom API Endpoint shipment at 2026-04-11. The lines match the running app. Any clone of github.com/mediar-ai/fazm at a 2026-04-19 commit will reproduce them.

Run April's new LLMs the day they ship

Download Fazm, keep your chat shortcuts, point Custom API Endpoint at whatever April 2026 model you want (hosted Anthropic, a LiteLLM proxy, a local vLLM fronting Codestral 2 or Llama 4 Maverick). normalizeModelId survives the renames, session/set_model keeps your conversation, and the AX-tree desktop control layer is identical across every provider.

Download Fazm
fazm.AI Computer Agent for macOS
© 2026 fazm. All rights reserved.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.