Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Client Laravel Package

google-gemini-php/client

Community-maintained PHP API client for Google's Gemini AI API. Send text, image, video, and audio prompts, hold multi-turn chats, stream responses, call functions, generate images and speech, and manage files and cached content.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Requirements

    • PHP 8.2+ is now required as of 2.8.0. Projects still on PHP 8.1 will stay on 2.7.x.
    • Confirm your app runs PHP 8.2 or newer before upgrading:
      php -v
      composer require php:^8.2
      
  2. Installation

    composer require google-gemini-php/client:^2.8.0
    

    Verify composer.json resolves to 2.8.0 and that CI uses PHP 8.2+.

  3. First Request Initialize the client with your API key from Google AI Studio:

    use Google\Gemini\Client;
    
    $client = new Client(config('services.gemini.key'));
    
  4. Basic Usage

    $response = $client->generateText('What is Laravel?');
    echo $response->getText();
    
  5. Where to Look First

    • src/Client.php: core client wiring.
    • src/Resources/: new API surfaces, including structured output, tools, and file search stores.
    • src/Tools/: tool integrations (file search, maps, server-side tools).
    • README.md: refreshed in 2.8.0 with current model names and examples.
    • src/Exceptions/: error classes, including the new ErrorException behavior for streamed 5xx responses.

Implementation Patterns

Workflows

  1. Structured Output with JSON Schema Use JSON Schema for structured generation:

    $response = $client->generativeModel('gemini-2.0-flash')
        ->withResponseSchema([
            'type' => 'object',
            'properties' => [
                'title' => ['type' => 'string'],
                'tags'  => ['type' => 'array', 'items' => ['type' => 'string']],
            ],
            'required' => ['title', 'tags'],
        ])
        ->generateContent('Summarize this article.');
    
  2. Function Declarations with JSON Schema Define callable functions with typed schemas:

    $model = $client->generativeModel('gemini-2.0-flash')
        ->withFunctionDeclaration(
            name: 'get_weather',
            description: 'Get the current weather for a city',
            parameters: [
                'type' => 'object',
                'properties' => [
                    'city' => ['type' => 'string'],
                ],
                'required' => ['city'],
            ],
        );
    
    $response = $model->generateContent('Weather in Paris?');
    
  3. Multimodal Function Responses Return media from a function call:

    $response = $model->generateContent(
        new FunctionResponse(
            name: 'get_weather',
            response: ['temperature' => 21],
            parts: [new Part(data: $imageBytes, mimeType: 'image/png')],
        ),
    );
    
  4. Server-Side Tool Invocations Use tools executed by Gemini itself:

    $response = $client->generativeModel('gemini-2.0-flash')
        ->withTools([new GoogleSearch()])
        ->generateContent('Latest Laravel release?');
    
  5. File Search Stores Upload and track files:

    $operation = $fileSearchStore->importFile('files/abc123');
    $operation = $fileSearchStore->getOperation($operation->name);
    

    Note: file names with the files/ prefix are now accepted.

  6. Per-Part Media Resolution and Image Size Control media resolution per part and image output size:

    $part = new Part(data: $imageBytes, mimeType: 'image/png')
        ->withMediaResolution(MediaResolution::High);
    
    $config = new ImageConfig();
    $config->imageSize = '1024x1024';
    
  7. Streaming Responses

    $response = $client->generateText('Explain Laravel', ['stream' => true]);
    foreach ($response->stream() as $chunk) {
        echo $chunk->getText();
    }
    

    Failed streamed requests with a 5xx JSON error body now throw ErrorException, matching non-streamed requests.

  8. Multi-Turn Chats ClientFake::startChat() now supports multi-turn and streamed chats for tests:

    ClientFake::fake();
    $chat = $client->startChat();
    $chat->sendMessage('Hello');
    $chat->sendMessage('Continue');
    

