sferra / delta
HTTP connection for AI providers OpenAI API Compatible with SSE stream type
Requires
- php: ^8.2
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
README
OpenAI-compatible SSE streaming client for PHP / Laravel.
Stream AI responses token-by-token via a clean, fluent API. Works with
any provider that exposes a /chat/completions endpoint.
Installation
composer require sferra/delta
Laravel will auto-discover the service provider. No manual registration needed.
Configuration
Publish the config file (optional):
php artisan vendor:publish --tag=delta-config
Or use environment variables:
DELTA_URL=http://localhost:8642/v1/chat/completions DELTA_KEY=my-api-key DELTA_MODEL=hermes-agent
Usage
Facade (Laravel)
use Sferra\Delta\Facades\Delta; $response = Delta::using( url: 'http://localhost:8642/v1/chat/completions', key: 'my-key', model: 'hermes-agent' )->stream( messages: [['role' => 'user', 'content' => 'What is PHP?']], onChunk: fn(string $chunk) => echo $chunk // real-time streaming );
Direct client
use Sferra\Delta\DeltaClient; $client = new DeltaClient( url: 'https://api.openai.com/v1/chat/completions', key: 'sk-...', model: 'gpt-4' ); $response = $client->stream( messages: [['role' => 'user', 'content' => 'Hello!']] ); echo $response; // complete response
Cancelling an in-flight stream
Pass a shouldCancel closure as the third argument. It is checked
before every byte read, so the stream aborts almost instantly when it
returns true. The partial content accumulated up to that point is
returned.
use Sferra\Delta\Facades\Delta; $shouldCancel = false; $response = Delta::stream( messages: [['role' => 'user', 'content' => 'Tell me a long story.']], onChunk: fn(string $chunk) => echo $chunk, shouldCancel: fn () => $shouldCancel ); // Later, from another part of the app (e.g. a Livewire cancel button): $shouldCancel = true;
Typical use case: a chat UI that needs to interrupt the AI when the
user clicks a "stop" button. In Livewire, point a public property at
the flag and bind the button with wire:click:
// SideChat.php (Livewire component) public bool $shouldCancel = false; public function cancelStream(): void { $this->shouldCancel = true; } #[On('sendToAI')] public function streamToAI(): void { $this->shouldCancel = false; Delta::stream( messages: $this->messages, onChunk: fn (string $chunk) => $this->stream('response', $chunk), shouldCancel: fn () => $this->shouldCancel ); }
Supported Providers
Any OpenAI-compatible API:
- Hermes Agent
- OpenCode
- Ollama
- OpenAI
- vLLM
- Custom
/chat/completionsendpoints
How It Works
Delta sends a POST request with stream: true and parses the SSE
(Server-Sent Events) response byte-by-byte, extracting
choices[0].delta.content from each chunk.
The $onChunk callback receives each text delta as it arrives,
enabling real-time streaming in Livewire components, console commands,
or any PHP application.
License
MIT