Laravel

Laravel AI SDK v1: What's New, What Breaks, and How to Upgrade

Abin Antony — Freelance Mobile App Developer Kerala Abin Antony
10 min read

Laravel released v1.0 of its AI SDK on 23 September 2026. The package, laravel/ai, gives a Laravel application one API for text, images, audio, embeddings, reranking and now classification, across OpenAI, Anthropic, Gemini, Azure, Bedrock, Groq, xAI, DeepSeek, Mistral, Ollama, OpenRouter and more. It has been in beta since earlier this year. The 1.0 tag means the API and, more importantly, the database schema for stored conversations are now meant to stay put.

I build Laravel backends and admin panels for client websites and for the mobile apps I ship, and most of those projects now include at least one AI feature. This post covers what the SDK does, what is new in 1.0, and what to check before upgrading from a 0.x beta.

What the Laravel AI SDK is

Before this package, adding AI to a Laravel app meant choosing a vendor SDK or a community wrapper, and switching providers later meant rewriting calls. The Laravel AI SDK sits in front of all of them. You describe an agent as a PHP class, with its instructions, tools and an optional structured-output schema, and prompt it the same way whichever provider answers. Conversations can be stored in your database, responses can be streamed or queued, and agents can be faked in tests like any other Laravel service.

Version 1.0 requires PHP 8.3 or later and supports Laravel 12 and 13.

Installing it

Shell
composer require laravel/ai
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan migrate

The migration creates the conversation tables. Provider keys go in your .env file, and the published config/ai.php decides which provider and model each capability uses by default. In 1.0 the default OpenAI model moved to GPT-6 and Anthropic's "smartest" default moved to Opus 5.5, so check that config if you care which model you are billed for.

Agents in one class

An agent is generated with php artisan make:agent and implements the Agent contract through the Promptable trait. Instructions, message history, tools and output schema are each a method:

PHP
<?php

namespace App\Ai\Agents;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;

class SalesCoach implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return 'You are a sales coach, analyzing transcripts and providing feedback and an overall sales strength score.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'feedback' => $schema->string()->required(),
            'score' => $schema->integer()->min(1)->max(10)->required(),
        ];
    }
}
PHP
$response = (new SalesCoach)->prompt('Analyze this sales transcript...');

return $response['score'];

Because the schema is declared once, the SDK asks each provider for structured output in whatever form that provider supports, and you read the result as an array. Tools are classes too, made with php artisan make:tool, each with a description, a JSON schema for its arguments and a handle() method.

Add the RemembersConversations trait and the SDK stores every turn for you. forUser($user) starts a conversation, continue($conversationId, as: $user) picks one up, and the new continueOrStart() does whichever applies, which removes an if/else from almost every chat controller.

New in 1.0: classification

Plenty of AI work in a real app is a decision rather than a piece of writing: is this message urgent, which team should get this ticket, is this contact-form entry spam? Running each of those through a general-purpose LLM is slow and costs more than it needs to. Version 1.0 adds classification as a capability of its own, backed today by TypeSafe's Jev models and by OpenRouter.

PHP
use Laravel\Ai\Classification;
use Laravel\Ai\Classification\Boolean;
use Laravel\Ai\Classification\Choice;
use Laravel\Ai\Classification\Score;

$response = Classification::of($ticket->body)->questions([
    'is_urgent' => new Boolean('Does this message convey urgency?'),
    'department' => new Choice('Which team should handle this?', [
        'billing' => 'Payments, invoicing, refunds',
        'technical' => 'Bugs, outages, integrations',
        'sales' => 'Pricing, plans, upgrades',
    ]),
    'frustration' => new Score('How frustrated is the customer?', [
        'Calm, stating facts', 'Frustrated but civil', 'Very angry',
    ]),
])->classify();

$response['is_urgent']->isTrue();
$response['department']->choice;         // 'technical'
$response['department']->probabilities;  // every option, scored
$response['frustration']->score;         // 0.0 to 1.0

For a single yes-or-no question there is now a decide macro on Str, with a threshold for how certain the model must be:

PHP
Str::of($message)->decide('Is this spam?');

Str::decide($message, 'Is this spam?', criteria: ['true' => 'Unsolicited bulk mail.'], threshold: 0.9);

This is the feature I expect to use most. Every business website with a contact form gets spam that slips past a honeypot and a CAPTCHA. The restaurant site I shipped this month already receives it. One Str::decide() call before a message is saved or emailed is a small change with a very visible payoff for the client.

New in 1.0: tools that wait for a human

