Skip to main content

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.