We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Gemini 4 Carbon: new top score on CursorBench, a cheap launch price, and /swarm
Google made Gemini 4 Carbon available to everyone after a two-week release limited to "a subset of cyber defenders" . Cursor says that at high effort it is the top model on CursorBench at 60.4% . Fable 5.2 scored 60% at max effort last period.
The price doubles on December 1. Until November 30 it costs $2/M input and $10/M output, then $4/$20. Cursor's comparison of effort levels is at cursor.com/evals . Simon Willison notes the launch price matches Sonnet 5.5, and the December price matches Opus 5.5 . If you want to test it on real work, do it this month. llm-gemini 0.36 adds support .
Antigravity /swarm. Carbon is in Antigravity's desktop app, CLI and IDE extensions for AI Ultra subscribers and Gemini for business. Google says it is built for "extended verification loops" . The new /swarm command turns one prompt into a team of agents working in parallel. They plan, build and verify on a shared live message board, and each role can use a different model . Sundar Pichai's demo shows the pattern worth copying. Builder and critic subagents worked in loops across Blender and Three.js, checking their own renders, until they had a playable 3D game .
Early opinions differ. Willison ran his Yonkers-mech Three.js prompt through Carbon in Antigravity. He had to ask separately for a "standalone HTML file" to get a version without external dependencies . Theo had early access and "wasn't super impressed." After more tests he said he had missed some things, and his video "will not be going how I initially planned" .
Theo on Fable 5.2: keep Opus as your default and avoid Max
Theo's Fable 5.2 video ("Nobody Is Competing With Anthropic") backs up last period's advice and adds detail:
- Opus 5.5 stays the daily driver. Anthropic recommends starting most coding work on Opus 5.5 and moving up to Fable as needed. Theo says he agrees "beyond hard" on that point . When he audited his Lakebed project, he realised afterwards that the strong feedback had come from Opus 5.5 high, because he forgot to switch models .
- Don't use Max effort for coding. He says Fable 5.2 Max scores worse on most coding tasks and costs more. Consider it only if lower efforts keep stopping too early and you are comparing results against them .
- It's mixed on his own codebase benchmarks. On tasks like analysing T3 Code and reviewing PRs, he found Fable below Opus and Sonnet in almost every test .
- Keep the design skill on. Without it, frontend output falls back to "Tailwind template slop" . When Fable kept adding unneeded eyebrow text and subheadings, he asked it what it calls them and why it adds them. He then changed his agent.md file, and they have appeared less often since .
- Give it sources so it can check itself. He told Fable to read his history, and it disproved a bad MCP recommendation. It confirmed his own view that device flow is only needed for CLI and remote agents .
- Check its work. A friend summed it up: "much more capable, but it does not have much more autonomy." Theo says it can still make basic mistakes, such as leaking the very info a "safe mode" view was built to hide .
Fireship describes a similar visual self-correction loop. In Claude Code, Fable spent 43 minutes building a Three.js horse. It took a screenshot of its first attempt, listed the flaws and fixed each one .
Geoffrey Huntley: invest in engineering, not skill packs
At every major model release, Huntley says to read the model card and "consider nuking skills/agentsmd" . He thinks building agent "factories" now is premature, because whatever fits today's models is overtaken by next week's. His alternatives:
- Use Buck2 or Nix.
- Speed up builds with content-aware caching.
- Prompt for deterministic outcomes.
- Make prod, dev and CI identical.
- Improve security incident response.
"If you invest in skill packs and agent astrology you go backwards when new model drops" . If you do build a factory, he says to:
- capture all agent traces
- measure time to merge, token spend per merge and ideation to merge
- track incidents and human productivity
His caveat: "lights off isn't a thing yet." Skilled humans are still needed to steer agents in planning mode .
Tools and smaller releases
- Cursor Team Projects (beta): teammates and their agents share context. Agents share plans before they start, flag conflicts while working, and unblock each other's tasks (blog) .
- Meta Muse Ember 1.0: a small model for repetitive agent work such as tool calls, coding subtasks, routing and long-document parsing. It costs $0.10/$0.50 per M tokens for prompts up to 200k, and $0.30/$1.50 above that . Willison argues cost per task matters more than token price. On Artificial Analysis, Ember xhigh scores about 34 at about $0.12 per task, against about $0.25 for Haiku 5.5 xhigh . In his SVG test, the "high" reasoning level failed to return a complete SVG, and higher levels did not reliably look better .
- Agents prefer tools with official MCPs: Resend gives agents more than 80 named MCP tools, for example to set up accounts, check pricing in Markdown and send emails . CEO Zeno Rocha says he lets computer use in Codex or Claude Code manage and debug his DNS records . He dropped Plausible for PostHog because PostHog's MCP is maintained by PostHog itself .
- Claude usage reset: Pro, Max, Ultra and Team users get one free full reset across all models and limits. Anthropic says it is making up for bugs that used more of users' limits than intended. Claim it before December 10 at 2 PM PT in Settings > Usage .
- Claude Code bug: Theo saw the input box double every key press . Another user reports random double letters in Claude Code desktop going back more than a week .
- Risk in automated PR merging: at T3 Code, an agent loop merging contributor PRs attached a stray "fable 5.5" commit message to a maintainer's username while he was asleep. It was one of more than 3,599 PRs he merged that month . If you run merge bots, check commit metadata as well as the diffs.
- Simon Willison started Beep Locator from an empty GitHub repository using Claude Code Cloud on his iPhone with Opus 5.5 at Extra thinking: Claude wrote a problem specification, found the BeepBeep acoustic-localization paper, and was then asked to build the system. He later ran the project on his laptop with Fable 5.2, observing it and requesting live changes; hot-swapping listener JavaScript over WebSockets avoided manually revisiting devices or repeatedly granting microphone permissions. The Python server coordinated browser-microphone listeners over WebSockets; clients kept 60-second audio buffers and used FFT/high-pass detection, while a server-triggered chirp helped align uploaded clips. Willison iterated with prompts for rough device placement, clap-based testing, timestamps and replay, and device repositioning; the system localized the mystery beep to within about 40 cm, leading him to a failing carbon monoxide detector.
-
To make agent-authored PRs easier to review, put a short, human-approved high-level introduction first (optionally with a screenshot) and the full agent-written explanation inside GitHub-supported
<details><summary>tags; use the model and sometimes its effort level as the summary. - For agents that should improve a codebase’s structure rather than only add to it, try explicitly saying the codebase is theirs to shape and maintain: Anthropic reports repeated code was merged in about half of small-task trials with that ownership prompt, versus under one tenth without it.
-
In a Claude Opus 5.5 investigation of a SQLite
parse_number()extension, Willison asked for a C-versus-Rust comparison covering performance and binary size; the Rust builds were 298 KB and 321 KB versus 14 KB for C, though Rust was initially faster. He then prompted Claude to write a faster C parser using Clinger’s fast path: the reported C results were 19/16/18 ns per row for mixed/integer/decimal inputs, versus 41/32/47 ns for the faster of the two Rust implementations; he had Claude turn the investigation into a repository-style research report. - Datasette Agent 0.5a0 added a panel that keeps agent chat beside Datasette pages; paired with datasette-apps, users can prompt a database-backed app into existence and modify it from that chat. Datasette Apps 0.3a0 also added app references in chat and checks that stored queries exist and are viewable, requiring user approval for write queries.
- Meta introduced Muse Ember for recurring agent work including tool calls, coding subtasks, routing, extraction, and long-document parsing. In Willison’s cited Artificial Analysis cost-per-task comparison, Ember xhigh and max scored about 34 and 36 at roughly $0.12 and $0.14 per task, respectively, and sat on the efficiency frontier; Haiku 5.5 xhigh scored about 34.5 at roughly $0.25.
- While building Jureck, Sanfilippo iterates on his intended product using prompts, screenshots, conversations with AI, and beta-tester feedback. He warns that a vague request for a camera-and-editor app is more likely to produce a poor result or a generic clone than an app designed for a specific workflow; give the agent a clear product direction and refine it through feedback.
- His reusable principle is that human leverage lies in project direction and choosing what to optimize. For a JavaScript-to-Rust port, for example, decide explicitly whether to sacrifice features for better performance rather than leaving the product trade-offs implicit.
- Sanfilippo says Mythos 5.2 found two important bugs in a particle DB version already fixed by Afir, after about 20 minutes of work; one bug created a duplicate record when two updates were grouped during a transition. He cautions that an audit finding no further bugs does not prove none remain.
- Use Opus 5.5 as the everyday coding workhorse and reserve Fable 5.2 for ambitious, technically difficult tasks; Theo found Fable stronger on hard, long-running problems but not more autonomous, so it still needs human steering and output audits.
- Avoid Fable 5.2 Max reasoning by default: Theo says it costs more and scores worse on most coding tasks; consider it only for a specific case where lower reasoning efforts stop too early, after comparing them.
- When Fable gave questionable MCP guidance, Theo asked it to inspect the conversation history; it caught problems in its prior recommendation. Providing sources and asking it to verify its own reasoning can help, though it still misses things.
-
For frontend work, enable the design skill: Theo found that turning it off led to generic Tailwind-template output. He also asked about Fable’s recurring eyebrow text and subheadings, then adjusted
agent.md, after which they appeared less often. - Theo’s repo evaluations were mixed: Fable made 4 incorrect claims among 61 in a TS-Rust codebase analysis costing about $23; in T3 Code analysis it ranked third behind Opus and made 6 false claims among 83. Reviewing 8 PRs took about 120 minutes, though he found Fable less prone to getting stuck on minor nitpicks.
- In a Claude Code demo, Fable built an interactive 3D horse for Three.js in 43 minutes from a prompt, generating it with signed distance fields rather than downloading a model; it took a screenshot of its first attempt, critiqued visual flaws, and revised them.
- The resulting horse had over 120,000 vertices and 38 bones, and used inverse kinematics to plant each hoof.
- Fireship reports that an engineer used Fable subagents for eight days on an empty-folder project to produce an OS that booted on a real laptop with its own kernel and drivers; in a separate test, a 1,000-agent swarm completed a formal-proof task in 30 hours with a proof seven times shorter, while Opus 5.5 reached 26% on the same setup.
- The video says Anthropic recommends Opus 5.5 for most work and switching to Fable only when needed.
- Sanfilippo reports that skilled programmers working on large projects are moving from running open models locally to APIs through OpenRouter, using an agent harness he calls “Pie,” developed in Vienna by Mario and Armin. He describes this as a small, highly skilled cohort rather than broad developer adoption.
- OpenRouter consolidates access to hosted models behind one key and balance, and publishes usage statistics; Sanfilippo says demand exceeded GLM’s server capacity and users began migrating.
- Treat model benchmarks and adoption as imperfect proxies for practical value: the discussion notes that deploying, maintaining, and comparing local models—and providing an effective harness—add overhead. A panelist also said older models were already useful for paper review, while explicitly leaving open whether coding work has different needs.
- For conference preparation, Salvatore Sanfilippo brainstormed with a top-tier model: he supplied the talk topics and examples, received additional examples, and found the model’s proposed sequence compelling even though he considered his own ordering arbitrary.
- Sanfilippo says AI is making code easier to write, and points to practical projects as an opportunity: in two afternoons he built a custom 3D-printing CAD combining mathematical representations of 3D topology with a separate representation for features such as chamfers; he judged it better than many free tools and said a month’s work could make it a commercial alternative. He also describes making a Mac screen recorder with an embedded camera and pause/resume.
- Rocha uses computer-use in Codex or Claude Code to manage DNS records; the agent debugs them and runs DNS checks, taking the setup and troubleshooting off his hands.
- Resend’s first MCP was an open-source local/remote implementation. Supporting remote MCP led the team to revisit its permissions model, then work through distribution and observability.
- Rocha treats vendor-owned MCP support as a factor in choosing software: he switched from Plausible, whose MCP was built by Sentry, to PostHog because PostHog had an MCP; he also says integrations that are frustrating to set up or unavailable where he wants to use them are a reason not to use a product.
- The host describes an agent-driven AEO experiment loop: connect agents to analytics and the codebase, have them research ideas and track past attempts, approve experiments, then use other agents to run and monitor them; he also built a custom AEO tracker.
- Salvatore says AI-assisted work is bringing new releases and features to projects that had been stalled for about 10 years, citing the Gym graphics software, the NetBSD kernel, and databases. He notes that changelogs rarely disclose AI use, but attributes these updates to the tools.
- For workplace adoption, the discussion recommends a bottom-up approach: let people experiment with AI tools in their personal lives, identify where they help, and then build a company plan; mandated top-down adoption risks resistance when employees lack AI literacy.
- The discussion sees AI as a source of substantial leverage for lean teams of roughly 2–10 people, while cautioning that organization-wide gains are limited by surrounding systems and are not 20×.
Google’s Antigravity /swarm demo used builder and critic subagents in iterative Blender and Three.js loops, checking their own renders to build a playable 3D pelican-biking game on the Mountain View campus—a concrete visual-coding loop of building, rendering, critiquing, and iterating.
Simon shared a Gemini 4 Carbon Three.js experiment and linked a Claude Fable 5.2 run of the same prompt: animate Yonkers standing up as a mech and stomping around Manhattan, Queens, and Brooklyn using OpenStreetMap data.
- Meta launched Muse Ember 1.0 as a small, efficient model for recurring agent work—tool calls, coding subtasks, routing, extraction, and long-document parsing—with up to 1M input tokens. Pricing is $0.10/M input ($0.004/M cached) and $0.50/M output for prompts up to 200k tokens; above 200k it rises to $0.30/M input ($0.012/M cached) and $1.50/M output.
- Token prices alone can mislead when models use different numbers of reasoning tokens; the post says Ember sits on Artificial Analysis’s efficiency frontier, quoting Meta’s claim that no model scores higher for less per task.
- In a hands-on SVG-generation test across Ember’s six reasoning levels, the high setting failed to return a complete SVG, and higher reasoning levels did not consistently produce better visuals. The author found the resulting pelicans comparable to Muse Wonder’s, which the post says costs 40 times as much.
-
llm-gemini 0.36is an LLM plugin for accessing Google’s Gemini models, and Google opened Gemini 4 Carbon to everyone after initially limiting it to a subset of cyber defenders. At launch, Carbon cost $2 per million input tokens and $10 per million output tokens, with prices scheduled to rise to $4/$20 on December 1. - Simon Willison tested Carbon in Google’s Antigravity IDE with a prompt for a Three.js animation of Yonkers as a mech stomping through New York using OpenStreetMap data; to get a standalone HTML version without external dependencies, he had to follow up with an explicit request for that format.
-
A YouTube demo cited in the post describes Antigravity’s
/swarmcoordinating subagents to model Blender assets from Omni and Nano Banana references, build a Three.js/WebGL game, and create procedural Web Audio effects with Lyria music.
Swyx relayed advice to stop coding locally and use a cloud agent, pointing to Ryan Carson’s talk about building with agents at HelloUntangle. Carson says they have been iterating quickly with Dale Spoonemore and Devin AI, but shares no specific workflow details in the post.
A 2026 census of benchmarks reported by frontier labs found SWE-Bench Pro, DeepSWE, and Terminal-Bench among those with universal adoption. DeepSWE went from first appearing in June to being reported by all 12 labs, while labs cycled through Terminal-Bench versions 2.0–4.0 in one year.
Swyx says his agents keep choosing Resend even when he does not want them to. The linked discussion says Resend offers agents more than 80 named MCP tools to set up accounts, check pricing in Markdown, and send emails, illustrating a concrete way a developer service can expose tasks to agents.
Theo reported that Claude Code’s input box duplicated every key press, a bug he encountered live while filming.
A quoted report says a company found 10,500 vulnerabilities across about 700 systems and spent three months applying fixes ; a later diagnostic rerun using OpenAI’s GPT-6 Astra reportedly identified 35,000 new vulnerabilities .
-
At each major model release, read the model card and reconsider removing existing skills or
agents.mdrather than assuming they still help. A prompt to test with Claude Fable 5.2 is “This codebase is yours”: Simon W. relays Anthropic testing in which the model merged repeated code about half the time with that instruction, versus under a tenth without it; results varied by task. - Geoffrey argues that building an agent factory around current model capabilities can become premature as models improve; he recommends investing instead in Buck2/Nix, content-aware build caching, deterministic outcomes, parity across production/development/CI, and security incident response.
- To assess a factory, capture agent traces and measure time to merge, token spend per merge, ideation-to-merge time, incidents, and human productivity; he also cautions that skilled humans are still needed to guide agents in planning mode.
Riley praised a video whose headline says Claude reverse-engineered a 32-year-old Jeep and then started controlling it, a notable project involving AI and a physical system but without a described workflow.
Gemini 4 Carbon is now available in the Gemini API and to Ultra subscribers; its announcement says it follows Argon by a few weeks and advances in coding, cyber, and knowledge work, but provides no specific coding workflow or performance evidence .
Logan Kilpatrick called Carbon “a great model,” but offered no details about its capabilities or use in coding workflows.
Locating the source of a mysterious beep with Claude
In this newsletter:
Locating the source of a mysterious beep with Claude
Hide your slop PR descriptions behind \<details>\<summary>
Plus 2 links, 3 quotations, 4 releases, 1 research report, 1 tool, and 3 comments
Thanks for reading Simon Willison’s Newsletter! Subscribe for free to receive new posts and support my work.
Sponsor message: Everyone is fighting for hardware, yet most of it is underused. Nobody has put AI between code and hardware, until now. doubleAI’s Maxwell accelerates software as it runs and mathematically proves every change is correct. Now in early access (opens in new tab).
Our house has a box room, full of boxes that we still haven’t unpacked from our last move. A couple of weeks ago something in that room started intermittently beeping. The beeps were far enough apart that standing in the room and trying to determine the source of the noise was frustrating, and I really didn’t want to dig through every one of those boxes. So I had Claude Code build Beep Locator (opens in new tab), a software system for triangulating the source of a mysterious beep using multiple devices scattered around the room.
Here’s what Beep Locator looks like after it has been running for a while:

