Latest LLM news, April 2026Compaction observabilityMac agent runtime

Latest LLM news, April 2026: the compaction events every roundup misses

Every April 2026 LLM recap names the same releases. Claude Opus 4.6 leading Arena. Gemini 2.5 Pro with 2M context on Vertex. GPT-5 Turbo multimodal. Llama 4 Scout with a 10M window. None of them describe what happens to context at runtime, when a live agent session fills up and the SDK quietly rewrites its own memory. Fazm, a shipping Mac automation app, patches Anthropic's Agent Client Protocol SDK to rescue four compaction events the vanilla agent drops on the floor. Line numbers below, grep-able for yourself.

F
Fazm
11 min read
4.9from 200+
Every claim pinned to a file and line in the Fazm desktop source tree
Shows four ACP SDK events the vanilla agent drops and Fazm forwards
Covers the runtime layer the top SERP results for this keyword all skip
4 dropped events

Fazm replaces ClaudeAcpAgent.prototype.prompt and wraps the SDK's message iterator to forward compact_boundary with trigger and pre_tokens. The vanilla agent drops that message. The patch is about ten lines.

acp-bridge/src/patched-acp-entry.mjs, lines 62-72 and 212

The anchor fact: ten lines in a .mjs file that turn a dropped SDK message into a typed Swift enum case

The Claude ACP SDK emits a system message with subtype "compact_boundary" when it rewrites a session's history to keep it inside the context window. The vanilla @agentclientprotocol/claude-agent-acp agent filters that message before it crosses into the parent process, so a host app sees nothing. Fazm opens the SDK and restores the signal.

acp-bridge/src/patched-acp-entry.mjs, lines 62-72

The patch hooks the SDK by replacing the prompt method. A vanilla install of the package never runs this file. It runs when Fazm's bundled bridge boots and loads its own entry point first.

acp-bridge/src/patched-acp-entry.mjs, line 212

The path a single compact_boundary event travels

From the Claude API to the user's Mac it passes through five hops. The middle hop is where most agents lose the signal. Fazm's patch sits at that exact hop.

compact_boundary path: Claude API -> user

Claude APIACP SDKPatch wrapperNode bridgeSwift UIsystem, subtype=compact_boundary, compact_metadataiterator yield (type=system)sessionUpdate{compact_boundary, trigger, preTokens}JSON line {type:compact_boundary,...}StatusEvent.compactBoundary(trigger, preTokens)

Six dropped signals, rescued by one patch file

compact_boundary is the headline. The same wrapper forwards compaction_start, compaction_delta, subtype=status, task_started, task_notification, api_retry, and rate_limit_event. Without this file a host app sees none of them. Here they are, flowing through the patch.

Dropped SDK events through patched-acp-entry.mjs into Swift

compact_boundary (trigger, pre_tokens)
compaction_start / compaction_delta
subtype=status (thinking, tool_exec)
task_started / task_notification
api_retry (httpStatus, errorType, attempt)
rate_limit_event (8 fields)
patched-acp-entry.mjs wrapper
status_change
compact_boundary
task_started / notification
api_retry
rate_limit StatusEvent

Every event the patch rescues, with its payload

A catalog of signals the Claude ACP SDK emits internally and the vanilla agent drops. Each one is forwarded by a specific branch inside patched-acp-entry.mjs or a specific case inside acp-bridge/src/index.ts. The file and line in each card is where the branch lives.

compact_boundary

Carries compact_metadata.trigger ('auto' or 'manual') and compact_metadata.pre_tokens (int). Fazm forwards it as an ACP sessionUpdate kind 'compact_boundary' at patched-acp-entry.mjs:65-72.

compaction_start / compaction_delta

Fired on content_block_start / content_block_delta when the block type is 'compaction'. Fazm emits compaction_start as a status_change and strips the high-frequency delta text at index.ts:2391-2400.

status (subtype)

Claude emits subtype: 'status' signals like 'thinking' and 'tool_exec'. Dropped by the vanilla SDK. Fazm promotes them into a status_change update with the status string preserved.

api_retry

HTTP-level retry events with httpStatus, errorType, attempt, maxRetries, retryDelayMs. Stored on session._lastApiError and emitted as an api_retry sessionUpdate for the UI and for post-mortem debugging.

rate_limit_event

