PHP Luminova: OpenAI Client Integration
Use OpenAI in Luminova for image generation, editing, speech, transcription, vision analysis, and fine-tuning. Includes clear PHP examples and usage patterns.
The Luminova OpenAI client (Luminova\AI\Client\OpenAI) wraps the OpenAI REST API and provides a clean interface for text generation, embeddings, image generation, text-to-speech, audio transcription, fine-tuning, and file management.
This guide focuses on OpenAI-specific methods and usage within Luminova.For shared AI features and client implementation, see: Base AI Class (Luminova\Base\AI).
To get started with OpenAI, refer to the official API documentation:https://platform.openai.com/docs/api-reference
Usages
Instantiation
use Luminova\AI\Client\OpenAI;
$client = new OpenAI(
apiKey: env('OPENAI_KEY'),
organization: 'org-abc123', // Optional
project: 'proj-xyz', // Optional
);Via Application Config
Set handler = 'OpenAI' in App\Config\AI and use the AI manager:
use Luminova\AI\AI;
$reply = AI::message('Hello from the config-driven client!');Text Generation
Single Message
$reply = $client->message('Explain quantum entanglement simply.');
echo $reply[0]['text'] ?? '';Chat Completion (Multi-Turn)
$reply = $client->chat([
['role' => 'system', 'content' => 'You are a helpful PHP tutor.'],
['role' => 'user', 'content' => 'What is a trait?'],
['role' => 'assistant', 'content' => 'A trait is a reusable set of methods...'],
['role' => 'user', 'content' => 'Can traits have properties?'],
]);
echo $reply[0]['text'] ?? '';With Options
$reply = $client->chat('Write a haiku about the ocean.', [
'model' => 'gpt-4.1',
'max_tokens' => 64,
'temperature' => 0.8,
]);Text Completion (generate)
generate() delegates to message() for OpenAI:
$response = $client->generate('List 5 PHP best practices.');
print_r($response);Web Search
Attach the built-in web_search_preview tool to retrieve AI-synthesised answers sourced from the live web.
$results = $client->webSearch('Latest PHP 8.4 features');
print_r($results);Embeddings
Generate vector embeddings for semantic search, clustering, or RAG pipelines.
Single Embedding
$vector = $client->embed('The quick brown fox');
// Returns a flat float array: [0.012, -0.034, ...]Batch Embeddings
$vectors = $client->embed(['Hello world', 'Hi there']);
// Returns an array of float arrays
use Luminova\AI\AI;
$similarity = AI::compareCosineVector($vectors[0], $vectors[1]);
echo $similarity; // e.g. ~0.97With Options
$vector = $client->embed('Some text', [
'model' => 'text-embedding-3-large',
'dimensions' => 512,
]);Image Generation
Basic Generation
$images = $client->image('A serene mountain lake at sunset, oil painting style.');
echo $images[0]['url'] ?? '';Multiple Images
$images = $client->image('A futuristic city skyline at night, digital art.', [
'model' => 'dall-e-3',
'size' => '1024x1024',
'response_format' => 'url',
'n' => 2,
]);
foreach ($images as $img) {
echo $img['url'] . PHP_EOL;
}Image Editing (Inpainting)
Pass an edits array with a source image and optional mask. Transparent areas in the mask will be replaced by the model.
$results = $client->image('Replace the sky with a dramatic sunset.', [
'size' => '1024x1024',
'edits' => [
'image' => '/path/to/original.png', // Max 4 MB PNG
'mask' => '/path/to/mask.png', // Max 4 MB PNG, transparent = editable
],
]);
echo $results[0]['url'] ?? '';Vision (Image Understanding)
Analyze an Image by URL
$content = $client->vision(
'Describe what you see in this image.',
'https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg'
);
echo $content[0]['text'] ?? '';Analyze a Local File
$content = $client->vision(
'Is there any text in this screenshot? If so, transcribe it.',
'/tmp/screenshot.png',
['model' => 'gpt-4.1']
);
echo $content[0]['text'] ?? '';Compare Two Images
$content = $client->vision(
'Which of these two logos is more recognizable and why?',
[
'https://example.com/logo-a.png',
'https://example.com/logo-b.png',
]
);With Detail Level
$content = $client->vision(
'Identify any defects on this product.',
'/tmp/product.jpg',
['detail' => 'high']
);Text-to-Speech (TTS)
Converts text to audio and saves it locally. Returns the public URL of the saved file.
$url = $client->speech('Welcome to Luminova!', [
'voice' => 'nova', // alloy, echo, fable, onyx, nova, shimmer
'speed' => 1.0,
'model' => 'gpt-4o-mini-tts',
'path' => '/var/www/html/audio', // Optional save directory
]);
echo $url; // https://example.com/audio/6789abc.mp3With Symlink (Public Serving)
$url = $client->speech('Hello, world!', [
'symlink' => 'public/audio',
]);Audio Transcription
Transcribe audio files to text using Whisper.
$text = $client->audio(
'Transcribe this meeting recording.',
'/tmp/meeting.mp3',
[
'model' => 'whisper-1',
'language' => 'en',
]
);
echo $text;With SRT Output
$srt = $client->audio('', '/tmp/interview.mp3', [
'response_format' => 'srt',
]);Fine-Tuning
From a JSONL File
$job = $client->fineTune('my-assistant', '/path/to/training.jsonl', [
'model' => 'gpt-4.1-mini',
]);
$jobId = $job['id'];
echo 'Job started: ' . $jobId;From a Structured Dataset
fineTuneDataset() handles JSONL conversion automatically.
$job = $client->fineTuneDataset([
['input' => 'What is your name?', 'output' => 'I am Lumi.'],
['input' => 'Who made you?', 'output' => 'Nanoblock Technology Ltd.'],
], [
'suffix' => 'lumi-v1',
'model' => 'gpt-4.1-mini',
]);Checking Fine-Tune Status
$status = $client->fineTuneStatus($job['id']);
if ($status['status'] === 'succeeded') {
$modelName = $status['fine_tuned_model'];
echo 'Model ready: ' . $modelName;
}File Management
Upload a File
$fileId = $client->upload('/path/to/training.jsonl', 'fine-tune');
echo 'Uploaded file ID: ' . $fileId;List Files
$files = $client->files(['purpose' => 'fine-tune']);
foreach ($files as $file) {
echo $file['id'] . ' — ' . $file['filename'] . PHP_EOL;
}Get File Metadata
$meta = $client->file('file-abc123');
echo $meta['filename'];Download File Content
// Stream to string
$content = $client->download('file-abc123');
// Save to disk
$ok = $client->download('file-abc123', '/tmp/downloaded.jsonl');Delete a File
$deleted = $client->delete('file-abc123');
var_dump($deleted); // bool(true)Listing Models
$models = $client->models();
foreach ($models as $model) {
echo $model['id'] . PHP_EOL;
}Get a Specific Model
$info = $client->model('gpt-4.1-mini');
print_r($info);Error Handling
use Luminova\Exceptions\AIException;
try {
$reply = $client->message('Hello!');
} catch (AIException $e) {
echo 'OpenAI Error: ' . $e->getMessage();
}Class Definition
- Full namespace:
\Luminova\AI\Client\OpenAI - Parent class: Luminova\Base\AI
- Implements: \Luminova\Interface\AIClientInterface
Properties
endpoints
OpenAI API endpoints.
protected array $endpoints = [
'responses' => 'responses',
'models' => 'models',
'images' => 'images',
'speech' => 'audio/speech',
'transcribe' => 'audio/transcriptions',
'embeddings' => 'embeddings',
'fineTune' => 'fine_tuning/jobs',
'files' => 'files',
];Methods
constructor
Create a new OpenAI client instance.
public __construct(string $apiKey, ?string $organization = null, ?string $project = null): mixedParameters:
| Parameter | Type | Description |
|---|---|---|
$apiKey | string | OpenAI secret API key (sk-…). |
$organization | string|null | Optional organization ID (org-…). |
$project | string|null | Optional project ID. |
Example:
use Luminova\AI\Client\OpenAI;
$client = new OpenAI(apiKey: env('OPENAI_KEY'), organization: 'org-abc123');
$reply = $client->message('Hello, OpenAI!');
App\Config\AIFor default application AI configuration.
upload
Upload a local file to OpenAI's file store.
public upload(string $filename, string $purpose = 'fine-tune', array $options = []): string|nullReturns the file ID string on success, which can be used as the$dataset argument in fineTune().
Parameters:
| Parameter | Type | Description |
|---|---|---|
$filename | string | Absolute path to the local file. |
$purpose | string | Upload purpose. Accepted values: fine-tune, assistants,batch, vision. Default fine-tune. |
$options | array | Additional request parameters. |
Return Value:
string|null - Uploaded file ID, or null on failure.
Throws:
- \Luminova\Exceptions\RuntimeException - If the file does not exist or is empty.
Example:
$fileId = $client->upload('/path/to/training.jsonl');
$job = $client->fineTune('my-model', $fileId);files
List all files uploaded to the OpenAI file store.
public files(array $options = []): arrayParameters:
| Parameter | Type | Description |
|---|---|---|
$options | array | Optional query parameters (e.g. ['purpose' => 'fine-tune']). |
Return Value:
array - Array of file objects.
Example:
$files = $client->files(['purpose' => 'fine-tune']);
foreach ($files as $file) {
echo $file['id'] . ' — ' . $file['filename'] . PHP_EOL;
}file
Retrieve metadata for a single uploaded file.
public file(string $fileId, array $options = []): arrayParameters:
| Parameter | Type | Description |
|---|---|---|
$fileId | string | File ID returned by upload(). |
$options | array | Optional query parameters. |
Return Value:
array - File metadata object.
Example:
$meta = $client->file('file-abc123');
echo $meta['filename']; // training.jsonldownload
Download the raw content of an uploaded file.
public download(string $fileId, ?string $saveTo = null): string|boolWhen $saveTo is provided, the content is written to that path andtrue is returned on success. When omitted, the raw content stringis returned directly.
Parameters:
| Parameter | Type | Description |
|---|---|---|
$fileId | string | The uploaded file ID. |
$saveTo | string|null | Optional absolute path to save the file content. |
Return Value:
string|bool - Raw content string, true if saved to disk, or false on failure.
Example:
// Stream to string
$content = $client->download('file-abc123');
// Save to disk
$ok = $client->download('file-abc123', '/tmp/downloaded.jsonl');delete
Delete an uploaded file from the OpenAI file store.
public delete(string $fileId): boolParameters:
| Parameter | Type | Description |
|---|---|---|
$fileId | string | File ID to delete. |
Return Value:
bool - Returns true if the file was successfully deleted.
Example:
$deleted = $client->delete('file-abc123');