You run Python web server to show the primary UI, and then use the QR code or URL to connect as many devices as you can spare to act as listeners - I was using two iPads, a phone, a MacBook Pro and a Surface Ultra.
The devices then play noises to each other to help estimate their locations. This didn’t work particularly well, so I added a “Rough mode” where you can drag their icons around in the space to provide rough locations which are then adjusted based on those sounds.
Once that’s set up, the devices all listen for the beep!
I added a clapping mode too so I could test it by clapping my hands in different locations around the room - displayed as diamonds on the map. This helped me gain confidence that it was capable of locating a sound.
Beeps show up on the map as an X, plus a line in the “Sounds located” log. You can replay these sounds (from each device in turn) to confirm they are the mysterious beep you are looking for, then click “This is the mystery beep” to mark them as such.
Once you’ve confirmed the mysterious beep frequency the system will listen out for it, measure the interval between beeps, and use the triangulated locations to lock down the most likely location on the map.
The system worked as intended. It gave me the position of the beep to within about 40cm, then I dug through that specific pile of boxes and found an ancient carbon monoxide detector that desperately wanted its batteries replaced.
How it works
When I started working through this problem with Claude it quickly dug up BeepBeep: A High-Accuracy Acoustic-Based System for Ranging and Localization Using COTS Devices (opens in new tab), a 2007 paper by Chunyi Peng, Guobin Shen, Yongguang Zhang, Yanlin Li, and Kun Tan. Here’s that paper’s abstract:
We present the design, implementation, and evaluation of BeepBeep, a high-accuracy acoustic-based ranging system. It operates in a spontaneous, ad-hoc, and device-to-device context without leveraging any pre-planned infrastructure. It is a pure software-based solution and uses only the most basic set of commodity hardware – a speaker, a microphone, and some form of device-to-device communication – so that it is readily applicable to many low-cost sensor platforms and to most commercial-off-the-shelf mobile devices like cell phones and PDAs. It achieves high accuracy through a combination of three techniques: two-way sensing, self-recording, and sample counting.
That sounded exactly like what we needed to build!
Beep Locator runs a Python web application server that does most of the work. The listening devices then connect to that server via WebSockets and present a UI which requests browser microphone access. The listeners mainly work by recording a 60 second buffer of recent audio. They also run a simple beep detection algorithm (see detector.js (opens in new tab)), which uses Fast Fourier Transform and a high-pass filter to identify potential beeps. It sends these events to the main server.
When a beep is reported, the server has a device play a short chirp (the device with the lowest round-trip time to the server), then asks every listener upload a clip from about 0.6s before the beep to 0.8s after that chirp. This chirp allows the clips to be aligned with each other, a crucial step in locating the beep.
How I built it
I started this project using Claude Code Cloud via my iPhone, with Opus 5.5 running in Extra thinking effort mode. Here’s that shared starter session (opens in new tab), which began with this prompt against a newly created empty GitHub repository:
Write out a problem.md file describing the problem we want to solve
There is a device beeping in a room and I cannot find it
I want to set up several devices - laptops, phones, iPads - around the room all listening at the same time and have them help triangulate where the beep comes from
There needs to be a Python web app which coordinates it all - one device shows a web page for the app, other devices join a URL which turns them into listeners - all via browser WebAudio and WebSockets back to the Python server app
Ideally I wouldn't need to manually input the relative locations of the devices - it would be amazing if they could play sounds to each other in order to locate each other in 2D space - is that even possible though?
That got me this problem.md file (opens in new tab). As part of writing that up Claude found and read the BeepBeep paper, which is described in that file.
The research looked good, so I told it:
Ok try and build it, add a mechanism so you can send new code to the listeners which they will then run automatically - that way I can set everything up in the room and then leave you alone to continue hacking and experiment while I do something else
That got me to this point (opens in new tab) - most of the system was built, but nothing had actually tried running it yet.
I cloned the new repository to my laptop and fired up Claude Code… and then Fable 5.2 was released (opens in new tab), and this project seemed like an excellent opportunity to put that through its paces.
I had Claude Code on my laptop start the server running, then made sure it could both see what was happening andmake live changes to the software as it ran.
This was already baked into the software: Opus 5.5 had built an installModule() (opens in new tab) method on the listeners that could be triggered over the WebSocket connection, meaning the admin server could execute arbitrary new code on any of its clients.
On some devices, web pages that listen on the microphone request user permission any time the page reloads. The hot-swap module mechanism meant that we could deploy new code without having to manually interact with each of the listening devices in turn.
From that point on my involvement was mainly to sit by the laptop chatting with Fable 5.2 about what was going on, and occasionally requesting new features. Here are some of the feature prompts I ran:
I think we need to make it so I can drag things around on the map in “rough mode”, where my job is just to put them roughly where they are, then switch out of rough mode and it attempts to get them accurate
This gave me the ability to drag listeners around the map.
what’s a good way for me to test this I wonder? Can we have it listen for claps, then I could clap and it could identify the location of the clap? [...]
Claps should use a different symbol on the map than beeps
That added the thing where any time I clapped it would show on the map as a different symbol from the beeps.
each symbol on the map should include a HH:MM:SS timestamp
That made it easier to spot which symbol likely reflected which real-world sound.
The log should show beeps and claps with their timestamps AND have a little play button which, when clicked, replays the recorded noise from each of the listeners in sequence (with clear text on screen showing which listener recorded which snippet) while temporarily turning off microphone recording while that replay plays
Now I could replay sounds, making it much easier to identify which recorded clip was the mysterious beep I was looking for.
There should be a button next to a recording for “This is the mystery beep” - then I can hit replay to see and then confirm it was the mystery beep if that’s the one I am looking for
Then the system can categorize noises in the future to see if they are likely that same mysterious beep and use that information to build a more accurate idea of where it is
At this point I was getting close - I had a solid idea of where the beep was coming from, but wouldn’t it be neat if I could reposition the listeners around that point to get an even finer location?
I want a feature for this, I don’t want to have to restart each listening device etc, I want to be able to click a “Reposition the devices” button which lets me switch into repositioning, then I click “Repositioned” and it puts me into Rough mode and asks me to roughly locate them, then I do that and click, then it starts up again. The previous session can be read-only viewed through the app.
And since I had one spare device, I then said:
add a feature where the map includes a spot that is a suggestion for a location that it would be useful to add a listener at - based on data collected so far
Giving Claude Code ears
I think the most interesting part of this project is that I demonstrated it’s possible to give Claude Code ears.
Claude doesn’t have native audio input (yet), but it can run JavaScript and Python code that can analyze audio captured by a microphone.
I told it to run a web server with WebSocket connections to multiple listening devices, then had it both run a WebAudio microphone on those devices and hook them up so they could be sent fresh JavaScript code to execute via that WebSocket.
Then I could pretty much leave Claude alone, hacking away at the problem, querying the audio logs, and reconfiguring its ears to help it solve the problem.
I’m reminded of a similar hack I heard about at GitHub Universe a few weeks ago, where Martin Woodward (opens in new tab) told me he had been debugging the GitHub Universe Badge computers (opens in new tab) by plugging them into a computer via USB-C and then pointing a webcam at their screen, so his coding agent could tell if updates were working correctly or not.
Figuring out ways to let coding agents perceive the world around them is a whole lot of fun.
Most of the changes I make to my projects these days come in the form of PRs opened for me by Claude Code or Codex. The PR is my unit of work - I use them to bundle commits together, iterating on them until a feature is complete, document decisions and then merge the finished result. Today’s coding agents are great at writing PR descriptions.
They’re too good at describing the work
The problem is that they are too good. An agent-written PR description is accurate and comprehensive. It describes the problem, the detailed solution, and the steps taken to verify it. That’s a lot of information to absorb.
It’s not necessarily slop, but it reads like slop!
It’s very easy to spot an AI-written PR, and as with other forms of AI writing my instant reaction is best summarized as “I’m not reading all of that”. It doesn’t matter how accurate or useful the information is, I’m instantly put off by the thought that it will take me longer to read than it took the driving author to write… even when that driving author is me!
I want human editorial judgement. I want someone to have thought just long enough about the PR to give me a human-approved introduction that helps me understand, at a high level, what the PR is for and whether it deserves more of my attention.
I think I’ve found a low-effort way to do this that feels right.
Hide most of it in a details/summary
The HTML <details><summary> elements render as a collapsed heading (the summary) that can be expanded to view the larger piece of text. The code looks like this:
<details>
<summary>Claude Opus 5.5</summary>
<h2>The hook</h2>
Plugins implement <code>register_agent_reference_types(datasette)</code>...
</details>When rendered, it looks like this (opens in new tab):