Eight fields: status, resetsAt, rateLimitType, utilization, overageStatus, overageDisabledReason, isUsingOverage, surpassedThreshold. See patched-acp-entry.mjs:131-152.

task_started / task_notification

Sub-agent lifecycle signals with task_id and description. Fazm tracks task_id through its task tracking store so it can detect stale notifications from previous turns (index.ts:2411-2419).

The seven-step path of a single compaction

Tracing what actually happens when a long Fazm session hits the context window and the SDK rewrites history. Each step pins to a file and a line in the source tree.

1

1. Session grows past the SDK's compaction threshold

A long Fazm chat or a tool-heavy agent loop accumulates turns. The ACP SDK's internal heuristic decides the next turn might bust the Claude context window.

2

2. Claude emits a system message with subtype: compact_boundary

The SDK receives compact_metadata containing trigger ('auto' when the SDK decided, 'manual' when code asked) and pre_tokens, the exact count before the rewrite.

3

3. Vanilla agent drops the message

Unpatched @agentclientprotocol/claude-agent-acp filters subtype: 'system' messages before they cross the protocol boundary. The parent process sees no signal.

4

4. Fazm's patch catches it inside the iterator

patched-acp-entry.mjs wraps the SDK's message iterator. When it sees subtype === 'compact_boundary' it calls acpClient.sessionUpdate with kind 'compact_boundary' and the two metadata fields.

5

5. index.ts forwards it to Swift as a JSON line

acp-bridge/src/index.ts case 'compact_boundary' at line 2376 packages {type: 'compact_boundary', trigger, preTokens} and writes it to stdout via sendWithSession.

6

6. Swift parses it into a typed enum

ACPBridge.swift lines 1082-1085 decode the JSON line into InboundMessage.compactBoundary(trigger, preTokens). Lines 856-857 route it out through onStatusEvent as StatusEvent.compactBoundary.

7

7. The user sees the runtime event

Floating control bar shows 'compacting' from the earlier status_change. On compact_boundary the app logs the trigger and pre_tokens, and any follow-up cache-write spike on the next turn is attributable to the rewrite.

The patch, by the numbers

0ACP SDK events the vanilla agent drops, that Fazm forwards
0Line where ClaudeAcpAgent.prototype.prompt gets replaced
0compact_metadata fields preserved (trigger, pre_tokens)
0rate_limit_event fields forwarded (utilization, overage, ...)

Four events: compact_boundary, compaction_start, compaction_delta, status_change for the compacting status. The 212 is the exact line where patched-acp-entry.mjs replaces the SDK's prompt method. The 2 is the shape of compact_metadata itself. The 8 is the full rate_limit_info fan-out at line 132.

Compaction pipeline token scale:0K+typical pre_tokens at auto compaction

Verify the patch with four greps

If you distrust any of the line-number claims above, run these against a local Fazm desktop source tree. Each line of output matches a line in the source.

Four greps against the April 2026 Fazm runtime

Press-release view vs runtime view of April 2026

The press-release view is what the top SERP results for this keyword are built on. The runtime view is what actually determines whether a Mac user sees their context being rewritten in a live session.

FeaturePress-release view (top SERP articles)Runtime view (Fazm source tree)
Context window storyMax context size in the model card (200K, 2M, 10M)compact_boundary event at ~150K pre_tokens, trigger=auto
Compaction observabilityNot mentionedcompaction_start, compaction_delta, compact_boundary forwarded
API retry behaviorNot mentionedapi_retry event with httpStatus, errorType, attempt, delay
Rate-limit telemetry429 errors, occasionally8 fields: status, resetsAt, type, utilization, overage, ...
Task lifecycleMentioned as 'sub-agents' in passingtask_started + task_notification with id + summary
What changes on a new Claude releaseA new bullet in next month's roundup@agentclientprotocol/claude-agent-acp version bump
How the news reaches a user's MacBlog post with screenshotsPatched SDK iterator + ACP sessionUpdate -> Swift enum
Verifiable fromLinked official release notesFile:line pins in the source tree

April 2026 LLM news, as the SERP lists it

Every one of these eventually meets a context boundary. The runtime-side question is whether the host app observes the boundary or lets the SDK eat it silently.

