idpromogroup/laravel-openai-responses

Laravel package for standardizing OpenAI API responses

Maintainers

Package info

github.com/iljainc/laravel-openai-responses

pkg:composer/idpromogroup/laravel-openai-responses

Statistics

Installs: 55

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-05-29 08:23 UTC

This package is auto-updated.

Last update: 2026-05-29 08:23:48 UTC


README

A Laravel package for standardizing OpenAI API responses in your applications.

Installation

composer require idpromogroup/laravel-openai-responses

Usage

Basic Usage

use Idpromogroup\LaravelOpenaiResponses\Services\LorService;

$service = new LorService($externalKey, 'Your message here');
$result = $service->setModel('gpt-4o-mini')
    ->setInstructions('You are a helpful assistant')
    ->execute();

if ($result->success) {
    echo $result->data;
}

Working with Files

The package supports file attachments for analysis, processing, and discussion:

Supported file types:

  • Images: JPG, PNG, WEBP
  • Documents: PDF only

File type restrictions:

  • Only images (JPG/PNG/WEBP) and PDF files are accepted
  • Unsupported formats will be rejected with error message

Upload and Attach Local Files

$service = new LorService($externalKey, 'Analyze this document')
    ->setModel('gpt-4o-mini')
    ->attachLocalFile(storage_path('app/documents/report.pdf'));

$result = $service->execute();

Attach Already Uploaded Files

// Upload file first
$apiService = app(LorApiService::class);
$uploadResult = $apiService->uploadFile('/path/to/file.pdf', 'assistants');
$fileId = $uploadResult['id'];

// Then attach to conversation
$service = new LorService($externalKey, 'Discuss this file')
    ->attachFile($fileId)
    ->execute();

Attach Multiple Files

$service = new LorService($externalKey, 'Compare these documents')
    ->attachFileIds(['file_123', 'file_456'])
    ->attachLocalFile(storage_path('app/contract.docx'))
    ->execute();

Custom Tools for File Processing

$service = new LorService($externalKey, 'Extract data from spreadsheet')
    ->attachFile($fileId)
    ->execute();

Note:

  • Images are sent as input_image type to OpenAI
  • PDF files are sent as input_file type to OpenAI
  • Unsupported file formats will be rejected immediately

Using Templates

$service = new LorService($externalKey, 'Your message')
    ->useTemplate('analysis_template') // by name
    ->execute();

// Or by ID
$service->useTemplate(1);

Conversation Mode

$service = new LorService($externalKey, 'Hello')
    ->setConversation('user123')
    ->execute();

// Subsequent messages will continue the conversation
$service = new LorService($externalKey, 'Follow up question')
    ->setConversation('user123')
    ->execute();

Function Calls

Configure function handler in config/openai-responses.php:

'function_handler' => App\Services\MyFunctionHandler::class,

Your handler should implement the execute method:

class MyFunctionHandler
{
    public function execute(string $functionName, array $args)
    {
        switch ($functionName) {
            case 'get_weather':
                return $this->getWeather($args['location']);
            default:
                return ['error' => 'Unknown function'];
        }
    }
}

Advanced Configuration

$service = new LorService($externalKey, 'Your message')
    ->setModel('gpt-4o-mini')
    ->setInstructions('Custom instructions')
    ->setTemperature(0.7)
    ->setTools([
        ['type' => 'function', 'function' => [...]]
    ])
    ->setJSONSchema([
        'type' => 'object',
        'properties' => [...]
    ])
    ->execute();

File Upload API

Direct file upload to OpenAI:

use Idpromogroup\LaravelOpenaiResponses\Services\LorApiService;

$apiService = new LorApiService();
$result = $apiService->uploadFile('/path/to/file.pdf', 'assistants');

if ($result) {
    $fileId = $result['id'];
    // Use $fileId in subsequent requests
}

Supported file purposes:

  • assistants (default) - for Assistant API
  • fine-tune - for fine-tuning
  • batch - for batch processing

Usage and cost tracking

After each successful /v1/responses call, token counts and estimated USD costs are written to lor_request_logs: input_cost, cached_input_cost, output_cost, total_cost (migrations 2026_05_19_*, 2026_05_24_*). Prices come from config/openai-responses.php under prices (per 1M tokens; keys are model prefixes so gpt-4o-mini-2024-07-18 matches gpt-4o-mini).

  • Disable with OPENAI_RESPONSES_BILLING=false or billing.enabled in config.
  • If no price row matches the response model, tokens are still stored and cost columns stay null.

Billing context (optional, all nullable for backward compatibility):

$service->setBillingContext(billingSourceCode: 0, billingUser: 42) // codes defined by host app
    ->setApiKey($userOpenAiKey) // optional; default: template → config
    ->execute();

Stored on each log row: billing_source_code, billing_user, api_key_hash (sha256 of the key used, not the secret).

Query logs:

use Idpromogroup\LaravelOpenaiResponses\Facades\Lor;

$sum = Lor::usage()
    ->forExternalKey($externalKey)
    ->betweenDates(now()->startOfMonth(), now())
    ->whereNotNull('total_cost')
    ->sum('total_cost');

License

MIT License