Crucially, <details><summary> is supported in GitHub Markdown. You can drop those tags directly into an issue comment or PR description and GitHub will hide the details and display just the summary plus an expansion arrow.
I’ve started using this for my AI-generated pull requests.
The opening paragraph of my PRs will be carefully selected to act as a high-level explanation of what’s going on - the shortest text a human can read that will help get them up to speed.
I’ll sometimes throw in a screenshot as well, since images are often the best way to quickly illustrate a new feature.
The full agent-written essay then follows in a <details><summary>. I use the model name and often the effort level as that summary, to make it abundantly clear what is going on - “Claude Opus 5.5 Medium” for example.
My PRs don’t feel nearly as sloppy now! The information is all still there, but a reader can glance at it and get the top, human-curated information without their eyes glazing over at multiple paragraphs of agent-written details.
I don’t always write the introduction myself - sometimes the agent has given me what I need already, hidden away in the avalanche of other text. My promise to the reader is that the short opener will represent my human judgement as to what is definitely worth their time.
Here are some recent examples where I’ve used this pattern, including the opener I used:
datasette PR #3052: Redesign row page as a vertical list of fields (opens in new tab) - “The row page showed its single row as a one-row table. For wide tables, like a 46-column GitHub
repostable, that scrolled far off to the right and left most of the page blank.” (then a screenshot)datasette PR #3043: Pagination bar showing which rows are on the current page (opens in new tab) - “Table pages that span more than one page now make it obvious where you are, and offer navigation at the top of the page as well as the bottom.” (plus screenshot)
datasette PR #3042: Load edit-tools.js on demand via a small loader (opens in new tab) - “
edit-tools.js(~220KB) was loaded on every table, row and database page, even for users who couldn’t edit anything. Now only load it for users who can edit when they first interact with an edit feature (including mouse over an edit link).”datasette-agent PR #51: register_agent_reference_types plugin hook (opens in new tab) - “Lets plugins add their own kinds of item to the
#tagging in the chat composer using a newregister_agent_reference_types(datasette)plugin hook.” - pictured above.llm PR #1838: Add llm openai endpoint add/list/remove/path commands (opens in new tab) - “Adds commands for managing the records in
extra-openai-models.yaml, so OpenAI-compatible endpoints can be saved from the command line instead of by hand-editing YAML.” - then copied--helpoutput.
The mnemonic
I used to have trouble remembering the order of the tags - is it <details><summary> or <summary><details>?
Here are two tricks that helped me.
First, and most obviously, the <summary> is clearly the bit where you summarize the details. That’s the tag for your line of text that can be clicked to expand - the <details> element must then wrap everything else.
An even better trick is to always refer to these two tags as “details-summary”.
“details-summary” is two syllables followed by three syllables. That rolls off the tongue more smoothly than the three-two punch of “summary-details”.
Say “details-summary” out loud just a few times and you’ll never forget the order of the tags again.
(I still wish GitHub would add a button to their Markdown editor for this - partly to save me painstakingly typing it on my mobile keyboard, and partly to help spread the word to more GitHub users that this feature exists.)
I don’t envy educators right now.
AI clearly means you need to change how you teach and evaluate students. We are only a few years in though, and it’s still extremely unclear what effective teaching with these tools looks like.
The worst part is that the evaluation loop is measured in multiple years! If you start trying some new education mechanism today you won’t get a robust idea of how well it works until your current cohort graduate in 3-6 years time.
Students effectively all become guinea pigs for untested new ways of learning and teaching.
Release: llm 0.37.1 (opens in new tab)
A bugfix release for LLM (opens in new tab), with contributions from Steven Huang (opens in new tab), Tao An (opens in new tab), Arjan Mossel (opens in new tab), and XQ (opens in new tab).
This is a significant release of Datasette Agent (opens in new tab). The most notable new feature is called the panel - it lets the agent chat open and then sit next to pages from Datasette, for example a table or query page.
When combined with datasette-apps (opens in new tab) this means you can prompt a database-backed app into existence and then modify it from the chat that sits next to that app.

