The option
reasoning is an effort, 'none' | 'minimal' | 'low' | 'medium' | 'high',
or an object:
Set it on
createAgent({ reasoning }) for every run, or per call with
send(input, { reasoning }) / stream(input, { reasoning }). A sub-agent
uses its own reasoning, not its parent’s. AgentExecutor.execute() takes
it as ExecuteOptions.reasoning, and a custom provider receives it as
GenerateOptions.reasoning.
'none' sends nothing: the model runs with its provider’s default (OpenAI
reasoning models still reason at their default effort).
Provider mapping
Constraints the provider packages apply for you:
@ai-sdk/anthropic adds the
thinking budget to max_tokens (so the budget always stays below it) and
drops temperature and topP, which Anthropic does not allow with thinking;
@ai-sdk/openai drops temperature for reasoning models. Both log a warning
when they drop a setting.
Which models get it
Options are only sent to model families known to accept them, so a model that does not reason never gets an unknown-option error:
For any other model id (a fine-tune, a new family) pass
{ effort, force: true }.
Events and results
agent.stream() emits reasoning.start, then reasoning.delta (text) as
the model thinks, then reasoning.done (text: all of it; tokens when the
provider has reported reasoning tokens by then). They come inside the step,
before the step’s first text.delta or tool.start. A provider that cannot
stream reports a step’s reasoning as one start/delta/done before its text.
result.reasoning is the reasoning text of the run’s steps, joined with a
blank line. result.usage.reasoningTokens (and each stepUsage entry) counts
reasoning tokens when the provider reports them; the chat span carries them
as lousho.usage.reasoning_tokens.
The consumers show it too: reduceAgentEvents() keeps it as the assistant
message’s reasoning, toUIMessageStream() emits reasoning-start /
reasoning-delta / reasoning-end parts for useChat, lousho acp sends
agent_thought_chunk updates, and lousho chat prints it dimmed.
What is kept in the transcript
Reasoning is never written into the transcript as text and never sent back to the model as content, with one exception the provider requires: Anthropic needs a turn’s thinking blocks, unmodified and with their signatures, when it continues after that turn’s tool calls. So:- An assistant message that made tool calls keeps its signed (or redacted)
thinking blocks in
message.reasoning; the Anthropic provider sends them back first in that turn. They survive the next step, a checkpoint, a crash resume and an approval pause, since they are part of the saved messages. - Unsigned reasoning (OpenAI, Ollama, OpenRouter) and the reasoning of a
final reply are not kept in
messages. OpenAI’s encrypted reasoning items are not carried between steps. - Other providers ignore
message.reasoning.