Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/phpaisdk/google/llms.txt

Use this file to discover all available pages before exploring further.

Three parser classes are responsible for converting raw Gemini API JSON into the typed PHP AI SDK response objects that your application code receives. GoogleResponseParser handles synchronous text responses, GoogleImageResponseParser handles image generation responses, and GoogleStreamParser handles SSE streaming events for text generation. You do not call these directly — GoogleTextModel and GoogleImageModel call them after receiving HTTP responses — but understanding their logic helps when debugging unexpected finish reasons, token counts, or missing content.

GoogleResponseParser

Namespace: AiSdk\Google\Support\GoogleResponseParser Converts a decoded Gemini text-generation response payload into a TextModelResponse.

parse(array $payload): TextModelResponse

/**
 * @param array<string, mixed> $payload
 */
public static function parse(array $payload): TextModelResponse
payload
array
required
The JSON-decoded response body from a /interactions POST. Can contain either the shorthand output_text / outputText field or the structured steps[].content[] format.
Returns a TextModelResponse with typed parts, finish reason, token usage, and provider metadata.

Content Extraction

The parser first looks for a shorthand text field. If found and non-empty, it creates a single TextPart from it and skips the structured parsing:
$outputText = $payload['output_text'] ?? $payload['outputText'] ?? null;
if (is_string($outputText) && $outputText !== '') {
    $parts[] = new TextPart($outputText);
}
If no shorthand text is present, the parser iterates steps[].content[] and maps each part by its type field:
Part typeSDK Part ClassNotes
textTextPartRequires text string field
thoughtReasoningPartThinking model output
function_callToolCallPartRequires id/call_id, name, and args fields
// Structured content extraction
foreach ($payload['steps'] as $step) {
    foreach ($step['content'] as $part) {
        match ($part['type']) {
            'text'          => new TextPart($part['text']),
            'thought'       => new ReasoningPart($part['text']),
            'function_call' => new ToolCallPart(
                id:        $part['id'] ?? $part['call_id'] ?? '',
                name:      $part['name'] ?? '',
                arguments: $part['args'] ?? [],
            ),
        };
    }
}

Finish Reason Mapping

The finish reason is resolved from $payload['finish_reason'] or $payload['finishReason']. Tool calls take priority — if any ToolCallPart was extracted, FinishReason::ToolCalls is returned regardless of the raw finish reason string:
Raw value(s)FinishReason
stop, stopped, end_turnStop
max_tokens, max_output_tokens, lengthLength
safety, content_filter, blockedContentFilter
Tool call part presentToolCalls
nullStop
Anything elseUnknown

Token Usage

The usage() method is public static and shared by both GoogleResponseParser and GoogleStreamParser. It resolves usage data from several possible field names to handle both camelCase and snake_case Gemini API variants:
public static function usage(array $payload): Usage
Usage metadata source lookup order: usage_metadatausageMetadatausage.
inputTokens
int
From input_tokens, promptTokenCount, or prompt_token_count. Defaults to 0.
outputTokens
int
From output_tokens, candidatesTokenCount, or candidates_token_count, plus any reasoning tokens (thoughtsTokenCount / thoughts_token_count). Reasoning tokens are added to the output token count.
reasoningTokens
int|null
From thoughtsTokenCount or thoughts_token_count. Set to null when zero.
cachedInputTokens
int|null
From cachedContentTokenCount or cached_content_token_count. Set to null when absent.
totalTokens
int|null
From total_tokens or totalTokenCount. Set to null when absent.

Provider Metadata

providerMetadata['google'] is populated with whichever of the following keys are present in the top-level payload:
id
string
The response ID assigned by the Gemini API.
model
string
The model ID echoed back in the response.
finish_reason
string
The raw finish reason string as returned by Gemini.
usage_metadata
array
The full token usage metadata object.
prompt_feedback
array
Safety and content filtering feedback for the prompt.

GoogleImageResponseParser

Namespace: AiSdk\Google\Support\GoogleImageResponseParser Converts a decoded Gemini generateContent response payload into an ImageResponse.

parse(array $payload, string $providerName): ImageResponse

/**
 * @param array<string, mixed> $payload
 */
public static function parse(array $payload, string $providerName): ImageResponse
payload
array
required
The JSON-decoded response body from a /models/{modelId}:generateContent POST.
providerName
string
required
The provider name string (always 'google'). Used as the key in providerMetadata.
Returns an ImageResponse containing ImageData objects, token usage, the raw response, and provider metadata.

