ATRIUMsearch → argument graph
Article · 2026-08-04 · 6 moments

New release of LLM adds support for reasoning traces, OpenAI Responses, server-side tools, and smarter logging

I released LLM 0.32 this morning, the most significant new version of LLM since the initial launch of the project. The new version includes support for visible reasoning traces, server-side provider tools, redesigned content-addressable SQLite logs, new models, and new features enabled by the OpenAI Responses API. I also released new versions of the llm-anthropic, llm-gemini, and llm-openrouter plugins, each with substantial updates of their own. Headline features for LLM CLI users Running LLM ✦ AI generated

01
Mechanism

A content-addressable message store modeled after Git solves the duplicate-JSON logging problem inherent in chat-completions-style APIs where message sequences are appended to on every request.

To avoid logging duplicate JSON for every turn in a growing message sequence, LLM 0.32 introduces a Git-like content-addressable message store that the log commands can reconstruct into human-readable format.

transcript

Simon Willison: The bigger challenge with that kind of API concerns logging. If we're going to support the pattern where the message sequence is appended to on every request, ideally we can avoid logging all of that duplicate JSON for every turn. The solution is the new content-addressable message store, modeled after Git. You can see the new schema for that in the documentation, but the llm logs and llm logs --json commands have both been upgraded to convert that format back into something that's easy to consume.

02
Claim

LLM 0.32 is the most significant new version of LLM since the initial launch of the project.

The author announces LLM 0.32 as a landmark release, bundling reasoning traces, server-side tools, redesigned logging, new models, and OpenAI Responses API features.

transcript

Simon Willison: I released LLM 0.32 this morning, the most significant new version of LLM since the initial launch of the project. The new version includes support for visible reasoning traces, server-side provider tools, redesigned content-addressable SQLite logs, new models, and new features enabled by the OpenAI Responses API.

03
Prediction

LLM is evolving into an agent framework, driven by Datasette Agent's needs, with tool chains that can pause for human approval and resume from stored message history — and the agent concept may be baked into the core library next.

Many lower-level changes in 0.32 were driven by Datasette Agent's requirements. The author now sees LLM as agent-shaped and is considering baking the agent concept into the core library in a future release.

transcript

Simon Willison: Quite a few of the lower-level tools changes in this release were driven by the needs of Datasette Agent. When I started work on LLM, the term "agent" had such a vague definition that I refused to use it. In September 2025 I came around to the idea that "An LLM agent runs tools in a loop to achieve a goal" is well established enough now that I could stop avoiding the term entirely. Tool chains can now pause for human approval and resume from a stored message history - both needed by Datasette Agent. Looking at LLM today it's beginning to look very agent-shaped to me. There's something neat about having a CLI utility that can mix and match different tools from different sources with different models all as a one-liner, and that includes a Python library powerful enough to build systems like Datasette Agent and llm-coding-agent. Maybe the next version of LLM will bake the concept of an "agent" into the core library. I'm still trying to figure out what that would look like.

gives example · 2

04
Claim

LLM now supports server-side tools from multiple providers, including OpenAI's CodeInterpreter and WebSearch, and Anthropic's WebSearch, WebFetch, CodeExecution, and MCP integration.

Server-side tools like code execution and web search are now invocable directly from LLM prompts across OpenAI and Anthropic providers, including Anthropic MCP calls against remote servers.

transcript

Simon Willison: LLM calls can now use server-side tools from various providers. OpenAI provide a code execution environment as a server-side tool; LLM can now run prompts that benefit from that like so: llm --tool CodeInterpreter 'Show current python and SQLite versions' OpenAI also gets a WebSearch tool. The llm-anthropic plugin adds WebSearch, WebFetch, CodeExecution, and AnthropicMCP, which looks like this: llm -m claude-sonnet-5 -T 'AnthropicMCP("https://datasette.simonwillison.net/-/mcp")' \ 'how many rows in the blog_blogmark table?' That causes Anthropic to execute MCP calls against my new datasette-mcp plugin as part of a single request/response interaction with their API.

extends · 1

05
Claim

Running LLM against reasoning models now displays their reasoning traces to standard error, keeping them separate from standard output that may be piped to other tools.

LLM 0.32 makes model reasoning visible by default on stderr, with a -R flag to suppress it, keeping stdout clean for tooling pipelines.

transcript

Simon Willison: Running LLM against reasoning models now displays their reasoning traces to standard error, so you can see what they are "thinking" without that information being included in the standard output that you might pipe to another tool. Add -R/--hide-reasoning to turn this off.

06
Mechanism

The Python API now supports a messages-based prompt parameter and structured streaming events, replacing the old single-string iterable approach to handle modern model outputs that include reasoning, tool calls, and attachments.

The old abstraction of sending messages one at a time to a conversation has been replaced with a direct messages list parameter, and string-only streaming has been superseded by typed stream_events that handle reasoning, text, tool calls, and attachments.

transcript

Simon Willison: LLM's Python API previously required you to create a conversation and then send messages to it one at a time. This was an abstraction over the true nature of LLMs, where each request carries a complete history of the messages that came before it. That abstraction started to get in the way for some more advanced cases, so the new release introduces a model.prompt(messages=[]) parameter... LLM previously returned an iterable sequence of strings from each prompt. This worked great when models returned a string response, but failed to predict the weird shape that models would evolve towards. Today many models return a mix of reasoning text, output strings, tool calls, and even image attachments. With LLM 0.32 you can do this instead: for event in model.prompt("Explain cats").stream_events(): if event.type == "reasoning": print(f"[thinking] {event.chunk}", end="", flush=True) elif event.type == "text": print(event.chunk, end="", flush=True) else: print(f"Other event: {event}")

Highlight slides
Related episodes