You can try it by signing in with your GitHub account to agent.datasette.io (opens in new tab).
Datasette Apps adds support for hosting and editing custom HTML applications inside of Datasette.
These can be created by hand, but it’s easier to create them using LLMs via Datasette Agent (opens in new tab). This release improves that integration:
Apps can now be tagged in Datasette Agent chat messages by typing #, which autocompletes from the apps the user has permission to view.
New app_add_stored_queries() and app_remove_stored_queries() tools let the agent manage which stored queries an app is allowed to call. Granting a write query requires approval from the user first.
app_create() now checks that each requested stored query exists and that the user can view it, and asks the user to approve any write queries before the app is created.
The “View app” buttons shown by the agent tools, and the links on # app references, now open the app full screen in the Datasette Agent panel.
Quote 2026-11-05
The web browser is very, very, very powerful software for applications, and the cost of accessing that power is going down seemingly every day.
Paul Ford (opens in new tab), The Web Is More Than Enough
Quote 2026-11-06
The products aren’t good enough to sell people on the costs.
You cannot tell people that you have to listen to the whine of a data center in their backyard for AI overviews and some of the most hilarious deep fake slop in history.
It’s not worth it. It just isn’t worth it to anyone. And agents aren’t real and they might not be being used the way that anyone wants them to yet. All these companies are spending more than they’re making on these products. Refrigerators holding blood storage in Europe are being hacked.
The costs are too high. The benefits are not real. And if you connect that to corruption, you’re like, in order to impose these costs on me, these CEOs are in the White House shaking Trump’s hand, renaming it to the Gulf of America, paying for this ballroom that we don’t want. It’s obvious crypto-corruption, and it’s still slop.
The AI industry will not get out of it until they make better products. Until everyone can see without needing to be convinced, without needing an ad campaign, without any of this stuff that just using these products makes your life better.
Nilay Patel (opens in new tab), The Vergecast: Big Tech lost big in the 2026 election
Terry Pratchett once wrote about the concept of “horizontal wealth”. Vertical wealth is where you spend money on rich people stuff - yachts and suchlike. Horizontal wealth is where you spend more money on the things you liked before you got rich: https://chibuikeani.blogspot.com/2017/02/the-price-of-happin… (opens in new tab)
But horizontal wealth means not letting your increased income dictate your tastes. You like books and now you have money? Buy more books! Change those catenary bookshelves for good hardwood ones! In my case, build a library extension to your office. And, of course, you buy what will be useful for that most wonderful of pursuits, blind research, which is research without direction for the sheer joy of it.
(Original source is his book A Slip of the Keyboard - this linked blog post quotes that bit.)
Link 2026-11-07 datasette #3046: Don’t serve link: rel=next HTTP headers to Firefox for HTML pages (opens in new tab):
I was looking at the Firefox network panel today when I noticed that requests to a Datasette table page were triggering an HTTP prefetch (opens in new tab) to the next page of rows in that table.
This was happening because Datasette pages serve an HTTP link header like this:
link: <https://latest.datasette.io/fixtures/compound_three_primary_keys?_next=a%2Cd%2Cv>; rel="next"
This is bad. A tiny fraction of the visitors to one of those pages will click the “next” link, which means for everyone else their browser is fetching unnecessary data and the Datasette server is having to render an entire page that then gets thrown away.
I dug in and learned that Firefox has an issue (opens in new tab) that has been open for 24 years about this behavior…
And one of the early comments on that issue links to my blog post from 2002 (opens in new tab) complaining about this feature. I hadn’t just forgotten that I had written about it, I had forgotten the feature entirely!
I was out walking the dog when I got curious about how easy/difficult it would be to write a SQLite C extension that adds a parse_number() function for turning strings like -$1,234.56 or '12.5%' into numeric values that could be summed and sorted.
I fired up regular Claude chat (Opus 5.5) and prompted (opens in new tab):
I'm thinking about a SQLite custom function 'parse_number(value)' that strips ',', '$', '£' and '%', handles a leading '-', and returns 'NULL' for anything it can’t parse
Explore the difference between building this as a SQLite extension in C v.s. in Rust - I want to compare performance and code complexity and size of the resulting.so(or whatever) file
This gave me a solid starting point - the Rust extension was 321 KB (using Rusqlite (opens in new tab)) and 298 KB (using sqlite-loadable-rs (opens in new tab)), while the C extension was 14 KB. But the Rust extension was faster!
Turns out that’s because the Rust equivalent of C’s strtod is “twice as fast”. So I prompted:
Try writing your own C function for parsing text into a decimal number that catches up to or beats the Rust implementation
And it did, using “Clinger’s fast path”:
Net cost per row over 2 million rows, lower is better:

Finally, I had it rewrite the prototype as a research report to match the others in simonw/research (opens in new tab) by prompting this:
Clone simonw/research from GitHub and turn your above investigation into a research report as seen in that repository - you can give me a zip file to download that contains your new folder
OK, this comment convinced me to give that a shot.
Here’s a thing I made in Three.js this morning - a Nudibranch themed Faberge Egg: https://static.simonwillison.net/static/2026/Hidden-Reef-Egg… (opens in new tab) (77KB)
I just asked Claude (Opus 5.5 Medium running in regular Claude Chat) to port that to Vanilla JS, in the same thread where it had built it, and got this: https://static.simonwillison.net/static/2026/Hidden-Reef-Egg… (opens in new tab) (98KB)
They aren’t identical - you can see what Claude said about that in the transcript (I don’t fully understand why it differed): https://claude.ai/share/e56d163e-2793-4677-aa11-191d5058b414 (opens in new tab)
But yeah, it turns out Claude Opus 5.5 is perfectly capable of 3D modeling in Vanilla JS + WebGL without Three.js.
In eyeballing the code I find the Three.js slightly easier to understand myself, but I rarely look at the code for these 3D projects so that isn’t a particularly big deal.
Anthropic released Fable 5.2 and Mythos 5.2 (opens in new tab) today. Fable 5.2 is currently ranked first on Artificial Analysis (opens in new tab). Anthropic say it “solved two open problems in the physics of black holes”, so clearly their internal benchmarks have become more ambitious!
I’ve added the new models to llm-anthropic, so you can now run prompts through Fable 5.2 like this:
uv tool install llm
llm install llm-anthropic
llm keys set anthropic
# paste key here
llm -m claude-fable-5.2 "Generate an SVG of a pelican riding a bicycle"
I ran pelicans at all five reasoning levels - low, medium, high, xhigh, and max. You can see them all here (opens in new tab) - here’s the best result I got, from xhigh:

