Laravel AI v0.11.0 landed on August 19, 2026 with 36 merged pull requests and twelve first-time contributors. The headline change is observability: a single invocation ID now threads through an entire agent run, including failover attempts, and a set of lifecycle events reports what happens at every step.
Seven pull requests from @pushpak1300 rework run reporting. The synchronous prompt() path now mints the run-level invocation ID up front, matching the existing behavior of streamPrompt(); previously sync middleware saw a null ID, and a three-provider failover produced three unrelated IDs for one run. A new RunContext carries the run's identity and dispatches events directly, replacing per-provider callbacks. The tool invocation ID is now minted inside executeTool(), which fixes a nesting bug where an agent invoked as a tool overwrote the outer call's ID. Tools can read it via Request::toolInvocationId().
StartingStep, StepCompleted, and StepFailed fire around every provider round-trip on both the sync and streaming paths. StartingStep carries the messages, resolved options, and the full message history; the end events carry wall time in milliseconds, matching QueryExecuted::$time. ToolFailed reports a throwing tool handler with its invocation ID before the exception is rethrown, and AgentFailed reports a terminal failure exactly once per run, after the failover chain is exhausted. A tool call also publishes its IDs so any agent it prompts inherits them as parentInvocationId and parentToolInvocationId, though the link does not cross a queue boundary.
A new ToolSearch wrapper from @behzadsp defers large tool catalogues so OpenAI and Anthropic load them on demand through hosted search instead of shipping every tool definition on each request. Tools need no changes. The wrapper maps to {"type":"tool_search"} on OpenAI and to tool_search_tool_* types on Anthropic, whose search strategy is a constructor argument validated against regex and bm25. Unsupported providers throw before the request is sent; only one wrapper is allowed per request, and OpenAI hosted search requires stored responses, so using ToolSearch with store=false throws an exception. The same PR adds stateless output replay for OpenAI.
Failover now covers three failure classes it previously missed. ConnectionException cases, such as a downed host or a stopped local Ollama instance, are rethrown as a ProviderConnectionException implementing FailoverableException (@JVillator0). The overloaded-provider status list grew from 503 alone to 502, 503, 504, 520, 522, and 524, deliberately excluding 500 (@sulimanbenhalim), and Anthropic received the same treatment. Anthropic's HTTP 400 spend-cap rejections now also trigger failover after @oddvalue reported roughly 990 unhandled exceptions in a month from that case.
Provider support expanded: xAI gained web search and file search (@timmcleod), transcription arrived for OpenAI-compatible providers and Groq, OpenRouter supports the web fetch server tool (@CamilleScholtz), and Anthropic web fetch citations now appear on $response->meta->citations for non-streaming responses. Gemini's default text model moved to gemini-3.7-flash.
For testing, assertPromptedTimes() joins the Promptable fake assertions, working like Bus::assertDispatchedTimes() (@F1nnG), and faked queued generation of transcriptions, images, audio, and embeddings now runs the then(...) callback (@gdebrauwer).
Smaller fixes include summed streamed usage across tool-call steps, preserved OpenAI cache write tokens, excluded DeepSeek cache-hit tokens, filtering of partially orphaned tool calls during history replay, repair of unknown local tool calls, Mistral block-list content handling, mapped Anthropic refusal and model_context_window_exceeded stop reasons, stripped markdown fences in OpenAI-compatible structured output, S3 attachment reconstruction in File::fromArray, text/plain document sources on Anthropic, and a stable MCP request binding.
Upgrade notes: a provider error inside a stream body now throws a non-failoverable StreamErrorException instead of silently ending the step; the provider's error event is available on ->error. AgentFailedOver gained a required string $invocationId argument, ToolInvoked a required float $time, and AgentFailedOver no longer fires for the final provider in a chain. Applications relying on Gemini's default model will move to gemini-3.7-flash unless they pin the model explicitly. Upgrade with composer update laravel/ai.
Comments
No comments yet — be the first.
Open the discussion
No account or password needed — just enter your e-mail and we’ll send you a one-time sign-in link. First time here? You’re set up automatically.
Your rating will be applied automatically after you sign in.
Check your inbox
We’ve sent a sign-in link to …. Open it on this device — this tab will sign you in automatically.
Nothing arrived? Check your spam folder — and mark the mail as "Not spam" so it lands in your inbox next time.