Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/phpaisdk/core/llms.txt

Use this file to discover all available pages before exploring further.

Some AI models can expose their internal chain-of-thought as a separate reasoning or “thinking” trace before producing their final answer. aisdk/core exposes this through the ->reasoning() method on PendingTextRequest and the Reasoning value object, giving you a portable, provider-agnostic way to control how much thinking budget a model receives.

Enabling Reasoning

Call ->reasoning() on any Generate::text() chain before ->run(). You can pass either a Reasoning instance or a plain effort string.
use AiSdk\Generate;
use AiSdk\Reasoning;
use AiSdk\Anthropic;

$result = Generate::text()
    ->model(Anthropic::model('claude-opus-4-5'))
    ->prompt('Prove that the square root of 2 is irrational.')
    ->reasoning(Reasoning::effort('high'))
    ->run();

echo $result->reasoning; // The model's thinking trace
echo $result->text;      // The final answer
Reasoning support is provider- and model-specific. The SDK requires Capability::Reasoning to be advertised by the model before it sends the request — if the capability is missing, a CapabilityNotSupportedException is thrown without making any network call. Check your provider’s documentation to confirm which models support extended thinking.

Effort Levels

Reasoning::effort(string $effort) accepts one of four named levels. Each level maps to a percentage of the model’s maximum reasoning budget:
ConstantStringBudget Percentage
Reasoning::EFFORT_MINIMAL'minimal'2% of max budget
Reasoning::EFFORT_LOW'low'10% of max budget
Reasoning::EFFORT_MEDIUM'medium'30% of max budget
Reasoning::EFFORT_HIGH'high'60% of max budget
The resulting token count is computed by ReasoningBudget::calculate() and is always clamped to at least MIN_BUDGET (1024 tokens) and at most the model’s declared maximum budget.
use AiSdk\Reasoning;

// All four named levels
Reasoning::effort(Reasoning::EFFORT_MINIMAL); // ~2% of max
Reasoning::effort(Reasoning::EFFORT_LOW);     // ~10% of max
Reasoning::effort(Reasoning::EFFORT_MEDIUM);  // ~30% of max
Reasoning::effort(Reasoning::EFFORT_HIGH);    // ~60% of max
Use effort levels when you want portable, relative control that adapts across different models and their varying maximum budgets. Use Reasoning::budget() when you are targeting a specific provider and need precise, reproducible token consumption — for example when benchmarking or controlling costs tightly.

Token Budget

Reasoning::budget(int $tokens) sets an exact number of reasoning tokens. The value you pass is clamped by the provider driver:
  • Lower bound: MIN_BUDGET — 1024 tokens. Values below this are raised automatically.
  • Upper bound: The model’s declared maximum budget. Values above this are reduced automatically.
use AiSdk\Reasoning;

// Request exactly 4096 reasoning tokens (clamped to [1024, maxBudget])
Reasoning::budget(4096)

Shorthand String Syntax

Because ->reasoning() is defined in the ConfiguresGeneration trait, it also accepts a plain string that is forwarded to Reasoning::effort(). This removes the use AiSdk\Reasoning import when the effort level is all you need:
use AiSdk\Generate;
use AiSdk\Anthropic;

$result = Generate::text()
    ->model(Anthropic::model('claude-opus-4-5'))
    ->prompt('What is the fastest sorting algorithm and why?')
    ->reasoning('high')  // Same as Reasoning::effort('high')
    ->run();
The default effort when no argument is passed is Reasoning::EFFORT_MEDIUM:
->reasoning() // Equivalent to ->reasoning('medium')

Reading the Reasoning Trace

After ->run() completes, the model’s thinking text is available on $result->reasoning. It is null when the model did not emit a reasoning trace (either because reasoning was not requested or the provider does not support it).
$result = Generate::text()
    ->model(Anthropic::model('claude-opus-4-5'))
    ->prompt('Explain why P ≠ NP is still unsolved.')
    ->reasoning(Reasoning::effort('medium'))
    ->run();

if ($result->reasoning !== null) {
    echo "=== Thinking ===" . PHP_EOL;
    echo $result->reasoning . PHP_EOL;
}

echo "=== Answer ===" . PHP_EOL;
echo $result->text;

The ReasoningBudget Class

Provider drivers use ReasoningBudget internally to translate a portable Reasoning value into a concrete token count. The default percentages and minimum budget are defined as overridable constants, so provider packages can subclass ReasoningBudget to apply provider-specific curves or clamping logic without changing the public API.
// Default percentages (from ReasoningBudget::EFFORT_PERCENTAGES)
// minimal => 0.02 (2%)
// low     => 0.10 (10%)
// medium  => 0.30 (30%)
// high    => 0.60 (60%)

// Default minimum: ReasoningBudget::MIN_BUDGET = 1024 tokens
You do not need to interact with ReasoningBudget directly unless you are writing a provider driver. From application code, Reasoning::effort() and Reasoning::budget() are the only two entry points.

Required Capability

The SDK checks for Capability::Reasoning on the model before the request is dispatched. If you are registering a custom model, include it explicitly:
use AiSdk\Capability;

Anthropic::registerModel('claude-future-model', capabilities: [
    Capability::TextGeneration,
    Capability::Streaming,
    Capability::Reasoning,
    Capability::TextInput,
]);

Build docs developers (and LLMs) love