meirdick/laravel-cf-workersai

Cloudflare Workers AI provider for Laravel AI SDK with AI Gateway support.

Maintainers

Package info

github.com/meirdick/laravel-cf-workersai

pkg:composer/meirdick/laravel-cf-workersai

Statistics

Installs: 13

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-05-25 17:38 UTC

This package is auto-updated.

Last update: 2026-05-25 17:39:47 UTC


README

A native Laravel AI provider for Cloudflare Workers AI with first-class support for Cloudflare AI Gateway.

  • Text generation, embeddings, structured output, tool calling, streaming.
  • Three URL shapes: direct Workers AI, AI Gateway routed, or arbitrary /compat endpoint.
  • Reasoning content replay across tool-call turns.
  • #[Strict] JSON schema opt-in.
  • Provider options pass-through.
  • Sub-agent tools.
  • Retry policy and AI Gateway session affinity.

Requirements

  • PHP ^8.3
  • laravel/ai ^0.7

Installation

composer require meirdick/laravel-cf-workersai

The service provider auto-registers via package discovery. No manual wiring needed.

Configuration

Add a workers-ai provider to config/ai.php:

'providers' => [
    'workers-ai' => [
        'api_key'             => env('CLOUDFLARE_AI_API_KEY'),
        'account_id'          => env('CLOUDFLARE_ACCOUNT_ID'),
        'gateway'             => env('CLOUDFLARE_AI_GATEWAY'),  // optional
        // 'url'              => env('CLOUDFLARE_AI_URL'),      // optional escape hatch
        // 'default_max_tokens' => 4096,                        // override the package default
    ],
],

default_max_tokens

Cloudflare's /v1/chat/completions defaults to 256 tokens when max_completion_tokens is omitted — far too small for any non-trivial structured output, which then arrives mid-JSON with a misreported finish_reason: "stop". The package sends 4096 by default to defuse this. Override the value per-provider, or set it to null to fall back to Cloudflare's endpoint default. Per-call #[MaxTokens(...)] (or TextGenerationOptions::$maxTokens) always wins.

The package also normalizes Cloudflare's misreported stop-at-budget into FinishReason::Length so laravel/ai's length-aware retry primitives can react to truncated completions.

Endpoint resolution

There are three ways to configure the endpoint, in priority order:

  1. url (explicit). When set, all requests go to this URL. Useful for /compat or self-hosted gateways.
  2. account_id + gateway. Routes through https://gateway.ai.cloudflare.com/v1/<account_id>/<gateway>/workers-ai/v1/... — get AI Gateway's caching, retries, cost tracking.
  3. account_id only. Hits the direct Workers AI API at https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1/....

Quickstart

use function Laravel\Ai\agent;

$response = agent('helper')->prompt('Say hi.', provider: 'workers-ai');
echo $response->text;

Use any Workers AI model — pass it as model::

agent('helper')
    ->prompt('Summarize this in one sentence.', provider: 'workers-ai', model: '@cf/meta/llama-3.3-70b-instruct-fp8-fast');

Embeddings

use Laravel\Ai\Embeddings;

$vectors = Embeddings::for(['hello', 'world'])
    ->generate(provider: 'workers-ai', model: '@cf/baai/bge-base-en-v1.5');

Forward arbitrary fields with providerOptions:

Embeddings::for(['hello'])
    ->generate(provider: 'workers-ai', providerOptions: ['encoding_format' => 'base64']);

Streaming

foreach (agent('helper')->streamed('Tell me a story.', provider: 'workers-ai') as $event) {
    if ($event instanceof \Laravel\Ai\Events\TextDelta) {
        echo $event->text;
    }
}

Reasoning-capable models (e.g. Kimi K2.5) emit ReasoningStartReasoningDeltaReasoningEnd events before text.

Tools

use Laravel\Ai\Attributes\Tool;

#[Tool(description: 'Look up the current weather.')]
function getWeather(string $city): string
{
    return "Sunny in {$city}.";
}

agent('helper')->withTools([getWeather(...)])->prompt('Weather in Tokyo?', provider: 'workers-ai');

Reasoning content from the tool-call turn is preserved and replayed in the follow-up automatically (providerContentBlocks).

Structured output

use Laravel\Ai\Attributes\Strict;

#[Strict] // opt-in to strict JSON schema enforcement
final class TaskAgent extends \Laravel\Ai\Agent {}

When #[Strict] is applied, strict: true is forwarded to Workers AI's /compat endpoint and the generated JSON schema requires all properties.

AI Gateway

Set the gateway config key to route through Cloudflare AI Gateway. You get free caching, retries, cost analytics, and request logs in the Cloudflare dashboard.

'workers-ai' => [
    'api_key'    => env('CLOUDFLARE_AI_API_KEY'),
    'account_id' => env('CLOUDFLARE_ACCOUNT_ID'),
    'gateway'    => 'my-gateway',
],

A session-affinity header is sent automatically so successive related requests hit the same cache shard.

Models

Workers AI hosts dozens of open-weight models. See the Cloudflare Workers AI models catalog for current options. Common prefixes:

  • @cf/meta/... — Llama variants
  • @cf/openai/... — OpenAI open-weight models on Cloudflare
  • @cf/google/... — Gemma
  • @cf/qwen/..., @cf/mistralai/..., @cf/microsoft/..., etc.
  • @cf/baai/... — embedding models

Provider keys

The provider can be referenced as workers-ai (primary) or workersai (alias).

Versioning

This package follows Semantic Versioning. Pinned to laravel/ai ^0.7.

License

MIT