max failed to return an image at all, running out of tokens after spending 128,000 thinking about them (opens in new tab). That’s the same bug that I saw with Opus 5.5 (opens in new tab) - but it’s new for the Fable series, both Fable 5 (opens in new tab) and Fable 5.1 (opens in new tab) returned max effort pelicans just fine.
It’s priced at \$8/million input and \$40/million output, which is a 20% discount on the previous Fable 5.1 (\$10/\$50).
I also used Fable 5.2 to help identify the source of a mysterious beep (opens in new tab).
I realized I didn’t know where Yonkers was, so I looked it up on Google Maps and then, to help embed it’s location and shape in my head (and to try out Claude Fable 5.2’s 3D modeling and animation skills), I prompted Fable 5.2 Medium (opens in new tab)to:
Make a three js animation where yonkers stands up as a big mech (cool stand up motion) and átomos around manhattan and queens and Brooklyn, use openstreetmap mapping data
It correctly deduced that “átomos” was a mobile keyboard typo for “stomps”:
Quote 2026-11-10
Claude Fable 5.2 responds closely to what the prompt says about who owns the code it works on. In Anthropic’s testing on small coding tasks, when a prompt said nothing about ownership or presented the code base as someone else’s, the model tended to add to the existing structure, even when that repeated existing code. […]
If you want the model to improve the structure as it works, say that the code is its own:
This codebase is yours: what it's for and how it's built are your call, and you'll keep building on it.
In Anthropic’s testing on small coding tasks, the model merged repeated code in about half of the tries with this sentence, and in under a tenth of the tries without it.
Prompting Claude Fable 5.2 (opens in new tab), Anthropic documentation
Meta AI just launched their entry in the Claude Haiku/GPT Luna category: Muse Ember, which they describe as:
[…] our smallest and most efficient model designed for complex reasoning execution and the work agents repeat all day: tool calls, coding subtasks, routing, extraction, and long document parsing.
For shorter prompts it’s priced the same as GPT-6 Luna and Claude Haiku 5.5 - both are \$0.10/million input tokens and \$0.50/million output. Today’s other big model release, Claude Fable 5.2, is 80x that price at \$8/\$40.
The pricing is a little less straightforward as prompts get longer, though. Luna, Ember, and Haiku all support up to a million input tokens, but they also all have a threshold after which the price goes up. Taking that threshold into account Ember is priced between the two others:

But comparing price-per-token doesn’t really make sense these days, when reasoning tokens mean that different models might use dramatically different numbers of tokens to solve the same problem.
For that, one measure that’s useful is the Artificial Analysis.

And even more useful than that is their Intelligence Index vs. Cost per Task chart, which shows the following for those three models:

The Muse Ember models sit right on that Pareto line - the line at which you can only improve one dimension by giving up another. Meta call this out in their announcement:
It also sits on the efficiency frontier of the full Artificial Analysis leaderboard: no model scores higher for less per task.
(That grey dot on the Pareto line in the middle of the green area is GPT-6.1 Terra (low) - clearly I should be paying more attention to the Terra family!)
Muse Ember has six reasoning levels - minimal, low, medium, high, xhigh, and max - so I rendered six pelicans riding bicycles (opens in new tab). The “high” reasoning level failed to return a full SVG, and the other SVGs were surprising in that the reasoning level didn’t cleanly map to the visual quality of the response.
Here’s the “max” one, but the others are worth a look too:

The Ember pelicans are comparable in quality to those I got from Muse Wonder (opens in new tab), which is 40x the price (opens in new tab) of Muse Ember.
If you find this newsletter useful, please consider sponsoring me via GitHub (opens in new tab). \$10/month and higher sponsors get a monthly newsletter with my summary of the most important trends of the past 30 days - here are previews from July (opens in new tab)and August (opens in new tab) and September (opens in new tab).
Thanks for reading Simon Willison’s Newsletter! Subscribe for free to receive new posts and support my work.
- Simon Willison started Beep Locator from an empty GitHub repository using Claude Code Cloud on his iPhone with Opus 5.5 at Extra thinking: Claude wrote a problem specification, found the BeepBeep acoustic-localization paper, and was then asked to build the system. He later ran the project on his laptop with Fable 5.2, observing it and requesting live changes; hot-swapping listener JavaScript over WebSockets avoided manually revisiting devices or repeatedly granting microphone permissions. The Python server coordinated browser-microphone listeners over WebSockets; clients kept 60-second audio buffers and used FFT/high-pass detection, while a server-triggered chirp helped align uploaded clips. Willison iterated with prompts for rough device placement, clap-based testing, timestamps and replay, and device repositioning; the system localized the mystery beep to within about 40 cm, leading him to a failing carbon monoxide detector.
-
To make agent-authored PRs easier to review, put a short, human-approved high-level introduction first (optionally with a screenshot) and the full agent-written explanation inside GitHub-supported
<details><summary>tags; use the model and sometimes its effort level as the summary. - For agents that should improve a codebase’s structure rather than only add to it, try explicitly saying the codebase is theirs to shape and maintain: Anthropic reports repeated code was merged in about half of small-task trials with that ownership prompt, versus under one tenth without it.
-
In a Claude Opus 5.5 investigation of a SQLite
parse_number()extension, Willison asked for a C-versus-Rust comparison covering performance and binary size; the Rust builds were 298 KB and 321 KB versus 14 KB for C, though Rust was initially faster. He then prompted Claude to write a faster C parser using Clinger’s fast path: the reported C results were 19/16/18 ns per row for mixed/integer/decimal inputs, versus 41/32/47 ns for the faster of the two Rust implementations; he had Claude turn the investigation into a repository-style research report. - Datasette Agent 0.5a0 added a panel that keeps agent chat beside Datasette pages; paired with datasette-apps, users can prompt a database-backed app into existence and modify it from that chat. Datasette Apps 0.3a0 also added app references in chat and checks that stored queries exist and are viewable, requiring user approval for write queries.
- Meta introduced Muse Ember for recurring agent work including tool calls, coding subtasks, routing, extraction, and long-document parsing. In Willison’s cited Artificial Analysis cost-per-task comparison, Ember xhigh and max scored about 34 and 36 at roughly $0.12 and $0.14 per task, respectively, and sat on the efficiency frontier; Haiku 5.5 xhigh scored about 34.5 at roughly $0.25.