← Selected work

Case study

Provider gateways - laravel/ai

Thirty-seven merged pull requests into Laravel's official AI SDK

Period
2026 - present
Role
Contributor
Stack
PHP 8 · Pest · OpenAI · Anthropic · Gemini · Mistral · Cohere · DeepSeek · Ollama · xAI · OpenRouter · Azure OpenAI · ElevenLabs · Jina · Voyage AI
Live
github.com/laravel/ai

The problem

laravel/ai is the framework's official SDK for models, embeddings, transcription and image generation. It talks to thirteen providers, and every one of them fails differently: different status codes, different error shapes, different ideas about what a "usage" object contains. An SDK that works in the demo and breaks when a provider runs out of credit is not one you can ship a product on. Most of my work has been on the unhappy paths.

What I changed

Failover that actually fails over. Added HandlesFailoverErrors to the Cohere, Jina and Voyage AI gateways so a provider error is classified and passed to the next provider in the list instead of surfacing as an exception (#423, #424). Made the model attribute and an explicitly requested model apply to every provider in a failover list, not just the first (#633).

Errors with names. OpenRouter and DeepSeek report exhausted credit as an ordinary client error. I added a typed InsufficientCreditsException so an application can catch the one thing it can actually do something about (#606).

Honest accounting. Captured the usage details several OpenAI-shaped providers were dropping, so token accounting is correct across vendors (#610).

Conversations that survive a reload. Attachments are rehydrated when history loads (#587); tool calls and results are re-indexed before persisting so they encode as JSON arrays rather than objects (#473); the conversation store respects a configured database connection (#469, #589).

Dead streams tell you they died. When a BroadcastAgent job fails, a stream_failed event is broadcast instead of the client waiting forever (#536).

Tests for every gateway. Feature test suites for embeddings, transcription, image generation and error handling across OpenAI, Gemini, Mistral, Ollama, Azure, xAI, DeepSeek, Cohere, Jina, ElevenLabs and Voyage AI. The pattern is the same every time: fake the provider's worst response, assert the SDK's best behaviour.

Why it matters

GEEKY AIQ, which scans a brand's visibility across several models on a schedule, is built on exactly these patterns. Contributing them upstream meant I did not have to maintain them alone.