@pushpak1300 tagged v0.6.6 of laravel/ai with twelve merged pull requests. The changes span test coverage, correctness fixes, new generation parameters, and broader provider support for image generation.
@sumaiazaman added feature tests for the OpenAI transcription provider in PR #468 and audio in PR #471. Both were gaps in the test suite that could let regressions slip through undetected. These tests cover the request and response paths for each feature against the OpenAI gateway.
@Cbrad24 merged PR #301, fixing a bug where reasoning_id and reasoning_summary were silently dropped when replaying a conversation from the database.
OpenAI's reasoning models require both fields on replayed messages to maintain their chain of reasoning across turns. Without them, any multi-turn agent using o1, o3, or similar models would lose context on every restore. The fix carries both fields through the restore path the same way all other message data is handled.
@Duetro added top_p nucleus sampling as a first-class option in PR #306. Previously, temperature was the only sampling parameter exposed. Now both are available.
1use Laravel\Ai\Facades\Ai;2use Laravel\Ai\Attributes\TopP;3 4$response = Ai::text('Summarize this article.')5 ->withAttributes([new TopP(0.9)])6 ->generate();
@seankndy merged PR #420, allowing tools to declare their name through an optional name() method rather than relying solely on the class name. A shared ResolvesToolName trait backs this across all first-party gateways.
1class SearchTool implements Tool2{3 public function name(): string4 {5 return 'web_search';6 }7 8 // ...9}
This matters when you have multiple tool variants that need distinct names at runtime, or when class naming conventions do not map cleanly to what the model expects.
@mohali-id merged PR #461, extending the attributes carried on tool call objects when mapping assistant messages. The additional attributes fill in fields that were previously missing from the mapped representation, which could cause data loss when persisting or replaying multi-step agent runs.
@morcken merged PR #282. Arbitrary aspect ratios passed to the Gemini image gateway were being dropped instead of forwarded to the provider. Now they flow through to the request as-is, so provider-specific aspect ratio strings work without workarounds.
1use Laravel\Ai\Image;2use Laravel\Ai\Enums\Lab;3 4$response = Image::of('A mountain landscape')5 ->withAspectRatio('3:4')6 ->generate(provider: Lab::Gemini);
@billyfranklim1 merged PR #333, adding a new OpenRouterImageGateway that routes image generation through OpenRouter's /api/v1/chat/completions endpoint using modalities: ["image", "text"]. Before this, calling Image::of()->generate(provider: Lab::OpenRouter) threw a LogicException. The default model is google/gemini-2.5-flash-image.
1use Laravel\Ai\Image;2use Laravel\Ai\Enums\Lab;3 4$response = Image::of('A sunset over mountains')5 ->landscape()6 ->generate(provider: Lab::OpenRouter, model: 'google/gemini-2.5-flash-image');7 8$binary = $response->firstImage()->content();
ai.default@JoshSalway merged PR #327. If ai.default was set to an array instead of a string provider key, the package would fail with a cryptic type error. Now it throws a clear, actionable exception at configuration resolution time so the misconfiguration is obvious.
@Button99 merged PR #345, fixing incorrect handling of iterable conversational messages during text generation. Messages passed as iterables were not being unwrapped correctly, which could produce malformed requests to the underlying provider.
@maherelgamil merged PR #482. Both the OpenAI and Gemini image gateways now parse and surface token usage from their responses. This gives the same usage visibility for image generation that text generation already provides.
1$response = Image::of('A forest at dusk')->generate();2 3$usage = $response->usage();4echo $usage->inputTokens;5echo $usage->outputTokens;
@sumaiazaman merged PR #473, fixing a persistence bug where tool calls and results with non-sequential keys were encoded as JSON objects instead of JSON arrays. The fix reindexes both collections before serialization, which ensures the database always stores a proper array structure regardless of how the keys ended up.
Seven of the twelve contributors made their first contribution in this release: @Cbrad24, @Duetro, @seankndy, @mohali-id, @morcken, @billyfranklim1, and @JoshSalway. The full changelog covers every diff between v0.6.5 and v0.6.6.
If you enjoyed this article, please consider supporting our work for as low as $5 / month.
Sponsor
Written by
Writing and maintaining @LaravelMagazine. Host of "The Laravel Magazine Podcast". Pronouns: vi/vim.