OpenAIProvider

Use OpenAI directly, or any OpenAI-compatible endpoint like OpenRouter, Ollama, or Cloudflare AI Gateway via a custom base URL.

OpenAIProvider is also the parent class for GeminiProvider and MistralProvider – both behave identically apart from base URL and default model.

Construction

public function __construct(
    ProviderConfig $config,
    ClientContract|null $client = null,
    Closure|null $sleep = null,
)
config
ProviderConfig
Resolved per-provider configuration (apiKey, model, baseUrl, timeout, plus a passthrough options bag).
client
ClientContract | null
Inject a custom OpenAI\Contracts\ClientContract (e.g. for tests). Defaults to the SDK client with the provider's timeout applied.
sleep
Closure | null
Inject a sleep function for retry timing. Defaults to PHP's built-in sleep(...).

Methods

generateObject

Builds a chat.completions request with response_format: { type: 'json_schema', strict: true }, sends it, and returns the decoded JSON object.

$provider->generateObject(
    messages: [
        ['role' => 'system', 'content' => 'Return JSON only.'],
        ['role' => 'user', 'content' => 'Pick three colors.'],
    ],
    schema: [
        'type' => 'object',
        'properties' => ['colors' => ['type' => 'array', 'items' => ['type' => 'string']]],
        'required' => ['colors'],
        'additionalProperties' => false,
    ],
);

Throws ProviderException when the decoded response is not a JSON object, or when the upstream call returns 4xx/5xx after the retry chain.

generateText

Sends a chat.completions request without response_format and returns the message content.

$provider->generateText(
    messages: [
        ['role' => 'user', 'content' => 'Describe three primary colors.'],
    ],
);

Throws ProviderException when the response carries no text content, or when the upstream call returns 4xx/5xx after the retry chain.

Retry Behavior

Rate limits (429), server errors (5xx), and network failures are retried up to three times, honoring Retry-After up to one minute; other 4xx errors and unreadable responses fail immediately.

A request that hits the timeout counts as a network failure and is retried like one.

A retried request may already have been completed and billed upstream before its socket was cut, so a stalling endpoint can cost more than one generation. Raise the timeout rather than lowering it where that matters.

Once the retries are exhausted, the provider throws ProviderException with the upstream error as previous, its HTTP status as httpCode, and the response body as responseExcerpt.

OpenAI-Compatible Endpoints

OpenAIProvider doubles as the transport for any OpenAI-compatible API. Configure the base URL and model in config.php:

'providers' => [
    'openai' => [
        'apiKey' => 'your-openrouter-api-key',
        'baseUrl' => 'https://openrouter.ai/api/v1',
        'model' => 'anthropic/claude-sonnet-5',
    ],
],

OpenAIProvider always calls Chat Completions – the api option applies to the Panel only.

Structured output through OpenAI-compat gateways depends on the gateway's json_schema translation. Test before relying on blocks or layout generation through this path.

Provider-Specific Options

Anything in providers.openai that isn't apiKey, model, baseUrl, completionModel, api, options, or timeout is forwarded with every request:

'providers' => [
    'openai' => [
        'apiKey' => 'your-openai-api-key',
        'reasoning_effort' => 'medium',
        'top_p' => 0.9,
    ],
],

The plugin doesn't validate option names – anything that doesn't match an OpenAI Chat Completions field is sent as-is and may be rejected upstream.