encurio/openai-service

A flexible OpenAI integration for Laravel

Maintainers

Package info

github.com/encurio/openai-service

pkg:composer/encurio/openai-service

Transparency log

Statistics

Installs: 55

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.18 2026-02-25 09:37 UTC

This package is auto-updated.

Last update: 2026-07-11 13:15:39 UTC


README

A Laravel package for working with OpenAI from application services.

The Responses API is now the recommended default for new implementations. Legacy Chat Completions and Assistants v2 Threads/Runs remain available for backward compatibility, but new projects should not build around Assistants/Threads.

Features

  • Responses API support for text, structured output, tools, conversation references, and model calls.
  • Conversation helper methods for the current OpenAI conversation model.
  • Legacy Chat Completions support.
  • Legacy Assistants v2 Threads/Runs support, marked as deprecated in code.
  • Embeddings, Moderations, Images, and Files helpers.
  • Per-request API key override through setProjectApiKey() or request options.

Installation

composer require encurio/openai-service

Configuration

Publish the config file when you want to customize defaults:

php artisan vendor:publish --tag=openai-config

Recommended .env configuration:

OPENAI_API_KEY=your_openai_project_key
OPENAI_DEFAULT_MODEL=gpt-4.1-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_IMAGE_MODEL=gpt-image-1
OPENAI_RETRIES=3
OPENAI_TIMEOUT=60

Backward-compatible keys still work, but should not be used for new projects:

OPENAI_API_KEY_COMPLETIONS=legacy_key
OPENAI_API_KEY_ASSISTANTS=legacy_key

Current recommended usage: Responses API

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::response([
    'model' => 'gpt-4.1-mini',
    'input' => 'Write a short SEO-friendly product description for a reusable coffee filter.',
    'instructions' => 'Write concise, factual ecommerce copy.',
    'max_output_tokens' => 300,
]);

print_r($response);

Structured output

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::response([
    'model' => 'gpt-4.1-mini',
    'input' => 'Extract the product name, material, and key benefit from: Stainless steel reusable coffee filter, dishwasher-safe, reduces paper waste.',
    'text' => [
        'format' => [
            'type' => 'json_schema',
            'name' => 'product_summary',
            'schema' => [
                'type' => 'object',
                'additionalProperties' => false,
                'properties' => [
                    'product_name' => ['type' => 'string'],
                    'material' => ['type' => 'string'],
                    'key_benefit' => ['type' => 'string'],
                ],
                'required' => ['product_name', 'material', 'key_benefit'],
            ],
        ],
    ],
]);

print_r($response);

Conversations

use Encurio\OpenAIService\Facades\OpenAI;

$conversationId = OpenAI::createConversation();

OpenAI::addConversationItem($conversationId, [
    'type' => 'message',
    'role' => 'user',
    'content' => [
        ['type' => 'input_text', 'text' => 'Remember that this customer prefers German invoices.'],
    ],
]);

$response = OpenAI::response([
    'model' => 'gpt-4.1-mini',
    'conversation' => $conversationId,
    'input' => 'Create the next customer support reply.',
]);

Images

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::image([
    'prompt' => 'A clean ecommerce product photo of a reusable stainless steel coffee filter on a white background.',
    'model' => 'gpt-image-1',
    'size' => '1024x1024',
    'quality' => 'high',
    'output_format' => 'png',
]);

print_r($response);

For GPT image models, the package no longer sends response_format=url by default. Pass response_format only when you intentionally use an older image model that supports it.

Embeddings

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::requestOpenAI([
    'type' => 'embedding',
    'model' => 'text-embedding-3-small',
    'input' => ['Your text to embed here'],
]);

print_r($response['data']);

Moderations

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::requestOpenAI([
    'type' => 'moderation',
    'input' => 'Text to classify for policy violations',
]);

print_r($response['results']);

Legacy Chat Completions

completion() and requestOpenAI(['type' => 'completion', ...]) remain available for existing projects.

use Encurio\OpenAIService\Facades\OpenAI;

$response = OpenAI::completion([
    'model' => 'gpt-4.1-mini',
    'messages' => [
        ['role' => 'user', 'content' => 'Tell me a joke.'],
    ],
    'temperature' => 0.9,
    'max_tokens' => 200,
]);

print_r($response);

Legacy Assistants v2 Threads/Runs

These methods remain in the package for backward compatibility, but are deprecated in code:

  • createThread()
  • appendMessageToThread()
  • startRun()
  • pollUntilRunComplete()
  • pollAndSubmitToolCalls()
  • getThreadMessages()
  • runThread()

Use response(), createConversation(), addConversationItem(), and listConversationItems() for new implementations.

Error handling

New Responses API methods throw OpenAIRequestException on HTTP or API failure. The exception exposes:

$exception->context();
$exception->status();
$exception->responseBody();
$exception->requestId();

Legacy requestOpenAI() keeps nullable failure behavior for backward compatibility.

License

This package is licensed under the MIT License.