kozmonos / vertex-ai
Vertex AI on-demand + batch pipeline for PHP
Package info
pkg:composer/kozmonos/vertex-ai
Requires
- php: ^8.3
- google/auth: ^1.47
- google/cloud-ai-platform: ^1.62
- google/cloud-storage: ^1.46
- guzzlehttp/guzzle: ^7.8
Requires (Dev)
- pestphp/pest: ^4.0
- phpstan/phpstan: ^2.0
README
Framework-agnostic Vertex AI client for PHP: on-demand Gemini/Imagen/Veo, Google Cloud TTS, Deepgram STT, and Vertex batch prediction jobs (JSONL + GCS).
Install
composer require kozmonos/vertex-ai
Published on Packagist. Path repositories are only needed when developing the package locally alongside a consuming app.
Configuration
Copy config/vertex-ai.php into your app or build VertexConfig::fromArray() manually:
use Kozmonos\VertexAi\Vertex\VertexConfig; $config = VertexConfig::fromArray(require 'vertex-ai.php', basePath: '/app');
Required for on-demand Vertex calls:
vertex.project_idvertex.credentials_path(service account JSON)
Required for batch:
vertex.batch.gcs_bucket
Outbound reference images
HTTP/HTTPS reference image downloads are denied unless you configure an allowlist:
'outbound' => [ 'allowed_hosts' => ['cdn.example.com'], ],
See SECURITY.md for the full hardening checklist.
On-demand text
use Kozmonos\VertexAi\Infrastructure\Auth\GoogleAuthTokenProvider; use Kozmonos\VertexAi\Infrastructure\Http\VertexHttpTransport; use Kozmonos\VertexAi\Support\AiModelRegistry; use Kozmonos\VertexAi\Vertex\VertexTextProvider; $registry = AiModelRegistry::fromDefaults(); $transport = new VertexHttpTransport($config, new GoogleAuthTokenProvider($config)); $text = new VertexTextProvider($transport, $registry); $result = $text->generateText( systemPrompt: 'You are helpful.', userPrompt: 'Say hello.', modelId: 'vertex-gemini-3.1-pro', );
On-demand video (Veo)
use Kozmonos\VertexAi\Support\HttpReferenceImageLoader; use Kozmonos\VertexAi\Vertex\VertexVideoProvider; $video = new VertexVideoProvider($transport, $registry, new HttpReferenceImageLoader($allowedHosts)); // Text → video $result = $video->generateVideo( prompt: 'A red balloon drifting over a city', modelId: 'veo-3.1-fast-vertex', durationSeconds: 4, options: [ 'aspect_ratio' => '16:9', 'storage_uri' => 'gs://my-bucket/veo-output/', ], ); // Image → video: HTTP/MinIO/data URIs are loaded via ReferenceImageLoader // (bytesBase64Encoded + mimeType). gs:// URIs are sent as gcsUri + mimeType. $result = $video->generateVideo( prompt: 'Slow camera push-in', modelId: 'veo-3.1-fast-vertex', durationSeconds: 4, options: [ 'source_image_url' => 'https://cdn.example.com/frame.png', // or: 'source_image_url' => 'gs://bucket/refs/frame.png', // or: 'source_image_base64' => $base64, 'source_image_mime_type' => 'image/png', ], );
Batch submit
use Kozmonos\VertexAi\Batch\Support\VertexBatchJsonl; use Kozmonos\VertexAi\Infrastructure\Batch\FakeBatchJobGateway; use Kozmonos\VertexAi\Infrastructure\Gcs\InMemoryGcsObjectStore; use Kozmonos\VertexAi\Vertex\VertexBatchService; $batch = new VertexBatchService($config, new InMemoryGcsObjectStore('my-bucket'), new FakeBatchJobGateway()); $submission = $batch->submitBatchJob( jsonlContent: VertexBatchJsonl::encode([['key' => 'line-1', 'request' => ['contents' => []]]]), modelResource: 'publishers/google/models/gemini-2.5-flash', displayName: 'my-batch', );
Gemini image batch requests keep Vertex safety filters enabled by default. Pass disableSafetyFilters: true to VertexBatchRequestBuilder::geminiImage() only when you explicitly need them disabled.
Usage recording
Wrap providers with Kozmonos\VertexAi\Usage\Recording\* and implement Kozmonos\VertexAi\Contracts\UsageRecorder, or use NullUsageRecorder in tests.
Tests
composer install
composer test
composer analyse
License
MIT. See LICENSE.