Some tools should never run on the model's word alone: deleting a file, issuing a refund, sending an email to a customer. A tool can now implement the Approvable contract and use the InteractsWithApprovals trait. When the agent reaches for it, the run pauses instead of executing:

PHP
use Laravel\Ai\Concerns\InteractsWithApprovals;
use Laravel\Ai\Contracts\Approvable;
use Laravel\Ai\Contracts\Tool;

class DeleteFile implements Approvable, Tool
{
    use InteractsWithApprovals;

    // ...
}
PHP
$response = (new FileAssistant)
    ->forUser($user)
    ->prompt('Delete the old invoice.');

if ($response->hasPendingApprovals()) {
    foreach ($response->pendingApprovals as $approval) {
        // $approval->id, $approval->tool, $approval->arguments, $approval->reason
    }
}

You resume the conversation with a decision for each pending call. A decision can approve the call, reject it with a reason the model gets to read, or edit the arguments before the tool runs:

PHP
use Laravel\Ai\Approvals\Decision;
use Laravel\Ai\Approvals\Decisions;

$response = (new FileAssistant)
    ->continue($conversationId, as: $user)
    ->prompt(Decisions::from([
        'call_abc' => Decision::approve(),
        'call_ghi' => Decision::reject('The invoice must be retained.'),
    ]));

Approvals work with prompt, stream, queue and the broadcast methods. For an admin-panel assistant, this is the difference between a demo and something a client can safely be handed.

New in 1.0: middleware on every step

Agent middleware used to run once per prompt. It now wraps each generation step, so an agent that calls three tools before answering runs your middleware three times. Each step arrives as a PendingStep, which you can copy with changes. The official example takes an expensive tool away once the agent has already used it:

PHP
use Closure;
use Laravel\Ai\PendingStep;

public function handle(PendingStep $step, Closure $next)
{
    if (! $step->isFirstStep()) {
        $step = $step->withoutTools('SearchDocumentation');
    }

    return $next($step);
}

PendingStep also has withModel(), withInstructions(), withMessages(), withTools(), onlyTools(), withToolChoice(), withMaxTokens() and withProviderOptions(). That makes middleware the natural place for cost control: switch to a cheaper model after the first step, trim a long history, or return a cached answer without calling the provider at all.

New in 1.0: fewer tools per request, and code execution

An agent with 30 tools describes all 30 on every request. That costs tokens and makes the model worse at choosing. Wrap the rarely used ones in ToolSearch and the provider loads them only when a prompt needs them. It works with OpenAI and Anthropic:

PHP
use Laravel\Ai\Providers\Tools\ToolSearch;

public function tools(): iterable
{
    return [
        new Weather,
        new ToolSearch(tools: [
            new SearchInvoices,
            new RefundOrder,
        ]),
    ];
}

The new CodeExecution provider tool lets the model run code in the provider's own sandbox, which gives far more reliable answers for calculations and data analysis than asking a model to do arithmetic in its head. It is supported on Anthropic, OpenAI, Azure, Gemini and xAI.

PHP
use Laravel\Ai\Providers\Tools\CodeExecution;

public function tools(): iterable
{
    return [new CodeExecution];
}

New in 1.0: chat front-ends without glue code

The SDK now reads requests and streams responses in the Vercel AI SDK chat protocol and in AG-UI, the Agent User Interaction protocol used by clients such as CopilotKit. One route handles the new message, updates the stored conversation and processes any approval decisions the user submitted:

PHP
use Illuminate\Http\Request;
use Laravel\Ai\Vercel\Vercel;

Route::post('/chat', function (Request $request) {
    $chat = Vercel::chat($request);

    return (new SupportAgent)
        ->withMessages($chat->history())
        ->stream($chat)
        ->usingProtocol($chat->protocol());
});

Vercel::toUiMessages() turns stored messages back into the shape the client expects, so a chat screen can be rebuilt after a page reload. For AG-UI clients, call usingAgentUserInteractionProtocol() on the stream.

Breaking changes to check before you upgrade

If you built on a 0.x beta, the upgrade guide rates each change by likelihood of impact. These are the ones rated high:

Conversation storage. The tool_calls and tool_results columns on agent_conversation_messages are replaced by a single steps JSON column with one entry per model round trip, and approval_state is replaced by a status column (completed, paused or failed). The package's own migration will not run again, so you create a new migration from the backfill code in the upgrade guide. Resolve or abandon any turns waiting for tool approval first: pending turns cannot be resumed after their approval_state data is removed. Any raw SQL against the old columns has to move to steps.

Middleware. handle() now receives a PendingStep and must return the StepResponse produced by $next($step), and it runs once per step rather than once per prompt. Middleware that counted prompts or logged whole runs will now fire several times.

