SpeechDirect link to Speech
The Google Voice implementation in Mastra provides both text-to-speech (TTS) and speech-to-text (STT) capabilities using Google Cloud services. It supports multiple voices, languages, advanced audio configuration options, and both standard API key authentication and Vertex AI mode for enterprise deployments.
Usage exampleDirect link to Usage example
import { GoogleVoice } from '@mastra/voice-google'
// Initialize with default configuration (uses GOOGLE_API_KEY environment variable)
const voice = new GoogleVoice()
// Text-to-Speech (plain text)
const audioStream = await voice.speak('Hello, world!', {
languageCode: 'en-US',
audioConfig: {
audioEncoding: 'LINEAR16',
},
})
// Text-to-Speech with SSML
const ssmlStream = await voice.speak('ignored', {
input: {
ssml: '<speak>Take <say-as interpret-as="unit">5 mg</say-as> daily.</speak>',
},
})
// Text-to-Speech with Gemini-TTS model
const geminiStream = await voice.speak('Hello from Gemini TTS!', {
voice: { name: 'Kore', modelName: 'gemini-2.5-flash-preview-tts' },
input: { prompt: 'Warm, calm tone.' },
})
// Speech-to-Text
const transcript = await voice.listen(audioStream, {
config: {
encoding: 'LINEAR16',
languageCode: 'en-US',
},
})
// Get available voices for a specific language
const voices = await voice.getSpeakers({ languageCode: 'en-US' })
Constructor parametersDirect link to Constructor parameters
speechModel?:
apiKey?:
keyFilename?:
credentials?:
listeningModel?:
apiKey?:
keyFilename?:
credentials?:
speaker?:
vertexAI?:
project?:
location?:
MethodsDirect link to Methods
speak()Direct link to speak
Converts text to speech using Google Cloud Text-to-Speech service.
input:
options?:
speaker?:
languageCode?:
input?:
ssml, markup, prompt (Gemini-TTS style steering), customPronunciations, and multiSpeakerMarkup. When provided without text, ssml, markup, or multiSpeakerMarkup, the positional input argument is used as the text field automatically.voice?:
name and languageCode). Supports modelName (e.g., 'gemini-2.5-flash-preview-tts') and multiSpeakerVoiceConfig.audioConfig?:
Returns: Promise<NodeJS.ReadableStream>
listen()Direct link to listen
Converts speech to text using Google Cloud Speech-to-Text service. Supports both v1 (default) and v2 APIs. The v2 API adds support for AAC-in-MP4 audio (iOS Safari) via auto-decoding.
v1 (default)Direct link to v1 (default)
audioStream:
options?:
config?:
v2Direct link to v2
Pass v2: true to use the Cloud Speech-to-Text v2 API, which supports additional audio formats like AAC-in-MP4 (iOS Safari).
const transcript = await voice.listen(iosSafariAacStream, {
v2: true,
config: {
autoDecodingConfig: {},
},
})
audioStream:
options:
v2:
config?:
languageCodes: ['en-US'] and model: 'long'. Set autoDecodingConfig: {} to auto-detect the audio format, or use explicitDecodingConfig to specify an encoding like MP4_AAC, M4A_AAC, or MOV_AAC.recognizer?:
projects/{project}/locations/global/recognizers/_ where {project} is resolved from the constructor project option, GOOGLE_CLOUD_PROJECT, or the client's default project.Returns: Promise<string>
getSpeakers()Direct link to getspeakers
Returns an array of available voice options, where each node contains:
voiceId:
languageCodes:
isUsingVertexAI()Direct link to isusingvertexai
Checks if Vertex AI mode is enabled.
Returns: boolean - true if using Vertex AI, false otherwise
getProject()Direct link to getproject
Gets the configured Google Cloud project ID.
Returns: string | undefined - The project ID or undefined if not set
getLocation()Direct link to getlocation
Gets the configured Google Cloud location/region.
Returns: string - The location (default: 'us-central1')
AuthenticationDirect link to Authentication
The Google Voice provider supports two authentication methods:
Standard Mode (API Key)Direct link to Standard Mode (API Key)
Uses a Google Cloud API key for authentication. Suitable for development and basic use cases.
// Using environment variable (GOOGLE_API_KEY)
const voice = new GoogleVoice()
// Using explicit API key
const voice = new GoogleVoice({
speechModel: { apiKey: 'your-api-key' },
listeningModel: { apiKey: 'your-api-key' },
speaker: 'en-US-Casual-K',
})
Vertex AI Mode (Service Account)Direct link to Vertex AI Mode (Service Account)
Uses Google Cloud project-based authentication with service accounts. Recommended for production and enterprise deployments.
Benefits:
- Better security (no API keys in code)
- IAM-based access control
- Project-level billing and quotas
- Audit logging
- Enterprise features
Configuration Options:
// Using Application Default Credentials (ADC)
// Set GOOGLE_APPLICATION_CREDENTIALS and GOOGLE_CLOUD_PROJECT env vars
const voice = new GoogleVoice({
vertexAI: true,
project: 'your-gcp-project',
location: 'us-central1', // Optional, defaults to 'us-central1'
})
// Using service account key file
const voice = new GoogleVoice({
vertexAI: true,
project: 'your-gcp-project',
speechModel: {
keyFilename: '/path/to/service-account.json',
},
listeningModel: {
keyFilename: '/path/to/service-account.json',
},
})
// Using in-memory credentials
const voice = new GoogleVoice({
vertexAI: true,
project: 'your-gcp-project',
speechModel: {
credentials: {
client_email: 'service-account@project.iam.gserviceaccount.com',
private_key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----',
},
},
})
Required PermissionsDirect link to Required Permissions
IAM RolesDirect link to IAM Roles
For Text-to-Speech:
roles/texttospeech.admin- Text-to-Speech Admin (full access)roles/texttospeech.editor- Text-to-Speech Editor (create and manage)roles/texttospeech.viewer- Text-to-Speech Viewer (read-only)
For Speech-to-Text:
roles/speech.client- Speech-to-Text Client
OAuth ScopesDirect link to OAuth Scopes
For synchronous Text-to-Speech synthesis:
https://www.googleapis.com/auth/cloud-platform- Full access to Google Cloud Platform services
For long-audio Text-to-Speech operations:
locations.longAudioSynthesize- Create long-audio synthesis operationsoperations.get- Get operation statusoperations.list- List operations
Important notesDirect link to Important notes
- Authentication: Either a Google Cloud API key (standard mode) or service account credentials (Vertex AI mode) is required.
- Environment Variables:
GOOGLE_API_KEY- API key for standard modeGOOGLE_CLOUD_PROJECT- Project ID for Vertex AI modeGOOGLE_CLOUD_LOCATION- Location for Vertex AI mode (defaults to 'us-central1')GOOGLE_APPLICATION_CREDENTIALS- Path to service account key file
- The default voice is set to
'en-US-Casual-K'. - Both text-to-speech and speech-to-text services use LINEAR16 as the default audio encoding.
- The
speak()method supports advanced audio configuration through the Google Cloud Text-to-Speech API. - The
listen()method supports various recognition configurations through the Google Cloud Speech-to-Text API. - Available voices can be filtered by language code using the
getSpeakers()method. - Vertex AI mode provides enterprise features including IAM control, audit logs, and project-level billing.
Gemini LiveDirect link to Gemini Live
The GeminiLiveVoice class provides real-time voice interaction capabilities using Google's Gemini Live API. It supports bidirectional audio streaming, tool calling, session management, and both standard Google API and Vertex AI authentication methods.
Usage exampleDirect link to Usage example
import { GeminiLiveVoice } from '@mastra/voice-google-gemini-live'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
// Initialize with Gemini API (using API key)
const voice = new GeminiLiveVoice({
apiKey: process.env.GOOGLE_API_KEY, // Required for Gemini API
model: 'gemini-2.0-flash-exp',
speaker: 'Puck', // Default voice
debug: true,
})
// Or initialize with Vertex AI (using OAuth)
const voiceWithVertexAI = new GeminiLiveVoice({
vertexAI: true,
project: 'your-gcp-project',
location: 'us-central1',
serviceAccountKeyFile: '/path/to/service-account.json',
model: 'gemini-2.0-flash-exp',
speaker: 'Puck',
})
// Or use the VoiceConfig pattern (recommended for consistency with other providers)
const voiceWithConfig = new GeminiLiveVoice({
speechModel: {
name: 'gemini-2.0-flash-exp',
apiKey: process.env.GOOGLE_API_KEY,
},
speaker: 'Puck',
realtimeConfig: {
model: 'gemini-2.0-flash-exp',
apiKey: process.env.GOOGLE_API_KEY,
options: {
debug: true,
sessionConfig: {
interrupts: { enabled: true },
},
},
},
})
// Establish connection (required before using other methods)
await voice.connect()
// Set up event listeners
voice.on('speaker', audioStream => {
// Handle audio stream (NodeJS.ReadableStream)
playAudio(audioStream)
})
voice.on('writing', ({ text, role }) => {
// Handle transcribed text
console.log(`${role}: ${text}`)
})
voice.on('turnComplete', ({ timestamp }) => {
// Handle turn completion
console.log('Turn completed at:', timestamp)
})
// Convert text to speech
await voice.speak('Hello, how can I help you today?', {
speaker: 'Charon', // Override default voice
responseModalities: ['AUDIO', 'TEXT'],
})
// Process audio input
const microphoneStream = getMicrophoneStream()
await voice.send(microphoneStream)
// Update session configuration
await voice.updateSessionConfig({
speaker: 'Kore',
instructions: 'Be more concise in your responses',
})
// When done, disconnect
await voice.disconnect()
// Or use the synchronous wrapper
voice.close()
ConfigurationDirect link to Configuration
Constructor optionsDirect link to Constructor options
apiKey?:
model?:
speaker?:
vertexAI?:
project?:
location?:
serviceAccountKeyFile?:
serviceAccountEmail?:
instructions?:
sessionConfig?:
interrupts?:
interrupts.enabled?:
interrupts.allowUserInterruption?:
contextCompression?:
debug?:
MethodsDirect link to Methods
connect()Direct link to connect
Establishes a connection to the Gemini Live API. Must be called before using speak, listen, or send methods.
requestContext?:
returns:
speak()Direct link to speak-1
Converts text to speech and sends it to the model. Can accept either a string or a readable stream as input.
input:
options?:
speaker?:
languageCode?:
responseModalities?:
Returns: Promise<void> (responses are emitted via speaker and writing events)
sendContext()Direct link to sendcontext
Sends conversation history into the live session without triggering a model response. Use this to seed prior turns (e.g. from Mastra Memory) on a cold connect so the model has context before the user speaks.
await voice.sendContext([
{ role: 'user', content: 'What is the weather?' },
{ role: 'assistant', content: 'It is 72°F in San Francisco.' },
])
// Model stays silent until the user actually speaks.
await voice.send(micStream)
turns:
role ("user" or "assistant") and content string. Both roles are supported on newer models (e.g. gemini-2.5-flash-native-audio-preview-12-2025). Some older models only accept user-role turns.options?:
turnComplete?:
Returns: Promise<void>
listen()Direct link to listen-1
Processes audio input for speech recognition. Takes a readable stream of audio data and returns the transcribed text.
audioStream:
options?:
Returns: Promise<string> - The transcribed text
send()Direct link to send
Streams audio data in real-time to the Gemini service for continuous audio streaming scenarios like live microphone input.
audioData:
Returns: Promise<void>
updateSessionConfig()Direct link to updatesessionconfig
Updates the session configuration at runtime. This can modify voice settings and speaker selection. It can also modify other runtime configurations.
config:
Returns: Promise<void>
addTools()Direct link to addtools
Adds a set of tools to the voice instance. Tools allow the model to perform additional actions during conversations. When GeminiLiveVoice is added to an Agent, any tools configured for the Agent will automatically be available to the voice interface.
tools:
Returns: void
addInstructions()Direct link to addinstructions
Adds or updates system instructions for the model.
instructions?:
Returns: void
answer()Direct link to answer
Triggers a response from the model. This method is primarily used internally when integrated with an Agent.
options?:
Returns: Promise<void>
getSpeakers()Direct link to getspeakers-1
Returns a list of available voice speakers for the Gemini Live API.
Returns: Promise<Array<{ voiceId: string; description?: string }>>
disconnect()Direct link to disconnect
Disconnects from the Gemini Live session and cleans up resources. This is the async method that properly handles cleanup.
Returns: Promise<void>
close()Direct link to close
Synchronous wrapper for disconnect(). Calls disconnect() internally without awaiting.
Returns: void
on()Direct link to on
Registers an event listener for voice events.
event:
callback:
Returns: void
off()Direct link to off
Removes a previously registered event listener.
event:
callback:
Returns: void
EventsDirect link to Events
The GeminiLiveVoice class emits the following events:
speaker:
speaking:
writing:
output_audio_transcription channel rather than modelTurn.parts.text.thinking:
modelTurn.parts.text. Callback receives { text: string }. Does not fire on non-native-audio models, where modelTurn.parts.text is the spoken response and is emitted as writing instead.session:
turnComplete:
toolCall:
usage:
error:
interrupt:
Native-audio behaviorDirect link to Native-audio behavior
Native-audio Gemini Live models (any model whose ID contains native-audio, such as gemini-2.5-flash-native-audio-preview-12-2025) split text output across two channels:
- The model's spoken reply is delivered as audio plus an
output_audio_transcriptiontranscript and surfaced aswritingwithrole: 'assistant'. - The model's internal reasoning is delivered as
modelTurn.parts.textand surfaced asthinking.
On non-native-audio models there is no output_audio_transcription channel, so modelTurn.parts.text is the spoken response itself and is emitted as writing. The thinking event doesn't fire.
Input transcription, output transcription, and barge-in detection (realtime_input_config.activity_handling = 'START_OF_ACTIVITY_INTERRUPTS') are enabled automatically in the setup payload. You don't need extra configuration.
Available modelsDirect link to Available models
The following Gemini Live models are available:
gemini-2.0-flash-exp(default)gemini-2.0-flash-exp-image-generationgemini-2.0-flash-live-001gemini-live-2.5-flash-preview-native-audiogemini-2.5-flash-exp-native-audio-thinking-dialoggemini-live-2.5-flash-previewgemini-2.6.flash-preview-tts
Available voicesDirect link to Available voices
The following voice options are available:
Puck(default): Conversational, friendlyCharon: Deep, authoritativeKore: Neutral, professionalFenrir: Warm, approachable
Authentication methodsDirect link to Authentication methods
Gemini API (Development)Direct link to Gemini API (Development)
The simplest method using an API key from Google AI Studio:
const voice = new GeminiLiveVoice({
apiKey: 'your-api-key', // Required for Gemini API
model: 'gemini-2.0-flash-exp',
})
Vertex AI (Production)Direct link to Vertex AI (Production)
For production use with OAuth authentication and Google Cloud Platform:
// Using service account key file
const voice = new GeminiLiveVoice({
vertexAI: true,
project: 'your-gcp-project',
location: 'us-central1',
serviceAccountKeyFile: '/path/to/service-account.json',
})
// Using Application Default Credentials
const voice = new GeminiLiveVoice({
vertexAI: true,
project: 'your-gcp-project',
location: 'us-central1',
})
// Using service account impersonation
const voice = new GeminiLiveVoice({
vertexAI: true,
project: 'your-gcp-project',
location: 'us-central1',
serviceAccountEmail: 'service-account@project.iam.gserviceaccount.com',
})
Advanced featuresDirect link to Advanced features
Session ManagementDirect link to Session Management
The Gemini Live API supports session resumption for handling network interruptions:
voice.on('sessionHandle', ({ handle, expiresAt }) => {
// Store session handle for resumption
saveSessionHandle(handle, expiresAt)
})
// Resume a previous session
const voice = new GeminiLiveVoice({
sessionConfig: {
enableResumption: true,
maxDuration: '2h',
},
})
Tool CallingDirect link to Tool Calling
Enable the model to call functions during conversations:
import { z } from 'zod'
voice.addTools({
weather: {
description: 'Get weather information',
parameters: z.object({
location: z.string(),
}),
execute: async ({ location }) => {
const weather = await getWeather(location)
return weather
},
},
})
voice.on('toolCall', ({ name, args, id }) => {
console.log(`Tool called: ${name} with args:`, args)
})
NotesDirect link to Notes
- The Gemini Live API uses WebSockets for real-time communication
- Audio is processed as 16kHz PCM16 for input and 24kHz PCM16 for output
- The voice instance must be connected with
connect()before using other methods - Always call
close()when done to properly clean up resources - Vertex AI authentication requires appropriate IAM permissions (
aiplatform.userrole) - Session resumption allows recovery from network interruptions
- The API supports real-time interactions with text and audio