Claude Opus 4.6 (Arena #1)Claude Sonnet 4.6Claude Haiku 4.5GPT-5 Turbo (native multimodal)GPT-6 (codename Spud, Apr 14)Gemini 2.5 Pro (2M ctx)Gemini 2.5 FlashLlama 4 Scout (10M ctx)Llama 4 MaverickGLM-5.1 (MIT, 744B MoE)Mistral Large 3DeepSeek R2Qwen 3.5ACP SDK 0.29.2Claude Skills (file-format capabilities)MCP ecosystem growth

Three reasons compaction observability is the April 2026 story

Not instead of model benchmarks. Beside them. Benchmarks tell you the upper bound of what a Claude tier can do. Compaction observability tells you what happens in the messy middle of a real session that ran for six hours.

Cache-write spikes become explainable

After compact_boundary the prompt prefix changes, the cache misses, and the next turn writes a fresh cache. Fazm tracks cacheReadTokens and cacheWriteTokens separately so the spike is attributable, not mysterious.

UI state has a name for it

"compacting" is now a status the floating control bar can show. It is not "thinking" and it is not "hung". It is a distinct runtime phase with a start, a delta stream, and a boundary event at the end.

Long sessions stop being opaque

When a Fazm chat goes from turn 1 to turn 300, the session is not a continuous conversation anymore, it is a sequence of rewrites. Knowing where each rewrite happened changes how you debug "Claude forgot what I said earlier."

See compaction events on your own Mac

Fazm ships the Agent Client Protocol SDK running as a patched Node subprocess. compact_boundary, compaction_start, status_change compacting, and an api_retry event surface as typed Swift enum cases in the floating control bar and in the app's session logs. The April 2026 LLM release cycle reaches you through that patch.

Download Fazm

Frequently asked questions

What is a compact_boundary event and why does it matter in April 2026?

It is the system message the Claude ACP SDK emits when the agent rewrites its conversation history to stay under the context window. The message includes compact_metadata.trigger (for example 'auto' when the session approaches the limit, or 'manual' when code forced it) and compact_metadata.pre_tokens (the token count immediately before compaction ran). The vanilla @agentclientprotocol/claude-agent-acp package drops this message before it reaches the parent process. Fazm patches the SDK at acp-bridge/src/patched-acp-entry.mjs lines 65-71 to forward it, so the Mac app can tell the user 'your context hit X tokens, Claude rewrote it' instead of letting the rewrite happen invisibly.

Where exactly is this patch, and what does it replace?

acp-bridge/src/patched-acp-entry.mjs. The file reaches into the ACP SDK and replaces ClaudeAcpAgent.prototype.prompt (line 212 in the patched file) and wraps the SDK's internal message iterator (lines 38-204). Inside the wrapper it calls acpClient.sessionUpdate with a new update kind 'compact_boundary' whenever it sees subtype === 'compact_boundary' on a system message. That update then travels over JSON-RPC to the parent Node process, out to Swift as a JSON line, and into the UI as a StatusEvent.compactBoundary(trigger, preTokens) Swift enum case.

What other events does the same patch rescue?

Three more. status (subtype === 'status' becomes a status_change update), task_started (subtype === 'task_started' becomes a task_started update with taskId + description), and api_retry (subtype === 'api_retry' becomes an api_retry update with httpStatus, errorType, attempt, maxRetries, retryDelayMs). It also forwards rate_limit_event at line 132 with eight fields including utilization, overageStatus, isUsingOverage, and surpassedThreshold. All of these are dropped by the vanilla SDK and all surface as typed Swift enum cases.

Is Fazm also streaming the compaction content itself, or just the boundary?

Both. The same patch watches for stream_event messages where the delta is a compaction_delta (patched-acp-entry.mjs lines 191-200). Each delta fires an acpClient.sessionUpdate with kind 'compaction_delta' carrying the incremental text. Upstream in index.ts at lines 2391-2400 the bridge converts 'compaction_start' into a status_change 'compacting' for the UI and intentionally suppresses the compaction_delta text back to Swift because it is too high frequency. The UI shows 'compacting' state via status_change, the eventual compact_boundary fires with the final token count, and the low-level text stream stays available in logs if debugging is needed.

Why does the vanilla ACP agent drop these messages?

Because most consumers of @agentclientprotocol/claude-agent-acp do not render a UI that benefits from them. The vanilla agent is designed to let the SDK own the conversation loop and only surface user-visible tokens through sessionUpdate kinds the protocol spec already knows about (agent_message_chunk, tool_call, etc). Compaction metadata, task start signals, and rate-limit telemetry do not map to those kinds. For a shipping Mac app these are exactly the signals you want, which is why Fazm opens the SDK and adds custom sessionUpdate kinds for each one.

What is the exact StatusEvent enum case in Swift?

case compactBoundary(trigger: String, preTokens: Int). It lives at /Users/matthewdi/fazm/Desktop/Sources/Chat/ACPBridge.swift lines 138-154, inside a public StatusEvent enum that also carries cases for compacting(Bool), taskStarted, taskNotification, toolProgress, toolUseSummary, and rateLimit. The InboundMessage decoder at lines 1082-1085 turns the JSON line {type: 'compact_boundary', trigger, preTokens} into .compactBoundary(trigger: trigger, preTokens: preTokens), and lines 856-857 route it out through onStatusEvent. That is the whole pipeline: dropped SDK message to typed Swift event in about four files.

How does this relate to the April 2026 headline models (Claude Opus 4.6, Gemini 2.5 Pro 2M, Llama 4 Scout 10M)?

Those numbers live in the press release. Compaction is the runtime answer to what happens when a long session gets near the top of any of those windows. Even Llama 4 Scout's 10 million token context, the April 2026 headline, still matters less to a live agent than the rewrite strategy kicking in when a session fills up. The observable boundary event is how a shipping app tells the user 'you just crossed a memory boundary' instead of silently pretending the conversation never changed.

Is this the same as Anthropic's context management API?

No. Anthropic's context management API, introduced earlier in 2026, is a server-side feature that controls how long-context prompts are packed and how cache breakpoints are inserted. compact_boundary is an SDK-level event emitted when the ACP agent itself triggers a compaction during a running session. Both can be active at once. Fazm cares about the SDK event because that is what arrives in the subprocess and needs to surface to the user.

What are the pre_tokens values typically?

They depend on the Claude tier. For Sonnet and Opus sessions in Fazm we see compactions triggering around the high 150,000s when the SDK's auto heuristic decides the next turn might bust the window. For Haiku the compaction activity on shorter windows triggers a little lower. The exact trigger heuristic lives inside the ACP SDK, which is one reason Fazm forwards both trigger and pre_tokens instead of computing them in the bridge, the SDK is the ground truth.

Where does this show up in the user's UI?

Two places. While compaction is running, the Fazm floating control bar shows a 'compacting' status, driven by the status_change: 'compacting' update that index.ts line 2392 emits when it sees compaction_start. When compaction finishes, the compact_boundary event lands with the final trigger and pre_tokens numbers, which the Swift side can log or surface (current build uses it for diagnostics and for picking smarter compaction prompts on repeated triggers in the same session).

Does compaction reset the prompt cache?

Yes and no. Anthropic's prompt cache is keyed on stable prefixes. After a compact_boundary, the conversation history has been rewritten, which means any cache breakpoints that used to match the prefix no longer do. Fazm accounts for this by tracking cacheReadTokens and cacheWriteTokens separately on each turn (acp-bridge/src/index.ts around line 1783), so an operator can see the cache-write spike on the first turn after compaction. This is useful for diagnosing 'why is my first message after a long chat so expensive' kinds of questions.

Can I use this angle to debug my own Claude agent runtime?

Yes. Even without Fazm, the pattern is worth copying. Spawn the Claude ACP SDK as a subprocess, but also run your own message iterator that sniffs for compact_boundary, compaction_start, and rate_limit_event at the raw SDK level. If you do not, those signals stay hidden inside the SDK loop and your top-level app only sees post-compaction state. The Fazm patch at patched-acp-entry.mjs is a small enough reference implementation to read through in ten minutes.

What the SERP cannot show about April 2026

Claude Opus 4.6 leads Arena. Gemini 2.5 Pro is on Vertex with a 2M token window. GPT-5 Turbo is natively multimodal. Llama 4 Scout advertises 10M tokens. These are facts, and every roundup lists them. They will still be the facts tomorrow.

The quiet thing that changes is what happens at the edge of those numbers. When a long agent session fills up, the SDK rewrites its own history. The vanilla ACP agent does not tell you it happened. A shipping Mac app cannot ignore it. So Fazm patches the SDK to forward compact_boundary with trigger and pre_tokens, forwards compaction_start as a status_change, forwards api_retry with httpStatus and errorType, and forwards rate_limit_event with eight fields including overage state. That is the runtime answer to the April 2026 news cycle.

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.