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():
| Method | Type | Default | Description |
|---|
->maxTokens(int) | int | 1024 | Maximum number of tokens in the model’s response. |
->temperature(float) | float | 1.0 | Sampling temperature. Lower values produce more deterministic output; higher values increase creativity. |
->topP(float) | float | null | Nucleus sampling cutoff. Use instead of — not alongside — temperature. |
->maxSteps(int) | int | 1 | Maximum 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);