Download the PHP package ez-php/ai without Composer
On this page you can find all versions of the php package ez-php/ai. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package ai
ez-php/ai
Multi-provider AI client for ez-php. Supports chat completions, streaming, tool calling, and embeddings across OpenAI, Anthropic, Gemini, Mistral, and Grok.
Installation
Requires PHP 8.5 and ez-php/http-client.
Configuration
Register AiServiceProvider in your application and add config/ai.php:
Driver options
AI_DRIVER value |
Description |
|---|---|
openai |
OpenAI chat completions API |
anthropic |
Anthropic Messages API |
gemini |
Google Gemini generateContent API |
mistral |
Mistral AI (OpenAI-compatible) |
grok |
xAI Grok (OpenAI-compatible) |
log |
Decorates another driver with error_log output |
null |
Returns empty responses; useful in tests |
Environment variables
| Variable | Default | Description |
|---|---|---|
AI_DRIVER |
null |
Active driver |
AI_STREAM_IDLE_TIMEOUT |
120 |
Seconds a stream may send nothing before it fails |
OPENAI_API_KEY |
— | OpenAI API key |
OPENAI_MODEL |
gpt-4o-mini |
Default OpenAI model |
OPENAI_BASE_URL |
https://api.openai.com |
Base URL (Azure / proxy support) |
ANTHROPIC_API_KEY |
— | Anthropic API key |
ANTHROPIC_MODEL |
claude-sonnet-4-6 |
Default Anthropic model |
ANTHROPIC_API_VERSION |
2023-06-01 |
anthropic-version header value |
GEMINI_API_KEY |
— | Google AI API key |
GEMINI_MODEL |
gemini-2.0-flash |
Default Gemini model |
MISTRAL_API_KEY |
— | Mistral API key |
MISTRAL_MODEL |
mistral-small-latest |
Default Mistral model |
MISTRAL_BASE_URL |
https://api.mistral.ai |
Mistral base URL |
GROK_API_KEY |
— | xAI (Grok) API key |
GROK_MODEL |
grok-3-mini |
Default Grok model |
GROK_BASE_URL |
https://api.x.ai |
Grok base URL |
AI_LOG_INNER_DRIVER |
openai |
Driver wrapped by the log driver |
Basic usage
Static facade
Direct driver injection
Building requests
AiRequest is immutable. All wither methods return new instances.
Messages
Streaming
Drivers that implement StreamingAiClientInterface support streaming responses.
All five production drivers (OpenAI, Anthropic, Gemini, Mistral, Grok) implement StreamingAiClientInterface.
Chunks arrive while the provider is still generating. stream() returns once the provider has answered with headers, so authentication, quota and model errors still throw AiRequestException there.
While iterating, AiStreamException signals a stream that cannot complete — the connection dropped or went silent, the provider sent an error event (providerErrorType() holds e.g. overloaded_error), or the stream ended without the provider's completion signal:
A stream holds its connection open until it is consumed or dropped — iterate it right away rather than keeping AiStream objects around.
AI_STREAM_IDLE_TIMEOUT (default 120 s) is how long a stream may send nothing before it fails; there is no total limit.
Forwarding a stream to the browser
toSseEvents() emits event: token with {"content": …} per chunk and a final event: done
with {"finish_reason": …}. Payloads are JSON, so newlines in model output cannot break SSE framing.
If the stream fails mid-way, StreamedResponse::sse() sends a generic event: error frame and reports the exception; closing the browser tab closes the provider connection.
Tool calling
Define tools, attach them to the request, and handle tool calls in a loop.
Gemini note: Gemini does not assign separate IDs to tool calls. The function name is used as the call ID. Use the function name as
toolCallIdin tool result messages for Gemini conversations.Streaming + tool calling: Tool calls are only parsed in
complete(). Thestream()path yields text chunks only.
Embeddings
AiServiceProvider wires embeddings through the Ai facade too, via a config key
independent of ai.driver (several completion providers — Anthropic, Mistral, Grok — have
no embeddings API, so it can't be derived from the completion driver):
Or use OpenAiEmbeddingDriver/GeminiEmbeddingDriver directly, without the facade:
| Driver | Default model | Endpoint |
|---|---|---|
OpenAiEmbeddingDriver |
text-embedding-3-small |
POST /v1/embeddings |
GeminiEmbeddingDriver |
text-embedding-004 |
POST /v1beta/models/{model}:embedContent |
Response object
Logging decorator
Wrap any driver to log every request and response via error_log:
Or construct LogDriver manually with a custom logger closure:
Retry decorator
Wrap any client to retry transient failures (HTTP 429 rate limits and 5xx server
errors) with exponential backoff. Non-retryable 4xx errors (other than 429) are
re-thrown immediately. On a 429, a retry_after field in the response body
overrides the computed backoff delay when present.
complete() is the only method — RetryAiClient implements AiClientInterface
directly, so it composes with any other decorator (e.g. LogDriver) or the Ai
facade the same way an undecorated driver does.
AI variant pool
AiVariantPool is a database-backed pool of AI-generated text variants for a
given cache key — useful for content that should vary between requests (e.g.
flavor text, item descriptions) without calling the AI provider on every read.
Variants are stored in a flat table (cache_key, content, created_at); the
table must exist before use (see the class docblock for the recommended schema).
OpenAI-compatible proxies and Azure
OpenAiDriver and MistralDriver accept a base_url config key, making them compatible with Azure OpenAI and any OpenAI-compatible proxy:
Testing
In unit tests, inject NullDriver or use FakeTransport from ez-php/http-client:
Use Ai::resetClient() in tearDown() when tests touch the static facade to prevent state leaking between test cases.
Quality suite
Start the development shell:
All versions of ai with dependencies
ez-php/http Version ^2.0
ez-php/http-client Version ^2.0
ez-php/contracts Version ^2.0