PHPackages                             avocet-shores/laravel-conduit - 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. avocet-shores/laravel-conduit

ActiveLibrary[API Development](/categories/api)

avocet-shores/laravel-conduit
=============================

Laravel Conduit offers a clean, unified API for working with multiple AI providers.

0.3.0(1y ago)1130[5 PRs](https://github.com/avocet-shores/laravel-conduit/pulls)MITPHPPHP ^8.3CI passing

Since Jan 22Pushed 1mo agoCompare

[ Source](https://github.com/avocet-shores/laravel-conduit)[ Packagist](https://packagist.org/packages/avocet-shores/laravel-conduit)[ Docs](https://github.com/avocet-shores/laravel-conduit)[ GitHub Sponsors]()[ RSS](/packages/avocet-shores-laravel-conduit/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (14)Versions (10)Used By (0)

Laravel Conduit
===============

[](#laravel-conduit)

[![Latest Version on Packagist](https://camo.githubusercontent.com/689baffb9413c20b810df73085f88a50ae3ceacd3827dae7bf3970e9385b19d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61766f6365742d73686f7265732f6c61726176656c2d636f6e647569742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/avocet-shores/laravel-conduit)[![GitHub Tests Action Status](https://camo.githubusercontent.com/b49e8057ba5ba6318c7739121db50e2b32b73656a2b764a77a426e611d514d1c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61766f6365742d73686f7265732f6c61726176656c2d636f6e647569742f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/avocet-shores/laravel-conduit/actions?query=workflow%3Arun-tests+branch%3Amain)[![Coverage Status](https://camo.githubusercontent.com/6072f36172deb151a684f3064deaf2e524cc6c6920f342086aacbc463bf2fd14/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f61766f6365742d73686f7265732f6c61726176656c2d636f6e647569743f7374796c653d666c61742d737175617265)](https://app.codecov.io/gh/avocet-shores/laravel-conduit/)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/06078270a4eba8c4257205faacc443dab092bc91f4048852f277d2d19b5118a3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61766f6365742d73686f7265732f6c61726176656c2d636f6e647569742f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/avocet-shores/laravel-conduit/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/2552e7f4d701611d3015b33ba7fd8a8ac8d783c385547c37e1b37471ad503cc3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f61766f6365742d73686f7265732f6c61726176656c2d636f6e647569742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/avocet-shores/laravel-conduit)

Why Conduit?
------------

[](#why-conduit)

Most AI packages today are tightly coupled with a single AI provider, locking you into their ecosystem (and their outages). Conduit offers a flexible, provider-agnostic solution that allows you to switch between providers without changing your code. You can even create custom drivers for your own AI services, all while maintaining a consistent API. Want to add OpenAI as a backup to your on-prem model in case of an outage? Just add a fallback:

```
$response = Conduit::make('on_prem_ai', 'my-model')
    ->withFallback('openai', 'gpt-4o')
    ->withInstructions('Write an inspirational message.')
    ->run();
```

Key Features
------------

[](#key-features)

- Unified API for various AI providers (Supports OpenAI and Amazon Bedrock out of the box, with more on the way)
- Automatic fallback to secondary drivers and/or models for improved reliability
- Easy extensibility: implement a simple interface to add custom drivers
- Pipeline-based middleware support
- Structured output and automatic JSON decoding

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

[](#installation)

1. You can install the package via composer:

    ```
    composer require avocet-shores/laravel-conduit

    ```
2. Optionally publish the configuration file:

    ```
    php artisan vendor:publish --provider="AvocetShores\Conduit\ConduitServiceProvider"

    ```

Basic Usage
-----------

[](#basic-usage)

Below is a typical usage example with the Conduit facade:

```
$response = Conduit::make('openai', 'gpt-4o')
    ->withInstructions(
        "Write a haiku about the user's input. " .
        'Return your response in the JSON format { "haiku": string }.'
    )
    ->addMessage('Laravel Conduit', Role::USER)
    ->withJsonOutput() // Automatically decodes the JSON into the response object
    ->run();

/**
 * Code flows in bridging
 * Weave AI in Laravel
 * Seamless paths converge
 */
echo $response->outputArray['haiku'];
```

1. Call the Conduit facade with `make('driver', 'model')`.
2. Provide optional instructions and messages.
3. Optionally enable jsonOutput to automatically decode the response.
4. Call `run()` to obtain a `ConversationResponse`.

### Setting a Fallback

[](#setting-a-fallback)

To ensure your application remains online if your primary provider fails, you can set a fallback driver and model:

```
use AvocetShores\Conduit\Enums\Role;

$response = Conduit::make('openai', 'gpt-4o')
    ->withFallback('amazon_bedrock', 'claude sonnet 3.5 v2')
    ->withInstructions('You are a helpful assistant.')
    ->addMessage('Hello from Conduit!', Role::USER)
    ->run();
```

When a server or rate limit error occurs, Conduit will automatically switch to the specified fallback provider and model, keeping your AI-driven features running.

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

[](#configuration)

Conduit's configuration file allows you to set up your provider-specific authentication variables.

### OpenAI

[](#openai)

To use OpenAI, you must provide your API key in the `.env` file:

```
OPENAI_API_KEY=your-api-key
```

### Amazon Bedrock

[](#amazon-bedrock)

To use Amazon Bedrock, you'll need to provide your AWS credentials in the `.env` file. By default, Conduit references the same `.env` variables as the AWS SDK and other AWS services, but you can always point them to your own custom variables by updating the `config/conduit.php` file.

```
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_DEFAULT_REGION=your-region
```

Advanced Usage
--------------

[](#advanced-usage)

### Structured Outputs

[](#structured-outputs)

> Currently only supported by some of OpenAI's models.
>
> Read more about structured outputs in [OpenAI's documentation](https://platform.openai.com/docs/guides/structured-outputs).

Certain drivers and models support specifying a complete schema that the model is then forced to adhere to. If your chosen driver/model supports it, you can enable structured output by passing a `Schema` into `enableStructuredOutput()`:

```
use AvocetShores\Conduit\Features\StructuredOutputs\Schema;

$response = Conduit::make('openai', 'gpt-4o')
    ->withInstructions('Please return a JSON object following the schema.')
    ->enableStructuredOutput(new Schema(/* ... */))
    ->run();
```

Conduit ensures that the schema request is formatted exactly how OpenAI expects, so your simple Schema definition:

```
new Schema(
    name: 'research_paper_extraction',
    description: 'Extract the title, authors, and abstract from a research paper.',
    properties: [
        Input::string('title', 'The title of the research paper.'),
        Input::array('authors', 'The authors of the research paper.', [Input::string()]),
        Input::string('abstract', 'The abstract of the research paper.')
    ]
);
```

...is automatically converted into the JSON format OpenAI requires:

```
{
    "response_format": {
        "type": "json_schema",
        "json_schema": {
            "name": "research_paper_extraction",
            "description": "Extract the title, authors, and abstract from a research paper.",
            "schema": {
                "type": "object",
                "properties": {
                    "title": {
                        "description": "The title of the research paper.",
                        "type": "string"
                    },
                    "authors": {
                        "type": "array",
                        "items": {
                            "description": "The authors of the research paper.",
                            "type": "string"
                        }
                    },
                    "abstract": {
                        "description": "The abstract of the research paper.",
                        "type": "string"
                    }
                },
                "required": [
                    "title",
                    "authors",
                    "abstract"
                ],
                "additionalProperties": false
            },
            "strict": true
        }
    }
}
```

#### What if my model doesn't support structured outputs?

[](#what-if-my-model-doesnt-support-structured-outputs)

You can still enjoy automatic json decoding by adding `withJsonOutput()` and defining your own schema somewhere within your prompt. It's important to note, however, that this will not enforce the schema on the AI model. You will need to validate the response yourself in a subsequent step:

```
$response = Conduit::make('openai', 'gpt-4o')
    ->withInstructions('Please return a JSON object in the format { "haiku": string }.')
    ->pushMiddleware(function (AIRequestContext $context, $next) {
        // Validate the response
        $response = $next($context);

        if (!isset($response->outputArray['haiku'])) {
            throw new Exception('The AI response did not match the expected schema.');
        }

        return $response;
    })
    ->withJsonOutput()
    ->run();
```

### Middleware and Pipelines

[](#middleware-and-pipelines)

Conduit uses Laravel’s Pipelines to provide you with a powerful extension system via middleware. You can add middleware by providing either a class that implements `MiddlewareInterface` or a closure:

```
$response = Conduit::make('openai', 'gpt-4o')
    ->pushMiddleware(function (AIRequestContext $context, $next) {
        // Example: remove SSN or credit card info from messages
        $messages = $context->getMessages();

        foreach ($messages as &$message) {
            $message->content = preg_replace('/\d{3}-\d{2}-\d{4}/', '[REDACTED_SSN]', $message->content);
            $message->content = preg_replace('/\b\d{16}\b/', '[REDACTED_CREDIT_CARD]', $message->content);
        }

        $context->setMessages($messages);

        // Continue down the pipeline
        return $next($context);
    })
    ->withInstructions('')
    ->run();
```

This can be useful for inspecting or modifying the AI request/response on its way through the pipeline. Or, for example, adding your own logging:

```
$response = Conduit::make('openai', 'gpt-4o')
    ->pushMiddleware(function (AIRequestContext $context, $next) {
        // Log the request
        Log::info('AI Request Messages: ', $context->getMessages());

        // Add some metadata
        $context->setMetadata('request_time', now());

        // Continue down the pipeline
        return $next($context);
    })
    ->pushMiddleware(function (AIRequestContext $context, $next) {
        // Run after the AI request is completed
        $response = $next($context);

        // Log the response and use the metadata from the previous middleware
        Log::info('AI Response: ', [
            'response' => $response->outputArray,
            'execution_time' => now() - $context->getMetadata('request_time')
        ]);

        return $response;
    })
    ->withInstructions('')
    ->run();
```

The `AIRequestContext` Object
-----------------------------

[](#the-airequestcontext-object)

The `AIRequestContext` object is passed through the pipeline to the designated driver, and contains all the data required for Conduit to handle the request. This includes the model, instructions, messages, responseFormat, and more. It also includes a blank slate `metadata` array for any additional data you wish to pass through the pipeline. You can access and modify this data as needed via its getter and setter methods.

If you're planning on creating your own driver, you'll need to familiarize yourself with the `AIRequestContext`object, as it's how you'll receive the data you need to make the AI request. Speaking of which...

### Adding Your Own Driver

[](#adding-your-own-driver)

Laravel Conduit is fully extensible to new or custom drivers. You only need to implement the `DriverInterface` and provide:

- A `run()` method to handle the AI request context.
- A return value of type `ConversationResponse`, ensuring a normalized data shape across drivers.

Finally, add your driver to the `drivers` array in the configuration file.

Example:

```
class MyCustomDriver implements DriverInterface
{
    public function run(AIRequestContext $context): ConversationResponse
    {
        // Make request to your custom AI service
        // Parse and return in a ConversationResponse
        return new ConversationResponse(
            outputArray: json_decode($response->getBody(), true)
        );
    }
}
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Jared Cannon](https://github.com/jared-cannon)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance70

Regular maintenance activity

Popularity14

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.4% 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 ~3 days

Total

4

Last Release

465d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8e39a4652a6267d9308f777fa82762f72a73d908a2525880e10fa67a1f0466e4?d=identicon)[jared-cannon](/maintainers/jared-cannon)

---

Top Contributors

[![jared-cannon](https://avatars.githubusercontent.com/u/60587282?v=4)](https://github.com/jared-cannon "jared-cannon (84 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

laravelAvocet Shoreslaravel-conduit

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/avocet-shores-laravel-conduit/health.svg)

```
[![Health](https://phpackages.com/badges/avocet-shores-laravel-conduit/health.svg)](https://phpackages.com/packages/avocet-shores-laravel-conduit)
```

###  Alternatives

[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.0k7.8M57](/packages/dedoc-scramble)[scalar/laravel

Render your OpenAPI-based API reference

6183.9k2](/packages/scalar-laravel)[ryangjchandler/bearer

Minimalistic token-based authentication for Laravel API endpoints.

8129.8k](/packages/ryangjchandler-bearer)[combindma/laravel-facebook-pixel

Meta pixel integration for Laravel

4956.9k](/packages/combindma-laravel-facebook-pixel)[stechstudio/laravel-hubspot

A Laravel SDK for the HubSpot CRM Api

2971.0k](/packages/stechstudio-laravel-hubspot)[njoguamos/laravel-plausible

A laravel package for interacting with plausible analytics api.

208.8k](/packages/njoguamos-laravel-plausible)

PHPackages © 2026

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