$ ls ./menu

© 2025 ESSA MAMDANI

LIVE
Fable 5.1 vs Gemini 3.8 Flash vs Muse Spark 1.3 vs GPT-6 Astra: AI Models Early September 2026GPT-6 Astra Safety: The Most Powerful Model Needs New GuardrailsGPT-6 Astra Turns AI Agents Into Digital CoworkersGPT-6 Astra and AGI: How Close Are We, Really?GPT-6 Astra: The Frontier Model That Changes the Agent EquationMuse Spark 1.3: Meta’s Frontier Coding AgentFable 5.1 vs Gemini 3.8 Flash vs Muse Spark 1.3 vs GPT-6 Astra: AI Models Early September 2026GPT-6 Astra Safety: The Most Powerful Model Needs New GuardrailsGPT-6 Astra Turns AI Agents Into Digital CoworkersGPT-6 Astra and AGI: How Close Are We, Really?GPT-6 Astra: The Frontier Model That Changes the Agent EquationMuse Spark 1.3: Meta’s Frontier Coding AgentFable 5.1 vs Gemini 3.8 Flash vs Muse Spark 1.3 vs GPT-6 Astra: AI Models Early September 2026GPT-6 Astra Safety: The Most Powerful Model Needs New GuardrailsGPT-6 Astra Turns AI Agents Into Digital CoworkersGPT-6 Astra and AGI: How Close Are We, Really?GPT-6 Astra: The Frontier Model That Changes the Agent EquationMuse Spark 1.3: Meta’s Frontier Coding AgentFable 5.1 vs Gemini 3.8 Flash vs Muse Spark 1.3 vs GPT-6 Astra: AI Models Early September 2026GPT-6 Astra Safety: The Most Powerful Model Needs New GuardrailsGPT-6 Astra Turns AI Agents Into Digital CoworkersGPT-6 Astra and AGI: How Close Are We, Really?GPT-6 Astra: The Frontier Model That Changes the Agent EquationMuse Spark 1.3: Meta’s Frontier Coding Agent
cd ../blog
6 min read
Developer Tools

LLM 0.32: Reasoning Traces, Server-Side Tools Arrive

> LLM 0.32 adds visible reasoning traces, server-side tools for OpenAI and Claude, a new Python streaming events API, and Git-style content-addressable logs.

ShareXLinkedIn

🎧 Listen — ~6 min

Ready · LLM 0.32: Reasoning Traces, Serv

0:00 / 6:00
LLM 0.32: Reasoning Traces, Server-Side Tools Arrive
Verified by Essa Mamdani

Simon Willison shipped LLM 0.32 on August 4, 2026, calling it "the most significant new version of LLM since the initial launch of the project." That is not marketing fluff. The release rewires how the CLI and Python library represent prompts, responses, tool calls, and logs — and it quietly repositions LLM as an agent framework, whether Willison wanted to use that word or not.

If you build on top of LLM, or you use it daily to talk to GPT, Claude, Gemini, or a local model through LM Studio, here is what actually changed and why it matters.

Reasoning traces you can finally see

Reasoning models have always been a black box in the terminal. You'd fire off a prompt, wait, and get an answer with no visibility into the thinking that produced it. LLM 0.32 fixes that by streaming reasoning traces to stderr while the model works.

llm -m gpt-5.6-luna "Explain why quicksort is worst-case O(n^2)"

Run that against a reasoning-capable model and you'll see the model's intermediate thinking scroll past on stderr, separate from the final answer on stdout. That separation matters: you can pipe the clean output into another tool without your reasoning trace polluting the pipeline, but you still get to watch the model work when you want to. Add -R or --hide-reasoning if you'd rather not see it at all.

LLM also ships GPT-5.6 support out of the box now, and the default model for a bare llm "prompt" has shifted to GPT-5.6 Luna — OpenAI's cheap, fast tier that got an 80% price cut on July 30. That's a deliberate choice: Willison wants the zero-config path to be inexpensive by default.

Server-side tools: the model's provider does the work

This is the headline architectural change. Previously, every tool LLM ran executed locally — your machine did the work, then fed results back to the model. 0.32 adds support for server-side tools, where the provider's own infrastructure executes the tool call, and you never leave the request/response cycle.

OpenAI models get a hosted CodeInterpreter and WebSearch:

llm --tool CodeInterpreter "Show current python and SQLite versions"

The llm-anthropic plugin (also updated, to 0.26) adds four server-side tools for Claude: WebSearch, WebFetch, CodeExecution, and AnthropicMCP. That last one is the most interesting — it lets a single API call to Anthropic reach out and execute Model Context Protocol calls against a remote MCP server on your behalf:

text
1llm -m claude-sonnet-5 -T 'AnthropicMCP("https://datasette.simonwillison.net/-/mcp")' \
2  'how many rows in the blog_blogmark table?'

That's a full MCP round-trip — model reasoning, MCP tool discovery, tool execution, and a synthesized answer — happening inside Anthropic's own infrastructure, triggered by one CLI invocation. No local MCP client, no local process spawning. For teams building agents against internal MCP servers, this removes an entire category of client-side plumbing.

A generic endpoint command for anything OpenAI-compatible

The new llm openai endpoint command turns any OpenAI-compatible API into a one-liner target, without installing LLM as a dependency:

text
1uvx --with llm-tools-quickjs \
2  llm openai endpoint http://localhost:1234/v1 -m google/gemma-4-12b \
3  -T QuickJS 'Use QuickJS to multiply 3434 * 2434'

That example hits a local Gemma 4 12B model running in LM Studio, using uvx to grab LLM and the QuickJS tool plugin on the fly, with zero permanent install. It's a genuinely useful pattern for testing local model deployments — LocalAI, vLLM, Ollama's OpenAI-compatible endpoint, or any self-hosted inference server — against LLM's tool-calling machinery without committing to a full install.

Calls made through llm openai endpoint aren't logged, which is a deliberate design choice for one-off exploratory prompts against arbitrary endpoints.

The Python API grows up

LLM's Python API used to make you build a conversation and send messages one at a time — an abstraction that leaked once real usage got complicated. 0.32 adds a model.prompt(messages=[]) parameter that accepts a full message history directly:

python
1import llm
2from llm import user, assistant, system
3
4model = llm.get_model("gpt-5.6-luna")
5response = model.prompt(messages=[
6    system("You are a helpful pirate."),
7    user("What is the capital of France?"),
8    assistant("Paris, matey."),
9    user("And Germany?"),
10])
11print(response.text())

More significantly, LLM now exposes a stream_events() iterator that reflects what models actually return in 2026: a mix of reasoning chunks, output text, tool calls, and image attachments — not just a flat string.

python
1for event in model.prompt("Explain cats").stream_events():
2    if event.type == "reasoning":
3        print(f"[thinking] {event.chunk}", end="", flush=True)
4    elif event.type == "text":
5        print(event.chunk, end="", flush=True)
6    else:
7        print(f"Other event: {event}")

If you've been hand-rolling event-type detection against raw API responses to build a custom chat UI or logging pipeline, this replaces that code with a stable, provider-agnostic interface.

Content-addressable logs, modeled after Git

Supporting append-only conversation history at scale exposed a logging problem: every turn was re-serializing the entire message history as duplicate JSON. LLM 0.32 replaces that with a content-addressable SQLite message store — each message stored once, referenced by hash, similar to how Git stores blobs. llm logs and llm logs --json transparently read both the legacy schema and the new one, so existing tooling built against llm logs --json output should keep working without changes.

This is the kind of unglamorous infrastructure work that matters more than it sounds like. If you're running LLM against long agent loops or multi-day conversations, the old approach meant your log database grew roughly quadratically with conversation length. The new store grows linearly.

Why this looks like an agent framework now

Willison has resisted the word "agent" for years, citing how vague the term became. In the announcement, he notes he came around to a working definition — "an LLM agent runs tools in a loop to achieve a goal" — and admits LLM is starting to look agent-shaped: tool chains can now pause for human approval mid-execution and resume from stored message history, both capabilities pulled directly from the needs of his in-progress Datasette Agent project.

Combined with the new llm-chat-completions-server plugin — which spins up a local OpenAI-compatible chat completions server backed by any model LLM supports — you can now stand up a local proxy that speaks the standard chat completions dialect while routing through LLM's plugin ecosystem underneath:

text
1llm install llm-chat-completions-server
2llm chat-completions-server --port 9000

Point any tool that expects an OpenAI-shaped endpoint at http://127.0.0.1:9000/v1 and it'll work against whatever model and provider you've configured in LLM, tool calls and all.

Should you upgrade?

Existing LLM plugins keep working, but plugins that register new models need an upgrade to 0.32 to participate in the streaming events system. If you maintain a model plugin, the "Structured messages and streaming events" guide in LLM's docs is the place to start. For everyone else: pip install -U llm or uv tool install llm, and the reasoning-trace streaming alone is worth the update if you work with GPT-5.6, Claude 5, or any other reasoning-capable model day to day.

Related reading

Keep reading

#LLM CLI#Simon Willison#Developer Tools#OpenAI#Anthropic#MCP#Reasoning Models#Open Source
ShareXLinkedIn

⚡ Daily AI Model Drop — Get Kimi K3 benchmarks before Twitter

Join 2,400+ AI engineers. 1 email/day, no spam, unsubscribe anytime

Comments