Image Extraction

The parser walks candidates[].content.parts[] and collects any part that contains an inlineData or inline_data object with a non-null data string:
foreach ($payload['candidates'] as $candidate) {
    foreach ($candidate['content']['parts'] as $part) {
        $inlineData = $part['inlineData'] ?? $part['inline_data'] ?? null;
        if (is_array($inlineData) && is_string($inlineData['data'] ?? null)) {
            $images[] = new ImageData(
                base64:   $inlineData['data'],
                mimeType: $inlineData['mimeType'] ?? $inlineData['mime_type'] ?? 'image/png',
            );
        }
    }
}
Parts that do not contain inlineData (such as accompanying text parts) are silently skipped.

Provider Metadata

providerMetadata[$providerName] contains whichever of the following keys are present:
KeyDescription
modelModel ID echoed in the response
promptFeedback / prompt_feedbackSafety feedback for the prompt
usageMetadata / usage_metadataToken usage metadata
Token usage for the response is extracted via the shared GoogleResponseParser::usage() method.

GoogleStreamParser

Namespace: AiSdk\Google\Support\GoogleStreamParser Processes an iterable stream of SSE events and yields typed StreamPart objects.

parse(iterable $events): Generator

/**
 * @param  iterable<int, array{event: ?string, data: string}>  $events
 * @return Generator<int, StreamPart>
 */
public static function parse(iterable $events): Generator
events
iterable
required
An iterable of SSE event arrays, each with a data key containing the raw data string. Produced by the SDK HTTP runner’s postStream() method.
Returns a Generator<int, StreamPart> that yields stream part objects as events are processed.

Event Processing

The parser loops over each event and skips it if the data field is empty or equals '[DONE]'. For all other events it JSON-decodes the data and processes the payload:
foreach ($events as $event) {
    $data = $event['data'];
    if ($data === '' || $data === '[DONE]') {
        continue;
    }

    $payload = json_decode($data, true);
    // ... process payload
}

Delta Yield Logic

Each event payload may contain a delta array. The parser calls an internal yieldDelta() method that maps delta types to stream parts:
Delta typeEmitted StreamPart(s)Condition
textTextDeltaParttext field is a non-empty string
thoughtReasoningDeltaParttext field is a non-empty string
function_callToolCallStartPart + ToolCallDeltaPartAlways; sets finish reason to ToolCalls
For function_call deltas, a monotonically increasing $toolIndex counter tracks each tool call’s position. The id is taken from delta['id'] or delta['call_id'], falling back to "call_{$index}". The args array is JSON-encoded for the ToolCallDeltaPart.

Accumulated State and Terminal Parts

The parser accumulates $usage, $finishReason, and $metadata across all events:
  • Usage is updated whenever an event payload contains usage_metadata, usageMetadata, or usage.
  • Finish reason is updated whenever finish_reason is present in the payload (using the same mapping as GoogleResponseParser).
  • Metadata accumulates the id, model, finish_reason, and usage_metadata fields from each event.
After all events are exhausted, two terminal parts are yielded:
// Emitted once, after all events
yield new ProviderMetadataPart('google', $metadata); // only if $metadata !== []
yield new FinishPart($finishReason, $usage);
ProviderMetadataPart
StreamPart
Carries the accumulated $metadata array under the 'google' provider key. Only emitted if at least one metadata field was received.
FinishPart
StreamPart
Carries the final FinishReason and the accumulated Usage object. Always the last part yielded.

Finish Reason Mapping (Stream)

The stream finish reason mapping uses the same string-to-enum values as the non-streaming parser, with one difference: when no finish_reason field appears in any event, the accumulated reason stays at the initial value of FinishReason::Stop. When a finish_reason field is present, any unrecognised value maps to FinishReason::Unknown (there is no null→Stop special case inside the stream method itself):
Raw value(s)FinishReason
stop, stopped, end_turnStop
max_tokens, max_output_tokens, lengthLength
safety, content_filter, blockedContentFilter
function_call delta receivedToolCalls
Anything elseUnknown
The usage() method on GoogleResponseParser is declared public static specifically so it can be shared. Both GoogleImageResponseParser and GoogleStreamParser call GoogleResponseParser::usage($payload) directly rather than duplicating the field-name resolution logic. This means any field aliases added to GoogleResponseParser::usage() automatically apply to image responses and stream terminal parts as well.

Build docs developers (and LLMs) love