Search by

saifulferoz / laravel-ai-realtime

saifulferoz

Realtime speech-to-speech voice sessions and WebRTC ephemeral credentials for Laravel AI

Package info

github.com/saifulferoz/laravel-ai-realtime

pkg:composer/saifulferoz/laravel-ai-realtime

Statistics

Installs: 22

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.0 2026-08-24 16:15 UTC

This package is not auto-updated.

Last update: 2026-11-03 15:58:00 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads License

Realtime speech-to-speech voice sessions and WebRTC ephemeral credential generation for Laravel AI (laravel/ai).

Supports OpenAI (POST /v1/realtime/client_secrets) and Azure OpenAI (POST /openai/v1/realtime/client_secrets) GA APIs.

๐Ÿš€ Architecture

[ Frontend / Mobile App ]
         โ”‚
         โ”‚ 1. Request session credentials
         โ–ผ
[ Laravel App (Control Plane) ] โ”€โ”€ (laravel-ai-realtime) โ”€โ”€โ–บ [ OpenAI / Azure ]
         โ”‚                                                      (Mints Ephemeral Token)
         โ”‚ 2. Returns short-lived client_secret (token)
         โ–ผ
[ Frontend / Mobile App ]
         โ”‚
         โ”‚ 3. Direct bidirectional audio stream (WebRTC / Data Plane)
         โ–ผ
[ OpenAI / Azure Realtime Server ]  (< 300ms latency, zero PHP server load)
  1. Security: Your master API key remains private on your backend server. Laravel mints a short-lived ephemeral client token (client_secret).
  2. Performance: Voice media streaming connects directly from client (browser/native app) to OpenAI/Azure via WebRTC, bypassing PHP processes and avoiding proxy bottlenecks.

๐Ÿ“ฆ Installation

composer require saifulferoz/laravel-ai-realtime

๐Ÿ› ๏ธ Usage

1. Using the realtime(...) Helper

use function Laravel\Ai\agent;
use function LaravelAi\Realtime\realtime;

$agent = agent(
    instructions: 'You are a warm customer service agent for ACME.',
    tools: [new LookupOrderTool],
);

// Generate ephemeral session credentials for WebRTC client
$session = realtime($agent, voice: 'alloy');

return response()->json([
    'client_secret' => $session->clientSecret(),
    'expires_at' => $session->expiresAt(),
    'session_id' => $session->id(),
]);

2. Using the Realtime Facade

use LaravelAi\Realtime\Facades\Realtime;

$session = Realtime::createSession(
    provider: 'openai',
    model: 'gpt-realtime',
    instructions: 'You are an airline customer support voice agent.',
    voice: 'marin',
    modalities: ['text', 'audio'],
    options: [
        'turn_detection' => ['type' => 'server_vad'],
        'output_audio_format' => 'pcm16',
    ]
);

return response()->json([
    'token' => $session->clientSecret(),
    'expires_at' => $session->expiresAt(),
]);

3. Using the HasRealtimeSession Trait in Class Agents

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
use LaravelAi\Realtime\Concerns\HasRealtimeSession;

class SupportAgent implements Agent
{
    use Promptable;
    use HasRealtimeSession;

    public function instructions(): string
    {
        return 'You are an intelligent support assistant.';
    }
}

// In Controller:
$agent = new SupportAgent();
$session = $agent->realtime(voice: 'alloy');

๐Ÿงช Testing and Fakes

Testing real-time voice credential endpoints is simple with Realtime::fake():

use LaravelAi\Realtime\Facades\Realtime;

test('voice session controller returns ephemeral credentials', function () {
    Realtime::fake([
        'id' => 'sess_fake_123',
        'value' => 'ek_fake_secret_token',
        'expires_at' => 1790000000,
    ]);

    $response = $this->postJson('/api/voice/session');

    $response->assertOk()
        ->assertJson([
            'client_secret' => 'ek_fake_secret_token',
        ]);

    Realtime::assertCreated(function ($prompt, $provider) {
        return $provider === 'openai';
    });
});

๐Ÿ“„ License

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