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.

Text generation is the foundation of aisdk/core. The Generate::text() entry point returns a fluent PendingTextRequest that you configure — model, prompt, parameters — and resolve by calling ->run(), which returns a TextResult containing the generated text, token usage, and finish metadata.

Basic example

Pass a prompt directly to Generate::text() and chain ->model() and ->run():
use AiSdk\Generate;
use AiSdk\OpenAI;

$result = Generate::text('Explain closures in PHP.')
    ->model(OpenAI::model('gpt-4o'))
    ->run();

echo $result->text;

Setting a default model

Registering a default model with Generate::model() removes the need to call ->model() on every request:
use AiSdk\Generate;
use AiSdk\OpenAI;

Generate::model(OpenAI::model('gpt-4o'));

$result = Generate::text('Explain closures in PHP.')->run();

echo $result->text;

System instructions

Use ->instructions() to pass a system prompt. It is sent separately from the user messages, so it never appears in the conversation history:
$result = Generate::text('Explain closures in PHP.')
    ->model(OpenAI::model('gpt-4o'))
    ->instructions('Write short, precise answers aimed at senior PHP developers.')
    ->run();

Explicit message arrays

For multi-turn conversations or when you need full control over roles, use ->messages() with an array of Message instances. Calling ->messages() replaces any prompt set via ->prompt():
use AiSdk\Generate;
use AiSdk\Message;
use AiSdk\OpenAI;

$result = Generate::text()
    ->model(OpenAI::model('gpt-4o'))
    ->messages([
        Message::system('You are a concise technical writer.'),
        Message::user('What is a PHP closure?'),
        Message::assistant('A closure is an anonymous function that can capture variables from its surrounding scope.'),
        Message::user('Give me one practical example.'),
    ])
    ->run();

echo $result->text;
->messages() expects an array of AiSdk\Message instances. Passing any other type throws an InvalidArgumentException.

Generation parameters

These methods are available on every PendingTextRequest and are applied on every call to ->run() or ->stream():
MethodTypeDefaultDescription
->maxTokens(int)int1024Maximum number of tokens in the model’s response.
->temperature(float)float1.0Sampling temperature. Lower values produce more deterministic output; higher values increase creativity.
->topP(float)floatnullNucleus sampling cutoff. Use instead of — not alongside — temperature.
->maxSteps(int)int1Maximum number of agentic loop iterations. Values greater than 1 enable automatic tool-call execution.
$result = Generate::text('Draft a haiku about PHP.')
    ->model(OpenAI::model('gpt-4o'))
    ->maxTokens(256)
    ->temperature(0.7)
    ->run();
->maxSteps() is the main knob for agentic workflows. Set it to 5 or more when you attach tools and want the model to iterate until it reaches a final answer without tool calls. See Tool Calling for a full walkthrough.

Working with TextResult

->run() returns a TextResult value object. All properties are readonly:
$result = Generate::text('Summarise the Liskov Substitution Principle.')
    ->model(OpenAI::model('gpt-4o'))
    ->run();

// The generated text
echo $result->text;

// Why the model stopped: FinishReason::Stop, FinishReason::Length, etc.
echo $result->finishReason->value;

// Optional reasoning trace (models that support it)
echo $result->reasoning;

// Structured output when ->output() is used (null otherwise)
$data = $result->output;

// Tool calls and results when tools are attached
$calls   = $result->toolCalls;   // array<int, ToolCall>
$results = $result->toolResults; // array<int, ToolResult>

// Raw provider response payload (useful for debugging)
$raw = $result->rawResponse;

// Provider-specific metadata (e.g. logprobs, content filters)
$meta = $result->providerMetadata;

Token usage

$result->usage is a Usage value object with these fields:
echo $result->usage->inputTokens;         // tokens sent to the model
echo $result->usage->outputTokens;        // tokens generated by the model
echo $result->usage->totalTokens;         // inputTokens + outputTokens
echo $result->usage->reasoningTokens;     // reasoning tokens (nullable)
echo $result->usage->cachedInputTokens;   // cached prompt tokens (nullable)
A complete usage example:
$result = Generate::text('List three PHP best practices.')
    ->model(OpenAI::model('gpt-4o'))
    ->run();

printf(
    "In: %d  Out: %d  Total: %d\n",
    $result->usage->inputTokens,
    $result->usage->outputTokens,
    $result->usage->totalTokens,
);

Provider options passthrough

Every provider exposes model-specific knobs that aren’t part of the portable API. Pass them through with ->providerOptions(provider, options). The SDK forwards them verbatim to the provider without validation:
$result = Generate::text('Classify this review as positive or negative.')
    ->model(OpenAI::model('gpt-4o'))
    ->providerOptions('openai', [
        'logprobs'      => true,
        'top_logprobs'  => 5,
    ])
    ->run();

// Provider-specific data lives in providerMetadata
$logprobs = $result->providerMetadata['logprobs'] ?? null;
You can call ->providerOptions() multiple times for different providers on the same request. Repeated calls for the same provider are merged with array_replace_recursive:
$result = Generate::text('Hello')
    ->model(OpenAI::model('gpt-4o'))
    ->providerOptions('openai', ['store' => true])
    ->providerOptions('openai', ['metadata' => ['session' => 'abc123']])
    ->run();
Provider options are forwarded without validation. An unrecognised key will cause the upstream provider API to return an error.

Testing

aisdk/core ships with a FakeTextModel for deterministic unit tests — no HTTP calls required:
use AiSdk\Generate;
use AiSdk\Tests\Fakes\FakeTextModel;

$result = Generate::text('Hi')
    ->model(FakeTextModel::text('Hello!'))
    ->run();

expect($result->text)->toBe('Hello!');
expect($result->usage->inputTokens)->toBe(10);
expect($result->usage->totalTokens)->toBe(15);

Build docs developers (and LLMs) love