Token usage. promptTokens and completionTokens are now inputTokens and outputTokens, and the totals now include cached, cache-written and reasoning tokens. If you bill clients or set budgets from these numbers, price the categories separately. The upgrade guide gives this pattern:

PHP
$usage = $response->usage;

$cost = $usage->uncachedInputTokens() * $baseRate
    + ($usage->cacheReadInputTokens ?? 0) * $cacheReadRate
    + ($usage->cacheWriteInputTokens ?? 0) * $cacheWriteRate;

Existing rows in the usage column keep the old key names, so reporting code that reads history must handle both formats.

Bedrock and Gemini. The AWS SDK is no longer installed for you, so Bedrock users need composer require aws/aws-sdk-php. Gemini moved to its Interactions API, and Gemini vector-store addFile() now waits for the import to finish and returns a different ID than before.

Medium-impact changes include stream protocols becoming objects (usingVercelDataProtocol() no longer takes a boolean), resumed turns folding into the message they paused on, and sub-agent activity being streamed by default.

Letting an AI assistant do the upgrade

Laravel's own recommendation is to hand the upgrade to a coding assistant through Laravel Boost, its MCP server:

Shell
composer require laravel/boost --dev

php artisan boost:install

Then run the /upgrade-ai-sdk-v1 slash command in Claude Code, Cursor, OpenCode, Gemini or VS Code, and Boost walks the assistant through the guide one change at a time against your codebase. Whether or not you use it, run the backfill migration on a copy of production data first, and deploy the migration before the code that reads the steps column.

Should you adopt it now?

For a new Laravel project that needs AI, yes. The 1.0 label is mostly a promise about the conversations table, which was the hardest part to change later, and that shape is now settled. You get provider independence, database-backed conversations, streaming, queues and test fakes with little code of your own.

For an existing beta integration, the upgrade is worthwhile but not a composer update and done. Budget time for the conversation migration and for reviewing any middleware and cost reporting. Classification alone may justify the work, if your app makes lots of small yes-or-no decisions that currently go through a full LLM call.

If you have a Laravel app, a website or a mobile app backend that needs an AI feature, or a beta integration to bring up to 1.0, get in touch.

Frequently Asked Questions

What is the Laravel AI SDK? +

The Laravel AI SDK (the laravel/ai Composer package) is Laravel's official package for adding AI to an application. It gives one API for text, images, audio, embeddings, reranking and classification across providers including OpenAI, Anthropic, Gemini, Azure, Bedrock, Groq, xAI, DeepSeek, Mistral, Ollama and OpenRouter, with agents, tools, stored conversations, streaming, queueing and test fakes.

When was Laravel AI SDK v1.0 released? +

Version 1.0.0 of laravel/ai was released on 23 September 2026, after a beta that began earlier in the year.

What are the requirements for Laravel AI SDK v1? +

PHP 8.3 or later and Laravel 12 or 13. Bedrock users must now also install aws/aws-sdk-php themselves.

What is new in Laravel AI SDK v1.0? +

Classification with Boolean, Choice and Score questions plus a Str::decide() macro; approvable tool calls that pause for a human decision; agent middleware that runs on every generation step via PendingStep; ToolSearch for loading rarely used tools on demand; a CodeExecution provider tool; Vercel chat and AG-UI protocol support; conversations stored as steps; and unified inputTokens and outputTokens usage reporting.

What are the breaking changes in Laravel AI SDK v1.0? +

The main ones are: conversation messages now store a single steps column instead of tool_calls and tool_results, with a backfill migration to run; middleware receives a PendingStep and runs once per step; promptTokens and completionTokens are renamed inputTokens and outputTokens and now include cached and reasoning tokens; stream protocols are objects; the AWS SDK is no longer bundled; and Gemini moved to the Interactions API.

How do I upgrade to Laravel AI SDK v1? +

Follow the official upgrade guide in the laravel/ai repository, or install Laravel Boost (composer require laravel/boost --dev, then php artisan boost:install) and run the /upgrade-ai-sdk-v1 slash command in your AI coding assistant. Resolve pending tool approvals and run the conversation backfill migration before deploying code that reads the new steps column.

Laravel Laravel AI SDK AI PHP Agents
Abin Antony — Freelance Mobile App Developer Kerala
Abin Antony
Freelance Mobile App Developer · Kerala, India · 5+ years experience

Specialising in Flutter, React Native, and native iOS/Android development. I help startups and businesses turn ideas into polished, high-performance mobile apps.

Hire Abin