PHPackages                             meirdick/laravel-cf-workersai - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. meirdick/laravel-cf-workersai

ActiveLibrary[API Development](/categories/api)

meirdick/laravel-cf-workersai
=============================

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

v0.6.0(2w ago)0535—2.5%[1 PRs](https://github.com/meirdick/laravel-cf-workersai/pulls)MITPHPPHP ^8.3CI passing

Since May 25Pushed 2w agoCompare

[ Source](https://github.com/meirdick/laravel-cf-workersai)[ Packagist](https://packagist.org/packages/meirdick/laravel-cf-workersai)[ RSS](/packages/meirdick-laravel-cf-workersai/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (12)Versions (11)Used By (0)

laravel-cf-workersai
====================

[](#laravel-cf-workersai)

A native [Laravel AI](https://github.com/laravel/ai) provider for [Cloudflare Workers AI](https://developers.cloudflare.com/workers-ai/) with first-class support for [Cloudflare AI Gateway](https://developers.cloudflare.com/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 and MCP tools.
- Streamed usage summed across tool-call steps.
- Retry policy and AI Gateway session affinity.
- Failover-ready: 429/402/502/503/504 map to laravel/ai's failoverable exceptions.

Requirements
------------

[](#requirements)

- PHP `^8.3`
- `laravel/ai ^0.9`

Need `laravel/ai ^0.7 || ^0.8`? Use `meirdick/laravel-cf-workersai ^0.5`. Version 0.6 migrates the gateway to laravel/ai 0.9's single-step `StepTextGateway` contract; the multi-step tool loop now runs in the SDK's `TextGenerationLoop`.

Installation
------------

[](#installation)

```
composer require meirdick/laravel-cf-workersai
```

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

Configuration
-------------

[](#configuration)

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

```
'providers' => [
    'workers-ai' => [
        'key'                 => env('CLOUDFLARE_AI_API_TOKEN'),
        '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
    ],
],
```

`key` is a Cloudflare API token with the `Workers AI: Read` permission, matching the credential key name every first-party laravel/ai provider uses. The `api_key` name from earlier releases of this package is still accepted as a fallback.

### `default_max_tokens`

[](#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

[](#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///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//ai/v1/...`.

Quickstart
----------

[](#quickstart)

```
use function Laravel\Ai\agent;

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

Use any [Workers AI model](https://developers.cloudflare.com/workers-ai/models/) — 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
----------

[](#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 `withProviderOptions` (named `providerOptions()` before laravel/ai 0.9):

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

Streaming
---------

[](#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 `ReasoningStart` → `ReasoningDelta` → `ReasoningEnd` events before text.

Tools
-----

[](#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`).

### Model choice matters for tool calling

[](#model-choice-matters-for-tool-calling)

Verified live against the production API (2026-06-11): **`@cf/meta/llama-3.3-70b-instruct-fp8-fast` — the package's default text model — does not emit tool calls** on the `/v1` endpoint; it answers in prose instead. `@cf/meta/llama-4-scout-17b-16e-instruct` and `@cf/openai/gpt-oss-120b` tool-call correctly, but under `tool_choice: auto` open-weight models only *choose* to call a tool some of the time. When the tool must run, force it via provider options:

```
public function providerOptions(Lab|string $provider): array
{
    // Custom drivers arrive as a plain string, not a Lab enum case.
    return $provider === 'workers-ai' ? ['tool_choice' => 'required'] : [];
}
```

The package automatically relaxes a forced `tool_choice` back to `auto` on tool-result follow-up turns — otherwise the model is forced to call a tool again instead of answering, looping until max-steps with empty text.

Timeouts
--------

[](#timeouts)

laravel/ai resolves a **60-second timeout** by default. Large models, structured output, and reasoning models on Workers AI can exceed it — observed live: a structured `llama-3.3-70b` request taking 60s+, and `kimi-k2.6` taking 45s on a small prompt. Raise it per agent or per call:

```
use Laravel\Ai\Attributes\Timeout;

#[Timeout(120)]
class ExtractionAgent implements Agent { /* ... */ }

// or per call:
$agent->prompt('...', provider: 'workers-ai', timeout: 120);
```

A request that exceeds the timeout fails after a single attempt with a `ConnectionException`. (Before v0.3.0 the retry policy re-ran timed-out requests, turning a 60s timeout into ~3 minutes of wall time before failing.) Connect-phase failures and transient 502/503/504 responses are still retried with backoff.

Structured output
-----------------

[](#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.

Reasoning models
----------------

[](#reasoning-models)

Some Workers AI models (Kimi K2.5/K2.6, QwQ, Gemma) emit a chain of thought before their answer. Following the laravel/ai convention — the same one used to pass Anthropic `thinking` or Gemini `thinkingConfig` — reasoning is controlled through `HasProviderOptions`, not a dedicated attribute. The returned options are merged into the request body verbatim. Kimi uses `chat_template_kwargs.thinking`:

```
use Laravel\Ai\Contracts\HasProviderOptions;
use Laravel\Ai\Enums\Lab;

class AnalysisAgent implements Agent, HasProviderOptions
{
    public function providerOptions(Lab|string $provider): array
    {
        // Workers AI is a custom driver, so $provider arrives as the string.
        return $provider === 'workers-ai'
            ? ['chat_template_kwargs' => ['thinking' => false]]
            : [];
    }
}
```

**Disabling reasoning** (`thinking => false`) is the right default for structured-output and extraction work: reasoning is incompatible with `response_format` (the model spends its token budget thinking instead of conforming to the schema) and roughly triples latency. Verified live on Kimi K2.6 — structured calls return valid JSON in ~4s with thinking off versus busting both the schema and the 60s timeout with it on.

**Enabling reasoning** (`thinking => true`) suits free-form, latency-tolerant judgment tasks. The package then:

- captures the model's reasoning (under either the `reasoning_content` or the K2.6 `reasoning` field) and replays it across tool-call turns so multi-step tool loops stay coherent;
- raises `max_completion_tokens` to a **2048 floor** when it would otherwise be lower, so the model isn't starved of answer tokens after reasoning (a small budget returns `content: null` / `finish_reason: "length"`). Pair it with a raised `#[Timeout]` (see above).

AI Gateway
----------

[](#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' => [
    'key'        => env('CLOUDFLARE_AI_API_TOKEN'),
    '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
------

[](#models)

Workers AI hosts dozens of open-weight models. See the [Cloudflare Workers AI models catalog](https://developers.cloudflare.com/workers-ai/models/) 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
-------------

[](#provider-keys)

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

Versioning
----------

[](#versioning)

This package follows [Semantic Versioning](https://semver.org/). Version 0.6+ requires `laravel/ai ^0.9` (the single-step `StepTextGateway` contract); use `^0.5` of this package for `laravel/ai ^0.7 || ^0.8`.

License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance97

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

6

Last Release

14d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f0407fad46cce273ed6b210601247b4b73a060bda91eba8f8f144a3850a49d48?d=identicon)[meirdick](/maintainers/meirdick)

---

Top Contributors

[![meirdick](https://avatars.githubusercontent.com/u/3604649?v=4)](https://github.com/meirdick "meirdick (4 commits)")

---

Tags

laravelaicloudflarelaravel-aiworkers-aiai-gateway

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/meirdick-laravel-cf-workersai/health.svg)

```
[![Health](https://phpackages.com/badges/meirdick-laravel-cf-workersai/health.svg)](https://phpackages.com/packages/meirdick-laravel-cf-workersai)
```

###  Alternatives

[hosseinhezami/laravel-gemini

A production-ready Laravel package to integrate with the Google Gemini API. Supports text, image, video, audio, long-context, structured output, files, caching, function-calling and understanding capabilities.

14015.5k1](/packages/hosseinhezami-laravel-gemini)[claude-php/claude-php-sdk-laravel

Laravel integration for the Claude PHP SDK - Anthropic Claude API

5223.2k](/packages/claude-php-claude-php-sdk-laravel)[thehocinesaad/stability-laravel

Stability Laravel is a comprehensive Laravel API client designed for seamless interaction with the Stability AI API.

111.3k](/packages/thehocinesaad-stability-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
