PHPackages                             iserter/laravel-uniformed-ai - 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. iserter/laravel-uniformed-ai

ActiveLibrary[API Development](/categories/api)

iserter/laravel-uniformed-ai
============================

Uniform AI API for Laravel (Chat, Images, Audio, Music, Search) across OpenAI, OpenRouter, Google AI Studio, KIE.AI, PIAPI.AI, Tavily, ElevenLabs, etc.

1.0.2(3mo ago)6846[1 PRs](https://github.com/iSerter/laravel-uniformed-ai/pulls)MITPHPPHP &gt;=8.2CI failing

Since Jan 23Pushed 1mo agoCompare

[ Source](https://github.com/iSerter/laravel-uniformed-ai)[ Packagist](https://packagist.org/packages/iserter/laravel-uniformed-ai)[ RSS](/packages/iserter-laravel-uniformed-ai/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (8)Versions (5)Used By (0)

Laravel Uniformed AI
====================

[](#laravel-uniformed-ai)

[![Laravel Uniformed AI](iserter-laravel-uniformed-ai.png)](iserter-laravel-uniformed-ai.png)

A Laravel package that exposes a single, uniform API over multiple AI providers (OpenAI, OpenRouter, Google AI Studio, Replicate.com, KIE.AI, PIAPI.AI, Tavily, ElevenLabs, etc.).

Features / Goals
----------------

[](#features--goals)

- Uniform Contracts for Chat, Images, Audio/Speech, Music, Video, and Web Search.
- Service Usage Logs &amp; Cost Measuring
- Clean DTOs for all requests/responses.
- Streaming &amp; (future) tool/function calling.
- Retries, rate limiting, caching, consistent error mapping.
- Easily extensible with custom providers.

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

[](#installation)

```
composer require iserter/laravel-uniformed-ai
```

Publish the config (optional to customize):

```
php artisan vendor:publish --tag=uniformed-ai-config
```

Set environment variables for any providers you will use:

```
OPENAI_API_KEY=...
OPENAI_CHAT_MODEL=gpt-4.1-mini
OPENAI_IMAGE_MODEL=gpt-image-1
OPENROUTER_API_KEY=...
GOOGLE_AI_API_KEY=...
TAVILY_API_KEY=...
ELEVENLABS_API_KEY=...
ELEVENLABS_VOICE_ID=Rachel
```

Quick Usage
-----------

[](#quick-usage)

```
use Iserter\UniformedAI\Facades\AI;
use Iserter\UniformedAI\Services\Chat\DTOs\{ChatMessage, ChatRequest};
use Iserter\UniformedAI\Services\Audio\DTOs\{AudioRequest, AudioTranscriptionRequest};
//...

// Chat
$response = AI::chat()->send(new ChatRequest([
    new ChatMessage('system', 'You are a helpful assistant.'),
    new ChatMessage('user', 'Write a haiku about Laravel.'),
]));

// Image
$img = AI::image()->create(new ImageRequest(prompt: 'A low-poly fox, 3D, studio light', size: '1024x1024'));
file_put_contents(storage_path('app/fox.png'), base64_decode($img->images[0]['b64']));

// On-the-fly provider override (bypasses configured default):
// Chat default may be openai, but call OpenRouter just for this request (streaming supported)
$or = AI::chat('openrouter')->send(new ChatRequest([
    new ChatMessage('user', 'Respond via OpenRouter only once.')
]));

// Image with named argument provider (works nicely with PHP named params)
$img2 = AI::image(provider: 'openai')->create(new ImageRequest(prompt: 'A serene lake at dawn'));

// Audio - Text-to-Speech (TTS)
$tts = AI::audio()->speak(new AudioRequest(text: 'Hello world from Laravel.', voice: 'Rachel', format: 'mp3'));
file_put_contents(storage_path('app/hello.mp3'), base64_decode($tts->b64Audio));

// Audio - Speech-to-Text (STT / Transcription)
$transcript = AI::audio()->transcribe(new AudioTranscriptionRequest(
    audioFile: storage_path('app/recording.mp3'),
    language: 'en'
));
echo $transcript->text; // "This is the transcribed text..."

// Audio transcription with base64 encoded audio
$transcript = AI::audio()->transcribe(new AudioTranscriptionRequest(
    audioFile: $base64AudioContent,
    isBase64: true,
    language: 'es'
));

// Search
$results = AI::search()->query(new SearchQuery('Latest on PHP 8.3 features', maxResults: 5));

// Video (placeholder drivers – not implemented yet; will throw ProviderException for now)
try {
    $video = AI::video()->generate(new VideoRequest(prompt: 'A serene flyover of a futuristic Laravel city', durationSeconds: 8));
    if ($video->hasUrl()) {
        file_put_contents(storage_path('app/clip.mp4'), file_get_contents($video->url));
    } elseif ($video->hasB64Video()) {
        file_put_contents(storage_path('app/clip.mp4'), base64_decode($video->b64Video));
    }
} catch (\Iserter\UniformedAI\Exceptions\ProviderException $e) {
    // Until implemented, this is expected.
}
```

Extending
---------

[](#extending)

```
app(\Iserter\UniformedAI\Services\Chat\ChatManager::class)->extend('myprovider', function($app) {
    return new \App\AI\Drivers\MyProviderChatDriver(config('services.myprovider'));
});
```

Provide a driver implementing the relevant Contract and map config / responses to the DTOs.

Testing
-------

[](#testing)

Uses Pest + Orchestra Testbench. Fakes HTTP calls via `Http::fake()` for provider payload shape + SSE streaming assertions (including mid-stream error events for OpenRouter).

Replicate chat support (prediction-based) is experimental: messages are flattened into a single prompt. Streaming &amp; tool calls for Replicate not yet implemented.

```
composer test
```

Roadmap
-------

[](#roadmap)

- Tool calling loop helper.
- JSON / function call modes.
- Multimodal attachments.
- Batching &amp; parallelism helpers.
- Observability (token usage + latency logs).

AI Operation Usage Logging (Observability)
------------------------------------------

[](#ai-operation-usage-logging-observability)

This package now includes an optional, privacy‑aware logging layer that records each AI operation (chat send/stream, image create/modify/upscale, audio speak, music compose, search query).

### Enable

[](#enable)

Enabled by default. Disable globally via:

```
SERVICE_USAGE_LOG_ENABLED=false
```

Publish migration &amp; config first (if not already):

```
php artisan vendor:publish --tag=uniformed-ai-config
php artisan vendor:publish --tag=uniformed-ai-migrations
php artisan migrate
```

### What Gets Logged

[](#what-gets-logged)

One row per operation with: provider, service\_type, service\_operation, model, status (success/error), latency\_ms, started/finished timestamps, sanitized request/response JSON, optional stream chunks, exception metadata on errors, and user\_id (if authenticated).

Secrets (API keys, tokens) are automatically redacted using pattern and heuristic detection. Large payload fields are truncated with a `...(truncated)` suffix.

### Key Config (excerpt)

[](#key-config-excerpt)

```
'logging' => [
    'enabled' => true,
    'queue' => ['enabled' => false], // turn on for lower latency
    'truncate' => [ 'request_chars' => 20000, 'response_chars' => 40000, 'chunk_chars' => 2000 ],
    'stream' => [ 'store_chunks' => true, 'max_chunks' => 500 ],
    'prune' => ['enabled' => true, 'days' => 30],
]
```

### Pruning

[](#pruning)

Old rows can be pruned via scheduled command:

```
php artisan ai-usage-logs:prune
```

Add to `app/Console/Kernel.php` schedule:

```
$schedule->command('ai-usage-logs:prune')->daily();
```

### Async Persistence

[](#async-persistence)

Set `SERVICE_USAGE_LOG_QUEUE=true` and configure your queue worker to offload insert work.

### Querying

[](#querying)

Use the `Iserter\UniformedAI\Models\ServiceUsageLog` model:

```
$errors = ServiceUsageLog::where('status','error')->latest()->limit(20)->get();
```

Future enhancements (tokens, cost, sampling, external sinks) will build on this foundation.

Catalog / Introspection
-----------------------

[](#catalog--introspection)

You can programmatically enumerate supported providers and curated model identifiers per service without hard‑coding them in your app. This is useful for building dynamic admin panels or select dropdowns.

```
use Iserter\UniformedAI\Facades\AI;

// Full catalog (service => provider => models[])
$catalog = AI::catalog();
// e.g. $catalog['chat']['openai'] contains: ['gpt-4.1-mini','gpt-4.1','gpt-4o-mini','o3-mini']

// List available chat providers
$providers = AI::chat()->getProviders(); // ['openai','openrouter','google','kie','piapi']

// List curated models for a provider
$models = AI::chat()->getModels('openai');

// Unknown provider returns an empty array (no exception)
$none = AI::chat()->getModels('does-not-exist'); // []

// Iterate to render a UI select
foreach (AI::catalog()['chat'] as $provider => $models) {
    // render option group for $provider with $models
}

// Video catalog enumeration (new)
foreach (AI::catalog()['video'] as $provider => $models) {
    // render video model options
}
```

The list is a curated static set (Phase 1). Future versions may allow config overrides or dynamic discovery.

License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance85

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

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 ~3 days

Total

3

Last Release

102d ago

### Community

Maintainers

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

---

Top Contributors

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

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/iserter-laravel-uniformed-ai/health.svg)

```
[![Health](https://phpackages.com/badges/iserter-laravel-uniformed-ai/health.svg)](https://phpackages.com/packages/iserter-laravel-uniformed-ai)
```

###  Alternatives

[skagarwal/google-places-api

Google Places Api

1913.0M8](/packages/skagarwal-google-places-api)[dcblogdev/laravel-microsoft-graph

A Laravel Microsoft Graph API (Office365) package

168285.5k1](/packages/dcblogdev-laravel-microsoft-graph)[vluzrmos/slack-api

Wrapper for Slack.com WEB API.

102589.1k3](/packages/vluzrmos-slack-api)[smodav/mpesa

M-Pesa API implementation

16363.7k1](/packages/smodav-mpesa)[jasara/php-amzn-selling-partner-api

A fluent interface for Amazon's Selling Partner API in PHP

1344.8k1](/packages/jasara-php-amzn-selling-partner-api)[grantholle/powerschool-api

A Laravel package to make interacting with PowerSchool less painful.

1715.6k1](/packages/grantholle-powerschool-api)

PHPackages © 2026

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