The month Anthropic announced Opus 4.7, Mythos, and a $25B Amazon deal. One Fazm pipeline stayed on Gemini on purpose.
Every April 2026 recap of Anthropic treats Claude as the one model in whatever app it is about. That framing works for the chat path inside Fazm, which absorbed the ACP bridge jump from 0.25.0 to 0.29.2, the Opus 4.7 ID rename to default, and the partial models label fix in 2.4.1. It does not work for a second, quieter pipeline: a 60-minute active-window video summarizer at GeminiAnalysisService.swift:67 that stayed on gemini-pro-latest the entire month. This page is about why that split exists, the exact constants that make it work, and why none of April's Anthropic news moved it.
THE HEADLINES
Five threads Anthropic shipped and signed in April 2026
I list them here so the rest of this page has a shared reference point. The subject is not the news. The subject is which parts of a Claude-heavy consumer Mac app had to change in response, and which parts deliberately did not.
Opus 4.7 generally available on April 22
Same price as Opus 4.6 at $5 per million input tokens and $25 per million output tokens. Stronger SWE-bench, more reliable long-running tool use, better vision. Distributed through the Anthropic direct API, Vertex AI, and the Claude Agent Client Protocol SDK. For consumer apps this is the model users want selectable in the picker on launch day.
Claude Mythos previewed via Project Glasswing
Mythos is a strong vulnerability-finding model. Anthropic distributed it through a gated cybersecurity consortium called Project Glasswing, with Amazon, Apple, Microsoft, and Nvidia on the list. Explicitly not a broad developer release. The Pentagon flagged supply-chain concerns, and Dario Amodei met with Susie Wiles and Scott Bessent in mid-April to discuss federal access.
Amazon expanded the investment to the $25B range
Bloomberg reported Amazon adding another $5 billion of Anthropic investment with optionality for $20 billion more. Anthropic committed more than $100 billion to Amazon cloud and chips across a decade. This is a capital and capacity story, not a change to the Claude wire format.
Google and Broadcom expanded TPU supply
Anthropic grew its existing relationship with Google and Broadcom to take more TPU capacity. Paying subscribers and API customers saw this as fewer overloaded turns during peak hours through the late-April Opus 4.7 launch window.
ACP v0.25.0 on April 7 to v0.29.2 on April 20
The Agent Client Protocol SDK Fazm's bridge depends on stepped through 0.25.0 on April 7 and landed at 0.29.2 with v2.4.0 on April 20. That upgrade introduced the Opus model ID rename to `default`, dynamic models reporting, and a few error-shape changes for credit exhaustion. It is the reason the chat path had a busy month.
THE GAP NOBODY WROTE ABOUT
A Claude-heavy Mac app with one job permanently off Claude
Fazm runs the interactive side on Claude via the ACP bridge. Chat turns, floating bar asks, tool calls, accessibility reads, Playwright browser reads, MCP server fan-out. All of it. That is the path every April 2026 Anthropic change touched, and it is the path that shipped six patch releases over twenty days to keep pace.
There is a second job that does not fit that shape. Watch roughly an hour of the user's active-window screen recording. Decide whether a single high-impact task should be surfaced. If yes, write a markdown document describing it. If no or unclear, stay quiet. It is asynchronous, multimodal, long-form, and strictly background. For this one job Fazm hard-codes a non-Claude model, sends MP4 files over the Gemini File API, and waits ~60 minutes between calls.
The choice predates April, and April's Anthropic announcements did not revisit it. That second paragraph is the whole thesis of this page, and the rest is the code that makes it real.
“Accumulates session recording chunks and periodically sends them to the Gemini API for multimodal video analysis to identify tasks an AI agent could help with.”
GeminiAnalysisService.swift, file header comment, lines 6 through 8
THE ANCHOR FACT
Four constants at the top of one file
Everything that makes the Gemini pipeline a Gemini pipeline fits on six lines at the top of one actor. The model name, the buffer cap, the 60-minute trigger, and the inline vs resumable-upload cutoff. None of these are configurable from the UI. None of them moved in April.
The feeder that produces chunks for this pipeline is equally terse. Two frames per second, one minute per chunk, only the frontmost window.
TWO PIPES, ONE APP
Where the split actually sits
Every user input flows through one of two paths inside Fazm. Typed prompts, tool calls, app-control actions, and accessibility reads go through the ACP bridge to Claude. Passive screen recordings go through the chunk buffer to Gemini. Nothing crosses the middle.
Claude on the left, Gemini on the right, the user's Mac in the middle
WHY GEMINI FOR THIS ONE JOB
Four reasons the video summarizer does not belong on Claude
The input is a multi-hour video, not an image set
Claude's vision path takes images. To feed it ~60 minutes of active-window recording you'd chunk the video into stills, which throws away the temporal signal the analysis depends on. Gemini's File API accepts the MP4 and the user's metadata as one request.
The job is batched, not conversational
No one is waiting on this turn. The analyzer fires once per hour in the background. Claude's per-turn pricing and rate-limit semantics are tuned for chat. A long batched summarizer fits Gemini's context and billing shape better.
Chat outages must not break task discovery
Late April 2026 saw capacity turbulence around the Opus 4.7 launch window. Because the Gemini pipe is physically separate, none of that turbulence reached discovered tasks. The chat path can be failing and Fazm still surfaces the one task at the next hour tick.
The retry policy is different
Chat retries a failed query immediately; a one-hour analyzer that retried on failure would pile up requests. GeminiAnalysisService.swift:78 sets `retryCooldown: TimeInterval = 300`. Five minutes between attempts, not immediate. Wrong policy for chat, right policy here.
THE PROMPT
What Fazm actually asks Gemini to do with the hour
The system prompt is blunt and opinionated. One verdict per hour. Use tools to check the existing observer and chat history before suggesting anything. If you would be guessing, return UNCLEAR. The full template lives in GeminiAnalysisService.swift starting at line 12.
THE CHUNK FLOW
What happens from frame grab to stored task
One hour of recording to one task row
ScreenCaptureKit grabs frames
2 FPS, frontmost window only. Driven by SessionRecorder running in the app process. The user's full desktop is never captured.
ffmpeg writes 60-second MP4 chunks
chunkDurationSeconds: 60.0. Files land in Application Support/Fazm/gemini-analysis/chunks. Buffer index persisted to disk so it survives restarts.
handleChunk appends to chunkBuffer
The actor accumulates entries with localURL, timestamps, and active-app metadata. maxChunks = 120 caps the buffer if analysis is delayed.
Trigger at ~3600 seconds buffered
targetDurationSeconds: 3600 fires one analysis. isAnalyzing flag prevents overlap. If lastFailedAnalysis is within retryCooldown (300s), the trigger waits.
Upload to Gemini File API or inline
inlineSizeLimit = 1,500,000. Chunks under 1.5 MB go base64 inline; larger chunks use resumable upload. Then one request with all chunk URIs plus metadata.
Verdict lands in observer_activity
Row inserted with type = 'gemini_analysis' and status = 'pending'. DiscoveredTasksSection.swift surfaces TASK_FOUND rows; NO_TASK and UNCLEAR silently stay in the table for future similarity checks.
VERSUS
| Feature | A Claude-on-every-path design | This pipeline (Gemini) |
|---|---|---|
| Input format | Would need to be still frames, losing temporal signal | MP4 clips, one per minute, ~60 minutes per call |
| Call frequency | Same hour-long batch would not fit Claude's turn shape | ~1 per hour per active user, batched |
| Where one failure lands | Shared failure domain with the interactive session | Waits 300s, does not touch the chat path |
| What Anthropic changed in April 2026 | ACP v0.29 rename, partial models label, credit errors | Nothing in this file since before April |
| Where the model id is pinned | ShortcutSettings @AppStorage, user selectable, migration logic | GeminiAnalysisService.swift line 67, private let, no UI |
| What the user sees when it fires | Would interleave with normal chat, risking noise | A Discovered Task card in the main window, one per hour at most |
LOG VIEW
What the pipeline logs during a normal hour in April 2026
Line shapes trimmed for readability. The important thing is that nothing in this transcript references Claude. During the same hour, the chat path was busy picking up the ACP v0.29 model list and adjusting to the `default` rename. Two pipes, same app, same minute.
WHAT STAYED ON CLAUDE, WHAT DID NOT
A quick audit of every April 2026 Fazm change
Nine Fazm releases shipped between April 7 and April 22, 2026. Every one of them touched the Claude path. None of them touched GeminiAnalysisService.swift or SessionRecordingManager in a way that changed the model or the trigger window. This matters because it shows the split is a stable boundary, not an accident of when-we-had-time.
Claude side changes during April 2026, for context
- v2.1.2, Apr 7: ACP protocol upgraded to v0.25.0 with improved credit-exhaustion and rate-limit error handling.
- v2.2.0, Apr 11: Added custom API endpoint setting (ANTHROPIC_BASE_URL) for proxies and corporate gateways.
- v2.3.2, Apr 16: Tightened privacy language in onboarding and system prompts to say local-first rather than nothing leaves your device.
- v2.4.0, Apr 20: ACP 0.29.2 upgrade, dynamic model list, custom MCP servers via ~/.fazm/mcp-servers.json, referrals section.
- v2.4.1, Apr 22: Fixed Smart label showing for Sonnet users when Anthropic reports a partial model list during the Opus 4.7 rollout window.
- Gemini pipeline at GeminiAnalysisService.swift, same window: zero change to model, buffer cap, trigger window, or upload threshold.
“You have tools available to investigate further before making your decision. USE THEM, especially when you see ambiguous activity.”
GeminiAnalysisService.swift, analysisPromptTemplate line 23
VERIFY IT YOURSELF
Five one-liners against the open repo
Fazm is MIT-licensed. Every claim on this page resolves to a grep in the repo at fazm.ai/gh. Run these.
Confirm the Gemini model pin
grep -n 'gemini-pro-latest' Desktop/Sources/GeminiAnalysisService.swift. One hit on line 67, inside the actor declaration, not a const in a shared config.
Confirm the 60-minute trigger
grep -n 'targetDurationSeconds' Desktop/Sources/GeminiAnalysisService.swift. One hit on line 69 with the literal 3600.
Confirm the chunk shape
grep -n 'chunkDurationSeconds\|framesPerSecond\|activeWindow' Desktop/Sources/SessionRecordingManager.swift. Three hits around lines 76 through 83, all inside SessionRecorder.Configuration init.
Confirm Claude is never imported by the analyzer
grep -n 'Anthropic\|claude' Desktop/Sources/GeminiAnalysisService.swift. No matches. The file does not mention Claude at all; the chat path is a completely separate seam.
Confirm April 2026 did not touch this file
git log --since=2026-04-01 --until=2026-04-30 -- Desktop/Sources/GeminiAnalysisService.swift. Compare to the same command against Providers/ChatProvider.swift, which saw a half dozen commits over the same window.
NOT COVERED, BY DESIGN
What this page deliberately leaves out
Benchmarks between Claude and Gemini on video understanding. The separation is not a claim about which model reasons better. It is a claim about which transport and billing shape fits which input. If Claude shipped MP4 input tomorrow, the economics and batched retry semantics would still push this job toward a pipe that is not shared with chat.
Prompt engineering on the Gemini side. The full analysisPromptTemplate is roughly fifty lines and would triple this page without changing the architectural point. The only excerpt above is the verdict format so you can see why UNCLEAR exists as a first-class output.
Mobile. The Gemini analyzer is desktop-only because the chunk source is macOS ScreenCaptureKit active-window recording, which has no iOS equivalent. The Flutter mobile app reads Discovered Tasks that were produced on the Mac and does not run its own analyzer.
A quick sanity figure for the anchor fact: 0 chunks buffered at the hard cap, 0 seconds per chunk, 0 frames per second, and 0 seconds of recordings before the one analysis fires. Four numbers, one model pin, one file. That is the whole pipeline.
Want the full walk-through of Fazm's two pipelines?
I am happy to open the Swift actor, run a live analysis trigger, and show the observer_activity row that lands at the end. About 20 minutes.
Anthropic announcements April 2026, read from inside Fazm
What did Anthropic actually announce in April 2026, briefly?
Five threads ran through the month. Claude Opus 4.7 went generally available on April 22 at $5 per million input tokens and $25 per million output tokens, matching Opus 4.6. Claude Mythos was previewed via Project Glasswing, a gated cybersecurity program with Amazon, Apple, Microsoft, and Nvidia. Amazon expanded its Anthropic investment to the $25 billion range with Anthropic committing more than $100 billion to Amazon cloud and chips over ten years. Google and Broadcom expanded TPU supply. JPMorgan rolled Claude out internally while Dario Amodei met with Susie Wiles and Scott Bessent after the Pentagon flagged supply-chain concerns about Mythos. On the SDK side the Agent Client Protocol moved from 0.25.0 on April 7 to 0.29.2 on April 20, which is the version Fazm 2.4.0 upgraded to.
If Fazm runs on Claude, why does one pipeline use Gemini?
Because Fazm has two very different jobs and they do not belong to the same model. The interactive chat, every tool call, every prompt you type, every accessibility read of another Mac app, and every floating bar ask run through Claude via the ACP bridge. That is the low-latency, tool-heavy, action-taking side. A second, separate job exists: watch ~60 minutes of short active-window screen recordings and decide whether an AI agent could take one task off the user's plate. That job wants a long multimodal video context and does not need to hold a conversation. At GeminiAnalysisService.swift line 67 Fazm hard-codes `private let model = "gemini-pro-latest"` and routes those chunks there. None of April's Anthropic announcements changed the answer for that one job.
Where exactly are the constants that define the Gemini side of the split?
All four live at the top of /Users/matthewdi/fazm/Desktop/Sources/GeminiAnalysisService.swift. Line 67 sets `private let model = "gemini-pro-latest"`. Line 68 sets `private let maxChunks = 120` as the hard cap on buffered chunks. Line 69 sets `private let targetDurationSeconds: TimeInterval = 3600`, so Fazm waits for roughly 60 minutes of recordings before firing one analysis. Line 71 sets `private let inlineSizeLimit = 1_500_000`, the 1.5 MB threshold above which a chunk uses the Gemini File API resumable upload instead of an inline base64 body. The chunk format itself is set by the feeder: SessionRecordingManager.swift lines 76 through 83 build a `SessionRecorder.Configuration` with `framesPerSecond: 2.0`, `chunkDurationSeconds: 60.0`, and `captureMode: .activeWindow`. Two frames per second, one minute per chunk, only the frontmost app window.
Did the Opus 4.7 GA on April 22 change this boundary at all?
No, and that is the point. Opus 4.7 GA only affected the ACP bridge path, which is Fazm's Claude side. The relevant work there was the ACP v0.29 model ID rename, the partial models_available label fix in v2.4.1 on April 22, and the dynamic model list picked up at ShortcutSettings.swift line 180. The Gemini path shipped no change during the April release train. The same model string, the same 60-minute window, the same 1.5 MB cutoff. You can verify this by scanning `git log --since=2026-04-01 --until=2026-04-30 -- Desktop/Sources/GeminiAnalysisService.swift` and comparing the result to the Claude-side files.
Why send 60-second 2 FPS active-window chunks rather than a full screen stream?
Three reasons, all spelled out in SessionRecordingManager.swift around line 76. First, 2 FPS is called out in the source as `Lower FPS than research recorder to save CPU` — this is a background observer that must not heat the user's laptop. Second, `captureMode: .activeWindow` restricts each frame to the frontmost app's window only, both for privacy and to make the resulting video actually useful, since a full desktop frame with every other window in shot is mostly noise. Third, chunking at 60 seconds lets the analyzer reason about a window of activity rather than a single moment. The Gemini analysis prompt literally tells the model: `You are watching ~60 minutes of a user's screen recording. Each video clip captures the active window of whatever app the user was using at that moment.`
Could the same pipeline run on Claude with vision?
Technically yes, but the constraints fight the use case. Claude's vision path accepts images, not multi-hour video. Feeding 120 sixty-second clips would require chunking to stills, which throws away exactly the temporal signal the task needs. Gemini's File API accepts the MP4 directly and lets a single request span the whole hour. The separation is not a judgment about which model is better at reasoning, it is a judgment about which transport fits the input shape. Claude stays on conversational agent work where it is strongest. The video summarizer stays on the pipe that was built for video.
Where do the Gemini-produced tasks land in the UI?
They land in the `observer_activity` table as rows with `type = 'gemini_analysis'`. The main window surfaces them through /Users/matthewdi/fazm/Desktop/Sources/MainWindow/Pages/DiscoveredTasksSection.swift. Each row carries the verdict (`NO_TASK`, `TASK_FOUND`, or `UNCLEAR`), a task summary, a description, and a fuller markdown document. The prompt in GeminiAnalysisService.swift explicitly forces `Return UNCLEAR if: you can't make out what the user is doing, the content is ambiguous, or you'd be guessing` and requires checking the last ten rows of `observer_activity` and the last ten chat messages before suggesting anything new. That guard is what keeps the same suggestion from appearing twice.
What happens when analysis fails — does the pipeline retry immediately?
No. `lastFailedAnalysis: Date?` at GeminiAnalysisService.swift line 77 plus `retryCooldown: TimeInterval = 300` on line 78 set a five-minute cooldown after any failed analysis. During April 2026 this was a useful property, because Claude saw a lot of capacity turbulence around the Opus 4.7 launch window, but the Gemini path was insulated from that by definition. When Gemini itself had a blip, the cooldown prevented spamming the API. Claude outages on the chat path never affected task discovery, and Gemini outages on the task path never affected chat. That is the whole value of keeping them split.
Does the app ship any Gemini key, or do users bring their own?
The analysis path uses a Fazm-managed Gemini key on a capped budget, the same managed pattern Fazm uses for the built-in Claude account. Users do not bring a key to watch their own screen recordings. This is consistent with the privacy position documented in the v2.3.2 release on April 16: `Tightened privacy language in onboarding and system prompts to accurately say 'local-first' instead of 'nothing leaves your device'`. Chunks leave the device only when the 60-minute analysis fires, and the model decides one task or returns NO_TASK or UNCLEAR.
How is this actually different from a screenshot-based agent?
Screenshot-based agents take a still image on demand, send it with a prompt, and ask the model to reason about what is on screen right now. That is a synchronous, foreground interaction. Fazm's Gemini analysis path is none of those things. It is an asynchronous background summarizer watching an hour of 2 FPS active-window video after the fact, and it is reading the user's own macOS accessibility tree for everything Claude needs in real time. The two mechanisms exist because they answer two different questions. Screenshots are good for `what is happening now`. An hour of video is good for `what have you been doing and could I help`. Fazm ships both, on different models, on purpose.
Different angles on the same April 2026 Anthropic window, each grounded in a different file inside the Fazm source tree.
Keep reading
Anthropic announcement, April 2026: the three lines that let a user aim Claude at a corporate gateway
Custom API Endpoint shipped in Fazm 2.2.0 on April 11. Three lines of env-var injection at ACPBridge.swift:380-382, one @AppStorage key, one restart hook.
Anthropic API changelog April 2026: the `default` pseudo-model migration
ACP v0.29 renamed Opus from `opus` to `default`, which broke saved preferences until ShortcutSettings.swift:170 migrated them. Every line.
Anthropic Claude latest news April 2026: the accessibility-tree pipeline that feeds Claude, not screenshots
On the other side of the split: Fazm reads the macOS accessibility tree and passes that, not pixels, to Claude for every interactive turn.