Integration Tips

  • Laravel Service Provider

    $this->app->singleton(Client::class, fn ($app) =>
        new Client(config('services.gemini.key'))
    );
    
  • Queues for Long Operations Use jobs for importFile() / getOperation() polling:

    dispatch(new PollFileSearchOperation($operationName));
    
  • Testing with ClientFake

    ClientFake::fake([
        new GenerateContentResponse(...),
    ]);
    
    $chat = $client->startChat();
    $chat->sendMessage('Hi');
    
  • Error Handling

    try {
        $response = $client->generateText('Risky prompt');
    } catch (Google\Gemini\Exception\ErrorException $e) {
        // Stream and non-stream 5xx now converge here.
    }
    
  • Response Metadata Inspect new metadata fields:

    $response->responseId;
    $response->modelStatus;
    $response->finishMessage;
    $response->urlContextMetadata;
    $response->serviceTier;
    

Gotchas and Tips

Pitfalls

  1. PHP 8.2 Upgrade

    • 2.8.0 drops PHP 8.1. Update composer.json, Docker images, and CI matrices together to avoid partial upgrades.
  2. Streamed Error Handling Changed

    • Streamed 5xx responses with a JSON error body now throw ErrorException instead of TransporterException. Update catch blocks and retry middleware.
  3. Chat History Shape Changed

    • streamSendMessage() now preserves thoughts, function calls, and tool calls as separate parts, including thoughtSignature. This fixes streamed function-call turns but $chat->history[$i]->parts may differ from before. Avoid strict assertions on chat history structure.
  4. Quick Accessor Error Messages

    • text() and parts() ValueError messages now include the finish or block reason. Update tests that assert exact exception messages.
  5. File Search Names

    • The files/ prefix is now accepted in file names, so normalize names before storage to avoid duplicates.
  6. Usage Metadata

    • Usage metadata without totalTokenCount is now accepted. Don’t assume the field always exists.
  7. Logprobs Token IDs

    • Logprob candidate token IDs are now serialized. If you persist or compare candidates, expect the token_id field.
  8. Wrapped API Errors

    • API errors returned wrapped in a list are now detected. If you previously worked around array-wrapped error payloads, remove the workaround.
  9. Rate Limits and Quotas

    • Tool-based features (file search, maps, server-side tools) may have separate quotas. Implement exponential backoff and monitor usage.
  10. API Key Exposure

    • Never hardcode keys. Use .env and restrict key permissions in Google Cloud Console:
      GEMINI_API_KEY=your_key_here
      

Debugging

  • Verbose Logging

    $client = new Client(config('services.gemini.key'), [
        'debug'  => true,
        'logger' => new \Monolog\Logger('gemini'),
    ]);
    
  • Common Errors

    Error Class Cause Fix
    InvalidArgumentException Malformed prompt or schema Validate prompt and JSON Schema
    Google\Gemini\Exception\AuthError Invalid API key Check .env
    Google\Gemini\Exception\ErrorException 5xx on stream or regular request Retry with jitter
    Google\Gemini\Exception\ToolError Invalid tool configuration Validate tool inputs
    ValueError text() / parts() called on incomplete response Inspect finish/block reason in message
  • File Search Debugging

    $operation = $fileSearchStore->getOperation($operationName);
    logger()->debug('File search operation', $operation->toArray());
    
  • Schema Validation Validate schemas before sending:

    if (!json_validate(json_encode($schema))) {
        throw new \InvalidArgumentException('Invalid JSON Schema');
    }
    

Extension Points

  1. Custom Prompt Templates Extend the prompt abstraction for reusable formats:

    class LaravelPrompt extends \Google\Gemini\Prompt
    {
        public function __construct(string $query)
        {
            parent::__construct('Laravel context: ' . $query);
        }
    }
    
  2. Request Middleware

    $client->setRequestMiddleware(function ($request) {
        $request->setHeader('X-Custom-Header', 'value');
    });
    
  3. Async Processing

    dispatch(new GenerateTextJob($prompt, $tools));
    
  4. Custom Tools

    class WeatherTool extends \Google\Gemini\Tool
    {
        public function __construct(string $location)
        {
            $this->setInput(['location' => $location]);
        }
    }
    
  5. Server-Side Tool Composition Combine built-in and custom tools:

    $model->withTools([
        new GoogleSearch(),
        new WeatherTool('Paris'),
    ]);
    
  6. Testing Extensions Add dedicated fake responses for multi-turn and streamed chats using ClientFake::startChat().

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc