laravel-ai-realtime maintained by saifulferoz
Laravel AI Realtime
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)
- Security: Your master API key remains private on your backend server. Laravel mints a short-lived ephemeral client token (
client_secret). - 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.