meirdick / laravel-cf-workersai
Cloudflare Workers AI provider for the Laravel AI SDK: text, embeddings, reranking, images, speech, transcription, Clef decisions and Clairic typed extraction, with AI Gateway routing.
Requires
- php: ^8.3
- laravel/ai: ^0.9 || ^0.10 || ^0.11 || ^1.0
Requires (Dev)
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^3.0 || ^4.0
- pestphp/pest-plugin-laravel: ^3.0 || ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-11 07:53:49 UTC
README
Cloudflare Workers AI provider for the Laravel AI SDK: text, embeddings, reranking, images, speech, transcription, Clef decisions and Clairic typed extraction, with AI Gateway routing.
Docs: laravel-cf-workersai-docs.mdick85.workers.dev/docs
Install
composer require meirdick/laravel-cf-workersai
It needs PHP ^8.3 and laravel/ai ^0.9 || ^0.10 || ^0.11 || ^1.0, and it's tested on v0.9.1, v0.10.3, v0.11.2, v1.0.0 and v1.3.0. If you're on laravel/ai 0.7 or 0.8, use this package at ^0.5.
Laravel's package discovery registers the provider, so there's nothing to publish. Add your credentials to your application's .env file:
CLOUDFLARE_AI_API_TOKEN= CLOUDFLARE_ACCOUNT_ID= CLOUDFLARE_AI_GATEWAY= # optional
Then add the provider to config/ai.php, which reads those values:
'providers' => [ 'workers-ai' => [ 'driver' => 'workers-ai', 'key' => env('CLOUDFLARE_AI_API_TOKEN'), 'account_id' => env('CLOUDFLARE_ACCOUNT_ID'), 'gateway' => env('CLOUDFLARE_AI_GATEWAY'), // optional ], ],
The token needs the Account, Workers AI, Read permission. With account_id alone, the package calls Workers AI directly. Add gateway to send the same calls through an AI Gateway. url replaces both, and you can't set it together with account_id. If your gateway has authentication turned on, it also needs gateway_token. See Direct and gateway routes.
Text
use function Laravel\Ai\agent; $response = agent('You are a helpful assistant.') ->prompt('Say hi.', provider: 'workers-ai'); echo $response->text;
The default model is @cf/meta/llama-3.3-70b-instruct-fp8-fast, and you can pass model: to use another. When the call sets no token cap, the package sends 4096, because Cloudflare's own default is 256.
Decisions and extraction
Clef is Cloudflare's decision model. It answers Laravel AI classification questions with a probability, and it needs laravel/ai 1.0 or later.
use Laravel\Ai\Classification; use Laravel\Ai\Classification\Boolean; $response = Classification::of($ticket) ->question('urgent', new Boolean('Does this need a human now?')) ->classify(provider: 'workers-ai'); $response['urgent']->isTrue();
The default model is @cf/cloudflare/clef. You can also use clef-flash and clef-omni.
Clairic is Cloudflare's extraction model. Instead of picking from answers you list, it returns a typed value for each field you ask for, or null when the input doesn't say. It works on every supported laravel/ai version.
use Meirdick\WorkersAi\Extraction; use Meirdick\WorkersAi\Extraction\Number; use Meirdick\WorkersAi\Extraction\Text; $invoice = Extraction::of($text) ->fields([ 'invoice_number' => new Text, 'total' => new Number(decimals: 2, unit: 'USD'), ]) ->extract(); $invoice['total']->value();
Laravel AI has no extraction API, so the package adds Extraction. It works like Classification, with Extraction::fake(), assertExtracted(), events and provider failover. Clairic is still a Cloudflare preview model.
Both models work on the direct route and through a gateway, with the same provider entry. A url that ends in /compat can't serve them, so the package throws.
Images, audio, reranking, documents and search
These use Laravel AI's own APIs, plus a small addition where Laravel AI has none (Markdown and CloudflareWebSearch). They work on the direct route and through a gateway.
use Laravel\Ai\Audio; use Laravel\Ai\Files\Document; use Laravel\Ai\Image; use Laravel\Ai\Reranking; use Laravel\Ai\Transcription; use Meirdick\WorkersAi\Markdown; use Meirdick\WorkersAi\Tools\CloudflareWebSearch; Image::of('A green apple.')->landscape()->generate(provider: 'workers-ai'); Audio::of('Your order has shipped.')->generate(provider: 'workers-ai'); Transcription::fromPath($path)->generate(provider: 'workers-ai'); Reranking::of($documents)->limit(5)->rerank($query, provider: 'workers-ai'); Markdown::of(Document::fromPath('invoice.pdf'))->convert(); agent(tools: [new CloudflareWebSearch])->prompt($question, provider: 'workers-ai', model: '@cf/openai/gpt-oss-120b');
Why this package
Laravel AI's openai-compatible driver can already call a Workers AI /compat URL. That's enough if you only send text to one model and every agent sets #[MaxTokens].
Use this package when you also want a default token cap, an exception when a reasoning model returns nothing, reasoning_effort, neuron figures (Cloudflare bills Workers AI in neurons, not tokens), retries on HTTP 429 and Cloudflare edge errors, Authenticated Gateway, or Clef and Clairic.
The rest is in the docs:
- Quickstart
- Clef and Clairic
- Direct and gateway routes
- Reranking, images, speech and transcription, documents, web search
- AI Gateway
- Configuration
- Upgrade to 1.0
License
MIT