Three parser classes are responsible for converting raw Gemini API JSON into the typed PHP AI SDK response objects that your application code receives.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.
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
The JSON-decoded response body from a
/interactions POST. Can contain either the shorthand output_text / outputText field or the structured steps[].content[] format.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 singleTextPart from it and skips the structured parsing:
steps[].content[] and maps each part by its type field:
Part type | SDK Part Class | Notes |
|---|---|---|
text | TextPart | Requires text string field |
thought | ReasoningPart | Thinking model output |
function_call | ToolCallPart | Requires id/call_id, name, and args fields |
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_turn | Stop |
max_tokens, max_output_tokens, length | Length |
safety, content_filter, blocked | ContentFilter |
| Tool call part present | ToolCalls |
null | Stop |
| Anything else | Unknown |
Token Usage
Theusage() 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:
usage_metadata → usageMetadata → usage.
From
input_tokens, promptTokenCount, or prompt_token_count. Defaults to 0.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.From
thoughtsTokenCount or thoughts_token_count. Set to null when zero.From
cachedContentTokenCount or cached_content_token_count. Set to null when absent.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:
The response ID assigned by the Gemini API.
The model ID echoed back in the response.
The raw finish reason string as returned by Gemini.
The full token usage metadata object.
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
The JSON-decoded response body from a
/models/{modelId}:generateContent POST.The provider name string (always
'google'). Used as the key in providerMetadata.ImageResponse containing ImageData objects, token usage, the raw response, and provider metadata.
Image Extraction
The parser walkscandidates[].content.parts[] and collects any part that contains an inlineData or inline_data object with a non-null data string:
inlineData (such as accompanying text parts) are silently skipped.
Provider Metadata
providerMetadata[$providerName] contains whichever of the following keys are present:
| Key | Description |
|---|---|
model | Model ID echoed in the response |
promptFeedback / prompt_feedback | Safety feedback for the prompt |
usageMetadata / usage_metadata | Token usage metadata |
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
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.Generator<int, StreamPart> that yields stream part objects as events are processed.
Event Processing
The parser loops over each event and skips it if thedata field is empty or equals '[DONE]'. For all other events it JSON-decodes the data and processes the payload:
Delta Yield Logic
Each event payload may contain adelta array. The parser calls an internal yieldDelta() method that maps delta types to stream parts:
Delta type | Emitted StreamPart(s) | Condition |
|---|---|---|
text | TextDeltaPart | text field is a non-empty string |
thought | ReasoningDeltaPart | text field is a non-empty string |
function_call | ToolCallStartPart + ToolCallDeltaPart | Always; sets finish reason to ToolCalls |
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, orusage. - Finish reason is updated whenever
finish_reasonis present in the payload (using the same mapping asGoogleResponseParser). - Metadata accumulates the
id,model,finish_reason, andusage_metadatafields from each event.
Carries the accumulated
$metadata array under the 'google' provider key. Only emitted if at least one metadata field was received.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 nofinish_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_turn | Stop |
max_tokens, max_output_tokens, length | Length |
safety, content_filter, blocked | ContentFilter |
function_call delta received | ToolCalls |
| Anything else | Unknown |
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.