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.

Every request to a text model is ultimately a list of Message objects. Each message has a role (user, assistant, system, or tool) and one or more Content parts. Content parts can be plain text, images, audio, or files — the SDK resolves the correct internal source representation automatically so you never have to manage base64 encoding by hand.

Message factory methods

Message is a final value object constructed exclusively through four static factories.

Message::system()

Injects a system prompt. Takes a plain string and wraps it in a single Content::text() part.
use AiSdk\Message;

$system = Message::system('You are a concise technical writer.');

Message::user()

Creates a user turn. Accepts either a plain string (converted to Content::text()) or an array of Content instances for multimodal input.
// Plain text
$message = Message::user('What is the capital of France?');

// Multimodal: image + follow-up question
$message = Message::user([
    Content::image('https://example.com/chart.png'),
    Content::text('Describe the trend shown in this chart.'),
]);

Message::assistant()

Represents a prior model turn, typically used when replaying conversation history. Optionally carries ToolCall objects from a previous agentic step.
$message = Message::assistant('The capital of France is Paris.');

Message::tool()

Records the result of a tool execution. The toolCallId must match the ID from the corresponding ToolCall the model emitted.
$message = Message::tool(
    toolCallId: 'call_abc123',
    output: '{"temperature": 18, "unit": "celsius"}',
    name: 'get_weather',
);

Content types

Content is a final value object with four static factories, each representing a different media type. All media content factories (image, audio, file) share the same signature:
Content::image(string|Stringable $source, ?string $mimeType = null, ?string $filename = null, ?InputEncoding $encoding = null): self
Content::audio(string|Stringable $source, ?string $mimeType = null, ?string $filename = null, ?InputEncoding $encoding = null): self
Content::file(string|Stringable $source,  ?string $mimeType = null, ?string $filename = null, ?InputEncoding $encoding = null): self

Content::text()

$part = Content::text('Summarise the following article:');

Content::image()

// From a public URL — no MIME type needed
$part = Content::image('https://example.com/diagram.png');

// From a local file path — MIME type auto-detected via mime_content_type()
$part = Content::image('/var/app/uploads/photo.jpg');

// From a raw base64 string — MIME type is required
use AiSdk\InputEncoding;

$part = Content::image(
    base64_encode(file_get_contents('/var/app/uploads/photo.jpg')),
    mimeType: 'image/jpeg',
    encoding: InputEncoding::Base64,
);

// From a data URI — MIME type extracted automatically
$part = Content::image('data:image/png;base64,iVBORw0KGgo=');

Content::audio() and Content::file()

These follow the same resolution rules as Content::image(). Use Content::audio() for models that support AudioInput and Content::file() for models that support FileInput.

ContentSource: how the SDK classifies input

ContentSource is a backed string enum used internally by Content to record how a piece of media arrived. You do not set it directly — the SDK’s resolveSource() logic picks the correct case based on what you pass in.
CaseValueWhen it is used
Text'text'Plain text content created via Content::text().
Url'url'A valid http:// or https:// URL.
DataUri'data_uri'A string beginning with data:.
Base64'base64'A string passed with InputEncoding::Base64.
Raw'raw'A readable file path (read into memory) or a raw binary string with a MIME type.
You can inspect the resolved source on a content part:
$part = Content::image('https://example.com/photo.jpg');

echo $part->source()->value; // 'url'
echo $part->url();           // 'https://example.com/photo.jpg'

InputEncoding

InputEncoding is a single-case backed enum used to signal that a string is already base64-encoded:
enum InputEncoding: string
{
    case Base64 = 'base64';
}
Without InputEncoding::Base64, a string that is not a URL, not a data URI, and not a readable file path is treated as raw binary and must be accompanied by a MIME type. Passing InputEncoding::Base64 tells the SDK to store the string as-is under ContentSource::Base64 and also requires a MIME type.
use AiSdk\Content;
use AiSdk\InputEncoding;

$part = Content::image(
    $base64String,
    mimeType: 'image/webp',
    encoding: InputEncoding::Base64,
);

Conversation history

Pass a full conversation history to ->messages() on a PendingTextRequest. This replaces any prompt previously set via ->prompt().
use AiSdk\Generate;
use AiSdk\Message;

$history = [
    Message::system('You are a helpful assistant.'),
    Message::user('What is 12 × 8?'),
    Message::assistant('12 × 8 is 96.'),
    Message::user('And divided by 4?'),
];

$result = Generate::text()
    ->messages($history)
    ->run();

echo $result->text; // "96 ÷ 4 is 24."
->messages() and ->prompt() both write to the same internal $messages array. ->prompt() appends a Message::user() to the array, while ->messages() replaces it entirely. Call ->instructions() to set a system instruction rather than prepending a Message::system() manually.

Multimodal message example

Here is a complete example that sends a user message containing both an image and a text question, alongside a system instruction:
use AiSdk\Content;
use AiSdk\Generate;
use AiSdk\Message;

$result = Generate::text()
    ->instructions('You are an expert data analyst.')
    ->messages([
        Message::user([
            Content::image('https://example.com/sales-chart-q3.png'),
            Content::text('Which month had the highest sales, and by how much did it exceed the average?'),
        ]),
    ])
    ->run();

echo $result->text;
When sending a local file you do not need to read it yourself — pass the absolute path to Content::image() (or Content::audio() / Content::file()) and the SDK will call file_get_contents() and auto-detect the MIME type via mime_content_type().
Content::image('https://cdn.example.com/image.jpg')
// source: Url
// url: 'https://cdn.example.com/image.jpg'

Build docs developers (and LLMs) love