@mastra/voice-google-gemini-live 0.11.0-beta.0 → 0.11.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +76 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -13
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/managers/AudioStreamManager.ts","../src/utils/errors.ts","../src/managers/ConnectionManager.ts","../src/managers/ContextManager.ts","../src/managers/AuthManager.ts","../src/managers/EventManager.ts","../src/index.ts"],"names":["EventEmitter","WebSocket"],"mappings":"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","file":"index.js","sourcesContent":["import { PassThrough } from 'stream';\nimport type { AudioConfig } from '../types';\n\n/**\n * Default audio configuration for Gemini Live API\n */\nexport const DEFAULT_AUDIO_CONFIG: AudioConfig = {\n inputSampleRate: 16000,\n outputSampleRate: 24000,\n encoding: 'pcm16',\n channels: 1,\n};\n\n/**\n * Manages audio streams for the Gemini Live Voice API\n * Handles speaker stream lifecycle, cleanup, and audio processing\n */\nexport class AudioStreamManager {\n private speakerStreams = new Map<string, PassThrough & { id?: string; created?: number }>();\n private currentResponseId?: string;\n private readonly MAX_CONCURRENT_STREAMS = 10;\n private readonly STREAM_TIMEOUT_MS = 30000; // 30 seconds\n private readonly debug: boolean;\n private readonly audioConfig: AudioConfig;\n private readonly maxChunkSize = 32768; // 32KB max chunk size per Gemini limits\n private readonly minSendInterval = 0; // No throttling - let the stream control the pace\n private lastSendTime = 0;\n private pendingChunks: Array<{ chunk: Buffer; timestamp: number }> = [];\n private pendingTimer?: NodeJS.Timeout;\n private sendToGemini?: (type: 'realtime_input' | 'client_content', message: Record<string, unknown>) => void;\n\n // Audio buffer management constants\n private readonly MAX_BUFFER_SIZE = 50 * 1024 * 1024; // 50MB maximum buffer size\n private readonly MAX_AUDIO_DURATION = 300; // 5 minutes maximum audio duration\n\n constructor(audioConfig: AudioConfig, debug: boolean = false) {\n this.audioConfig = audioConfig;\n this.debug = debug;\n }\n\n /**\n * Provide a sender callback that will be used to deliver messages to Gemini\n */\n setSender(sender: (type: 'realtime_input' | 'client_content', message: Record<string, unknown>) => void): void {\n this.sendToGemini = sender;\n }\n\n /**\n * Get the default audio configuration\n */\n static getDefaultAudioConfig(): AudioConfig {\n return { ...DEFAULT_AUDIO_CONFIG };\n }\n\n /**\n * Create a merged audio configuration with defaults\n */\n static createAudioConfig(customConfig?: Partial<AudioConfig>): AudioConfig {\n return {\n ...DEFAULT_AUDIO_CONFIG,\n ...customConfig,\n };\n }\n\n /**\n * Get the current response ID for the next audio chunk\n */\n getCurrentResponseId(): string | undefined {\n return this.currentResponseId;\n }\n\n /**\n * Set the current response ID for the next audio chunk\n */\n setCurrentResponseId(responseId: string): void {\n this.currentResponseId = responseId;\n }\n\n /**\n * Get the current speaker stream\n */\n getCurrentSpeakerStream(): NodeJS.ReadableStream | null {\n const currentResponseId = this.getCurrentResponseId();\n if (!currentResponseId) {\n return null;\n }\n\n const currentStream = this.speakerStreams.get(currentResponseId);\n return currentStream ? (currentStream as NodeJS.ReadableStream) : null;\n }\n\n /**\n * Add a new speaker stream for a response\n */\n addSpeakerStream(responseId: string, stream: PassThrough): void {\n const streamWithMetadata = Object.assign(stream, {\n id: responseId,\n created: Date.now(),\n });\n\n this.speakerStreams.set(responseId, streamWithMetadata);\n this.log(`Added speaker stream for response: ${responseId}`);\n\n // Enforce stream limits after adding\n this.enforceStreamLimits();\n }\n\n /**\n * Remove a specific speaker stream\n */\n removeSpeakerStream(responseId: string): void {\n const stream = this.speakerStreams.get(responseId);\n if (stream && !stream.destroyed) {\n stream.end();\n setTimeout(() => {\n if (!stream.destroyed) {\n stream.destroy();\n this.log(`Force destroyed stream for response: ${responseId}`);\n }\n }, 1000);\n }\n\n this.speakerStreams.delete(responseId);\n this.log(`Removed speaker stream for response: ${responseId}`);\n }\n\n /**\n * Clean up all speaker streams\n */\n cleanupSpeakerStreams(): void {\n try {\n if (this.speakerStreams.size === 0) {\n return;\n }\n\n this.log(`Cleaning up ${this.speakerStreams.size} speaker streams`);\n\n for (const [responseId, stream] of this.speakerStreams.entries()) {\n try {\n // Check if stream is already ended/destroyed\n if (!stream.destroyed) {\n stream.end();\n\n // Force destroy after a short timeout if end() doesn't work\n setTimeout(() => {\n if (!stream.destroyed) {\n stream.destroy();\n this.log(`Force destroyed stream for response: ${responseId}`);\n }\n }, 1000);\n }\n\n this.speakerStreams.delete(responseId);\n this.log(`Cleaned up speaker stream for response: ${responseId}`);\n } catch (streamError) {\n this.log(`Error cleaning up stream ${responseId}:`, streamError);\n // Force remove from map even if cleanup failed\n this.speakerStreams.delete(responseId);\n }\n }\n\n this.currentResponseId = undefined;\n this.log('All speaker streams cleaned up');\n } catch (error) {\n this.log('Error during speaker stream cleanup:', error);\n // Force clear the map if cleanup fails\n this.speakerStreams.clear();\n this.currentResponseId = undefined;\n }\n }\n\n /**\n * Clean up old/stale streams to prevent memory leaks\n */\n cleanupStaleStreams(): void {\n try {\n const now = Date.now();\n const staleCutoff = now - this.STREAM_TIMEOUT_MS;\n const staleStreams: string[] = [];\n\n for (const [responseId, stream] of this.speakerStreams.entries()) {\n const created = stream.created || 0;\n if (created < staleCutoff) {\n staleStreams.push(responseId);\n }\n }\n\n if (staleStreams.length > 0) {\n this.log(`Cleaning up ${staleStreams.length} stale streams`);\n for (const responseId of staleStreams) {\n const stream = this.speakerStreams.get(responseId);\n if (stream && !stream.destroyed) {\n stream.end();\n }\n this.speakerStreams.delete(responseId);\n }\n }\n } catch (error) {\n this.log('Error cleaning up stale streams:', error);\n }\n }\n\n /**\n * Enforce stream limits to prevent memory exhaustion\n */\n enforceStreamLimits(): void {\n try {\n if (this.speakerStreams.size <= this.MAX_CONCURRENT_STREAMS) {\n return;\n }\n\n this.log(\n `Stream limit exceeded (${this.speakerStreams.size}/${this.MAX_CONCURRENT_STREAMS}), cleaning up oldest streams`,\n );\n\n // Sort streams by creation time and remove oldest ones\n const sortedStreams = Array.from(this.speakerStreams.entries()).sort(\n ([, a], [, b]) => (a.created || 0) - (b.created || 0),\n );\n\n const streamsToRemove = sortedStreams.slice(0, this.speakerStreams.size - this.MAX_CONCURRENT_STREAMS);\n\n for (const [responseId, stream] of streamsToRemove) {\n if (!stream.destroyed) {\n stream.end();\n }\n this.speakerStreams.delete(responseId);\n this.log(`Removed old stream for response: ${responseId}`);\n }\n } catch (error) {\n this.log('Error enforcing stream limits:', error);\n }\n }\n\n /**\n * Get information about current streams for debugging\n */\n getStreamInfo(): {\n totalStreams: number;\n currentResponseId?: string;\n streamDetails: Array<{ responseId: string; created: number; destroyed: boolean }>;\n } {\n const streamDetails = Array.from(this.speakerStreams.entries()).map(([responseId, stream]) => ({\n responseId,\n created: stream.created || 0,\n destroyed: stream.destroyed,\n }));\n\n return {\n totalStreams: this.speakerStreams.size,\n currentResponseId: this.currentResponseId,\n streamDetails,\n };\n }\n\n /**\n * Convert Int16Array audio data to base64 string for WebSocket transmission\n */\n int16ArrayToBase64(int16Array: Int16Array): string {\n const buffer = new ArrayBuffer(int16Array.length * 2);\n const view = new DataView(buffer);\n\n // Convert Int16Array to bytes with little-endian format\n for (let i = 0; i < int16Array.length; i++) {\n view.setInt16(i * 2, int16Array[i]!, true);\n }\n\n const nodeBuffer = Buffer.from(buffer);\n return nodeBuffer.toString('base64');\n }\n\n /**\n * Convert base64 string to Int16Array audio data\n */\n base64ToInt16Array(base64Audio: string): Int16Array {\n try {\n const buffer = Buffer.from(base64Audio, 'base64');\n\n // Convert Buffer to Int16Array\n if (buffer.length % 2 !== 0) {\n throw new Error('Invalid audio data: buffer length must be even for 16-bit audio');\n }\n\n return new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 2);\n } catch (error) {\n throw new Error(\n `Failed to decode base64 audio data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Validate and convert audio data to the required format for Gemini Live API\n * Gemini Live expects 16kHz PCM16 for input\n */\n validateAndConvertAudioInput(audioData: Buffer | Int16Array): Int16Array {\n if (Buffer.isBuffer(audioData)) {\n // Convert Buffer to Int16Array\n if (audioData.length % 2 !== 0) {\n throw new Error('Audio buffer length must be even for 16-bit audio');\n }\n return new Int16Array(audioData.buffer, audioData.byteOffset, audioData.byteLength / 2);\n }\n\n if (audioData instanceof Int16Array) {\n return audioData;\n }\n\n throw new Error('Unsupported audio data format. Expected Buffer or Int16Array');\n }\n\n /**\n * Process audio chunk for streaming - handles format validation and conversion\n */\n processAudioChunk(chunk: Buffer | Uint8Array | Int16Array): string {\n let int16Array: Int16Array;\n\n if (chunk instanceof Int16Array) {\n int16Array = chunk;\n } else if (Buffer.isBuffer(chunk)) {\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n int16Array = new Int16Array(chunk.buffer, chunk.byteOffset, chunk.byteLength / 2);\n } else if (chunk instanceof Uint8Array) {\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n int16Array = new Int16Array(chunk.buffer, chunk.byteOffset, chunk.byteLength / 2);\n } else {\n throw new Error('Unsupported audio chunk format');\n }\n\n return this.int16ArrayToBase64(int16Array);\n }\n\n /**\n * Validate audio format and sample rate for Gemini Live API requirements\n */\n validateAudioFormat(sampleRate?: number, channels?: number): void {\n if (sampleRate && sampleRate !== this.audioConfig.inputSampleRate) {\n this.log(\n `Warning: Audio sample rate ${sampleRate}Hz does not match expected ${this.audioConfig.inputSampleRate}Hz`,\n );\n }\n\n if (channels && channels !== this.audioConfig.channels) {\n throw new Error(`Unsupported channel count: ${channels}. Gemini Live API requires mono audio (1 channel)`);\n }\n }\n\n /**\n * Create an audio message for the Gemini Live API\n */\n createAudioMessage(audioData: string, messageType: 'input' | 'realtime' = 'realtime'): Record<string, unknown> {\n if (messageType === 'input') {\n // For conversation item creation (traditional listen method)\n return {\n client_content: {\n turns: [\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n mimeType: 'audio/pcm',\n data: audioData,\n },\n },\n ],\n },\n ],\n turnComplete: true,\n },\n };\n } else {\n // For real-time streaming\n return {\n realtime_input: {\n media_chunks: [\n {\n mime_type: 'audio/pcm',\n data: audioData,\n },\n ],\n },\n };\n }\n }\n\n /**\n * Get a speaker stream by response ID\n */\n getSpeakerStream(responseId: string): PassThrough | undefined {\n return this.speakerStreams.get(responseId);\n }\n\n /**\n * Create a new speaker stream for a response ID\n */\n createSpeakerStream(responseId: string): PassThrough {\n const stream = new PassThrough() as PassThrough & { id?: string; created?: number };\n stream.id = responseId;\n stream.created = Date.now();\n\n // Add the stream to the manager\n this.addSpeakerStream(responseId, stream);\n\n return stream;\n }\n\n /**\n * Get the number of active streams\n */\n getActiveStreamCount(): number {\n return this.speakerStreams.size;\n }\n\n /**\n * Check if a specific response ID has an active stream\n */\n hasStream(responseId: string): boolean {\n return this.speakerStreams.has(responseId);\n }\n\n /**\n * Get all active response IDs\n */\n getActiveResponseIds(): string[] {\n return Array.from(this.speakerStreams.keys());\n }\n\n /**\n * Reset the manager state (useful for testing or reconnection)\n */\n reset(): void {\n this.cleanupSpeakerStreams();\n this.currentResponseId = undefined;\n this.log('AudioStreamManager reset');\n }\n\n /**\n * Validate audio chunk size and format\n */\n validateAudioChunk(chunk: Buffer): void {\n if (chunk.length === 0) {\n throw new Error('Audio chunk cannot be empty');\n }\n\n if (chunk.length > this.maxChunkSize) {\n throw new Error(`Audio chunk size ${chunk.length} exceeds maximum allowed size ${this.maxChunkSize}`);\n }\n\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n }\n\n /**\n * Send audio chunk with throttling and validation\n */\n sendAudioChunk(chunk: Buffer): void {\n try {\n this.validateAudioChunk(chunk);\n\n const now = Date.now();\n if (now - this.lastSendTime < this.minSendInterval) {\n // Throttle if needed - enqueue for later processing\n this.pendingChunks.push({ chunk, timestamp: now });\n const delay = this.minSendInterval - (now - this.lastSendTime);\n if (!this.pendingTimer) {\n this.pendingTimer = setTimeout(\n () => {\n this.pendingTimer = undefined;\n this.processPendingChunks();\n },\n Math.max(0, delay),\n );\n }\n return;\n }\n\n this.processChunk(chunk);\n this.processPendingChunks();\n } catch (error) {\n this.log('Error sending audio chunk:', error);\n throw error;\n }\n }\n\n /**\n * Handle audio stream processing\n */\n async handleAudioStream(stream: NodeJS.ReadableStream): Promise<void> {\n return new Promise((resolve, reject) => {\n const cleanup = () => {\n stream.removeAllListeners();\n };\n\n stream.on('data', (chunk: Buffer) => {\n try {\n if (chunk.length > this.maxChunkSize) {\n // Split large chunks\n const chunks = this.splitAudioChunk(chunk);\n for (const subChunk of chunks) {\n this.validateAudioChunk(subChunk);\n this.sendAudioChunk(subChunk);\n }\n } else {\n this.validateAudioChunk(chunk);\n this.sendAudioChunk(chunk);\n }\n } catch (error) {\n cleanup();\n reject(error);\n }\n });\n\n stream.on('end', () => {\n cleanup();\n resolve();\n });\n\n stream.on('error', error => {\n cleanup();\n reject(error);\n });\n });\n }\n\n /**\n * Split large audio chunks into smaller ones\n */\n private splitAudioChunk(chunk: Buffer): Buffer[] {\n const chunks: Buffer[] = [];\n let offset = 0;\n\n while (offset < chunk.length) {\n const size = Math.min(this.maxChunkSize, chunk.length - offset);\n chunks.push(chunk.subarray(offset, offset + size));\n offset += size;\n }\n\n return chunks;\n }\n\n /**\n * Calculate audio duration from buffer length\n */\n calculateAudioDuration(bufferLength: number, sampleRate?: number): number {\n const effectiveSampleRate = sampleRate || this.audioConfig.inputSampleRate;\n return bufferLength / (effectiveSampleRate * 2); // 2 bytes per sample for 16-bit audio\n }\n\n /**\n * Validate audio buffer size and duration\n */\n validateAudioBuffer(buffer: Buffer): void {\n if (buffer.length === 0) {\n throw new Error('Audio buffer cannot be empty');\n }\n\n if (buffer.length > this.MAX_BUFFER_SIZE) {\n throw new Error(\n `Audio buffer size ${buffer.length} exceeds maximum allowed size ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`,\n );\n }\n\n if (buffer.length % 2 !== 0) {\n throw new Error('Audio buffer length must be even for 16-bit audio');\n }\n\n const duration = this.calculateAudioDuration(buffer.length);\n if (duration > this.MAX_AUDIO_DURATION) {\n throw new Error(\n `Audio duration ${duration.toFixed(2)}s exceeds maximum allowed duration ${this.MAX_AUDIO_DURATION}s`,\n );\n }\n }\n\n /**\n * Process audio buffer for transcription\n * Combines chunks, validates format, and converts to base64\n */\n processAudioBufferForTranscription(audioBuffer: Buffer): { base64Audio: string; duration: number; size: number } {\n // Validate audio format\n if (audioBuffer.length % 2 !== 0) {\n throw new Error('Invalid audio data: buffer length must be even for 16-bit audio');\n }\n\n // Calculate duration\n const duration = this.calculateAudioDuration(audioBuffer.length);\n\n // Convert to base64\n const base64Audio = audioBuffer.toString('base64');\n\n return {\n base64Audio,\n duration,\n size: audioBuffer.length,\n };\n }\n\n /**\n * Process audio chunks for transcription with buffer management\n * Handles chunk collection, size validation, and buffer management\n */\n processAudioChunksForTranscription(\n chunks: Buffer[],\n totalBufferSize: number,\n ): { audioBuffer: Buffer; base64Audio: string; duration: number; size: number } {\n // Check buffer size to prevent memory overflow\n if (totalBufferSize > this.MAX_BUFFER_SIZE) {\n throw new Error(`Audio data exceeds maximum size of ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`);\n }\n\n // Combine all chunks\n const audioBuffer = Buffer.concat(chunks);\n\n // Process for transcription\n const result = this.processAudioBufferForTranscription(audioBuffer);\n\n return {\n audioBuffer,\n ...result,\n };\n }\n\n /**\n * Validate audio chunks and calculate total size\n */\n validateAudioChunks(chunks: Buffer[]): { totalSize: number; isValid: boolean; error?: string } {\n let totalSize = 0;\n\n for (const chunk of chunks) {\n if (!Buffer.isBuffer(chunk)) {\n return { totalSize: 0, isValid: false, error: 'Invalid chunk format' };\n }\n\n totalSize += chunk.length;\n\n if (totalSize > this.MAX_BUFFER_SIZE) {\n return {\n totalSize,\n isValid: false,\n error: `Total size ${totalSize} exceeds maximum allowed size ${this.MAX_BUFFER_SIZE}`,\n };\n }\n }\n\n return { totalSize, isValid: true };\n }\n\n /**\n * Get audio buffer limits and configuration\n */\n getAudioBufferLimits(): { maxBufferSize: number; maxAudioDuration: number; maxChunkSize: number } {\n return {\n maxBufferSize: this.MAX_BUFFER_SIZE,\n maxAudioDuration: this.MAX_AUDIO_DURATION,\n maxChunkSize: this.maxChunkSize,\n };\n }\n\n /**\n * Get audio configuration\n */\n getAudioConfig(): AudioConfig {\n return this.audioConfig;\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[AudioStreamManager] ${message}`, ...args);\n }\n }\n\n /**\n * Handle complete audio transcription workflow\n * Manages stream processing, chunk collection, and transcription\n */\n async handleAudioTranscription(\n audioStream: NodeJS.ReadableStream,\n sendAndAwaitTranscript: (base64Audio: string) => Promise<string>,\n onError: (error: Error) => void,\n timeoutMs: number = 30000,\n ): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const chunks: Buffer[] = [];\n let isCleanedUp = false;\n let totalBufferSize = 0;\n let isResolved = false;\n\n // Set up timeout\n const timeout = setTimeout(() => {\n if (!isResolved) {\n cleanup();\n reject(new Error(`Transcription timeout - no response received within ${timeoutMs / 1000} seconds`));\n }\n }, timeoutMs);\n\n // Stream event handlers\n const onStreamData = (chunk: Buffer) => {\n try {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n\n // Check buffer size to prevent memory overflow\n totalBufferSize += buffer.length;\n if (totalBufferSize > this.MAX_BUFFER_SIZE) {\n cleanup();\n reject(new Error(`Audio data exceeds maximum size of ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`));\n return;\n }\n\n chunks.push(buffer);\n } catch (error) {\n cleanup();\n reject(\n new Error(`Failed to process audio chunk: ${error instanceof Error ? error.message : 'Unknown error'}`),\n );\n }\n };\n\n const onStreamError = (error: Error) => {\n cleanup();\n reject(new Error(`Audio stream error: ${error.message}`));\n };\n\n const onStreamEnd = async () => {\n try {\n // Remove stream listeners as we're done with the stream\n audioStream.removeListener('data', onStreamData);\n audioStream.removeListener('error', onStreamError);\n\n // Process chunks for transcription\n const result = this.processAudioChunksForTranscription(chunks, totalBufferSize);\n\n this.log('Processing audio for transcription:', {\n chunks: chunks.length,\n totalSize: result.size,\n duration: result.duration,\n });\n\n // Send audio and await the transcript from the caller\n try {\n const transcript = await sendAndAwaitTranscript(result.base64Audio);\n if (!isResolved) {\n isResolved = true;\n cleanup();\n resolve(transcript.trim());\n }\n } catch (error) {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(\n new Error(\n `Failed to obtain transcription: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n );\n }\n }\n } catch (error) {\n cleanup();\n reject(\n new Error(`Failed to process audio stream: ${error instanceof Error ? error.message : 'Unknown error'}`),\n );\n }\n };\n\n // Comprehensive cleanup function\n const cleanup = () => {\n if (isCleanedUp) return; // Prevent double cleanup\n isCleanedUp = true;\n\n // Clear all timers\n clearTimeout(timeout);\n\n // Remove stream event listeners\n audioStream.removeListener('data', onStreamData);\n audioStream.removeListener('error', onStreamError);\n audioStream.removeListener('end', onStreamEnd);\n\n // Clear chunks array to free memory\n chunks.length = 0;\n };\n\n // Set up stream event listeners\n audioStream.on('data', onStreamData);\n audioStream.on('error', onStreamError);\n audioStream.on('end', onStreamEnd);\n });\n }\n\n private processChunk(chunk: Buffer): void {\n // Convert raw audio buffer to base64 PCM16 and build message\n const base64Audio = this.processAudioChunk(chunk);\n const message = this.createAudioMessage(base64Audio, 'realtime');\n\n // Send via injected sender\n if (this.sendToGemini) {\n this.sendToGemini('realtime_input', message);\n } else {\n this.log('No sender configured for AudioStreamManager; dropping audio chunk');\n }\n\n // Update throttle timing and log\n this.lastSendTime = Date.now();\n this.log(`Sent audio chunk of size: ${chunk.length} bytes`);\n }\n\n private processPendingChunks(): void {\n while (this.pendingChunks.length > 0) {\n const nextChunk = this.pendingChunks[0];\n const now = Date.now();\n if (nextChunk && now - this.lastSendTime >= this.minSendInterval) {\n this.pendingChunks.shift();\n this.processChunk(nextChunk.chunk);\n } else {\n const delay = this.minSendInterval - (now - this.lastSendTime);\n if (!this.pendingTimer) {\n this.pendingTimer = setTimeout(\n () => {\n this.pendingTimer = undefined;\n this.processPendingChunks();\n },\n Math.max(0, delay),\n );\n }\n break;\n }\n }\n }\n}\n","import type { GeminiLiveErrorCode } from '../types';\n\n/**\n * Helper class for consistent error handling across managers and provider\n */\nexport class GeminiLiveError extends Error {\n public readonly code: string;\n public readonly details?: unknown;\n public readonly timestamp: number;\n\n constructor(code: GeminiLiveErrorCode | string, message: string, details?: unknown) {\n super(message);\n this.name = 'GeminiLiveError';\n this.code = code;\n this.details = details;\n this.timestamp = Date.now();\n }\n\n toEventData() {\n return {\n message: this.message,\n code: this.code,\n details: this.details,\n timestamp: this.timestamp,\n };\n }\n}\n","import { EventEmitter } from 'events';\nimport { WebSocket } from 'ws';\nimport { GeminiLiveErrorCode } from '../types';\nimport { GeminiLiveError } from '../utils/errors';\n\nexport interface ConnectionConfig {\n debug: boolean;\n timeoutMs?: number;\n}\n\nexport class ConnectionManager {\n private ws?: WebSocket;\n private eventEmitter: EventEmitter;\n private readonly debug: boolean;\n private readonly timeoutMs: number;\n\n constructor(config: ConnectionConfig) {\n this.eventEmitter = new EventEmitter();\n this.debug = config.debug;\n this.timeoutMs = config.timeoutMs || 30000;\n }\n\n /**\n * Set the WebSocket instance\n */\n setWebSocket(ws: WebSocket): void {\n this.ws = ws;\n }\n\n /**\n * Get the current WebSocket instance\n */\n getWebSocket(): WebSocket | undefined {\n return this.ws;\n }\n\n /**\n * Check if WebSocket is connected\n */\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Check if WebSocket is connecting\n */\n isConnecting(): boolean {\n return this.ws?.readyState === WebSocket.CONNECTING;\n }\n\n /**\n * Check if WebSocket is closed\n */\n isClosed(): boolean {\n return this.ws?.readyState === WebSocket.CLOSED;\n }\n\n /**\n * Wait for WebSocket to open\n */\n async waitForOpen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.ws) {\n reject(new Error('WebSocket not initialized'));\n return;\n }\n\n // If already open, resolve immediately\n if (this.ws.readyState === WebSocket.OPEN) {\n resolve();\n return;\n }\n\n // Set up event listeners with cleanup\n const onOpen = () => {\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(new Error(`WebSocket connection failed: ${error.message}`));\n };\n\n const onClose = () => {\n cleanup();\n reject(new Error('WebSocket connection closed before opening'));\n };\n\n const cleanup = () => {\n this.ws?.removeListener('open', onOpen);\n this.ws?.removeListener('error', onError);\n this.ws?.removeListener('close', onClose);\n };\n\n // Add event listeners\n this.ws.once('open', onOpen);\n this.ws.once('error', onError);\n this.ws.once('close', onClose);\n\n // Add timeout to prevent hanging indefinitely\n setTimeout(() => {\n cleanup();\n reject(new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_FAILED, 'WebSocket connection timeout'));\n }, this.timeoutMs);\n });\n }\n\n /**\n * Send data through WebSocket\n */\n send(data: string | Buffer): void {\n if (!this.ws) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket not initialized');\n }\n\n if (this.ws.readyState !== WebSocket.OPEN) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket is not open');\n }\n\n this.ws.send(data);\n }\n\n /**\n * Close the WebSocket connection\n */\n close(): void {\n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n }\n\n /**\n * Get connection state\n */\n getConnectionState(): 'disconnected' | 'connecting' | 'connected' | 'closed' {\n if (!this.ws) return 'disconnected';\n\n switch (this.ws.readyState) {\n case WebSocket.CONNECTING:\n return 'connecting';\n case WebSocket.OPEN:\n return 'connected';\n case WebSocket.CLOSED:\n return 'closed';\n default:\n return 'disconnected';\n }\n }\n\n /**\n * Validate WebSocket state for operations\n */\n validateWebSocketState(): void {\n if (!this.ws) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket not initialized');\n }\n\n if (this.ws.readyState !== WebSocket.OPEN) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket is not open');\n }\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[ConnectionManager] ${message}`, ...args);\n }\n }\n}\n","export interface ContextEntry {\n role: 'user' | 'assistant';\n content: string;\n timestamp: number;\n}\n\nexport interface ContextConfig {\n maxEntries?: number;\n maxContentLength?: number;\n compressionThreshold?: number;\n compressionEnabled?: boolean;\n}\n\nexport class ContextManager {\n private contextHistory: ContextEntry[] = [];\n private readonly maxEntries: number;\n private readonly maxContentLength: number;\n private readonly compressionThreshold: number;\n private compressionEnabled: boolean;\n\n constructor(config: ContextConfig = {}) {\n this.maxEntries = config.maxEntries || 100;\n this.maxContentLength = config.maxContentLength || 10000; // 10KB per entry\n this.compressionThreshold = config.compressionThreshold || 50;\n this.compressionEnabled = config.compressionEnabled ?? false;\n }\n\n /**\n * Add entry to context history\n */\n addEntry(role: 'user' | 'assistant', content: string): void {\n // Validate content length\n let processedContent = content;\n if (content.length > this.maxContentLength) {\n processedContent = content.substring(0, this.maxContentLength) + '...';\n }\n\n const entry: ContextEntry = {\n role,\n content: processedContent,\n timestamp: Date.now(),\n };\n\n this.contextHistory.push(entry);\n\n if (this.contextHistory.length > this.maxEntries) {\n if (this.compressionEnabled) {\n this.compressContext();\n } else {\n this.contextHistory = this.contextHistory.slice(-this.maxEntries);\n }\n }\n }\n\n /**\n * Get context history\n */\n getContextHistory(): ContextEntry[] {\n return [...this.contextHistory];\n }\n\n /**\n * Get context history as array of role/content pairs\n */\n getContextArray(): Array<{ role: string; content: string }> {\n return this.contextHistory.map(entry => ({\n role: entry.role,\n content: entry.content,\n }));\n }\n\n /**\n * Clear context history\n */\n clearContext(): void {\n this.contextHistory = [];\n }\n\n /**\n * Get context size\n */\n getContextSize(): number {\n return this.contextHistory.length;\n }\n\n /**\n * Compress context when it exceeds threshold\n */\n private compressContext(): void {\n if (!this.compressionEnabled || this.contextHistory.length <= this.compressionThreshold) {\n return;\n }\n\n // Keep first and last entries, compress middle ones\n const keepCount = Math.floor(this.compressionThreshold / 3);\n const firstEntries = this.contextHistory.slice(0, keepCount);\n const lastEntries = this.contextHistory.slice(-keepCount);\n\n // Create compressed middle entry\n const middleEntries = this.contextHistory.slice(keepCount, -keepCount);\n if (middleEntries.length > 0) {\n const compressedEntry: ContextEntry = {\n role: 'assistant',\n content: `[Compressed ${middleEntries.length} previous messages]`,\n timestamp: Date.now(),\n };\n\n this.contextHistory = [...firstEntries, compressedEntry, ...lastEntries];\n } else {\n this.contextHistory = [...firstEntries, ...lastEntries];\n }\n }\n\n /**\n * Enable or disable compression at runtime\n */\n setCompressionEnabled(enabled: boolean): void {\n this.compressionEnabled = enabled;\n }\n\n /**\n * Get context summary\n */\n getContextSummary(): {\n totalEntries: number;\n userEntries: number;\n assistantEntries: number;\n oldestTimestamp: number | null;\n newestTimestamp: number | null;\n } {\n if (this.contextHistory.length === 0) {\n return {\n totalEntries: 0,\n userEntries: 0,\n assistantEntries: 0,\n oldestTimestamp: null,\n newestTimestamp: null,\n };\n }\n\n const userEntries = this.contextHistory.filter(entry => entry.role === 'user').length;\n const assistantEntries = this.contextHistory.filter(entry => entry.role === 'assistant').length;\n const timestamps = this.contextHistory.map(entry => entry.timestamp);\n\n return {\n totalEntries: this.contextHistory.length,\n userEntries,\n assistantEntries,\n oldestTimestamp: Math.min(...timestamps),\n newestTimestamp: Math.max(...timestamps),\n };\n }\n\n /**\n * Search context for specific content\n */\n searchContext(query: string, role?: 'user' | 'assistant'): ContextEntry[] {\n const searchQuery = query.toLowerCase();\n\n return this.contextHistory.filter(entry => {\n const matchesRole = role ? entry.role === role : true;\n const matchesContent = entry.content.toLowerCase().includes(searchQuery);\n\n return matchesRole && matchesContent;\n });\n }\n\n /**\n * Get recent context entries\n */\n getRecentEntries(count: number): ContextEntry[] {\n return this.contextHistory.slice(-count);\n }\n\n /**\n * Get context entries by role\n */\n getEntriesByRole(role: 'user' | 'assistant'): ContextEntry[] {\n return this.contextHistory.filter(entry => entry.role === role);\n }\n}\n","import { GoogleAuth } from 'google-auth-library';\nimport { GeminiLiveErrorCode } from '../types';\nimport type { AuthOptions } from '../types';\nimport { GeminiLiveError } from '../utils/errors';\n\nexport interface AuthConfig {\n apiKey?: string;\n vertexAI?: boolean;\n project?: string;\n debug: boolean;\n serviceAccountKeyFile?: string;\n serviceAccountEmail?: string;\n tokenExpirationTime?: number;\n}\n\nexport class AuthManager {\n private authClient?: GoogleAuth;\n private accessToken?: string;\n private tokenExpirationTime?: number;\n private readonly config: AuthConfig;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.tokenExpirationTime = config.tokenExpirationTime ?? 50 * 60 * 1000;\n }\n\n /**\n * Initialize authentication based on configuration\n */\n async initialize(): Promise<void> {\n if (this.config.vertexAI) {\n await this.initializeVertexAI();\n } else if (this.config.apiKey) {\n // API key auth doesn't need initialization\n return;\n } else {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.API_KEY_MISSING,\n 'Either API key or Vertex AI configuration is required',\n );\n }\n }\n\n /**\n * Initialize Vertex AI authentication\n */\n private async initializeVertexAI(): Promise<void> {\n if (!this.config.project) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.PROJECT_ID_MISSING,\n 'Google Cloud project ID is required when using Vertex AI',\n );\n }\n\n const authOptions: AuthOptions = {\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n projectId: this.config.project,\n };\n\n // Support service account key file\n if (this.config.serviceAccountKeyFile) {\n authOptions.keyFilename = this.config.serviceAccountKeyFile;\n this.log('Using service account key file for authentication:', this.config.serviceAccountKeyFile);\n }\n\n // Support impersonation via service account email\n if (this.config.serviceAccountEmail) {\n authOptions.clientOptions = { subject: this.config.serviceAccountEmail };\n this.log('Using service account impersonation:', this.config.serviceAccountEmail);\n }\n\n try {\n this.authClient = new GoogleAuth(authOptions);\n } catch (error) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.AUTHENTICATION_FAILED,\n `Failed to initialize Vertex AI authentication: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get access token for Vertex AI\n */\n async getAccessToken(): Promise<string> {\n if (!this.config.vertexAI) {\n throw new GeminiLiveError(GeminiLiveErrorCode.AUTHENTICATION_FAILED, 'Vertex AI authentication not configured');\n }\n\n if (!this.authClient) {\n throw new GeminiLiveError(GeminiLiveErrorCode.AUTHENTICATION_FAILED, 'Authentication client not initialized');\n }\n\n // Check if we have a valid cached token\n if (this.accessToken && this.tokenExpirationTime && Date.now() < this.tokenExpirationTime) {\n return this.accessToken;\n }\n\n try {\n const client = await this.authClient.getClient();\n const token = await client.getAccessToken();\n\n if (!token.token) {\n throw new Error('No access token received');\n }\n\n this.accessToken = token.token;\n\n // Set expiry time (tokens typically last 1 hour, so set to 50 minutes to be safe)\n this.tokenExpirationTime = Date.now() + 50 * 60 * 1000;\n\n this.log('Successfully obtained new access token');\n return this.accessToken;\n } catch (error) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.AUTHENTICATION_FAILED,\n `Failed to get access token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get API key if using API key authentication\n */\n getApiKey(): string | undefined {\n if (this.config.vertexAI) {\n return undefined;\n }\n return this.config.apiKey;\n }\n\n /**\n * Check if using Vertex AI authentication\n */\n isUsingVertexAI(): boolean {\n return this.config.vertexAI === true;\n }\n\n /**\n * Check if authentication is configured\n */\n isConfigured(): boolean {\n return !!(this.config.apiKey || (this.config.vertexAI && this.config.project));\n }\n\n /**\n * Check if access token is valid\n */\n hasValidToken(): boolean {\n if (!this.config.vertexAI) return false;\n return !!(this.accessToken && this.tokenExpirationTime && Date.now() < this.tokenExpirationTime);\n }\n\n /**\n * Clear cached authentication data\n */\n clearCache(): void {\n this.accessToken = undefined;\n this.tokenExpirationTime = undefined;\n }\n\n /**\n * Get authentication configuration\n */\n getConfig(): AuthConfig {\n return { ...this.config };\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.info(`[AuthManager] ${message}`, ...args);\n }\n }\n}\n","import { EventEmitter } from 'events';\n// Make the event manager generic over an event map\nexport type EventMap = Record<string, unknown>;\n\nexport interface EventConfig {\n debug: boolean;\n}\n\nexport class EventManager<TEvents extends EventMap = Record<string, unknown>> {\n private eventEmitter: EventEmitter;\n private readonly debug: boolean;\n private eventCounts: Record<string, number> = {};\n\n constructor(config: EventConfig) {\n this.eventEmitter = new EventEmitter();\n this.debug = config.debug;\n }\n\n /**\n * Emit an event with data\n */\n emit<K extends Extract<keyof TEvents, string>>(event: K, data: TEvents[K]): boolean {\n this.incrementEventCount(event);\n const result = this.eventEmitter.emit(event, data);\n\n if (this.debug) {\n this.log(`Emitted event: ${event}`, data);\n }\n\n return result;\n }\n\n /**\n * Add event listener\n */\n on<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.on(event, callback);\n\n if (this.debug) {\n this.log(`Added listener for event: ${event}`);\n }\n }\n\n /**\n * Remove event listener\n */\n off<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.off(event, callback);\n\n if (this.debug) {\n this.log(`Removed listener for event: ${event}`);\n }\n }\n\n /**\n * Add one-time event listener\n */\n once<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.once(event, callback);\n\n if (this.debug) {\n this.log(`Added one-time listener for event: ${event}`);\n }\n }\n\n /**\n * Remove all listeners for an event\n */\n removeAllListeners(event?: string): void {\n this.eventEmitter.removeAllListeners(event);\n\n if (this.debug) {\n this.log(`Removed all listeners${event ? ` for event: ${event}` : ''}`);\n }\n }\n\n /**\n * Get event listener count\n */\n getListenerCount(event: string): number {\n return this.eventEmitter.listenerCount(event);\n }\n\n /**\n * Get event listener info\n */\n getEventListenerInfo(): Record<string, number> {\n const events = this.eventEmitter.eventNames();\n const info: Record<string, number> = {};\n\n events.forEach(event => {\n const eventName = typeof event === 'string' ? event : event.toString();\n info[eventName] = this.eventEmitter.listenerCount(event);\n });\n\n return info;\n }\n\n /**\n * Get event emission counts\n */\n getEventCounts(): Record<string, number> {\n return { ...this.eventCounts };\n }\n\n /**\n * Reset event counts\n */\n resetEventCounts(): void {\n this.eventCounts = {};\n }\n\n /**\n * Clean up event listeners\n */\n cleanup(): void {\n this.eventEmitter.removeAllListeners();\n this.resetEventCounts();\n\n if (this.debug) {\n this.log('Cleaned up all event listeners');\n }\n }\n\n /**\n * Get the underlying EventEmitter\n */\n getEventEmitter(): EventEmitter {\n return this.eventEmitter;\n }\n\n /**\n * Increment event count for tracking\n */\n private incrementEventCount(event: string): void {\n this.eventCounts[event] = (this.eventCounts[event] || 0) + 1;\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[EventManager] ${message}`, ...args);\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport { MastraVoice } from '@mastra/core/voice';\nimport type { VoiceEventType, VoiceConfig } from '@mastra/core/voice';\nimport type { WebSocket as WSType } from 'ws';\nimport { WebSocket } from 'ws';\nimport { AudioStreamManager, ConnectionManager, ContextManager, AuthManager, EventManager } from './managers';\nimport { GeminiLiveErrorCode } from './types';\nimport type {\n GeminiLiveVoiceConfig,\n GeminiLiveVoiceOptions,\n GeminiLiveEventMap,\n GeminiVoiceModel,\n GeminiVoiceName,\n GeminiToolConfig,\n AudioConfig,\n GeminiLiveServerMessage,\n GeminiSessionConfig,\n UpdateMessage,\n} from './types';\nimport { GeminiLiveError } from './utils/errors';\n\n// Narrow event keys to strings for the typed EventManager\ntype GeminiEventName = Extract<keyof GeminiLiveEventMap, string>;\n\n/**\n * Default configuration values\n */\nconst DEFAULT_MODEL: GeminiVoiceModel = 'gemini-2.0-flash-exp';\nconst DEFAULT_VOICE: GeminiVoiceName = 'Puck';\n\n/**\n * Helper class for consistent error handling\n */\n// GeminiLiveError is now defined in types.ts for reuse across managers\n\n/**\n * GeminiLiveVoice provides real-time multimodal voice interactions using Google's Gemini Live API.\n *\n * Features:\n * - Bidirectional audio streaming\n * - Built-in VAD and interrupt handling\n * - Tool calling capabilities\n * - Session management and resumption\n * - Live transcription\n * - Support for both Gemini API and Vertex AI\n *\n * @example Backward compatibility - Direct options (legacy)\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * apiKey: 'your-api-key',\n * model: 'gemini-2.0-flash-live-001',\n * speaker: 'Puck',\n * instructions: 'You are a helpful assistant'\n * });\n * ```\n *\n * @example Mastra VoiceConfig pattern - Recommended\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * speechModel: { name: 'gemini-2.0-flash-live-001', apiKey: 'your-api-key' },\n * speaker: 'Puck',\n * realtimeConfig: {\n * model: 'gemini-2.0-flash-live-001',\n * apiKey: 'your-api-key',\n * options: {\n * instructions: 'You are a helpful assistant',\n * debug: true\n * }\n * }\n * });\n * ```\n *\n * @example Using Vertex AI (with OAuth)\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * realtimeConfig: {\n * model: 'gemini-2.0-flash-live-001',\n * options: {\n * vertexAI: true,\n * project: 'your-gcp-project',\n * location: 'us-central1',\n * serviceAccountKeyFile: '/path/to/service-account.json',\n * }\n * }\n * });\n * ```\n */\nexport class GeminiLiveVoice extends MastraVoice<\n GeminiLiveVoiceConfig,\n GeminiLiveVoiceOptions,\n GeminiLiveVoiceOptions,\n ToolsInput,\n GeminiLiveEventMap\n> {\n private ws?: WSType;\n private eventManager: EventManager;\n private state: 'disconnected' | 'connected' = 'disconnected';\n private sessionHandle?: string;\n private readonly debug: boolean;\n private readonly audioConfig: AudioConfig;\n private queue: unknown[] = [];\n\n // Managers\n private connectionManager: ConnectionManager;\n private contextManager: ContextManager;\n private authManager: AuthManager;\n\n // Audio chunk concatenation - optimized stream management\n private audioStreamManager: AudioStreamManager;\n\n // Session management properties\n private sessionId?: string;\n private sessionStartTime?: number;\n private isResuming = false;\n private sessionDurationTimeout?: NodeJS.Timeout;\n\n // Tool integration properties\n private tools?: ToolsInput;\n private requestContext?: any;\n\n // Store the configuration options\n private options: GeminiLiveVoiceConfig;\n\n /**\n * Normalize configuration to ensure proper VoiceConfig format\n * Handles backward compatibility with direct GeminiLiveVoiceConfig\n * @private\n */\n private static normalizeConfig(\n config: VoiceConfig<GeminiLiveVoiceConfig> | GeminiLiveVoiceConfig,\n ): VoiceConfig<GeminiLiveVoiceConfig> {\n // Check if this is already a proper VoiceConfig (has realtimeConfig or standard VoiceConfig properties)\n if ('realtimeConfig' in config || 'speechModel' in config || 'listeningModel' in config) {\n return config as VoiceConfig<GeminiLiveVoiceConfig>;\n }\n\n // Convert direct GeminiLiveVoiceConfig to VoiceConfig format\n const geminiConfig = config as GeminiLiveVoiceConfig;\n return {\n speechModel: {\n name: geminiConfig.model || DEFAULT_MODEL,\n apiKey: geminiConfig.apiKey,\n },\n speaker: geminiConfig.speaker || DEFAULT_VOICE,\n realtimeConfig: {\n model: geminiConfig.model || DEFAULT_MODEL,\n apiKey: geminiConfig.apiKey,\n options: geminiConfig,\n },\n };\n }\n\n /**\n * Creates a new GeminiLiveVoice instance\n *\n * @param config Configuration options\n */\n constructor(config: VoiceConfig<GeminiLiveVoiceConfig> | GeminiLiveVoiceConfig = {}) {\n // Handle backward compatibility - if config has Gemini-specific properties directly,\n // convert to proper VoiceConfig format\n const normalizedConfig = GeminiLiveVoice.normalizeConfig(config);\n super(normalizedConfig);\n\n // Extract options from realtimeConfig\n this.options = normalizedConfig.realtimeConfig?.options || {};\n\n // Validate API key\n const apiKey = this.options.apiKey;\n if (!apiKey && !this.options.vertexAI) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.API_KEY_MISSING,\n 'Google API key is required. Set GOOGLE_API_KEY environment variable or pass apiKey to constructor',\n );\n }\n\n this.debug = this.options.debug || false;\n\n // Merge provided audio config with defaults\n this.audioConfig = {\n ...AudioStreamManager.getDefaultAudioConfig(),\n ...this.options.audioConfig,\n };\n\n // Initialize AudioStreamManager\n this.audioStreamManager = new AudioStreamManager(this.audioConfig, this.debug);\n // Inject sender so AudioStreamManager can deliver realtime audio\n this.audioStreamManager.setSender((type, message) => this.sendEvent(type, message));\n\n this.eventManager = new EventManager<GeminiLiveEventMap>({ debug: this.debug });\n this.connectionManager = new ConnectionManager({ debug: this.debug, timeoutMs: 30000 });\n this.contextManager = new ContextManager({\n maxEntries: 100,\n compressionThreshold: 50,\n compressionEnabled: this.options.sessionConfig?.contextCompression ?? false,\n });\n this.authManager = new AuthManager({\n apiKey: this.options.apiKey,\n vertexAI: this.options.vertexAI,\n project: this.options.project,\n serviceAccountKeyFile: this.options.serviceAccountKeyFile,\n serviceAccountEmail: this.options.serviceAccountEmail,\n debug: this.debug,\n tokenExpirationTime: this.options.tokenExpirationTime,\n });\n\n if (this.options.vertexAI && !this.options.project) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.PROJECT_ID_MISSING,\n 'Google Cloud project ID is required when using Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or pass project to constructor',\n );\n }\n\n // Auth initialization handled by AuthManager during connect\n }\n\n /**\n * Register an event listener\n * @param event Event name (e.g., 'speaking', 'writing', 'error', 'speaker')\n * @param callback Callback function that receives event data\n *\n * @example\n * ```typescript\n * // Listen for audio responses\n * voice.on('speaking', ({ audio, audioData, sampleRate }) => {\n * console.log('Received audio chunk:', audioData.length);\n * });\n *\n * // Listen for text responses and transcriptions\n * voice.on('writing', ({ text, role }) => {\n * console.log(`${role}: ${text}`);\n * });\n *\n * // Listen for audio streams (for concatenated playback)\n * voice.on('speaker', (audioStream) => {\n * audioStream.pipe(playbackDevice);\n * });\n *\n * // Handle errors\n * voice.on('error', ({ message, code, details }) => {\n * console.error('Voice error:', message);\n * });\n * ```\n */\n on<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.on(event as GeminiEventName, callback as any);\n this.log(`Event listener registered for: ${event}`);\n } catch (error) {\n this.log(`Failed to register event listener for ${event}:`, error);\n throw error;\n }\n }\n\n /**\n * Remove an event listener\n * @param event Event name\n * @param callback Callback function to remove\n */\n off<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.off(event as GeminiEventName, callback as any);\n this.log(`Event listener removed for: ${event}`);\n } catch (error) {\n this.log(`Failed to remove event listener for ${event}:`, error);\n }\n }\n\n /**\n * Register a one-time event listener that automatically removes itself after the first emission\n * @param event Event name\n * @param callback Callback function that receives event data\n */\n once<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.once(event as GeminiEventName, callback as any);\n this.log(`One-time event listener registered for: ${event}`);\n } catch (error) {\n this.log(`Failed to register one-time event listener for ${event}:`, error);\n throw error;\n }\n }\n\n /**\n * Emit an event to listeners with improved error handling\n * @private\n */\n private emit<K extends keyof GeminiLiveEventMap>(event: K, data: GeminiLiveEventMap[K]): boolean {\n try {\n const listenerCount = this.eventManager.getListenerCount(event as string);\n if (listenerCount === 0 && this.debug) {\n this.log(`No listeners for event: ${String(event)}`);\n }\n\n const result = this.eventManager.emit(event as GeminiEventName, data as any);\n\n if (this.debug && listenerCount > 0) {\n this.log(`Emitted event: ${String(event)} to ${listenerCount} listeners`);\n }\n\n return result;\n } catch (error) {\n this.log(`Error emitting event ${String(event)}:`, error);\n\n // Emit error event if this wasn't already an error event (prevent infinite loops)\n if (event !== 'error') {\n try {\n // Use underlying emitter directly to avoid recursion\n this.eventManager.getEventEmitter().emit('error', {\n message: `Failed to emit event: ${String(event)}`,\n code: 'event_emission_error',\n details: error,\n });\n } catch (nestedError) {\n // If we can't even emit the error event, log it\n this.log('Critical: Failed to emit error event:', nestedError);\n }\n }\n\n return false;\n }\n }\n\n /**\n * Clean up event listeners to prevent memory leaks\n * @private\n */\n private cleanupEventListeners(): void {\n try {\n // Get current listener counts for debugging\n const events = this.eventManager.getEventEmitter().eventNames();\n if (this.debug && events.length > 0) {\n this.log(\n 'Cleaning up event listeners:',\n events.map(event => `${String(event)}: ${this.eventManager.getListenerCount(String(event))}`).join(', '),\n );\n }\n\n // Remove all listeners\n this.eventManager.cleanup();\n\n this.log('Event listeners cleaned up');\n } catch (error) {\n this.log('Error cleaning up event listeners:', error);\n }\n }\n\n /**\n * Get current event listener information for debugging\n * @returns Object with event names and listener counts\n */\n getEventListenerInfo(): Record<string, number> {\n try {\n return this.eventManager.getEventListenerInfo();\n } catch (error) {\n this.log('Error getting event listener info:', error);\n return {} as Record<string, number>;\n }\n }\n\n /**\n * Create and emit a standardized error\n * @private\n */\n private createAndEmitError(code: GeminiLiveErrorCode, message: string, details?: unknown): GeminiLiveError {\n const error = new GeminiLiveError(code, message, details);\n this.log(`Error [${code}]: ${message}`, details);\n this.emit('error', error.toEventData());\n return error;\n }\n\n /**\n * Handle connection state validation with standardized errors\n * @private\n */\n private validateConnectionState(): void {\n if (this.state !== 'connected') {\n throw this.createAndEmitError(\n GeminiLiveErrorCode.NOT_CONNECTED,\n 'Not connected to Gemini Live API. Call connect() first.',\n { currentState: this.state },\n );\n }\n }\n\n /**\n * Handle WebSocket state validation with standardized errors\n * @private\n */\n private validateWebSocketState(): void {\n if (!this.connectionManager.isConnected()) {\n throw this.createAndEmitError(GeminiLiveErrorCode.WEBSOCKET_ERROR, 'WebSocket is not open', {\n wsExists: !!this.connectionManager.getWebSocket(),\n readyState: this.connectionManager.getWebSocket()?.readyState,\n expectedState: WebSocket.OPEN,\n });\n }\n }\n\n /**\n * Establish connection to the Gemini Live API\n */\n async connect({ requestContext }: { requestContext?: any } = {}): Promise<void> {\n if (this.state === 'connected') {\n this.log('Already connected to Gemini Live API');\n return;\n }\n\n // Store request context for tool execution\n this.requestContext = requestContext;\n\n // Emit connecting event\n this.emit('session', { state: 'connecting' });\n\n try {\n // Build WebSocket URL based on official Gemini Live API documentation\n let wsUrl: string;\n let headers: WebSocket.ClientOptions = {};\n\n if (this.options.vertexAI) {\n // Vertex AI endpoint\n wsUrl = `wss://${this.options.location}-aiplatform.googleapis.com/ws/google.cloud.aiplatform.v1beta1.PredictionService.ServerStreamingPredict`;\n // Initialize auth and get token\n await this.authManager.initialize();\n const accessToken = await this.authManager.getAccessToken();\n headers = { headers: { Authorization: `Bearer ${accessToken}` } };\n this.log('Using Vertex AI authentication with OAuth token');\n } else {\n // Live API endpoint - this is specifically for the Live API\n wsUrl = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent`;\n headers = {\n headers: {\n 'x-goog-api-key': this.options.apiKey || '',\n 'Content-Type': 'application/json',\n },\n };\n this.log('Using Live API authentication with API key');\n }\n\n this.log('Connecting to:', wsUrl);\n this.ws = new WebSocket(wsUrl, undefined, headers);\n this.connectionManager.setWebSocket(this.ws);\n\n this.setupEventListeners();\n\n // Wait for WebSocket connection to open via ConnectionManager\n await this.connectionManager.waitForOpen();\n\n // Send initial configuration or resume session\n if (this.isResuming && this.sessionHandle) {\n await this.sendSessionResumption();\n } else {\n this.sendInitialConfig();\n this.sessionStartTime = Date.now();\n this.sessionId = randomUUID();\n }\n\n // Wait for session to be created after sending config\n await this.waitForSessionCreated();\n\n this.state = 'connected';\n\n // Emit session connected event\n this.emit('session', {\n state: 'connected',\n config: {\n sessionId: this.sessionId,\n isResuming: this.isResuming,\n toolCount: Object.keys(this.tools || {}).length,\n },\n });\n\n this.log('Successfully connected to Gemini Live API', {\n sessionId: this.sessionId,\n isResuming: this.isResuming,\n toolCount: Object.keys(this.tools || {}).length,\n });\n\n // Start session duration monitoring if configured\n if (this.options.sessionConfig?.maxDuration) {\n this.startSessionDurationMonitor();\n }\n } catch (error) {\n this.state = 'disconnected';\n this.log('Connection failed', error);\n throw error;\n }\n }\n\n /**\n * Disconnect from the Gemini Live API\n */\n async disconnect(): Promise<void> {\n if (this.state === 'disconnected') {\n this.log('Already disconnected');\n return;\n }\n\n // Emit disconnecting event\n this.emit('session', { state: 'disconnecting' });\n\n // Clean up session duration monitoring\n if (this.sessionDurationTimeout) {\n clearTimeout(this.sessionDurationTimeout);\n this.sessionDurationTimeout = undefined;\n }\n\n // Save session handle before disconnecting if resumption is enabled\n if (this.options.sessionConfig?.enableResumption && this.sessionId) {\n // In a real implementation, the session handle would come from the server\n // For now, we'll use the session ID as a placeholder\n this.sessionHandle = this.sessionId;\n this.log('Session handle saved for resumption', { handle: this.sessionHandle });\n }\n\n if (this.ws) {\n this.connectionManager.close();\n this.ws = undefined;\n }\n\n // Clean up speaker streams with improved handling\n this.audioStreamManager.cleanupSpeakerStreams();\n\n // Clear cached OAuth token via AuthManager\n this.authManager.clearCache();\n\n this.state = 'disconnected';\n this.isResuming = false;\n\n // Emit final session event before cleanup\n this.emit('session', { state: 'disconnected' });\n\n // Clean up event listeners to prevent memory leaks\n this.cleanupEventListeners();\n\n this.log('Disconnected from Gemini Live API', {\n sessionId: this.sessionId,\n sessionDuration: this.sessionStartTime ? Date.now() - this.sessionStartTime : undefined,\n });\n }\n\n /**\n * Send text to be converted to speech\n */\n async speak(input: string | NodeJS.ReadableStream, options?: GeminiLiveVoiceOptions): Promise<void> {\n this.validateConnectionState();\n\n if (typeof input !== 'string') {\n const chunks: Buffer[] = [];\n for await (const chunk of input) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n input = Buffer.concat(chunks).toString('utf-8');\n }\n\n if (input.trim().length === 0) {\n throw this.createAndEmitError(GeminiLiveErrorCode.INVALID_AUDIO_FORMAT, 'Input text is empty');\n }\n\n // Add to context history\n this.addToContext('user', input);\n\n // Build text message to Gemini Live API\n const textMessage: any = {\n client_content: {\n turns: [\n {\n role: 'user',\n parts: [\n {\n text: input,\n },\n ],\n },\n ],\n turnComplete: true,\n },\n };\n\n // If runtime options provided, send a session.update first to apply per-turn settings\n if (options && (options.speaker || options.languageCode || options.responseModalities)) {\n const updateMessage: UpdateMessage = {\n type: 'session.update',\n session: {\n generation_config: {\n ...(options.responseModalities ? { response_modalities: options.responseModalities } : {}),\n speech_config: {\n ...(options.languageCode ? { language_code: options.languageCode } : {}),\n ...(options.speaker ? { voice_config: { prebuilt_voice_config: { voice_name: options.speaker } } } : {}),\n },\n },\n },\n };\n\n try {\n this.sendEvent('session.update', updateMessage);\n this.log('Applied per-turn runtime options', options);\n } catch (error) {\n this.log('Failed to apply per-turn runtime options', error);\n }\n }\n\n try {\n this.sendEvent('client_content', textMessage);\n this.log('Text message sent', { text: input });\n\n // The response will come via the event system (handleServerContent)\n // Audio will be emitted through 'speaking' events\n // Text responses will be emitted through 'writing' events\n } catch (error) {\n this.log('Failed to send text message', error);\n throw this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Failed to send text message', error);\n }\n }\n\n /**\n * Send audio stream for processing\n */\n async send(audioData: NodeJS.ReadableStream | Int16Array): Promise<void> {\n this.validateConnectionState();\n\n if ('readable' in audioData && typeof audioData.on === 'function') {\n const stream = audioData as NodeJS.ReadableStream;\n\n stream.on('data', (chunk: Buffer) => {\n try {\n const base64Audio = this.audioStreamManager.processAudioChunk(chunk);\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'realtime');\n this.sendEvent('realtime_input', message);\n } catch (error) {\n this.log('Failed to process audio chunk', error);\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Failed to process audio chunk', error);\n }\n });\n\n stream.on('error', (error: Error) => {\n this.log('Audio stream error', error);\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_STREAM_ERROR, 'Audio stream error', error);\n });\n\n stream.on('end', () => {\n this.log('Audio stream ended');\n });\n } else {\n const validateAudio = this.audioStreamManager.validateAndConvertAudioInput(audioData as Int16Array);\n const base64Audio = this.audioStreamManager.int16ArrayToBase64(validateAudio);\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'realtime');\n this.sendEvent('realtime_input', message);\n }\n }\n\n /**\n * Process speech from audio stream (traditional STT interface)\n */\n async listen(audioStream: NodeJS.ReadableStream, _options?: GeminiLiveVoiceOptions): Promise<string> {\n this.validateConnectionState();\n\n let transcriptionText = '';\n\n // Listen for transcription responses\n const onWriting = (data: { text: string; role: 'assistant' | 'user' }) => {\n if (data.role === 'user') {\n transcriptionText += data.text;\n this.log('Received transcription text:', { text: data.text, total: transcriptionText });\n }\n // Note: We only collect user role text as transcription\n // Assistant role text would be responses, not transcription\n };\n\n // Listen for errors\n const onError = (error: { message: string; code?: string; details?: unknown }) => {\n throw new Error(`Transcription failed: ${error.message}`);\n };\n\n // Listen for session events\n const onSession = (data: { state: string }) => {\n if (data.state === 'disconnected') {\n throw new Error('Session disconnected during transcription');\n }\n };\n\n // Set up GeminiLiveVoice event listeners\n this.on('writing', onWriting);\n this.on('error', onError);\n this.on('session', onSession);\n\n try {\n // Use AudioStreamManager to handle the transcription workflow\n const result = await this.audioStreamManager.handleAudioTranscription(\n audioStream,\n (base64Audio: string) => {\n // Send audio and await transcript until turn completes\n return new Promise<string>((resolve, reject) => {\n try {\n // Create audio message for transcription\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'input');\n\n const cleanup = () => {\n this.off('turnComplete' as any, onTurnComplete as any);\n this.off('error', onErr as any);\n };\n\n // Handlers\n const onTurnComplete = () => {\n cleanup();\n resolve(transcriptionText.trim());\n };\n\n const onErr = (e: { message: string }) => {\n cleanup();\n reject(new Error(e.message));\n };\n\n // Wire listeners before sending\n this.on('turnComplete' as any, onTurnComplete as any);\n this.on('error', onErr as any);\n\n // Send to Gemini Live API\n this.sendEvent('client_content', message);\n this.log('Sent audio for transcription');\n } catch (err) {\n reject(err as Error);\n }\n });\n },\n (error: Error) => {\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Audio transcription failed', error);\n },\n );\n\n return result;\n } finally {\n // Clean up event listeners\n this.off('writing', onWriting);\n this.off('error', onError);\n this.off('session', onSession);\n }\n }\n\n /**\n * Get available speakers/voices\n */\n async getSpeakers(): Promise<Array<{ voiceId: string; description?: string }>> {\n // Return available Gemini Live voices\n return [\n { voiceId: 'Puck', description: 'Conversational, friendly' },\n { voiceId: 'Charon', description: 'Deep, authoritative' },\n { voiceId: 'Kore', description: 'Neutral, professional' },\n { voiceId: 'Fenrir', description: 'Warm, approachable' },\n ];\n }\n\n /**\n * Resume a previous session using a session handle\n */\n async resumeSession(handle: string, context?: Array<{ role: string; content: string }>): Promise<void> {\n if (this.state === 'connected') {\n throw new Error('Cannot resume session while already connected. Disconnect first.');\n }\n\n this.log('Attempting to resume session', { handle });\n\n this.sessionHandle = handle;\n this.isResuming = true;\n\n // Restore context history if provided using ContextManager\n if (context && context.length > 0) {\n this.contextManager.clearContext();\n for (const item of context) {\n this.contextManager.addEntry(item.role as 'user' | 'assistant', item.content);\n }\n }\n\n try {\n await this.connect();\n this.log('Session resumed successfully', { handle, contextItems: context?.length || 0 });\n } catch (error) {\n this.isResuming = false;\n this.sessionHandle = undefined;\n throw new Error(`Failed to resume session: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Update session configuration during an active session\n * Allows dynamic updates to voice, instructions, tools, and other settings\n *\n * @param config Partial configuration to update\n * @throws Error if not connected or update fails\n *\n * @example\n * ```typescript\n * // Change voice during conversation\n * await voice.updateSessionConfig({\n * speaker: 'Charon'\n * });\n *\n * // Update instructions\n * await voice.updateSessionConfig({\n * instructions: 'You are now a helpful coding assistant'\n * });\n *\n * // Add or update tools\n * await voice.updateSessionConfig({\n * tools: [{ name: 'new_tool', ... }]\n * });\n * ```\n */\n async updateSessionConfig(config: Partial<GeminiLiveVoiceConfig>): Promise<void> {\n this.validateConnectionState();\n this.validateWebSocketState();\n\n return new Promise((resolve, reject) => {\n // Validate configuration\n if (config.model) {\n this.log('Warning: Model cannot be changed during an active session. Ignoring model update.');\n }\n\n if (config.vertexAI !== undefined || config.project !== undefined || config.location !== undefined) {\n this.log('Warning: Authentication settings cannot be changed during an active session.');\n }\n\n const updateMessage: UpdateMessage = {\n type: 'session.update',\n session: {},\n };\n\n let hasUpdates = false;\n\n // Update voice/speaker if provided\n if (config.speaker) {\n hasUpdates = true;\n updateMessage.session.generation_config = {\n ...updateMessage.session.generation_config,\n speech_config: {\n voice_config: {\n prebuilt_voice_config: {\n voice_name: config.speaker,\n },\n },\n },\n };\n\n // Update internal state\n this.speaker = config.speaker;\n this.log('Updating speaker to:', config.speaker);\n }\n\n // Update instructions if provided\n if (config.instructions !== undefined) {\n hasUpdates = true;\n updateMessage.session.system_instruction = {\n parts: [{ text: config.instructions }],\n };\n\n this.log('Updating instructions');\n }\n\n // Update tools if provided\n if (config.tools !== undefined) {\n hasUpdates = true;\n if (config.tools.length > 0) {\n updateMessage.session.tools = config.tools.map((tool: GeminiToolConfig) => ({\n function_declarations: [\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n ],\n }));\n } else {\n // Clear tools if empty array provided\n updateMessage.session.tools = [];\n }\n\n this.log('Updating tools:', config.tools.length, 'tools');\n }\n\n // Also check for tools from addTools method\n if (this.tools && Object.keys(this.tools).length > 0) {\n hasUpdates = true;\n const allTools: Array<{\n function_declarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }> = [];\n\n for (const [toolName, tool] of Object.entries(this.tools)) {\n try {\n let parameters: unknown;\n\n // Handle different tool formats\n if ('inputSchema' in tool && tool.inputSchema) {\n // Convert Zod schema to JSON schema if needed\n if (typeof tool.inputSchema === 'object' && 'safeParse' in tool.inputSchema) {\n // This is a Zod schema - we need to convert it\n parameters = this.convertZodSchemaToJsonSchema(tool.inputSchema);\n } else {\n parameters = tool.inputSchema;\n }\n } else if ('parameters' in tool && tool.parameters) {\n parameters = tool.parameters;\n } else {\n // Default empty object if no schema found\n parameters = { type: 'object', properties: {} };\n }\n\n allTools.push({\n function_declarations: [\n {\n name: toolName,\n description: tool.description || `Tool: ${toolName}`,\n parameters,\n },\n ],\n });\n } catch (error) {\n this.log('Failed to process tool for session update', { toolName, error });\n }\n }\n\n if (allTools.length > 0) {\n updateMessage.session.tools = allTools;\n this.log('Updating tools from addTools method:', allTools.length, 'tools');\n }\n }\n\n // Update session configuration if provided\n if (config.sessionConfig) {\n // Handle VAD settings\n if (config.sessionConfig.vad) {\n hasUpdates = true;\n updateMessage.session.vad = {\n enabled: config.sessionConfig.vad.enabled ?? true,\n sensitivity: config.sessionConfig.vad.sensitivity ?? 0.5,\n silence_duration_ms: config.sessionConfig.vad.silenceDurationMs ?? 1000,\n };\n this.log('Updating VAD settings:', config.sessionConfig.vad);\n }\n\n // Handle interrupt settings\n if (config.sessionConfig.interrupts) {\n hasUpdates = true;\n updateMessage.session.interrupts = {\n enabled: config.sessionConfig.interrupts.enabled ?? true,\n allow_user_interruption: config.sessionConfig.interrupts.allowUserInterruption ?? true,\n };\n this.log('Updating interrupt settings:', config.sessionConfig.interrupts);\n }\n\n // Handle context compression\n if (config.sessionConfig.contextCompression !== undefined) {\n hasUpdates = true;\n updateMessage.session.context_compression = config.sessionConfig.contextCompression;\n this.log('Updating context compression:', config.sessionConfig.contextCompression);\n // Apply to ContextManager\n this.contextManager.setCompressionEnabled(config.sessionConfig.contextCompression);\n }\n }\n\n // Check if there are any updates to send\n if (!hasUpdates) {\n this.log('No valid configuration updates to send');\n resolve();\n return;\n }\n\n // Set up timeout for response\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Session configuration update timeout - no response received'));\n }, 10000); // 10 second timeout\n\n // Listen for update confirmation\n const onSessionUpdated = (data: GeminiLiveServerMessage) => {\n cleanup();\n this.log('Session configuration updated successfully', data);\n resolve();\n };\n\n // Listen for errors\n const onError = (error: { message?: string; code?: string; details?: unknown }) => {\n cleanup();\n this.log('Session configuration update failed', error);\n reject(new Error(`Failed to update session configuration: ${error.message || 'Unknown error'}`));\n };\n\n // Set up event listeners\n const cleanup = () => {\n clearTimeout(timeout);\n this.eventManager.getEventEmitter().removeListener('session.updated', onSessionUpdated as any);\n this.eventManager.getEventEmitter().removeListener('error', onError as any);\n };\n\n this.eventManager.getEventEmitter().once('session.updated', onSessionUpdated as any);\n this.eventManager.getEventEmitter().once('error', onError as any);\n\n // Send the update message\n try {\n this.sendEvent('session.update', updateMessage);\n this.log('Sent session configuration update', updateMessage);\n } catch (error) {\n cleanup();\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.log('Failed to send session configuration update', error);\n reject(new Error(`Failed to send session configuration update: ${errorMessage}`));\n }\n });\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): 'disconnected' | 'connected' {\n return this.state;\n }\n\n /**\n * Check if currently connected\n */\n isConnected(): boolean {\n return this.state === 'connected';\n }\n\n /**\n * Get current speaker stream for audio concatenation\n * This allows external access to the current audio stream being built\n */\n getCurrentSpeakerStream(): NodeJS.ReadableStream | null {\n return this.audioStreamManager.getCurrentSpeakerStream();\n }\n\n /**\n * Get session handle for resumption\n */\n getSessionHandle(): string | undefined {\n // TODO: Return actual session handle when Gemini Live API supports session resumption\n return this.sessionHandle;\n }\n\n /**\n * Get comprehensive session information\n */\n getSessionInfo(): {\n id?: string;\n handle?: string;\n startTime?: Date;\n duration?: number;\n state: string;\n config?: GeminiSessionConfig;\n contextSize: number;\n } {\n return {\n id: this.sessionId,\n handle: this.sessionHandle,\n startTime: this.sessionStartTime ? new Date(this.sessionStartTime) : undefined,\n duration: this.sessionStartTime ? Date.now() - this.sessionStartTime : undefined,\n state: this.state,\n config: this.options.sessionConfig,\n contextSize: this.contextManager.getContextSize(),\n };\n }\n\n /**\n * Get session context history\n */\n getContextHistory(): Array<{ role: string; content: string; timestamp: number }> {\n return this.contextManager.getContextHistory();\n }\n\n /**\n * Add to context history for session continuity\n */\n addToContext(role: 'user' | 'assistant', content: string): void {\n this.contextManager.addEntry(role, content);\n }\n\n /**\n * Clear session context\n */\n clearContext(): void {\n this.contextManager.clearContext();\n this.log('Session context cleared');\n }\n\n /**\n * Enable or disable automatic reconnection\n */\n setAutoReconnect(enabled: boolean): void {\n if (!this.options.sessionConfig) {\n this.options.sessionConfig = {};\n }\n this.options.sessionConfig.enableResumption = enabled;\n this.log(`Auto-reconnect ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Send session resumption message\n * @private\n */\n private async sendSessionResumption(): Promise<void> {\n if (!this.sessionHandle) {\n throw new Error('No session handle available for resumption');\n }\n\n const context = this.contextManager.getContextArray();\n const resumeMessage = {\n session_resume: {\n handle: this.sessionHandle,\n ...(context.length > 0 && {\n context,\n }),\n },\n };\n\n try {\n if (this.ws?.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not ready for session resumption');\n }\n\n this.sendEvent('session_resume', resumeMessage);\n this.log('Session resumption message sent', { handle: this.sessionHandle });\n } catch (error) {\n this.log('Failed to send session resumption', error);\n throw new Error(`Failed to send session resumption: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Start monitoring session duration\n * @private\n */\n private startSessionDurationMonitor(): void {\n if (!this.options.sessionConfig?.maxDuration) {\n return;\n }\n\n // Parse duration string (e.g., '24h', '2h', '30m')\n const durationMs = this.parseDuration(this.options.sessionConfig.maxDuration);\n\n if (!durationMs) {\n this.log('Invalid session duration format', { duration: this.options.sessionConfig.maxDuration });\n return;\n }\n\n // Clear existing monitor if any\n if (this.sessionDurationTimeout) {\n clearTimeout(this.sessionDurationTimeout);\n }\n\n // Set timeout for session expiry warning\n const warningTime = durationMs - 5 * 60 * 1000; // 5 minutes before expiry\n\n if (warningTime > 0) {\n setTimeout(() => {\n this.emit('sessionExpiring', {\n expiresIn: 5 * 60 * 1000,\n sessionId: this.sessionId,\n });\n }, warningTime);\n }\n\n // Set timeout for session expiry\n this.sessionDurationTimeout = setTimeout(() => {\n this.log('Session duration limit reached, disconnecting');\n void this.disconnect();\n }, durationMs);\n }\n\n /**\n * Parse duration string to milliseconds\n * @private\n */\n private parseDuration(duration: string): number | null {\n const match = duration.match(/^(\\d+)([hms])$/);\n if (!match) return null;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2];\n\n switch (unit) {\n case 'h':\n return value * 60 * 60 * 1000;\n case 'm':\n return value * 60 * 1000;\n case 's':\n return value * 1000;\n default:\n return null;\n }\n }\n\n /**\n * Compress context history to manage memory\n * @private\n */\n private compressContext(): void {\n // Deprecated: ContextManager handles compression\n this.log('compressContext is deprecated; handled by ContextManager');\n }\n\n /**\n * Setup WebSocket event listeners for Gemini Live API messages\n * @private\n */\n private setupEventListeners(): void {\n if (!this.ws) {\n throw new Error('WebSocket not initialized');\n }\n\n // Handle WebSocket connection events\n this.ws.on('open', () => {\n this.log('WebSocket connection opened');\n // Note: We transition to 'connected' in connect() after setup is complete\n // This is just confirming the WebSocket is open\n });\n\n this.ws.on('close', (code: number, reason: Buffer) => {\n this.log('WebSocket connection closed', { code, reason: reason.toString() });\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n });\n\n this.ws.on('error', (error: Error) => {\n this.log('WebSocket error', error);\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n this.emit('error', {\n message: error.message,\n code: 'websocket_error',\n details: error,\n });\n });\n\n // Handle incoming messages from Gemini Live API\n this.ws.on('message', async (message: Buffer | string) => {\n try {\n const data = JSON.parse(message.toString());\n await this.handleGeminiMessage(data);\n } catch (error) {\n this.log('Failed to parse WebSocket message', error);\n this.emit('error', {\n message: 'Failed to parse WebSocket message',\n code: 'parse_error',\n details: error,\n });\n }\n });\n }\n\n /**\n * Handle different types of messages from Gemini Live API\n * @private\n */\n private async handleGeminiMessage(data: GeminiLiveServerMessage): Promise<void> {\n // Always log received messages in debug mode or when troubleshooting\n this.log('Received message:', JSON.stringify(data, null, 2));\n\n // Extract response ID if present in the message\n if ((data as any).responseId) {\n this.setCurrentResponseId((data as any).responseId);\n this.log('Set current response ID:', (data as any).responseId);\n }\n\n // Handle different Gemini Live API message structures\n if (data.setup) {\n this.log('Processing setup message');\n this.handleSetupComplete(data);\n } else if (data.setupComplete) {\n this.log('Processing setupComplete message');\n this.handleSetupComplete(data);\n } else if (data.serverContent) {\n this.log('Processing server content message');\n this.handleServerContent(data.serverContent);\n } else if (data.toolCall) {\n this.log('Processing tool call message');\n await this.handleToolCall(data);\n } else if (data.usageMetadata) {\n this.log('Processing usage metadata message');\n this.handleUsageUpdate(data);\n } else if (data.sessionEnd) {\n this.log('Processing session end message');\n this.handleSessionEnd(data);\n } else if (data.error) {\n this.log('Processing error message');\n this.handleError(data.error);\n } else {\n // Handle alternative message formats by checking for common fields\n const messageData = data as any; // Use any for flexible message handling\n\n // Check for various possible setup completion indicators\n if (messageData.type === 'setup' || messageData.type === 'session.ready' || messageData.type === 'ready') {\n // Handle alternative setup message formats\n this.log('Processing alternative setup message with type:', messageData.type);\n this.handleSetupComplete(data);\n } else if (messageData.sessionHandle) {\n // Handle session handle in response\n this.log('Processing session handle message');\n this.handleSetupComplete(data);\n } else if (\n messageData.session ||\n messageData.ready ||\n messageData.status === 'ready' ||\n messageData.status === 'setup_complete'\n ) {\n // Try to handle as setup completion if it has any setup-related fields\n this.log('Processing setup completion message with status:', messageData.status);\n this.handleSetupComplete(data);\n } else if (messageData.candidates || messageData.promptFeedback) {\n // Handle successful response from BidiGenerateContent\n this.log('Processing BidiGenerateContent response');\n this.handleSetupComplete(data);\n } else if (messageData.contents && Array.isArray(messageData.contents)) {\n // Handle content response\n this.log('Processing content response');\n this.handleServerContent({ modelTurn: { parts: messageData.contents.flatMap((c: any) => c.parts || []) } });\n // Also treat this as setup completion since we got a response\n this.handleSetupComplete(data);\n } else if (messageData.candidates && Array.isArray(messageData.candidates)) {\n // Handle candidates response (common in Gemini API)\n this.log('Processing candidates response');\n this.handleSetupComplete(data);\n } else {\n this.log('Unknown message format - no recognized fields found');\n }\n }\n }\n\n /**\n * Handle setup completion message\n * @private\n */\n private handleSetupComplete(data: GeminiLiveServerMessage): void {\n this.log('Setup completed');\n\n // Process all queued messages now that the session is ready\n const queue = this.queue.splice(0, this.queue.length);\n if (queue.length > 0) {\n this.log('Processing queued messages:', queue.length);\n for (const queuedMessage of queue) {\n try {\n this.connectionManager.send(JSON.stringify(queuedMessage));\n this.log('Sent queued message:', queuedMessage);\n } catch (err) {\n this.log('Failed to send queued message, re-queuing:', err);\n this.queue.unshift(queuedMessage);\n break;\n }\n }\n }\n\n // Emit event for waitForSessionCreated to resolve\n this.eventManager.getEventEmitter().emit('setupComplete', data as any);\n // Session is now ready for communication\n }\n\n /**\n * Handle session update confirmation\n * @private\n */\n private handleSessionUpdated(data: GeminiLiveServerMessage): void {\n this.log('Session updated', data);\n // Emit event for updateSessionConfig to resolve\n this.eventManager.getEventEmitter().emit('session.updated', data as any);\n\n // Also emit a general session event for any external listeners\n this.emit('session', {\n state: 'updated',\n config: data as Record<string, unknown>,\n });\n }\n\n /**\n * Handle server content (text/audio responses)\n * @private\n */\n private handleServerContent(data: GeminiLiveServerMessage['serverContent']): void {\n if (!data) {\n return;\n }\n\n let assistantResponse = '';\n\n if (data.modelTurn?.parts) {\n for (const part of data.modelTurn.parts) {\n // Handle text content\n if (part.text) {\n assistantResponse += part.text;\n this.emit('writing', {\n text: part.text,\n role: 'assistant',\n });\n }\n\n // Handle audio content - implement chunk concatenation with proper response ID tracking\n if (part.inlineData?.mimeType?.includes('audio') && typeof part.inlineData.data === 'string') {\n try {\n const audioData = part.inlineData.data;\n const int16Array = this.audioStreamManager.base64ToInt16Array(audioData);\n\n // Use the tracked response ID or generate one if not available\n const responseId = this.getCurrentResponseId() || randomUUID();\n\n // Get or create the speaker stream for this response\n let speakerStream = this.audioStreamManager.getSpeakerStream(responseId);\n if (!speakerStream) {\n // Clean up stale streams and enforce limits before creating new ones\n this.audioStreamManager.cleanupStaleStreams();\n this.audioStreamManager.enforceStreamLimits();\n\n // Create new stream through the manager\n speakerStream = this.audioStreamManager.createSpeakerStream(responseId);\n\n // Add error handling to the stream\n speakerStream.on('error', (streamError: Error) => {\n this.log(`Speaker stream error for ${responseId}:`, streamError);\n this.audioStreamManager.removeSpeakerStream(responseId);\n this.emit('error', {\n message: 'Speaker stream error',\n code: 'speaker_stream_error',\n details: { responseId, error: streamError },\n });\n });\n\n // Auto-cleanup when stream ends\n speakerStream.on('end', () => {\n this.log(`Speaker stream ended for response: ${responseId}`);\n this.audioStreamManager.removeSpeakerStream(responseId);\n });\n\n // Auto-cleanup when stream is destroyed\n speakerStream.on('close', () => {\n this.log(`Speaker stream closed for response: ${responseId}`);\n this.audioStreamManager.removeSpeakerStream(responseId);\n });\n\n this.log('Created new speaker stream for response:', responseId);\n\n // Emit the speaker stream for external listeners\n this.emit('speaker', speakerStream as NodeJS.ReadableStream);\n }\n\n // Write the audio chunk to the stream\n const audioBuffer = Buffer.from(int16Array.buffer, int16Array.byteOffset, int16Array.byteLength);\n speakerStream.write(audioBuffer);\n\n this.log('Wrote audio chunk to stream:', {\n responseId,\n chunkSize: audioBuffer.length,\n totalStreams: this.audioStreamManager.getActiveStreamCount(),\n });\n\n // Also emit the individual speaking event for backward compatibility\n this.emit('speaking', {\n audio: audioData, // Base64 string\n audioData: int16Array,\n sampleRate: this.audioConfig.outputSampleRate, // Gemini Live outputs at 24kHz\n });\n } catch (error) {\n this.log('Error processing audio data:', error);\n this.emit('error', {\n message: 'Failed to process audio data',\n code: 'audio_processing_error',\n details: error,\n });\n }\n }\n }\n }\n\n // Add assistant response to context if there was text content\n if (assistantResponse.trim()) {\n this.addToContext('assistant', assistantResponse);\n }\n\n // Check for turn completion\n if (data.turnComplete) {\n this.log('Turn completed');\n\n // End all active speaker streams for this turn\n this.audioStreamManager.cleanupSpeakerStreams();\n\n // Emit turn completion event\n this.emit('turnComplete', {\n timestamp: Date.now(),\n });\n }\n }\n\n /**\n * Handle tool call requests from the model\n * @private\n */\n private async handleToolCall(data: GeminiLiveServerMessage): Promise<void> {\n if (!data.toolCall) {\n return;\n }\n\n const toolName = data.toolCall.name || '';\n const toolArgs = data.toolCall.args || {};\n const toolId = data.toolCall.id || randomUUID();\n\n this.log('Processing tool call', { toolName, toolArgs, toolId });\n\n // Emit tool call event\n this.emit('toolCall', {\n name: toolName,\n args: toolArgs,\n id: toolId,\n });\n\n // Find the tool\n const tool = this.tools?.[toolName];\n if (!tool) {\n this.log('Tool not found', { toolName });\n this.createAndEmitError(GeminiLiveErrorCode.TOOL_NOT_FOUND, `Tool \"${toolName}\" not found`, {\n toolName,\n availableTools: Object.keys(this.tools || {}),\n });\n return;\n }\n\n try {\n // Execute the tool\n let result: unknown;\n\n if (tool.execute) {\n this.log('Executing tool', { toolName, toolArgs });\n\n // Execute with proper context\n result = await tool.execute(toolArgs, { requestContext: this.requestContext });\n\n this.log('Tool executed successfully', { toolName, result });\n } else {\n this.log('Tool has no execute function', { toolName });\n result = { error: 'Tool has no execute function' };\n }\n\n // Send tool result back to Gemini Live API\n const toolResultMessage = {\n tool_result: {\n tool_call_id: toolId,\n result: result,\n },\n };\n\n this.sendEvent('tool_result', toolResultMessage);\n this.log('Tool result sent', { toolName, toolId, result });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.log('Tool execution failed', { toolName, error: errorMessage });\n\n // Send error result back to Gemini Live API\n const errorResultMessage = {\n tool_result: {\n tool_call_id: toolId,\n result: { error: errorMessage },\n },\n };\n\n this.sendEvent('tool_result', errorResultMessage);\n\n // Emit error event\n this.createAndEmitError(GeminiLiveErrorCode.TOOL_EXECUTION_ERROR, `Tool execution failed: ${errorMessage}`, {\n toolName,\n toolArgs,\n error,\n });\n }\n }\n\n /**\n * Handle token usage information\n * @private\n */\n private handleUsageUpdate(data: GeminiLiveServerMessage): void {\n if (data.usageMetadata) {\n this.emit('usage', {\n inputTokens: data.usageMetadata.promptTokenCount || 0,\n outputTokens: data.usageMetadata.responseTokenCount || 0,\n totalTokens: data.usageMetadata.totalTokenCount || 0,\n modality: this.determineModality(data),\n });\n }\n }\n\n /**\n * Handle session end\n * @private\n */\n private handleSessionEnd(data: GeminiLiveServerMessage): void {\n this.log('Session ended', data.sessionEnd?.reason);\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n }\n\n /**\n * Handle errors\n * @private\n */\n private handleError(error: GeminiLiveServerMessage['error']): void {\n if (!error) {\n this.log('Received error from Gemini Live API (no error details)');\n return;\n }\n\n this.log('Received error from Gemini Live API', error);\n this.emit('error', {\n message: error.message || 'Unknown error',\n code: error.code || 'unknown_error',\n details: error.details,\n });\n }\n\n /**\n * Determine the modality from message data\n * @private\n */\n private determineModality(data: GeminiLiveServerMessage): 'audio' | 'text' | 'video' {\n // Simple heuristic - this could be more sophisticated\n if (data.serverContent?.modelTurn?.parts?.some(part => part.inlineData?.mimeType?.includes('audio'))) {\n return 'audio';\n }\n // Support for video is not yet implemented, leaving this here for future use if needed\n if (data.serverContent?.modelTurn?.parts?.some(part => part.inlineData?.mimeType?.includes('video'))) {\n return 'video';\n }\n return 'text';\n }\n\n /**\n * Send initial configuration to Gemini Live API\n * @private\n */\n private sendInitialConfig(): void {\n if (!this.ws || !this.connectionManager.isConnected()) {\n throw new Error('WebSocket not connected');\n }\n\n // Live API format - based on the official documentation\n interface LiveGenerateContentSetup {\n model?: string;\n generationConfig?: {\n temperature?: number;\n topK?: number;\n topP?: number;\n maxOutputTokens?: number;\n stopSequences?: string[];\n candidateCount?: number;\n responseModalities?: string[];\n speechConfig?: {\n voiceConfig?: {\n prebuiltVoiceConfig?: {\n voiceName?: string;\n };\n };\n };\n };\n systemInstruction?: {\n parts: Array<{\n text: string;\n }>;\n };\n tools?: Array<{\n functionDeclarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }>;\n }\n\n // Build the Live API setup message\n const setupMessage: { setup: LiveGenerateContentSetup } = {\n setup: {\n model: `models/${this.options.model}`,\n },\n };\n\n // Add system instructions if provided\n if (this.options.instructions) {\n setupMessage.setup.systemInstruction = {\n parts: [{ text: this.options.instructions }],\n };\n }\n\n // Collect tools from both options and addTools method\n const allTools: Array<{\n functionDeclarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }> = [];\n\n // Add tools from options (GeminiToolConfig[])\n if (this.options.tools && this.options.tools.length > 0) {\n for (const tool of this.options.tools) {\n allTools.push({\n functionDeclarations: [\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n ],\n });\n }\n }\n\n // Add tools from addTools method (ToolsInput)\n if (this.tools && Object.keys(this.tools).length > 0) {\n for (const [toolName, tool] of Object.entries(this.tools)) {\n try {\n let parameters: unknown;\n\n // Handle different tool formats\n if ('inputSchema' in tool && tool.inputSchema) {\n // Convert Zod schema to JSON schema if needed\n if (typeof tool.inputSchema === 'object' && 'safeParse' in tool.inputSchema) {\n // This is a Zod schema - we need to convert it\n parameters = this.convertZodSchemaToJsonSchema(tool.inputSchema);\n } else {\n parameters = tool.inputSchema;\n }\n } else if ('parameters' in tool && tool.parameters) {\n parameters = tool.parameters;\n } else {\n // Default empty object if no schema found\n parameters = { type: 'object', properties: {} };\n }\n\n allTools.push({\n functionDeclarations: [\n {\n name: toolName,\n description: tool.description || `Tool: ${toolName}`,\n parameters,\n },\n ],\n });\n } catch (error) {\n this.log('Failed to process tool', { toolName, error });\n }\n }\n }\n\n // Add tools to setup message if any exist\n if (allTools.length > 0) {\n setupMessage.setup.tools = allTools;\n this.log('Including tools in setup message', { toolCount: allTools.length });\n }\n\n this.log('Sending Live API setup message:', setupMessage);\n\n try {\n this.sendEvent('setup', setupMessage);\n } catch (error) {\n this.log('Failed to send Live API setup message:', error);\n throw new Error(\n `Failed to send Live API setup message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Wait for Gemini Live session to be created and ready\n * @private\n */\n private waitForSessionCreated(): Promise<void> {\n return new Promise((resolve, reject) => {\n // For Gemini Live API, we need to wait for the setup completion\n // This will be triggered by the setupComplete message type\n\n let isResolved = false;\n\n const onSetupComplete = () => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n resolve();\n }\n };\n\n const onError = (errorData: { message?: string; code?: string; details?: unknown }) => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error(`Session creation failed: ${errorData.message || 'Unknown error'}`));\n }\n };\n\n const onSessionEnd = () => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error('Session ended before setup completed'));\n }\n };\n\n const cleanup = () => {\n this.eventManager.getEventEmitter().removeListener('setupComplete', onSetupComplete as any);\n this.eventManager.getEventEmitter().removeListener('error', onError as any);\n this.eventManager.getEventEmitter().removeListener('sessionEnd', onSessionEnd as any);\n };\n\n // Listen for setup completion\n this.eventManager.getEventEmitter().once('setupComplete', onSetupComplete as any);\n this.eventManager.getEventEmitter().once('error', onError as any);\n this.eventManager.getEventEmitter().once('sessionEnd', onSessionEnd as any);\n\n // Add timeout to prevent hanging indefinitely\n setTimeout(() => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error('Session creation timeout'));\n }\n }, 30000); // 30 second timeout\n });\n }\n\n /**\n * Get OAuth access token for Vertex AI authentication\n * Implements token caching and automatic refresh\n * @private\n */\n private async getAccessToken(): Promise<string> {\n if (!this.options.vertexAI) {\n throw new Error('getAccessToken should only be called for Vertex AI mode');\n }\n return this.authManager.getAccessToken();\n }\n\n /**\n * Get the current response ID from the server message\n * This is needed to associate audio chunks with their respective responses.\n * @private\n */\n private getCurrentResponseId(): string | undefined {\n return this.audioStreamManager.getCurrentResponseId();\n }\n\n /**\n * Set the current response ID for the next audio chunk.\n * This is used to track the response ID for the current turn.\n * @private\n */\n private setCurrentResponseId(responseId: string): void {\n this.audioStreamManager.setCurrentResponseId(responseId);\n }\n\n /**\n * Send an event to the Gemini Live API with queueing support\n * @private\n */\n private sendEvent(type: string, data: any): void {\n // Handle messages that already have their own structure\n let message: any;\n if (type === 'setup' && data.setup) {\n // For setup messages, use the data as-is\n message = data;\n } else if (type === 'client_content' && data.client_content) {\n // For client_content messages, use the data as-is\n message = data;\n } else if (type === 'realtime_input' && data.realtime_input) {\n // For realtime_input messages, use the data as-is\n message = data;\n } else if (type === 'session.update' && data.session) {\n // For session update messages, use the data as-is\n message = data;\n } else {\n // For other messages, create the standard structure\n message = { type: type, ...data };\n }\n\n if (!this.ws || !this.connectionManager.isConnected()) {\n // Queue the message if WebSocket is not ready\n this.queue.push(message);\n this.log('Queued message:', { type, data });\n } else {\n // Send immediately if WebSocket is ready\n this.connectionManager.send(JSON.stringify(message));\n this.log('Sent message:', { type, data });\n }\n }\n\n /**\n * Equip the voice provider with tools\n * @param tools Object containing tool definitions that can be called by the voice model\n *\n * @example\n * ```typescript\n * const weatherTool = createTool({\n * id: \"getWeather\",\n * description: \"Get the current weather for a location\",\n * inputSchema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\"),\n * }),\n * execute: async (inputData) => {\n * // Fetch weather data from an API\n * const response = await fetch(\n * `https://api.weather.com?location=${encodeURIComponent(inputData.location)}`,\n * );\n * const data = await response.json();\n * return {\n * message: `The current temperature in ${inputData.location} is ${data.temperature}°F with ${data.conditions}.`,\n * };\n * },\n * });\n *\n * voice.addTools({\n * getWeather: weatherTool,\n * });\n * ```\n */\n addTools(tools: ToolsInput): void {\n this.tools = tools;\n this.log('Tools added to Gemini Live Voice', { toolCount: Object.keys(tools || {}).length });\n }\n\n /**\n * Get the current tools configured for this voice instance\n * @returns Object containing the current tools\n */\n listTools(): ToolsInput | undefined {\n return this.tools;\n }\n\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[GeminiLiveVoice] ${message}`, ...args);\n }\n }\n\n /**\n * Convert Zod schema to JSON Schema for tool parameters\n * @private\n */\n private convertZodSchemaToJsonSchema(schema: any): unknown {\n try {\n // Try to use the schema's toJSON method if available\n if (typeof schema.toJSON === 'function') {\n return schema.toJSON();\n }\n\n // Try to use the schema's _def property if available (Zod internal)\n if (schema._def) {\n return this.convertZodDefToJsonSchema(schema._def);\n }\n\n // If it's already a plain object, return as is\n if (typeof schema === 'object' && !schema.safeParse) {\n return schema;\n }\n\n // Default fallback\n return {\n type: 'object',\n properties: {},\n description: schema.description || '',\n };\n } catch (error) {\n this.log('Failed to convert Zod schema to JSON schema', { error, schema });\n return {\n type: 'object',\n properties: {},\n description: 'Schema conversion failed',\n };\n }\n }\n\n /**\n * Convert Zod definition to JSON Schema\n * @private\n */\n private convertZodDefToJsonSchema(def: any): unknown {\n switch (def.typeName) {\n case 'ZodString':\n return {\n type: 'string',\n description: def.description || '',\n };\n case 'ZodNumber':\n return {\n type: 'number',\n description: def.description || '',\n };\n case 'ZodBoolean':\n return {\n type: 'boolean',\n description: def.description || '',\n };\n case 'ZodArray':\n return {\n type: 'array',\n items: this.convertZodDefToJsonSchema(def.type._def),\n description: def.description || '',\n };\n case 'ZodObject':\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(def.shape())) {\n properties[key] = this.convertZodDefToJsonSchema((value as any)._def);\n if ((value as any)._def.typeName === 'ZodOptional') {\n // Optional field, don't add to required\n } else {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n description: def.description || '',\n };\n case 'ZodOptional':\n return this.convertZodDefToJsonSchema(def.innerType._def);\n case 'ZodEnum':\n return {\n type: 'string',\n enum: def.values,\n description: def.description || '',\n };\n default:\n return {\n type: 'object',\n properties: {},\n description: def.description || '',\n };\n }\n }\n\n /**\n * Close the connection (alias for disconnect)\n */\n close(): void {\n void this.disconnect();\n }\n\n /**\n * Trigger voice provider to respond\n */\n async answer(_options?: Record<string, unknown>): Promise<void> {\n this.validateConnectionState();\n\n // Send a signal to trigger response generation\n this.sendEvent('response.create', {});\n }\n\n /**\n * Equip the voice provider with instructions\n * @param instructions Instructions to add\n */\n addInstructions(instructions?: string): void {\n if (instructions) {\n this.options.instructions = instructions;\n this.log('Instructions added:', instructions);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/managers/AudioStreamManager.ts","../src/utils/errors.ts","../src/managers/ConnectionManager.ts","../src/managers/ContextManager.ts","../src/managers/AuthManager.ts","../src/managers/EventManager.ts","../src/index.ts"],"names":["EventEmitter","WebSocket"],"mappings":"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","file":"index.js","sourcesContent":["import { PassThrough } from 'stream';\nimport type { AudioConfig } from '../types';\n\n/**\n * Default audio configuration for Gemini Live API\n */\nexport const DEFAULT_AUDIO_CONFIG: AudioConfig = {\n inputSampleRate: 16000,\n outputSampleRate: 24000,\n encoding: 'pcm16',\n channels: 1,\n};\n\n/**\n * Manages audio streams for the Gemini Live Voice API\n * Handles speaker stream lifecycle, cleanup, and audio processing\n */\nexport class AudioStreamManager {\n private speakerStreams = new Map<string, PassThrough & { id?: string; created?: number }>();\n private currentResponseId?: string;\n private readonly MAX_CONCURRENT_STREAMS = 10;\n private readonly STREAM_TIMEOUT_MS = 30000; // 30 seconds\n private readonly debug: boolean;\n private readonly audioConfig: AudioConfig;\n private readonly maxChunkSize = 32768; // 32KB max chunk size per Gemini limits\n private readonly minSendInterval = 0; // No throttling - let the stream control the pace\n private lastSendTime = 0;\n private pendingChunks: Array<{ chunk: Buffer; timestamp: number }> = [];\n private pendingTimer?: NodeJS.Timeout;\n private sendToGemini?: (type: 'realtime_input' | 'client_content', message: Record<string, unknown>) => void;\n\n // Audio buffer management constants\n private readonly MAX_BUFFER_SIZE = 50 * 1024 * 1024; // 50MB maximum buffer size\n private readonly MAX_AUDIO_DURATION = 300; // 5 minutes maximum audio duration\n\n constructor(audioConfig: AudioConfig, debug: boolean = false) {\n this.audioConfig = audioConfig;\n this.debug = debug;\n }\n\n /**\n * Provide a sender callback that will be used to deliver messages to Gemini\n */\n setSender(sender: (type: 'realtime_input' | 'client_content', message: Record<string, unknown>) => void): void {\n this.sendToGemini = sender;\n }\n\n /**\n * Get the default audio configuration\n */\n static getDefaultAudioConfig(): AudioConfig {\n return { ...DEFAULT_AUDIO_CONFIG };\n }\n\n /**\n * Create a merged audio configuration with defaults\n */\n static createAudioConfig(customConfig?: Partial<AudioConfig>): AudioConfig {\n return {\n ...DEFAULT_AUDIO_CONFIG,\n ...customConfig,\n };\n }\n\n /**\n * Get the current response ID for the next audio chunk\n */\n getCurrentResponseId(): string | undefined {\n return this.currentResponseId;\n }\n\n /**\n * Set the current response ID for the next audio chunk\n */\n setCurrentResponseId(responseId: string): void {\n this.currentResponseId = responseId;\n }\n\n /**\n * Get the current speaker stream\n */\n getCurrentSpeakerStream(): NodeJS.ReadableStream | null {\n const currentResponseId = this.getCurrentResponseId();\n if (!currentResponseId) {\n return null;\n }\n\n const currentStream = this.speakerStreams.get(currentResponseId);\n return currentStream ? (currentStream as NodeJS.ReadableStream) : null;\n }\n\n /**\n * Add a new speaker stream for a response\n */\n addSpeakerStream(responseId: string, stream: PassThrough): void {\n const streamWithMetadata = Object.assign(stream, {\n id: responseId,\n created: Date.now(),\n });\n\n this.speakerStreams.set(responseId, streamWithMetadata);\n this.log(`Added speaker stream for response: ${responseId}`);\n\n // Enforce stream limits after adding\n this.enforceStreamLimits();\n }\n\n /**\n * Remove a specific speaker stream\n */\n removeSpeakerStream(responseId: string): void {\n const stream = this.speakerStreams.get(responseId);\n if (stream && !stream.destroyed) {\n stream.end();\n setTimeout(() => {\n if (!stream.destroyed) {\n stream.destroy();\n this.log(`Force destroyed stream for response: ${responseId}`);\n }\n }, 1000);\n }\n\n this.speakerStreams.delete(responseId);\n this.log(`Removed speaker stream for response: ${responseId}`);\n }\n\n /**\n * Clean up all speaker streams\n */\n cleanupSpeakerStreams(): void {\n try {\n if (this.speakerStreams.size === 0) {\n return;\n }\n\n this.log(`Cleaning up ${this.speakerStreams.size} speaker streams`);\n\n for (const [responseId, stream] of this.speakerStreams.entries()) {\n try {\n // Check if stream is already ended/destroyed\n if (!stream.destroyed) {\n stream.end();\n\n // Force destroy after a short timeout if end() doesn't work\n setTimeout(() => {\n if (!stream.destroyed) {\n stream.destroy();\n this.log(`Force destroyed stream for response: ${responseId}`);\n }\n }, 1000);\n }\n\n this.speakerStreams.delete(responseId);\n this.log(`Cleaned up speaker stream for response: ${responseId}`);\n } catch (streamError) {\n this.log(`Error cleaning up stream ${responseId}:`, streamError);\n // Force remove from map even if cleanup failed\n this.speakerStreams.delete(responseId);\n }\n }\n\n this.currentResponseId = undefined;\n this.log('All speaker streams cleaned up');\n } catch (error) {\n this.log('Error during speaker stream cleanup:', error);\n // Force clear the map if cleanup fails\n this.speakerStreams.clear();\n this.currentResponseId = undefined;\n }\n }\n\n /**\n * Clean up old/stale streams to prevent memory leaks\n */\n cleanupStaleStreams(): void {\n try {\n const now = Date.now();\n const staleCutoff = now - this.STREAM_TIMEOUT_MS;\n const staleStreams: string[] = [];\n\n for (const [responseId, stream] of this.speakerStreams.entries()) {\n const created = stream.created || 0;\n if (created < staleCutoff) {\n staleStreams.push(responseId);\n }\n }\n\n if (staleStreams.length > 0) {\n this.log(`Cleaning up ${staleStreams.length} stale streams`);\n for (const responseId of staleStreams) {\n const stream = this.speakerStreams.get(responseId);\n if (stream && !stream.destroyed) {\n stream.end();\n }\n this.speakerStreams.delete(responseId);\n }\n }\n } catch (error) {\n this.log('Error cleaning up stale streams:', error);\n }\n }\n\n /**\n * Enforce stream limits to prevent memory exhaustion\n */\n enforceStreamLimits(): void {\n try {\n if (this.speakerStreams.size <= this.MAX_CONCURRENT_STREAMS) {\n return;\n }\n\n this.log(\n `Stream limit exceeded (${this.speakerStreams.size}/${this.MAX_CONCURRENT_STREAMS}), cleaning up oldest streams`,\n );\n\n // Sort streams by creation time and remove oldest ones\n const sortedStreams = Array.from(this.speakerStreams.entries()).sort(\n ([, a], [, b]) => (a.created || 0) - (b.created || 0),\n );\n\n const streamsToRemove = sortedStreams.slice(0, this.speakerStreams.size - this.MAX_CONCURRENT_STREAMS);\n\n for (const [responseId, stream] of streamsToRemove) {\n if (!stream.destroyed) {\n stream.end();\n }\n this.speakerStreams.delete(responseId);\n this.log(`Removed old stream for response: ${responseId}`);\n }\n } catch (error) {\n this.log('Error enforcing stream limits:', error);\n }\n }\n\n /**\n * Get information about current streams for debugging\n */\n getStreamInfo(): {\n totalStreams: number;\n currentResponseId?: string;\n streamDetails: Array<{ responseId: string; created: number; destroyed: boolean }>;\n } {\n const streamDetails = Array.from(this.speakerStreams.entries()).map(([responseId, stream]) => ({\n responseId,\n created: stream.created || 0,\n destroyed: stream.destroyed,\n }));\n\n return {\n totalStreams: this.speakerStreams.size,\n currentResponseId: this.currentResponseId,\n streamDetails,\n };\n }\n\n /**\n * Convert Int16Array audio data to base64 string for WebSocket transmission\n */\n int16ArrayToBase64(int16Array: Int16Array): string {\n const buffer = new ArrayBuffer(int16Array.length * 2);\n const view = new DataView(buffer);\n\n // Convert Int16Array to bytes with little-endian format\n for (let i = 0; i < int16Array.length; i++) {\n view.setInt16(i * 2, int16Array[i]!, true);\n }\n\n const nodeBuffer = Buffer.from(buffer);\n return nodeBuffer.toString('base64');\n }\n\n /**\n * Convert base64 string to Int16Array audio data\n */\n base64ToInt16Array(base64Audio: string): Int16Array {\n try {\n const buffer = Buffer.from(base64Audio, 'base64');\n\n // Convert Buffer to Int16Array\n if (buffer.length % 2 !== 0) {\n throw new Error('Invalid audio data: buffer length must be even for 16-bit audio');\n }\n\n return new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 2);\n } catch (error) {\n throw new Error(\n `Failed to decode base64 audio data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Validate and convert audio data to the required format for Gemini Live API\n * Gemini Live expects 16kHz PCM16 for input\n */\n validateAndConvertAudioInput(audioData: Buffer | Int16Array): Int16Array {\n if (Buffer.isBuffer(audioData)) {\n // Convert Buffer to Int16Array\n if (audioData.length % 2 !== 0) {\n throw new Error('Audio buffer length must be even for 16-bit audio');\n }\n return new Int16Array(audioData.buffer, audioData.byteOffset, audioData.byteLength / 2);\n }\n\n if (audioData instanceof Int16Array) {\n return audioData;\n }\n\n throw new Error('Unsupported audio data format. Expected Buffer or Int16Array');\n }\n\n /**\n * Process audio chunk for streaming - handles format validation and conversion\n */\n processAudioChunk(chunk: Buffer | Uint8Array | Int16Array): string {\n let int16Array: Int16Array;\n\n if (chunk instanceof Int16Array) {\n int16Array = chunk;\n } else if (Buffer.isBuffer(chunk)) {\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n int16Array = new Int16Array(chunk.buffer, chunk.byteOffset, chunk.byteLength / 2);\n } else if (chunk instanceof Uint8Array) {\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n int16Array = new Int16Array(chunk.buffer, chunk.byteOffset, chunk.byteLength / 2);\n } else {\n throw new Error('Unsupported audio chunk format');\n }\n\n return this.int16ArrayToBase64(int16Array);\n }\n\n /**\n * Validate audio format and sample rate for Gemini Live API requirements\n */\n validateAudioFormat(sampleRate?: number, channels?: number): void {\n if (sampleRate && sampleRate !== this.audioConfig.inputSampleRate) {\n this.log(\n `Warning: Audio sample rate ${sampleRate}Hz does not match expected ${this.audioConfig.inputSampleRate}Hz`,\n );\n }\n\n if (channels && channels !== this.audioConfig.channels) {\n throw new Error(`Unsupported channel count: ${channels}. Gemini Live API requires mono audio (1 channel)`);\n }\n }\n\n /**\n * Create an audio message for the Gemini Live API\n */\n createAudioMessage(audioData: string, messageType: 'input' | 'realtime' = 'realtime'): Record<string, unknown> {\n if (messageType === 'input') {\n // For conversation item creation (traditional listen method)\n return {\n client_content: {\n turns: [\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n mimeType: 'audio/pcm',\n data: audioData,\n },\n },\n ],\n },\n ],\n turnComplete: true,\n },\n };\n } else {\n // For real-time streaming\n return {\n realtime_input: {\n media_chunks: [\n {\n mime_type: 'audio/pcm',\n data: audioData,\n },\n ],\n },\n };\n }\n }\n\n /**\n * Get a speaker stream by response ID\n */\n getSpeakerStream(responseId: string): PassThrough | undefined {\n return this.speakerStreams.get(responseId);\n }\n\n /**\n * Create a new speaker stream for a response ID\n */\n createSpeakerStream(responseId: string): PassThrough {\n const stream = new PassThrough() as PassThrough & { id?: string; created?: number };\n stream.id = responseId;\n stream.created = Date.now();\n\n // Add the stream to the manager\n this.addSpeakerStream(responseId, stream);\n\n return stream;\n }\n\n /**\n * Get the number of active streams\n */\n getActiveStreamCount(): number {\n return this.speakerStreams.size;\n }\n\n /**\n * Check if a specific response ID has an active stream\n */\n hasStream(responseId: string): boolean {\n return this.speakerStreams.has(responseId);\n }\n\n /**\n * Get all active response IDs\n */\n getActiveResponseIds(): string[] {\n return Array.from(this.speakerStreams.keys());\n }\n\n /**\n * Reset the manager state (useful for testing or reconnection)\n */\n reset(): void {\n this.cleanupSpeakerStreams();\n this.currentResponseId = undefined;\n this.log('AudioStreamManager reset');\n }\n\n /**\n * Validate audio chunk size and format\n */\n validateAudioChunk(chunk: Buffer): void {\n if (chunk.length === 0) {\n throw new Error('Audio chunk cannot be empty');\n }\n\n if (chunk.length > this.maxChunkSize) {\n throw new Error(`Audio chunk size ${chunk.length} exceeds maximum allowed size ${this.maxChunkSize}`);\n }\n\n if (chunk.length % 2 !== 0) {\n throw new Error('Audio chunk length must be even for 16-bit audio');\n }\n }\n\n /**\n * Send audio chunk with throttling and validation\n */\n sendAudioChunk(chunk: Buffer): void {\n try {\n this.validateAudioChunk(chunk);\n\n const now = Date.now();\n if (now - this.lastSendTime < this.minSendInterval) {\n // Throttle if needed - enqueue for later processing\n this.pendingChunks.push({ chunk, timestamp: now });\n const delay = this.minSendInterval - (now - this.lastSendTime);\n if (!this.pendingTimer) {\n this.pendingTimer = setTimeout(\n () => {\n this.pendingTimer = undefined;\n this.processPendingChunks();\n },\n Math.max(0, delay),\n );\n }\n return;\n }\n\n this.processChunk(chunk);\n this.processPendingChunks();\n } catch (error) {\n this.log('Error sending audio chunk:', error);\n throw error;\n }\n }\n\n /**\n * Handle audio stream processing\n */\n async handleAudioStream(stream: NodeJS.ReadableStream): Promise<void> {\n return new Promise((resolve, reject) => {\n const cleanup = () => {\n stream.removeAllListeners();\n };\n\n stream.on('data', (chunk: Buffer) => {\n try {\n if (chunk.length > this.maxChunkSize) {\n // Split large chunks\n const chunks = this.splitAudioChunk(chunk);\n for (const subChunk of chunks) {\n this.validateAudioChunk(subChunk);\n this.sendAudioChunk(subChunk);\n }\n } else {\n this.validateAudioChunk(chunk);\n this.sendAudioChunk(chunk);\n }\n } catch (error) {\n cleanup();\n reject(error);\n }\n });\n\n stream.on('end', () => {\n cleanup();\n resolve();\n });\n\n stream.on('error', error => {\n cleanup();\n reject(error);\n });\n });\n }\n\n /**\n * Split large audio chunks into smaller ones\n */\n private splitAudioChunk(chunk: Buffer): Buffer[] {\n const chunks: Buffer[] = [];\n let offset = 0;\n\n while (offset < chunk.length) {\n const size = Math.min(this.maxChunkSize, chunk.length - offset);\n chunks.push(chunk.subarray(offset, offset + size));\n offset += size;\n }\n\n return chunks;\n }\n\n /**\n * Calculate audio duration from buffer length\n */\n calculateAudioDuration(bufferLength: number, sampleRate?: number): number {\n const effectiveSampleRate = sampleRate || this.audioConfig.inputSampleRate;\n return bufferLength / (effectiveSampleRate * 2); // 2 bytes per sample for 16-bit audio\n }\n\n /**\n * Validate audio buffer size and duration\n */\n validateAudioBuffer(buffer: Buffer): void {\n if (buffer.length === 0) {\n throw new Error('Audio buffer cannot be empty');\n }\n\n if (buffer.length > this.MAX_BUFFER_SIZE) {\n throw new Error(\n `Audio buffer size ${buffer.length} exceeds maximum allowed size ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`,\n );\n }\n\n if (buffer.length % 2 !== 0) {\n throw new Error('Audio buffer length must be even for 16-bit audio');\n }\n\n const duration = this.calculateAudioDuration(buffer.length);\n if (duration > this.MAX_AUDIO_DURATION) {\n throw new Error(\n `Audio duration ${duration.toFixed(2)}s exceeds maximum allowed duration ${this.MAX_AUDIO_DURATION}s`,\n );\n }\n }\n\n /**\n * Process audio buffer for transcription\n * Combines chunks, validates format, and converts to base64\n */\n processAudioBufferForTranscription(audioBuffer: Buffer): { base64Audio: string; duration: number; size: number } {\n // Validate audio format\n if (audioBuffer.length % 2 !== 0) {\n throw new Error('Invalid audio data: buffer length must be even for 16-bit audio');\n }\n\n // Calculate duration\n const duration = this.calculateAudioDuration(audioBuffer.length);\n\n // Convert to base64\n const base64Audio = audioBuffer.toString('base64');\n\n return {\n base64Audio,\n duration,\n size: audioBuffer.length,\n };\n }\n\n /**\n * Process audio chunks for transcription with buffer management\n * Handles chunk collection, size validation, and buffer management\n */\n processAudioChunksForTranscription(\n chunks: Buffer[],\n totalBufferSize: number,\n ): { audioBuffer: Buffer; base64Audio: string; duration: number; size: number } {\n // Check buffer size to prevent memory overflow\n if (totalBufferSize > this.MAX_BUFFER_SIZE) {\n throw new Error(`Audio data exceeds maximum size of ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`);\n }\n\n // Combine all chunks\n const audioBuffer = Buffer.concat(chunks);\n\n // Process for transcription\n const result = this.processAudioBufferForTranscription(audioBuffer);\n\n return {\n audioBuffer,\n ...result,\n };\n }\n\n /**\n * Validate audio chunks and calculate total size\n */\n validateAudioChunks(chunks: Buffer[]): { totalSize: number; isValid: boolean; error?: string } {\n let totalSize = 0;\n\n for (const chunk of chunks) {\n if (!Buffer.isBuffer(chunk)) {\n return { totalSize: 0, isValid: false, error: 'Invalid chunk format' };\n }\n\n totalSize += chunk.length;\n\n if (totalSize > this.MAX_BUFFER_SIZE) {\n return {\n totalSize,\n isValid: false,\n error: `Total size ${totalSize} exceeds maximum allowed size ${this.MAX_BUFFER_SIZE}`,\n };\n }\n }\n\n return { totalSize, isValid: true };\n }\n\n /**\n * Get audio buffer limits and configuration\n */\n getAudioBufferLimits(): { maxBufferSize: number; maxAudioDuration: number; maxChunkSize: number } {\n return {\n maxBufferSize: this.MAX_BUFFER_SIZE,\n maxAudioDuration: this.MAX_AUDIO_DURATION,\n maxChunkSize: this.maxChunkSize,\n };\n }\n\n /**\n * Get audio configuration\n */\n getAudioConfig(): AudioConfig {\n return this.audioConfig;\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[AudioStreamManager] ${message}`, ...args);\n }\n }\n\n /**\n * Handle complete audio transcription workflow\n * Manages stream processing, chunk collection, and transcription\n */\n async handleAudioTranscription(\n audioStream: NodeJS.ReadableStream,\n sendAndAwaitTranscript: (base64Audio: string) => Promise<string>,\n onError: (error: Error) => void,\n timeoutMs: number = 30000,\n ): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const chunks: Buffer[] = [];\n let isCleanedUp = false;\n let totalBufferSize = 0;\n let isResolved = false;\n\n // Set up timeout\n const timeout = setTimeout(() => {\n if (!isResolved) {\n cleanup();\n reject(new Error(`Transcription timeout - no response received within ${timeoutMs / 1000} seconds`));\n }\n }, timeoutMs);\n\n // Stream event handlers\n const onStreamData = (chunk: Buffer) => {\n try {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n\n // Check buffer size to prevent memory overflow\n totalBufferSize += buffer.length;\n if (totalBufferSize > this.MAX_BUFFER_SIZE) {\n cleanup();\n reject(new Error(`Audio data exceeds maximum size of ${this.MAX_BUFFER_SIZE / (1024 * 1024)}MB`));\n return;\n }\n\n chunks.push(buffer);\n } catch (error) {\n cleanup();\n reject(\n new Error(`Failed to process audio chunk: ${error instanceof Error ? error.message : 'Unknown error'}`),\n );\n }\n };\n\n const onStreamError = (error: Error) => {\n cleanup();\n reject(new Error(`Audio stream error: ${error.message}`));\n };\n\n const onStreamEnd = async () => {\n try {\n // Remove stream listeners as we're done with the stream\n audioStream.removeListener('data', onStreamData);\n audioStream.removeListener('error', onStreamError);\n\n // Process chunks for transcription\n const result = this.processAudioChunksForTranscription(chunks, totalBufferSize);\n\n this.log('Processing audio for transcription:', {\n chunks: chunks.length,\n totalSize: result.size,\n duration: result.duration,\n });\n\n // Send audio and await the transcript from the caller\n try {\n const transcript = await sendAndAwaitTranscript(result.base64Audio);\n if (!isResolved) {\n isResolved = true;\n cleanup();\n resolve(transcript.trim());\n }\n } catch (error) {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(\n new Error(\n `Failed to obtain transcription: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n );\n }\n }\n } catch (error) {\n cleanup();\n reject(\n new Error(`Failed to process audio stream: ${error instanceof Error ? error.message : 'Unknown error'}`),\n );\n }\n };\n\n // Comprehensive cleanup function\n const cleanup = () => {\n if (isCleanedUp) return; // Prevent double cleanup\n isCleanedUp = true;\n\n // Clear all timers\n clearTimeout(timeout);\n\n // Remove stream event listeners\n audioStream.removeListener('data', onStreamData);\n audioStream.removeListener('error', onStreamError);\n audioStream.removeListener('end', onStreamEnd);\n\n // Clear chunks array to free memory\n chunks.length = 0;\n };\n\n // Set up stream event listeners\n audioStream.on('data', onStreamData);\n audioStream.on('error', onStreamError);\n audioStream.on('end', onStreamEnd);\n });\n }\n\n private processChunk(chunk: Buffer): void {\n // Convert raw audio buffer to base64 PCM16 and build message\n const base64Audio = this.processAudioChunk(chunk);\n const message = this.createAudioMessage(base64Audio, 'realtime');\n\n // Send via injected sender\n if (this.sendToGemini) {\n this.sendToGemini('realtime_input', message);\n } else {\n this.log('No sender configured for AudioStreamManager; dropping audio chunk');\n }\n\n // Update throttle timing and log\n this.lastSendTime = Date.now();\n this.log(`Sent audio chunk of size: ${chunk.length} bytes`);\n }\n\n private processPendingChunks(): void {\n while (this.pendingChunks.length > 0) {\n const nextChunk = this.pendingChunks[0];\n const now = Date.now();\n if (nextChunk && now - this.lastSendTime >= this.minSendInterval) {\n this.pendingChunks.shift();\n this.processChunk(nextChunk.chunk);\n } else {\n const delay = this.minSendInterval - (now - this.lastSendTime);\n if (!this.pendingTimer) {\n this.pendingTimer = setTimeout(\n () => {\n this.pendingTimer = undefined;\n this.processPendingChunks();\n },\n Math.max(0, delay),\n );\n }\n break;\n }\n }\n }\n}\n","import type { GeminiLiveErrorCode } from '../types';\n\n/**\n * Helper class for consistent error handling across managers and provider\n */\nexport class GeminiLiveError extends Error {\n public readonly code: string;\n public readonly details?: unknown;\n public readonly timestamp: number;\n\n constructor(code: GeminiLiveErrorCode | string, message: string, details?: unknown) {\n super(message);\n this.name = 'GeminiLiveError';\n this.code = code;\n this.details = details;\n this.timestamp = Date.now();\n }\n\n toEventData() {\n return {\n message: this.message,\n code: this.code,\n details: this.details,\n timestamp: this.timestamp,\n };\n }\n}\n","import { EventEmitter } from 'events';\nimport { WebSocket } from 'ws';\nimport { GeminiLiveErrorCode } from '../types';\nimport { GeminiLiveError } from '../utils/errors';\n\nexport interface ConnectionConfig {\n debug: boolean;\n timeoutMs?: number;\n}\n\nexport class ConnectionManager {\n private ws?: WebSocket;\n private eventEmitter: EventEmitter;\n private readonly debug: boolean;\n private readonly timeoutMs: number;\n\n constructor(config: ConnectionConfig) {\n this.eventEmitter = new EventEmitter();\n this.debug = config.debug;\n this.timeoutMs = config.timeoutMs || 30000;\n }\n\n /**\n * Set the WebSocket instance\n */\n setWebSocket(ws: WebSocket): void {\n this.ws = ws;\n }\n\n /**\n * Get the current WebSocket instance\n */\n getWebSocket(): WebSocket | undefined {\n return this.ws;\n }\n\n /**\n * Check if WebSocket is connected\n */\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Check if WebSocket is connecting\n */\n isConnecting(): boolean {\n return this.ws?.readyState === WebSocket.CONNECTING;\n }\n\n /**\n * Check if WebSocket is closed\n */\n isClosed(): boolean {\n return this.ws?.readyState === WebSocket.CLOSED;\n }\n\n /**\n * Wait for WebSocket to open\n */\n async waitForOpen(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.ws) {\n reject(new Error('WebSocket not initialized'));\n return;\n }\n\n // If already open, resolve immediately\n if (this.ws.readyState === WebSocket.OPEN) {\n resolve();\n return;\n }\n\n // Set up event listeners with cleanup\n const onOpen = () => {\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(new Error(`WebSocket connection failed: ${error.message}`));\n };\n\n const onClose = () => {\n cleanup();\n reject(new Error('WebSocket connection closed before opening'));\n };\n\n const cleanup = () => {\n this.ws?.removeListener('open', onOpen);\n this.ws?.removeListener('error', onError);\n this.ws?.removeListener('close', onClose);\n };\n\n // Add event listeners\n this.ws.once('open', onOpen);\n this.ws.once('error', onError);\n this.ws.once('close', onClose);\n\n // Add timeout to prevent hanging indefinitely\n setTimeout(() => {\n cleanup();\n reject(new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_FAILED, 'WebSocket connection timeout'));\n }, this.timeoutMs);\n });\n }\n\n /**\n * Send data through WebSocket\n */\n send(data: string | Buffer): void {\n if (!this.ws) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket not initialized');\n }\n\n if (this.ws.readyState !== WebSocket.OPEN) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket is not open');\n }\n\n this.ws.send(data);\n }\n\n /**\n * Close the WebSocket connection\n */\n close(): void {\n if (this.ws) {\n this.ws.close();\n this.ws = undefined;\n }\n }\n\n /**\n * Get connection state\n */\n getConnectionState(): 'disconnected' | 'connecting' | 'connected' | 'closed' {\n if (!this.ws) return 'disconnected';\n\n switch (this.ws.readyState) {\n case WebSocket.CONNECTING:\n return 'connecting';\n case WebSocket.OPEN:\n return 'connected';\n case WebSocket.CLOSED:\n return 'closed';\n default:\n return 'disconnected';\n }\n }\n\n /**\n * Validate WebSocket state for operations\n */\n validateWebSocketState(): void {\n if (!this.ws) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket not initialized');\n }\n\n if (this.ws.readyState !== WebSocket.OPEN) {\n throw new GeminiLiveError(GeminiLiveErrorCode.CONNECTION_NOT_ESTABLISHED, 'WebSocket is not open');\n }\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[ConnectionManager] ${message}`, ...args);\n }\n }\n}\n","export interface ContextEntry {\n role: 'user' | 'assistant';\n content: string;\n timestamp: number;\n}\n\nexport interface ContextConfig {\n maxEntries?: number;\n maxContentLength?: number;\n compressionThreshold?: number;\n compressionEnabled?: boolean;\n}\n\nexport class ContextManager {\n private contextHistory: ContextEntry[] = [];\n private readonly maxEntries: number;\n private readonly maxContentLength: number;\n private readonly compressionThreshold: number;\n private compressionEnabled: boolean;\n\n constructor(config: ContextConfig = {}) {\n this.maxEntries = config.maxEntries || 100;\n this.maxContentLength = config.maxContentLength || 10000; // 10KB per entry\n this.compressionThreshold = config.compressionThreshold || 50;\n this.compressionEnabled = config.compressionEnabled ?? false;\n }\n\n /**\n * Add entry to context history\n */\n addEntry(role: 'user' | 'assistant', content: string): void {\n // Validate content length\n let processedContent = content;\n if (content.length > this.maxContentLength) {\n processedContent = content.substring(0, this.maxContentLength) + '...';\n }\n\n const entry: ContextEntry = {\n role,\n content: processedContent,\n timestamp: Date.now(),\n };\n\n this.contextHistory.push(entry);\n\n if (this.contextHistory.length > this.maxEntries) {\n if (this.compressionEnabled) {\n this.compressContext();\n } else {\n this.contextHistory = this.contextHistory.slice(-this.maxEntries);\n }\n }\n }\n\n /**\n * Get context history\n */\n getContextHistory(): ContextEntry[] {\n return [...this.contextHistory];\n }\n\n /**\n * Get context history as array of role/content pairs\n */\n getContextArray(): Array<{ role: string; content: string }> {\n return this.contextHistory.map(entry => ({\n role: entry.role,\n content: entry.content,\n }));\n }\n\n /**\n * Clear context history\n */\n clearContext(): void {\n this.contextHistory = [];\n }\n\n /**\n * Get context size\n */\n getContextSize(): number {\n return this.contextHistory.length;\n }\n\n /**\n * Compress context when it exceeds threshold\n */\n private compressContext(): void {\n if (!this.compressionEnabled || this.contextHistory.length <= this.compressionThreshold) {\n return;\n }\n\n // Keep first and last entries, compress middle ones\n const keepCount = Math.floor(this.compressionThreshold / 3);\n const firstEntries = this.contextHistory.slice(0, keepCount);\n const lastEntries = this.contextHistory.slice(-keepCount);\n\n // Create compressed middle entry\n const middleEntries = this.contextHistory.slice(keepCount, -keepCount);\n if (middleEntries.length > 0) {\n const compressedEntry: ContextEntry = {\n role: 'assistant',\n content: `[Compressed ${middleEntries.length} previous messages]`,\n timestamp: Date.now(),\n };\n\n this.contextHistory = [...firstEntries, compressedEntry, ...lastEntries];\n } else {\n this.contextHistory = [...firstEntries, ...lastEntries];\n }\n }\n\n /**\n * Enable or disable compression at runtime\n */\n setCompressionEnabled(enabled: boolean): void {\n this.compressionEnabled = enabled;\n }\n\n /**\n * Get context summary\n */\n getContextSummary(): {\n totalEntries: number;\n userEntries: number;\n assistantEntries: number;\n oldestTimestamp: number | null;\n newestTimestamp: number | null;\n } {\n if (this.contextHistory.length === 0) {\n return {\n totalEntries: 0,\n userEntries: 0,\n assistantEntries: 0,\n oldestTimestamp: null,\n newestTimestamp: null,\n };\n }\n\n const userEntries = this.contextHistory.filter(entry => entry.role === 'user').length;\n const assistantEntries = this.contextHistory.filter(entry => entry.role === 'assistant').length;\n const timestamps = this.contextHistory.map(entry => entry.timestamp);\n\n return {\n totalEntries: this.contextHistory.length,\n userEntries,\n assistantEntries,\n oldestTimestamp: Math.min(...timestamps),\n newestTimestamp: Math.max(...timestamps),\n };\n }\n\n /**\n * Search context for specific content\n */\n searchContext(query: string, role?: 'user' | 'assistant'): ContextEntry[] {\n const searchQuery = query.toLowerCase();\n\n return this.contextHistory.filter(entry => {\n const matchesRole = role ? entry.role === role : true;\n const matchesContent = entry.content.toLowerCase().includes(searchQuery);\n\n return matchesRole && matchesContent;\n });\n }\n\n /**\n * Get recent context entries\n */\n getRecentEntries(count: number): ContextEntry[] {\n return this.contextHistory.slice(-count);\n }\n\n /**\n * Get context entries by role\n */\n getEntriesByRole(role: 'user' | 'assistant'): ContextEntry[] {\n return this.contextHistory.filter(entry => entry.role === role);\n }\n}\n","import { GoogleAuth } from 'google-auth-library';\nimport { GeminiLiveErrorCode } from '../types';\nimport type { AuthOptions } from '../types';\nimport { GeminiLiveError } from '../utils/errors';\n\nexport interface AuthConfig {\n apiKey?: string;\n vertexAI?: boolean;\n project?: string;\n debug: boolean;\n serviceAccountKeyFile?: string;\n serviceAccountEmail?: string;\n tokenExpirationTime?: number;\n}\n\nexport class AuthManager {\n private authClient?: GoogleAuth;\n private accessToken?: string;\n private tokenExpirationTime?: number;\n private readonly config: AuthConfig;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.tokenExpirationTime = config.tokenExpirationTime ?? 50 * 60 * 1000;\n }\n\n /**\n * Initialize authentication based on configuration\n */\n async initialize(): Promise<void> {\n if (this.config.vertexAI) {\n await this.initializeVertexAI();\n } else if (this.config.apiKey) {\n // API key auth doesn't need initialization\n return;\n } else {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.API_KEY_MISSING,\n 'Either API key or Vertex AI configuration is required',\n );\n }\n }\n\n /**\n * Initialize Vertex AI authentication\n */\n private async initializeVertexAI(): Promise<void> {\n if (!this.config.project) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.PROJECT_ID_MISSING,\n 'Google Cloud project ID is required when using Vertex AI',\n );\n }\n\n const authOptions: AuthOptions = {\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n projectId: this.config.project,\n };\n\n // Support service account key file\n if (this.config.serviceAccountKeyFile) {\n authOptions.keyFilename = this.config.serviceAccountKeyFile;\n this.log('Using service account key file for authentication:', this.config.serviceAccountKeyFile);\n }\n\n // Support impersonation via service account email\n if (this.config.serviceAccountEmail) {\n authOptions.clientOptions = { subject: this.config.serviceAccountEmail };\n this.log('Using service account impersonation:', this.config.serviceAccountEmail);\n }\n\n try {\n this.authClient = new GoogleAuth(authOptions);\n } catch (error) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.AUTHENTICATION_FAILED,\n `Failed to initialize Vertex AI authentication: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get access token for Vertex AI\n */\n async getAccessToken(): Promise<string> {\n if (!this.config.vertexAI) {\n throw new GeminiLiveError(GeminiLiveErrorCode.AUTHENTICATION_FAILED, 'Vertex AI authentication not configured');\n }\n\n if (!this.authClient) {\n throw new GeminiLiveError(GeminiLiveErrorCode.AUTHENTICATION_FAILED, 'Authentication client not initialized');\n }\n\n // Check if we have a valid cached token\n if (this.accessToken && this.tokenExpirationTime && Date.now() < this.tokenExpirationTime) {\n return this.accessToken;\n }\n\n try {\n const client = await this.authClient.getClient();\n const token = await client.getAccessToken();\n\n if (!token.token) {\n throw new Error('No access token received');\n }\n\n this.accessToken = token.token;\n\n // Set expiry time (tokens typically last 1 hour, so set to 50 minutes to be safe)\n this.tokenExpirationTime = Date.now() + 50 * 60 * 1000;\n\n this.log('Successfully obtained new access token');\n return this.accessToken;\n } catch (error) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.AUTHENTICATION_FAILED,\n `Failed to get access token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get API key if using API key authentication\n */\n getApiKey(): string | undefined {\n if (this.config.vertexAI) {\n return undefined;\n }\n return this.config.apiKey;\n }\n\n /**\n * Check if using Vertex AI authentication\n */\n isUsingVertexAI(): boolean {\n return this.config.vertexAI === true;\n }\n\n /**\n * Check if authentication is configured\n */\n isConfigured(): boolean {\n return !!(this.config.apiKey || (this.config.vertexAI && this.config.project));\n }\n\n /**\n * Check if access token is valid\n */\n hasValidToken(): boolean {\n if (!this.config.vertexAI) return false;\n return !!(this.accessToken && this.tokenExpirationTime && Date.now() < this.tokenExpirationTime);\n }\n\n /**\n * Clear cached authentication data\n */\n clearCache(): void {\n this.accessToken = undefined;\n this.tokenExpirationTime = undefined;\n }\n\n /**\n * Get authentication configuration\n */\n getConfig(): AuthConfig {\n return { ...this.config };\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.config.debug) {\n console.info(`[AuthManager] ${message}`, ...args);\n }\n }\n}\n","import { EventEmitter } from 'events';\n// Make the event manager generic over an event map\nexport type EventMap = Record<string, unknown>;\n\nexport interface EventConfig {\n debug: boolean;\n}\n\nexport class EventManager<TEvents extends EventMap = Record<string, unknown>> {\n private eventEmitter: EventEmitter;\n private readonly debug: boolean;\n private eventCounts: Record<string, number> = {};\n\n constructor(config: EventConfig) {\n this.eventEmitter = new EventEmitter();\n this.debug = config.debug;\n }\n\n /**\n * Emit an event with data\n */\n emit<K extends Extract<keyof TEvents, string>>(event: K, data: TEvents[K]): boolean {\n this.incrementEventCount(event);\n const result = this.eventEmitter.emit(event, data);\n\n if (this.debug) {\n this.log(`Emitted event: ${event}`, data);\n }\n\n return result;\n }\n\n /**\n * Add event listener\n */\n on<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.on(event, callback);\n\n if (this.debug) {\n this.log(`Added listener for event: ${event}`);\n }\n }\n\n /**\n * Remove event listener\n */\n off<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.off(event, callback);\n\n if (this.debug) {\n this.log(`Removed listener for event: ${event}`);\n }\n }\n\n /**\n * Add one-time event listener\n */\n once<E extends Extract<keyof TEvents, string>>(event: E, callback: (data: TEvents[E]) => void): void {\n this.eventEmitter.once(event, callback);\n\n if (this.debug) {\n this.log(`Added one-time listener for event: ${event}`);\n }\n }\n\n /**\n * Remove all listeners for an event\n */\n removeAllListeners(event?: string): void {\n this.eventEmitter.removeAllListeners(event);\n\n if (this.debug) {\n this.log(`Removed all listeners${event ? ` for event: ${event}` : ''}`);\n }\n }\n\n /**\n * Get event listener count\n */\n getListenerCount(event: string): number {\n return this.eventEmitter.listenerCount(event);\n }\n\n /**\n * Get event listener info\n */\n getEventListenerInfo(): Record<string, number> {\n const events = this.eventEmitter.eventNames();\n const info: Record<string, number> = {};\n\n events.forEach(event => {\n const eventName = typeof event === 'string' ? event : event.toString();\n info[eventName] = this.eventEmitter.listenerCount(event);\n });\n\n return info;\n }\n\n /**\n * Get event emission counts\n */\n getEventCounts(): Record<string, number> {\n return { ...this.eventCounts };\n }\n\n /**\n * Reset event counts\n */\n resetEventCounts(): void {\n this.eventCounts = {};\n }\n\n /**\n * Clean up event listeners\n */\n cleanup(): void {\n this.eventEmitter.removeAllListeners();\n this.resetEventCounts();\n\n if (this.debug) {\n this.log('Cleaned up all event listeners');\n }\n }\n\n /**\n * Get the underlying EventEmitter\n */\n getEventEmitter(): EventEmitter {\n return this.eventEmitter;\n }\n\n /**\n * Increment event count for tracking\n */\n private incrementEventCount(event: string): void {\n this.eventCounts[event] = (this.eventCounts[event] || 0) + 1;\n }\n\n /**\n * Log message if debug is enabled\n */\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[EventManager] ${message}`, ...args);\n }\n }\n}\n","import { randomUUID } from 'crypto';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport { MastraVoice } from '@mastra/core/voice';\nimport type { VoiceEventType, VoiceConfig } from '@mastra/core/voice';\nimport type { WebSocket as WSType } from 'ws';\nimport { WebSocket } from 'ws';\nimport { AudioStreamManager, ConnectionManager, ContextManager, AuthManager, EventManager } from './managers';\nimport { GeminiLiveErrorCode } from './types';\nimport type {\n GeminiLiveVoiceConfig,\n GeminiLiveVoiceOptions,\n GeminiLiveEventMap,\n GeminiVoiceModel,\n GeminiVoiceName,\n GeminiToolConfig,\n AudioConfig,\n GeminiLiveServerMessage,\n GeminiSessionConfig,\n UpdateMessage,\n} from './types';\nimport { GeminiLiveError } from './utils/errors';\n\n// Narrow event keys to strings for the typed EventManager\ntype GeminiEventName = Extract<keyof GeminiLiveEventMap, string>;\n\n/**\n * Default configuration values\n */\nconst DEFAULT_MODEL: GeminiVoiceModel = 'gemini-2.0-flash-exp';\nconst DEFAULT_VOICE: GeminiVoiceName = 'Puck';\n\n/**\n * Helper class for consistent error handling\n */\n// GeminiLiveError is now defined in types.ts for reuse across managers\n\n/**\n * GeminiLiveVoice provides real-time multimodal voice interactions using Google's Gemini Live API.\n *\n * Features:\n * - Bidirectional audio streaming\n * - Built-in VAD and interrupt handling\n * - Tool calling capabilities\n * - Session management and resumption\n * - Live transcription\n * - Support for both Gemini API and Vertex AI\n *\n * @example Backward compatibility - Direct options (legacy)\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * apiKey: 'your-api-key',\n * model: 'gemini-2.0-flash-live-001',\n * speaker: 'Puck',\n * instructions: 'You are a helpful assistant'\n * });\n * ```\n *\n * @example Mastra VoiceConfig pattern - Recommended\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * speechModel: { name: 'gemini-2.0-flash-live-001', apiKey: 'your-api-key' },\n * speaker: 'Puck',\n * realtimeConfig: {\n * model: 'gemini-2.0-flash-live-001',\n * apiKey: 'your-api-key',\n * options: {\n * instructions: 'You are a helpful assistant',\n * debug: true\n * }\n * }\n * });\n * ```\n *\n * @example Using Vertex AI (with OAuth)\n * ```typescript\n * const voice = new GeminiLiveVoice({\n * realtimeConfig: {\n * model: 'gemini-2.0-flash-live-001',\n * options: {\n * vertexAI: true,\n * project: 'your-gcp-project',\n * location: 'us-central1',\n * serviceAccountKeyFile: '/path/to/service-account.json',\n * }\n * }\n * });\n * ```\n */\nexport class GeminiLiveVoice extends MastraVoice<\n GeminiLiveVoiceConfig,\n GeminiLiveVoiceOptions,\n GeminiLiveVoiceOptions,\n ToolsInput,\n GeminiLiveEventMap\n> {\n private ws?: WSType;\n private eventManager: EventManager;\n private state: 'disconnected' | 'connected' = 'disconnected';\n private sessionHandle?: string;\n private readonly debug: boolean;\n private readonly audioConfig: AudioConfig;\n private queue: unknown[] = [];\n\n // Managers\n private connectionManager: ConnectionManager;\n private contextManager: ContextManager;\n private authManager: AuthManager;\n\n // Audio chunk concatenation - optimized stream management\n private audioStreamManager: AudioStreamManager;\n\n // Session management properties\n private sessionId?: string;\n private sessionStartTime?: number;\n private isResuming = false;\n private sessionDurationTimeout?: NodeJS.Timeout;\n\n // Tool integration properties\n private tools?: ToolsInput;\n private requestContext?: any;\n\n // Store the configuration options\n private options: GeminiLiveVoiceConfig;\n\n /**\n * Normalize configuration to ensure proper VoiceConfig format\n * Handles backward compatibility with direct GeminiLiveVoiceConfig\n * @private\n */\n private static normalizeConfig(\n config: VoiceConfig<GeminiLiveVoiceConfig> | GeminiLiveVoiceConfig,\n ): VoiceConfig<GeminiLiveVoiceConfig> {\n // Check if this is already a proper VoiceConfig (has realtimeConfig or standard VoiceConfig properties)\n if ('realtimeConfig' in config || 'speechModel' in config || 'listeningModel' in config) {\n return config as VoiceConfig<GeminiLiveVoiceConfig>;\n }\n\n // Convert direct GeminiLiveVoiceConfig to VoiceConfig format\n const geminiConfig = config as GeminiLiveVoiceConfig;\n return {\n speechModel: {\n name: geminiConfig.model || DEFAULT_MODEL,\n apiKey: geminiConfig.apiKey,\n },\n speaker: geminiConfig.speaker || DEFAULT_VOICE,\n realtimeConfig: {\n model: geminiConfig.model || DEFAULT_MODEL,\n apiKey: geminiConfig.apiKey,\n options: geminiConfig,\n },\n };\n }\n\n /**\n * Creates a new GeminiLiveVoice instance\n *\n * @param config Configuration options\n */\n constructor(config: VoiceConfig<GeminiLiveVoiceConfig> | GeminiLiveVoiceConfig = {}) {\n // Handle backward compatibility - if config has Gemini-specific properties directly,\n // convert to proper VoiceConfig format\n const normalizedConfig = GeminiLiveVoice.normalizeConfig(config);\n super(normalizedConfig);\n\n // Extract options from realtimeConfig\n this.options = normalizedConfig.realtimeConfig?.options || {};\n\n // Validate API key\n const apiKey = this.options.apiKey;\n if (!apiKey && !this.options.vertexAI) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.API_KEY_MISSING,\n 'Google API key is required. Set GOOGLE_API_KEY environment variable or pass apiKey to constructor',\n );\n }\n\n this.debug = this.options.debug || false;\n\n // Merge provided audio config with defaults\n this.audioConfig = {\n ...AudioStreamManager.getDefaultAudioConfig(),\n ...this.options.audioConfig,\n };\n\n // Initialize AudioStreamManager\n this.audioStreamManager = new AudioStreamManager(this.audioConfig, this.debug);\n // Inject sender so AudioStreamManager can deliver realtime audio\n this.audioStreamManager.setSender((type, message) => this.sendEvent(type, message));\n\n this.eventManager = new EventManager<GeminiLiveEventMap>({ debug: this.debug });\n this.connectionManager = new ConnectionManager({ debug: this.debug, timeoutMs: 30000 });\n this.contextManager = new ContextManager({\n maxEntries: 100,\n compressionThreshold: 50,\n compressionEnabled: this.options.sessionConfig?.contextCompression ?? false,\n });\n this.authManager = new AuthManager({\n apiKey: this.options.apiKey,\n vertexAI: this.options.vertexAI,\n project: this.options.project,\n serviceAccountKeyFile: this.options.serviceAccountKeyFile,\n serviceAccountEmail: this.options.serviceAccountEmail,\n debug: this.debug,\n tokenExpirationTime: this.options.tokenExpirationTime,\n });\n\n if (this.options.vertexAI && !this.options.project) {\n throw new GeminiLiveError(\n GeminiLiveErrorCode.PROJECT_ID_MISSING,\n 'Google Cloud project ID is required when using Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or pass project to constructor',\n );\n }\n\n // Auth initialization handled by AuthManager during connect\n }\n\n /**\n * Register an event listener\n * @param event Event name (e.g., 'speaking', 'writing', 'error', 'speaker')\n * @param callback Callback function that receives event data\n *\n * @example\n * ```typescript\n * // Listen for audio responses\n * voice.on('speaking', ({ audio, audioData, sampleRate }) => {\n * console.log('Received audio chunk:', audioData.length);\n * });\n *\n * // Listen for text responses and transcriptions\n * voice.on('writing', ({ text, role }) => {\n * console.log(`${role}: ${text}`);\n * });\n *\n * // Listen for audio streams (for concatenated playback)\n * voice.on('speaker', (audioStream) => {\n * audioStream.pipe(playbackDevice);\n * });\n *\n * // Handle errors\n * voice.on('error', ({ message, code, details }) => {\n * console.error('Voice error:', message);\n * });\n * ```\n */\n on<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.on(event as GeminiEventName, callback as any);\n this.log(`Event listener registered for: ${event}`);\n } catch (error) {\n this.log(`Failed to register event listener for ${event}:`, error);\n throw error;\n }\n }\n\n /**\n * Remove an event listener\n * @param event Event name\n * @param callback Callback function to remove\n */\n off<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.off(event as GeminiEventName, callback as any);\n this.log(`Event listener removed for: ${event}`);\n } catch (error) {\n this.log(`Failed to remove event listener for ${event}:`, error);\n }\n }\n\n /**\n * Register a one-time event listener that automatically removes itself after the first emission\n * @param event Event name\n * @param callback Callback function that receives event data\n */\n once<E extends VoiceEventType>(\n event: E,\n callback: (data: E extends keyof GeminiLiveEventMap ? GeminiLiveEventMap[E] : unknown) => void,\n ): void {\n try {\n this.eventManager.once(event as GeminiEventName, callback as any);\n this.log(`One-time event listener registered for: ${event}`);\n } catch (error) {\n this.log(`Failed to register one-time event listener for ${event}:`, error);\n throw error;\n }\n }\n\n /**\n * Emit an event to listeners with improved error handling\n * @private\n */\n private emit<K extends keyof GeminiLiveEventMap>(event: K, data: GeminiLiveEventMap[K]): boolean {\n try {\n const listenerCount = this.eventManager.getListenerCount(event as string);\n if (listenerCount === 0 && this.debug) {\n this.log(`No listeners for event: ${String(event)}`);\n }\n\n const result = this.eventManager.emit(event as GeminiEventName, data as any);\n\n if (this.debug && listenerCount > 0) {\n this.log(`Emitted event: ${String(event)} to ${listenerCount} listeners`);\n }\n\n return result;\n } catch (error) {\n this.log(`Error emitting event ${String(event)}:`, error);\n\n // Emit error event if this wasn't already an error event (prevent infinite loops)\n if (event !== 'error') {\n try {\n // Use underlying emitter directly to avoid recursion\n this.eventManager.getEventEmitter().emit('error', {\n message: `Failed to emit event: ${String(event)}`,\n code: 'event_emission_error',\n details: error,\n });\n } catch (nestedError) {\n // If we can't even emit the error event, log it\n this.log('Critical: Failed to emit error event:', nestedError);\n }\n }\n\n return false;\n }\n }\n\n /**\n * Clean up event listeners to prevent memory leaks\n * @private\n */\n private cleanupEventListeners(): void {\n try {\n // Get current listener counts for debugging\n const events = this.eventManager.getEventEmitter().eventNames();\n if (this.debug && events.length > 0) {\n this.log(\n 'Cleaning up event listeners:',\n events.map(event => `${String(event)}: ${this.eventManager.getListenerCount(String(event))}`).join(', '),\n );\n }\n\n // Remove all listeners\n this.eventManager.cleanup();\n\n this.log('Event listeners cleaned up');\n } catch (error) {\n this.log('Error cleaning up event listeners:', error);\n }\n }\n\n /**\n * Get current event listener information for debugging\n * @returns Object with event names and listener counts\n */\n getEventListenerInfo(): Record<string, number> {\n try {\n return this.eventManager.getEventListenerInfo();\n } catch (error) {\n this.log('Error getting event listener info:', error);\n return {} as Record<string, number>;\n }\n }\n\n /**\n * Create and emit a standardized error\n * @private\n */\n private createAndEmitError(code: GeminiLiveErrorCode, message: string, details?: unknown): GeminiLiveError {\n const error = new GeminiLiveError(code, message, details);\n this.log(`Error [${code}]: ${message}`, details);\n this.emit('error', error.toEventData());\n return error;\n }\n\n /**\n * Handle connection state validation with standardized errors\n * @private\n */\n private validateConnectionState(): void {\n if (this.state !== 'connected') {\n throw this.createAndEmitError(\n GeminiLiveErrorCode.NOT_CONNECTED,\n 'Not connected to Gemini Live API. Call connect() first.',\n { currentState: this.state },\n );\n }\n }\n\n /**\n * Handle WebSocket state validation with standardized errors\n * @private\n */\n private validateWebSocketState(): void {\n if (!this.connectionManager.isConnected()) {\n throw this.createAndEmitError(GeminiLiveErrorCode.WEBSOCKET_ERROR, 'WebSocket is not open', {\n wsExists: !!this.connectionManager.getWebSocket(),\n readyState: this.connectionManager.getWebSocket()?.readyState,\n expectedState: WebSocket.OPEN,\n });\n }\n }\n\n /**\n * Establish connection to the Gemini Live API\n */\n async connect({ requestContext }: { requestContext?: any } = {}): Promise<void> {\n if (this.state === 'connected') {\n this.log('Already connected to Gemini Live API');\n return;\n }\n\n // Store request context for tool execution\n this.requestContext = requestContext;\n\n // Emit connecting event\n this.emit('session', { state: 'connecting' });\n\n try {\n // Build WebSocket URL based on official Gemini Live API documentation\n let wsUrl: string;\n let headers: WebSocket.ClientOptions = {};\n\n if (this.options.vertexAI) {\n const location = this.getVertexLocation();\n // Vertex AI endpoint - using correct LlmBidiService endpoint\n wsUrl = `wss://${location}-aiplatform.googleapis.com/ws/google.cloud.aiplatform.v1beta1.LlmBidiService/BidiGenerateContent`;\n // Initialize auth and get token\n await this.authManager.initialize();\n const accessToken = await this.authManager.getAccessToken();\n headers = { headers: { Authorization: `Bearer ${accessToken}` } };\n this.log('Using Vertex AI authentication with OAuth token');\n } else {\n // Live API endpoint - this is specifically for the Live API\n wsUrl = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent`;\n headers = {\n headers: {\n 'x-goog-api-key': this.options.apiKey || '',\n 'Content-Type': 'application/json',\n },\n };\n this.log('Using Live API authentication with API key');\n }\n\n this.log('Connecting to:', wsUrl);\n this.ws = new WebSocket(wsUrl, undefined, headers);\n this.connectionManager.setWebSocket(this.ws);\n\n this.setupEventListeners();\n\n // Wait for WebSocket connection to open via ConnectionManager\n await this.connectionManager.waitForOpen();\n\n // Send initial configuration or resume session\n if (this.isResuming && this.sessionHandle) {\n await this.sendSessionResumption();\n } else {\n this.sendInitialConfig();\n this.sessionStartTime = Date.now();\n this.sessionId = randomUUID();\n }\n\n // Wait for session to be created after sending config\n await this.waitForSessionCreated();\n\n this.state = 'connected';\n\n // Emit session connected event\n this.emit('session', {\n state: 'connected',\n config: {\n sessionId: this.sessionId,\n isResuming: this.isResuming,\n toolCount: Object.keys(this.tools || {}).length,\n },\n });\n\n this.log('Successfully connected to Gemini Live API', {\n sessionId: this.sessionId,\n isResuming: this.isResuming,\n toolCount: Object.keys(this.tools || {}).length,\n });\n\n // Start session duration monitoring if configured\n if (this.options.sessionConfig?.maxDuration) {\n this.startSessionDurationMonitor();\n }\n } catch (error) {\n this.state = 'disconnected';\n this.log('Connection failed', error);\n throw error;\n }\n }\n\n /**\n * Disconnect from the Gemini Live API\n */\n async disconnect(): Promise<void> {\n if (this.state === 'disconnected') {\n this.log('Already disconnected');\n return;\n }\n\n // Emit disconnecting event\n this.emit('session', { state: 'disconnecting' });\n\n // Clean up session duration monitoring\n if (this.sessionDurationTimeout) {\n clearTimeout(this.sessionDurationTimeout);\n this.sessionDurationTimeout = undefined;\n }\n\n // Save session handle before disconnecting if resumption is enabled\n if (this.options.sessionConfig?.enableResumption && this.sessionId) {\n // In a real implementation, the session handle would come from the server\n // For now, we'll use the session ID as a placeholder\n this.sessionHandle = this.sessionId;\n this.log('Session handle saved for resumption', { handle: this.sessionHandle });\n }\n\n if (this.ws) {\n this.connectionManager.close();\n this.ws = undefined;\n }\n\n // Clean up speaker streams with improved handling\n this.audioStreamManager.cleanupSpeakerStreams();\n\n // Clear cached OAuth token via AuthManager\n this.authManager.clearCache();\n\n this.state = 'disconnected';\n this.isResuming = false;\n\n // Emit final session event before cleanup\n this.emit('session', { state: 'disconnected' });\n\n // Clean up event listeners to prevent memory leaks\n this.cleanupEventListeners();\n\n this.log('Disconnected from Gemini Live API', {\n sessionId: this.sessionId,\n sessionDuration: this.sessionStartTime ? Date.now() - this.sessionStartTime : undefined,\n });\n }\n\n /**\n * Send text to be converted to speech\n */\n async speak(input: string | NodeJS.ReadableStream, options?: GeminiLiveVoiceOptions): Promise<void> {\n this.validateConnectionState();\n\n if (typeof input !== 'string') {\n const chunks: Buffer[] = [];\n for await (const chunk of input) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n input = Buffer.concat(chunks).toString('utf-8');\n }\n\n if (input.trim().length === 0) {\n throw this.createAndEmitError(GeminiLiveErrorCode.INVALID_AUDIO_FORMAT, 'Input text is empty');\n }\n\n // Add to context history\n this.addToContext('user', input);\n\n // Build text message to Gemini Live API\n const textMessage: any = {\n client_content: {\n turns: [\n {\n role: 'user',\n parts: [\n {\n text: input,\n },\n ],\n },\n ],\n turnComplete: true,\n },\n };\n\n // If runtime options provided, send a session.update first to apply per-turn settings\n if (options && (options.speaker || options.languageCode || options.responseModalities)) {\n const updateMessage: UpdateMessage = {\n type: 'session.update',\n session: {\n generation_config: {\n ...(options.responseModalities ? { response_modalities: options.responseModalities } : {}),\n speech_config: {\n ...(options.languageCode ? { language_code: options.languageCode } : {}),\n ...(options.speaker ? { voice_config: { prebuilt_voice_config: { voice_name: options.speaker } } } : {}),\n },\n },\n },\n };\n\n try {\n this.sendEvent('session.update', updateMessage);\n this.log('Applied per-turn runtime options', options);\n } catch (error) {\n this.log('Failed to apply per-turn runtime options', error);\n }\n }\n\n try {\n this.sendEvent('client_content', textMessage);\n this.log('Text message sent', { text: input });\n\n // The response will come via the event system (handleServerContent)\n // Audio will be emitted through 'speaking' events\n // Text responses will be emitted through 'writing' events\n } catch (error) {\n this.log('Failed to send text message', error);\n throw this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Failed to send text message', error);\n }\n }\n\n /**\n * Send audio stream for processing\n */\n async send(audioData: NodeJS.ReadableStream | Int16Array): Promise<void> {\n this.validateConnectionState();\n\n if ('readable' in audioData && typeof audioData.on === 'function') {\n const stream = audioData as NodeJS.ReadableStream;\n\n stream.on('data', (chunk: Buffer) => {\n try {\n const base64Audio = this.audioStreamManager.processAudioChunk(chunk);\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'realtime');\n this.sendEvent('realtime_input', message);\n } catch (error) {\n this.log('Failed to process audio chunk', error);\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Failed to process audio chunk', error);\n }\n });\n\n stream.on('error', (error: Error) => {\n this.log('Audio stream error', error);\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_STREAM_ERROR, 'Audio stream error', error);\n });\n\n stream.on('end', () => {\n this.log('Audio stream ended');\n });\n } else {\n const validateAudio = this.audioStreamManager.validateAndConvertAudioInput(audioData as Int16Array);\n const base64Audio = this.audioStreamManager.int16ArrayToBase64(validateAudio);\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'realtime');\n this.sendEvent('realtime_input', message);\n }\n }\n\n /**\n * Process speech from audio stream (traditional STT interface)\n */\n async listen(audioStream: NodeJS.ReadableStream, _options?: GeminiLiveVoiceOptions): Promise<string> {\n this.validateConnectionState();\n\n let transcriptionText = '';\n\n // Listen for transcription responses\n const onWriting = (data: { text: string; role: 'assistant' | 'user' }) => {\n if (data.role === 'user') {\n transcriptionText += data.text;\n this.log('Received transcription text:', { text: data.text, total: transcriptionText });\n }\n // Note: We only collect user role text as transcription\n // Assistant role text would be responses, not transcription\n };\n\n // Listen for errors\n const onError = (error: { message: string; code?: string; details?: unknown }) => {\n throw new Error(`Transcription failed: ${error.message}`);\n };\n\n // Listen for session events\n const onSession = (data: { state: string }) => {\n if (data.state === 'disconnected') {\n throw new Error('Session disconnected during transcription');\n }\n };\n\n // Set up GeminiLiveVoice event listeners\n this.on('writing', onWriting);\n this.on('error', onError);\n this.on('session', onSession);\n\n try {\n // Use AudioStreamManager to handle the transcription workflow\n const result = await this.audioStreamManager.handleAudioTranscription(\n audioStream,\n (base64Audio: string) => {\n // Send audio and await transcript until turn completes\n return new Promise<string>((resolve, reject) => {\n try {\n // Create audio message for transcription\n const message = this.audioStreamManager.createAudioMessage(base64Audio, 'input');\n\n const cleanup = () => {\n this.off('turnComplete' as any, onTurnComplete as any);\n this.off('error', onErr as any);\n };\n\n // Handlers\n const onTurnComplete = () => {\n cleanup();\n resolve(transcriptionText.trim());\n };\n\n const onErr = (e: { message: string }) => {\n cleanup();\n reject(new Error(e.message));\n };\n\n // Wire listeners before sending\n this.on('turnComplete' as any, onTurnComplete as any);\n this.on('error', onErr as any);\n\n // Send to Gemini Live API\n this.sendEvent('client_content', message);\n this.log('Sent audio for transcription');\n } catch (err) {\n reject(err as Error);\n }\n });\n },\n (error: Error) => {\n this.createAndEmitError(GeminiLiveErrorCode.AUDIO_PROCESSING_ERROR, 'Audio transcription failed', error);\n },\n );\n\n return result;\n } finally {\n // Clean up event listeners\n this.off('writing', onWriting);\n this.off('error', onError);\n this.off('session', onSession);\n }\n }\n\n /**\n * Get available speakers/voices\n */\n async getSpeakers(): Promise<Array<{ voiceId: string; description?: string }>> {\n // Return available Gemini Live voices\n return [\n { voiceId: 'Puck', description: 'Conversational, friendly' },\n { voiceId: 'Charon', description: 'Deep, authoritative' },\n { voiceId: 'Kore', description: 'Neutral, professional' },\n { voiceId: 'Fenrir', description: 'Warm, approachable' },\n ];\n }\n\n /**\n * Resume a previous session using a session handle\n */\n async resumeSession(handle: string, context?: Array<{ role: string; content: string }>): Promise<void> {\n if (this.state === 'connected') {\n throw new Error('Cannot resume session while already connected. Disconnect first.');\n }\n\n this.log('Attempting to resume session', { handle });\n\n this.sessionHandle = handle;\n this.isResuming = true;\n\n // Restore context history if provided using ContextManager\n if (context && context.length > 0) {\n this.contextManager.clearContext();\n for (const item of context) {\n this.contextManager.addEntry(item.role as 'user' | 'assistant', item.content);\n }\n }\n\n try {\n await this.connect();\n this.log('Session resumed successfully', { handle, contextItems: context?.length || 0 });\n } catch (error) {\n this.isResuming = false;\n this.sessionHandle = undefined;\n throw new Error(`Failed to resume session: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Update session configuration during an active session\n * Allows dynamic updates to voice, instructions, tools, and other settings\n *\n * @param config Partial configuration to update\n * @throws Error if not connected or update fails\n *\n * @example\n * ```typescript\n * // Change voice during conversation\n * await voice.updateSessionConfig({\n * speaker: 'Charon'\n * });\n *\n * // Update instructions\n * await voice.updateSessionConfig({\n * instructions: 'You are now a helpful coding assistant'\n * });\n *\n * // Add or update tools\n * await voice.updateSessionConfig({\n * tools: [{ name: 'new_tool', ... }]\n * });\n * ```\n */\n async updateSessionConfig(config: Partial<GeminiLiveVoiceConfig>): Promise<void> {\n this.validateConnectionState();\n this.validateWebSocketState();\n\n return new Promise((resolve, reject) => {\n // Validate configuration\n if (config.model) {\n this.log('Warning: Model cannot be changed during an active session. Ignoring model update.');\n }\n\n if (config.vertexAI !== undefined || config.project !== undefined || config.location !== undefined) {\n this.log('Warning: Authentication settings cannot be changed during an active session.');\n }\n\n const updateMessage: UpdateMessage = {\n type: 'session.update',\n session: {},\n };\n\n let hasUpdates = false;\n\n // Update voice/speaker if provided\n if (config.speaker) {\n hasUpdates = true;\n updateMessage.session.generation_config = {\n ...updateMessage.session.generation_config,\n speech_config: {\n voice_config: {\n prebuilt_voice_config: {\n voice_name: config.speaker,\n },\n },\n },\n };\n\n // Update internal state\n this.speaker = config.speaker;\n this.log('Updating speaker to:', config.speaker);\n }\n\n // Update instructions if provided\n if (config.instructions !== undefined) {\n hasUpdates = true;\n updateMessage.session.system_instruction = {\n parts: [{ text: config.instructions }],\n };\n\n this.log('Updating instructions');\n }\n\n // Update tools if provided\n if (config.tools !== undefined) {\n hasUpdates = true;\n if (config.tools.length > 0) {\n updateMessage.session.tools = config.tools.map((tool: GeminiToolConfig) => ({\n function_declarations: [\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n ],\n }));\n } else {\n // Clear tools if empty array provided\n updateMessage.session.tools = [];\n }\n\n this.log('Updating tools:', config.tools.length, 'tools');\n }\n\n // Also check for tools from addTools method\n if (this.tools && Object.keys(this.tools).length > 0) {\n hasUpdates = true;\n const allTools: Array<{\n function_declarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }> = [];\n\n for (const [toolName, tool] of Object.entries(this.tools)) {\n try {\n let parameters: unknown;\n\n // Handle different tool formats\n if ('inputSchema' in tool && tool.inputSchema) {\n // Convert Zod schema to JSON schema if needed\n if (typeof tool.inputSchema === 'object' && 'safeParse' in tool.inputSchema) {\n // This is a Zod schema - we need to convert it\n parameters = this.convertZodSchemaToJsonSchema(tool.inputSchema);\n } else {\n parameters = tool.inputSchema;\n }\n } else if ('parameters' in tool && tool.parameters) {\n parameters = tool.parameters;\n } else {\n // Default empty object if no schema found\n parameters = { type: 'object', properties: {} };\n }\n\n allTools.push({\n function_declarations: [\n {\n name: toolName,\n description: tool.description || `Tool: ${toolName}`,\n parameters,\n },\n ],\n });\n } catch (error) {\n this.log('Failed to process tool for session update', { toolName, error });\n }\n }\n\n if (allTools.length > 0) {\n updateMessage.session.tools = allTools;\n this.log('Updating tools from addTools method:', allTools.length, 'tools');\n }\n }\n\n // Update session configuration if provided\n if (config.sessionConfig) {\n // Handle VAD settings\n if (config.sessionConfig.vad) {\n hasUpdates = true;\n updateMessage.session.vad = {\n enabled: config.sessionConfig.vad.enabled ?? true,\n sensitivity: config.sessionConfig.vad.sensitivity ?? 0.5,\n silence_duration_ms: config.sessionConfig.vad.silenceDurationMs ?? 1000,\n };\n this.log('Updating VAD settings:', config.sessionConfig.vad);\n }\n\n // Handle interrupt settings\n if (config.sessionConfig.interrupts) {\n hasUpdates = true;\n updateMessage.session.interrupts = {\n enabled: config.sessionConfig.interrupts.enabled ?? true,\n allow_user_interruption: config.sessionConfig.interrupts.allowUserInterruption ?? true,\n };\n this.log('Updating interrupt settings:', config.sessionConfig.interrupts);\n }\n\n // Handle context compression\n if (config.sessionConfig.contextCompression !== undefined) {\n hasUpdates = true;\n updateMessage.session.context_compression = config.sessionConfig.contextCompression;\n this.log('Updating context compression:', config.sessionConfig.contextCompression);\n // Apply to ContextManager\n this.contextManager.setCompressionEnabled(config.sessionConfig.contextCompression);\n }\n }\n\n // Check if there are any updates to send\n if (!hasUpdates) {\n this.log('No valid configuration updates to send');\n resolve();\n return;\n }\n\n // Set up timeout for response\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Session configuration update timeout - no response received'));\n }, 10000); // 10 second timeout\n\n // Listen for update confirmation\n const onSessionUpdated = (data: GeminiLiveServerMessage) => {\n cleanup();\n this.log('Session configuration updated successfully', data);\n resolve();\n };\n\n // Listen for errors\n const onError = (error: { message?: string; code?: string; details?: unknown }) => {\n cleanup();\n this.log('Session configuration update failed', error);\n reject(new Error(`Failed to update session configuration: ${error.message || 'Unknown error'}`));\n };\n\n // Set up event listeners\n const cleanup = () => {\n clearTimeout(timeout);\n this.eventManager.getEventEmitter().removeListener('session.updated', onSessionUpdated as any);\n this.eventManager.getEventEmitter().removeListener('error', onError as any);\n };\n\n this.eventManager.getEventEmitter().once('session.updated', onSessionUpdated as any);\n this.eventManager.getEventEmitter().once('error', onError as any);\n\n // Send the update message\n try {\n this.sendEvent('session.update', updateMessage);\n this.log('Sent session configuration update', updateMessage);\n } catch (error) {\n cleanup();\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.log('Failed to send session configuration update', error);\n reject(new Error(`Failed to send session configuration update: ${errorMessage}`));\n }\n });\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): 'disconnected' | 'connected' {\n return this.state;\n }\n\n /**\n * Check if currently connected\n */\n isConnected(): boolean {\n return this.state === 'connected';\n }\n\n /**\n * Get current speaker stream for audio concatenation\n * This allows external access to the current audio stream being built\n */\n getCurrentSpeakerStream(): NodeJS.ReadableStream | null {\n return this.audioStreamManager.getCurrentSpeakerStream();\n }\n\n /**\n * Get session handle for resumption\n */\n getSessionHandle(): string | undefined {\n // TODO: Return actual session handle when Gemini Live API supports session resumption\n return this.sessionHandle;\n }\n\n /**\n * Get comprehensive session information\n */\n getSessionInfo(): {\n id?: string;\n handle?: string;\n startTime?: Date;\n duration?: number;\n state: string;\n config?: GeminiSessionConfig;\n contextSize: number;\n } {\n return {\n id: this.sessionId,\n handle: this.sessionHandle,\n startTime: this.sessionStartTime ? new Date(this.sessionStartTime) : undefined,\n duration: this.sessionStartTime ? Date.now() - this.sessionStartTime : undefined,\n state: this.state,\n config: this.options.sessionConfig,\n contextSize: this.contextManager.getContextSize(),\n };\n }\n\n /**\n * Get session context history\n */\n getContextHistory(): Array<{ role: string; content: string; timestamp: number }> {\n return this.contextManager.getContextHistory();\n }\n\n /**\n * Add to context history for session continuity\n */\n addToContext(role: 'user' | 'assistant', content: string): void {\n this.contextManager.addEntry(role, content);\n }\n\n /**\n * Clear session context\n */\n clearContext(): void {\n this.contextManager.clearContext();\n this.log('Session context cleared');\n }\n\n /**\n * Enable or disable automatic reconnection\n */\n setAutoReconnect(enabled: boolean): void {\n if (!this.options.sessionConfig) {\n this.options.sessionConfig = {};\n }\n this.options.sessionConfig.enableResumption = enabled;\n this.log(`Auto-reconnect ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Send session resumption message\n * @private\n */\n private async sendSessionResumption(): Promise<void> {\n if (!this.sessionHandle) {\n throw new Error('No session handle available for resumption');\n }\n\n const context = this.contextManager.getContextArray();\n const resumeMessage = {\n session_resume: {\n handle: this.sessionHandle,\n ...(context.length > 0 && {\n context,\n }),\n },\n };\n\n try {\n if (this.ws?.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not ready for session resumption');\n }\n\n this.sendEvent('session_resume', resumeMessage);\n this.log('Session resumption message sent', { handle: this.sessionHandle });\n } catch (error) {\n this.log('Failed to send session resumption', error);\n throw new Error(`Failed to send session resumption: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Start monitoring session duration\n * @private\n */\n private startSessionDurationMonitor(): void {\n if (!this.options.sessionConfig?.maxDuration) {\n return;\n }\n\n // Parse duration string (e.g., '24h', '2h', '30m')\n const durationMs = this.parseDuration(this.options.sessionConfig.maxDuration);\n\n if (!durationMs) {\n this.log('Invalid session duration format', { duration: this.options.sessionConfig.maxDuration });\n return;\n }\n\n // Clear existing monitor if any\n if (this.sessionDurationTimeout) {\n clearTimeout(this.sessionDurationTimeout);\n }\n\n // Set timeout for session expiry warning\n const warningTime = durationMs - 5 * 60 * 1000; // 5 minutes before expiry\n\n if (warningTime > 0) {\n setTimeout(() => {\n this.emit('sessionExpiring', {\n expiresIn: 5 * 60 * 1000,\n sessionId: this.sessionId,\n });\n }, warningTime);\n }\n\n // Set timeout for session expiry\n this.sessionDurationTimeout = setTimeout(() => {\n this.log('Session duration limit reached, disconnecting');\n void this.disconnect();\n }, durationMs);\n }\n\n /**\n * Parse duration string to milliseconds\n * @private\n */\n private parseDuration(duration: string): number | null {\n const match = duration.match(/^(\\d+)([hms])$/);\n if (!match) return null;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2];\n\n switch (unit) {\n case 'h':\n return value * 60 * 60 * 1000;\n case 'm':\n return value * 60 * 1000;\n case 's':\n return value * 1000;\n default:\n return null;\n }\n }\n\n /**\n * Compress context history to manage memory\n * @private\n */\n private compressContext(): void {\n // Deprecated: ContextManager handles compression\n this.log('compressContext is deprecated; handled by ContextManager');\n }\n\n /**\n * Setup WebSocket event listeners for Gemini Live API messages\n * @private\n */\n private setupEventListeners(): void {\n if (!this.ws) {\n throw new Error('WebSocket not initialized');\n }\n\n // Handle WebSocket connection events\n this.ws.on('open', () => {\n this.log('WebSocket connection opened');\n // Note: We transition to 'connected' in connect() after setup is complete\n // This is just confirming the WebSocket is open\n });\n\n this.ws.on('close', (code: number, reason: Buffer) => {\n this.log('WebSocket connection closed', { code, reason: reason.toString() });\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n });\n\n this.ws.on('error', (error: Error) => {\n this.log('WebSocket error', error);\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n this.emit('error', {\n message: error.message,\n code: 'websocket_error',\n details: error,\n });\n });\n\n // Handle incoming messages from Gemini Live API\n this.ws.on('message', async (message: Buffer | string) => {\n try {\n const data = JSON.parse(message.toString());\n await this.handleGeminiMessage(data);\n } catch (error) {\n this.log('Failed to parse WebSocket message', error);\n this.emit('error', {\n message: 'Failed to parse WebSocket message',\n code: 'parse_error',\n details: error,\n });\n }\n });\n }\n\n /**\n * Handle different types of messages from Gemini Live API\n * @private\n */\n private async handleGeminiMessage(data: GeminiLiveServerMessage): Promise<void> {\n // Always log received messages in debug mode or when troubleshooting\n this.log('Received message:', JSON.stringify(data, null, 2));\n\n // Extract response ID if present in the message\n if ((data as any).responseId) {\n this.setCurrentResponseId((data as any).responseId);\n this.log('Set current response ID:', (data as any).responseId);\n }\n\n // Handle different Gemini Live API message structures\n if (data.setup) {\n this.log('Processing setup message');\n this.handleSetupComplete(data);\n } else if (data.setupComplete) {\n this.log('Processing setupComplete message');\n this.handleSetupComplete(data);\n } else if (data.serverContent) {\n this.log('Processing server content message');\n this.handleServerContent(data.serverContent);\n } else if (data.toolCall) {\n this.log('Processing tool call message');\n await this.handleToolCall(data);\n } else if (data.usageMetadata) {\n this.log('Processing usage metadata message');\n this.handleUsageUpdate(data);\n } else if (data.sessionEnd) {\n this.log('Processing session end message');\n this.handleSessionEnd(data);\n } else if (data.error) {\n this.log('Processing error message');\n this.handleError(data.error);\n } else {\n // Handle alternative message formats by checking for common fields\n const messageData = data as any; // Use any for flexible message handling\n\n // Check for various possible setup completion indicators\n if (messageData.type === 'setup' || messageData.type === 'session.ready' || messageData.type === 'ready') {\n // Handle alternative setup message formats\n this.log('Processing alternative setup message with type:', messageData.type);\n this.handleSetupComplete(data);\n } else if (messageData.sessionHandle) {\n // Handle session handle in response\n this.log('Processing session handle message');\n this.handleSetupComplete(data);\n } else if (\n messageData.session ||\n messageData.ready ||\n messageData.status === 'ready' ||\n messageData.status === 'setup_complete'\n ) {\n // Try to handle as setup completion if it has any setup-related fields\n this.log('Processing setup completion message with status:', messageData.status);\n this.handleSetupComplete(data);\n } else if (messageData.candidates || messageData.promptFeedback) {\n // Handle successful response from BidiGenerateContent\n this.log('Processing BidiGenerateContent response');\n this.handleSetupComplete(data);\n } else if (messageData.contents && Array.isArray(messageData.contents)) {\n // Handle content response\n this.log('Processing content response');\n this.handleServerContent({ modelTurn: { parts: messageData.contents.flatMap((c: any) => c.parts || []) } });\n // Also treat this as setup completion since we got a response\n this.handleSetupComplete(data);\n } else if (messageData.candidates && Array.isArray(messageData.candidates)) {\n // Handle candidates response (common in Gemini API)\n this.log('Processing candidates response');\n this.handleSetupComplete(data);\n } else {\n this.log('Unknown message format - no recognized fields found');\n }\n }\n }\n\n /**\n * Handle setup completion message\n * @private\n */\n private handleSetupComplete(data: GeminiLiveServerMessage): void {\n this.log('Setup completed');\n\n // Process all queued messages now that the session is ready\n const queue = this.queue.splice(0, this.queue.length);\n if (queue.length > 0) {\n this.log('Processing queued messages:', queue.length);\n for (const queuedMessage of queue) {\n try {\n this.connectionManager.send(JSON.stringify(queuedMessage));\n this.log('Sent queued message:', queuedMessage);\n } catch (err) {\n this.log('Failed to send queued message, re-queuing:', err);\n this.queue.unshift(queuedMessage);\n break;\n }\n }\n }\n\n // Emit event for waitForSessionCreated to resolve\n this.eventManager.getEventEmitter().emit('setupComplete', data as any);\n // Session is now ready for communication\n }\n\n /**\n * Handle session update confirmation\n * @private\n */\n private handleSessionUpdated(data: GeminiLiveServerMessage): void {\n this.log('Session updated', data);\n // Emit event for updateSessionConfig to resolve\n this.eventManager.getEventEmitter().emit('session.updated', data as any);\n\n // Also emit a general session event for any external listeners\n this.emit('session', {\n state: 'updated',\n config: data as Record<string, unknown>,\n });\n }\n\n /**\n * Handle server content (text/audio responses)\n * @private\n */\n private handleServerContent(data: GeminiLiveServerMessage['serverContent']): void {\n if (!data) {\n return;\n }\n\n let assistantResponse = '';\n\n if (data.modelTurn?.parts) {\n for (const part of data.modelTurn.parts) {\n // Handle text content\n if (part.text) {\n assistantResponse += part.text;\n this.emit('writing', {\n text: part.text,\n role: 'assistant',\n });\n }\n\n // Handle function calls (tool calls) embedded in parts\n // Gemini Live API sends tool calls inside serverContent.modelTurn.parts\n if (part.functionCall) {\n this.log('Found function call in serverContent.modelTurn.parts', part.functionCall);\n\n // Convert to toolCall format and handle\n const toolCallData: GeminiLiveServerMessage = {\n toolCall: {\n name: part.functionCall.name,\n args: part.functionCall.args || {},\n id: part.functionCall.id || randomUUID(),\n },\n };\n\n // Handle the tool call asynchronously\n void this.handleToolCall(toolCallData);\n\n // Continue to next part without processing audio/text\n continue;\n }\n\n // Handle audio content - implement chunk concatenation with proper response ID tracking\n if (part.inlineData?.mimeType?.includes('audio') && typeof part.inlineData.data === 'string') {\n try {\n const audioData = part.inlineData.data;\n const int16Array = this.audioStreamManager.base64ToInt16Array(audioData);\n\n // Use the tracked response ID or generate one if not available\n const responseId = this.getCurrentResponseId() || randomUUID();\n\n // Get or create the speaker stream for this response\n let speakerStream = this.audioStreamManager.getSpeakerStream(responseId);\n if (!speakerStream) {\n // Clean up stale streams and enforce limits before creating new ones\n this.audioStreamManager.cleanupStaleStreams();\n this.audioStreamManager.enforceStreamLimits();\n\n // Create new stream through the manager\n speakerStream = this.audioStreamManager.createSpeakerStream(responseId);\n\n // Add error handling to the stream\n speakerStream.on('error', (streamError: Error) => {\n this.log(`Speaker stream error for ${responseId}:`, streamError);\n this.audioStreamManager.removeSpeakerStream(responseId);\n this.emit('error', {\n message: 'Speaker stream error',\n code: 'speaker_stream_error',\n details: { responseId, error: streamError },\n });\n });\n\n // Auto-cleanup when stream ends\n speakerStream.on('end', () => {\n this.log(`Speaker stream ended for response: ${responseId}`);\n this.audioStreamManager.removeSpeakerStream(responseId);\n });\n\n // Auto-cleanup when stream is destroyed\n speakerStream.on('close', () => {\n this.log(`Speaker stream closed for response: ${responseId}`);\n this.audioStreamManager.removeSpeakerStream(responseId);\n });\n\n this.log('Created new speaker stream for response:', responseId);\n\n // Emit the speaker stream for external listeners\n this.emit('speaker', speakerStream as NodeJS.ReadableStream);\n }\n\n // Write the audio chunk to the stream\n const audioBuffer = Buffer.from(int16Array.buffer, int16Array.byteOffset, int16Array.byteLength);\n speakerStream.write(audioBuffer);\n\n this.log('Wrote audio chunk to stream:', {\n responseId,\n chunkSize: audioBuffer.length,\n totalStreams: this.audioStreamManager.getActiveStreamCount(),\n });\n\n // Also emit the individual speaking event for backward compatibility\n this.emit('speaking', {\n audio: audioData, // Base64 string\n audioData: int16Array,\n sampleRate: this.audioConfig.outputSampleRate, // Gemini Live outputs at 24kHz\n });\n } catch (error) {\n this.log('Error processing audio data:', error);\n this.emit('error', {\n message: 'Failed to process audio data',\n code: 'audio_processing_error',\n details: error,\n });\n }\n }\n }\n }\n\n // Add assistant response to context if there was text content\n if (assistantResponse.trim()) {\n this.addToContext('assistant', assistantResponse);\n }\n\n // Check for turn completion\n if (data.turnComplete) {\n this.log('Turn completed');\n\n // End all active speaker streams for this turn\n this.audioStreamManager.cleanupSpeakerStreams();\n\n // Emit turn completion event\n this.emit('turnComplete', {\n timestamp: Date.now(),\n });\n }\n }\n\n /**\n * Handle tool call requests from the model\n * @private\n */\n private async handleToolCall(data: GeminiLiveServerMessage): Promise<void> {\n if (!data.toolCall) {\n return;\n }\n\n // Handle both formats:\n // 1. Direct format: { toolCall: { name, args, id } }\n // 2. Array format: { toolCall: { functionCalls: [{ name, args, id }] } }\n let toolCalls: Array<{ name?: string; args?: Record<string, any>; id?: string }> = [];\n\n if (data.toolCall.functionCalls && Array.isArray(data.toolCall.functionCalls)) {\n // Array format (actual Gemini API format)\n toolCalls = data.toolCall.functionCalls;\n } else if (data.toolCall.name) {\n // Direct format (for backward compatibility)\n toolCalls = [{ name: data.toolCall.name, args: data.toolCall.args, id: data.toolCall.id }];\n }\n\n // Process each tool call\n for (const toolCall of toolCalls) {\n const toolName = toolCall.name || '';\n const toolArgs = toolCall.args || {};\n const toolId = toolCall.id || randomUUID();\n\n await this.processSingleToolCall(toolName, toolArgs, toolId);\n }\n }\n\n /**\n * Process a single tool call\n * @private\n */\n private async processSingleToolCall(toolName: string, toolArgs: Record<string, any>, toolId: string): Promise<void> {\n this.log('Processing tool call', { toolName, toolArgs, toolId });\n\n // Emit tool call event\n this.emit('toolCall', {\n name: toolName,\n args: toolArgs,\n id: toolId,\n });\n\n // Find the tool\n const tool = this.tools?.[toolName];\n if (!tool) {\n this.log('Tool not found', { toolName });\n this.createAndEmitError(GeminiLiveErrorCode.TOOL_NOT_FOUND, `Tool \"${toolName}\" not found`, {\n toolName,\n availableTools: Object.keys(this.tools || {}),\n });\n return;\n }\n\n try {\n // Execute the tool\n let result: unknown;\n\n if (tool.execute) {\n this.log('Executing tool', { toolName, toolArgs });\n\n // Execute with proper context\n result = await tool.execute(toolArgs, { requestContext: this.requestContext });\n\n this.log('Tool executed successfully', { toolName, result });\n } else {\n this.log('Tool has no execute function', { toolName });\n result = { error: 'Tool has no execute function' };\n }\n\n // Send tool result back to Gemini Live API\n const toolResultMessage = {\n toolResponse: {\n functionResponses: [\n {\n id: toolId,\n response: result,\n },\n ],\n },\n };\n\n this.sendEvent('toolResponse', toolResultMessage);\n this.log('Tool result sent', { toolName, toolId, result });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.log('Tool execution failed', { toolName, error: errorMessage });\n\n // Send error result back to Gemini Live API\n const errorResultMessage = {\n toolResponse: {\n functionResponses: [\n {\n id: toolId,\n response: { error: errorMessage },\n },\n ],\n },\n };\n\n this.sendEvent('toolResponse', errorResultMessage);\n\n // Emit error event\n this.createAndEmitError(GeminiLiveErrorCode.TOOL_EXECUTION_ERROR, `Tool execution failed: ${errorMessage}`, {\n toolName,\n toolArgs,\n error,\n });\n }\n }\n\n /**\n * Handle token usage information\n * @private\n */\n private handleUsageUpdate(data: GeminiLiveServerMessage): void {\n if (data.usageMetadata) {\n this.emit('usage', {\n inputTokens: data.usageMetadata.promptTokenCount || 0,\n outputTokens: data.usageMetadata.responseTokenCount || 0,\n totalTokens: data.usageMetadata.totalTokenCount || 0,\n modality: this.determineModality(data),\n });\n }\n }\n\n /**\n * Handle session end\n * @private\n */\n private handleSessionEnd(data: GeminiLiveServerMessage): void {\n this.log('Session ended', data.sessionEnd?.reason);\n this.state = 'disconnected';\n this.emit('session', { state: 'disconnected' });\n }\n\n /**\n * Handle errors\n * @private\n */\n private handleError(error: GeminiLiveServerMessage['error']): void {\n if (!error) {\n this.log('Received error from Gemini Live API (no error details)');\n return;\n }\n\n this.log('Received error from Gemini Live API', error);\n this.emit('error', {\n message: error.message || 'Unknown error',\n code: error.code || 'unknown_error',\n details: error.details,\n });\n }\n\n /**\n * Determine the modality from message data\n * @private\n */\n private determineModality(data: GeminiLiveServerMessage): 'audio' | 'text' | 'video' {\n // Simple heuristic - this could be more sophisticated\n if (data.serverContent?.modelTurn?.parts?.some(part => part.inlineData?.mimeType?.includes('audio'))) {\n return 'audio';\n }\n // Support for video is not yet implemented, leaving this here for future use if needed\n if (data.serverContent?.modelTurn?.parts?.some(part => part.inlineData?.mimeType?.includes('video'))) {\n return 'video';\n }\n return 'text';\n }\n\n /**\n * Resolve Vertex AI location with sensible default\n * @private\n */\n private getVertexLocation(): string {\n return this.options.location?.trim() || 'us-central1';\n }\n\n /**\n * Resolve the correct model identifier for Gemini API or Vertex AI\n * @private\n */\n private resolveModelIdentifier(): string {\n const model = this.options.model ?? DEFAULT_MODEL;\n\n if (!this.options.vertexAI) {\n return `models/${model}`;\n }\n\n if (!this.options.project) {\n throw this.createAndEmitError(\n GeminiLiveErrorCode.PROJECT_ID_MISSING,\n 'Google Cloud project ID is required when using Vertex AI.',\n );\n }\n\n const location = this.getVertexLocation();\n return `projects/${this.options.project}/locations/${location}/publishers/google/models/${model}`;\n }\n\n /**\n * Send initial configuration to Gemini Live API\n * @private\n */\n private sendInitialConfig(): void {\n if (!this.ws || !this.connectionManager.isConnected()) {\n throw new Error('WebSocket not connected');\n }\n\n // Live API format - based on the official documentation\n interface LiveGenerateContentSetup {\n model?: string;\n generationConfig?: {\n temperature?: number;\n topK?: number;\n topP?: number;\n maxOutputTokens?: number;\n stopSequences?: string[];\n candidateCount?: number;\n responseModalities?: string[];\n speechConfig?: {\n voiceConfig?: {\n prebuiltVoiceConfig?: {\n voiceName?: string;\n };\n };\n };\n };\n systemInstruction?: {\n parts: Array<{\n text: string;\n }>;\n };\n tools?: Array<{\n functionDeclarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }>;\n }\n\n // Build the Live API setup message\n const setupMessage: { setup: LiveGenerateContentSetup } = {\n setup: {\n model: this.resolveModelIdentifier(),\n },\n };\n\n // Add system instructions if provided\n if (this.options.instructions) {\n setupMessage.setup.systemInstruction = {\n parts: [{ text: this.options.instructions }],\n };\n }\n\n // Collect tools from both options and addTools method\n const allTools: Array<{\n functionDeclarations: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }> = [];\n\n // Add tools from options (GeminiToolConfig[])\n if (this.options.tools && this.options.tools.length > 0) {\n for (const tool of this.options.tools) {\n allTools.push({\n functionDeclarations: [\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n ],\n });\n }\n }\n\n // Add tools from addTools method (ToolsInput)\n if (this.tools && Object.keys(this.tools).length > 0) {\n for (const [toolName, tool] of Object.entries(this.tools)) {\n try {\n let parameters: unknown;\n\n // Handle different tool formats\n if ('inputSchema' in tool && tool.inputSchema) {\n // Convert Zod schema to JSON schema if needed\n if (typeof tool.inputSchema === 'object' && 'safeParse' in tool.inputSchema) {\n // This is a Zod schema - we need to convert it\n parameters = this.convertZodSchemaToJsonSchema(tool.inputSchema);\n } else {\n parameters = tool.inputSchema;\n }\n } else if ('parameters' in tool && tool.parameters) {\n parameters = tool.parameters;\n } else {\n // Default empty object if no schema found\n parameters = { type: 'object', properties: {} };\n }\n\n allTools.push({\n functionDeclarations: [\n {\n name: toolName,\n description: tool.description || `Tool: ${toolName}`,\n parameters,\n },\n ],\n });\n } catch (error) {\n this.log('Failed to process tool', { toolName, error });\n }\n }\n }\n\n // Add tools to setup message if any exist\n if (allTools.length > 0) {\n setupMessage.setup.tools = allTools;\n this.log('Including tools in setup message', { toolCount: allTools.length });\n }\n\n this.log('Sending Live API setup message:', setupMessage);\n\n try {\n this.sendEvent('setup', setupMessage);\n } catch (error) {\n this.log('Failed to send Live API setup message:', error);\n throw new Error(\n `Failed to send Live API setup message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Wait for Gemini Live session to be created and ready\n * @private\n */\n private waitForSessionCreated(): Promise<void> {\n return new Promise((resolve, reject) => {\n // For Gemini Live API, we need to wait for the setup completion\n // This will be triggered by the setupComplete message type\n\n let isResolved = false;\n\n const onSetupComplete = () => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n resolve();\n }\n };\n\n const onError = (errorData: { message?: string; code?: string; details?: unknown }) => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error(`Session creation failed: ${errorData.message || 'Unknown error'}`));\n }\n };\n\n const onSessionEnd = () => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error('Session ended before setup completed'));\n }\n };\n\n const cleanup = () => {\n this.eventManager.getEventEmitter().removeListener('setupComplete', onSetupComplete as any);\n this.eventManager.getEventEmitter().removeListener('error', onError as any);\n this.eventManager.getEventEmitter().removeListener('sessionEnd', onSessionEnd as any);\n };\n\n // Listen for setup completion\n this.eventManager.getEventEmitter().once('setupComplete', onSetupComplete as any);\n this.eventManager.getEventEmitter().once('error', onError as any);\n this.eventManager.getEventEmitter().once('sessionEnd', onSessionEnd as any);\n\n // Add timeout to prevent hanging indefinitely\n setTimeout(() => {\n if (!isResolved) {\n isResolved = true;\n cleanup();\n reject(new Error('Session creation timeout'));\n }\n }, 30000); // 30 second timeout\n });\n }\n\n /**\n * Get OAuth access token for Vertex AI authentication\n * Implements token caching and automatic refresh\n * @private\n */\n private async getAccessToken(): Promise<string> {\n if (!this.options.vertexAI) {\n throw new Error('getAccessToken should only be called for Vertex AI mode');\n }\n return this.authManager.getAccessToken();\n }\n\n /**\n * Get the current response ID from the server message\n * This is needed to associate audio chunks with their respective responses.\n * @private\n */\n private getCurrentResponseId(): string | undefined {\n return this.audioStreamManager.getCurrentResponseId();\n }\n\n /**\n * Set the current response ID for the next audio chunk.\n * This is used to track the response ID for the current turn.\n * @private\n */\n private setCurrentResponseId(responseId: string): void {\n this.audioStreamManager.setCurrentResponseId(responseId);\n }\n\n /**\n * Send an event to the Gemini Live API with queueing support\n * @private\n */\n private sendEvent(type: string, data: any): void {\n // Handle messages that already have their own structure\n let message: any;\n if (type === 'setup' && data.setup) {\n // For setup messages, use the data as-is\n message = data;\n } else if (type === 'client_content' && data.client_content) {\n // For client_content messages, use the data as-is\n message = data;\n } else if (type === 'realtime_input' && data.realtime_input) {\n // For realtime_input messages, use the data as-is\n message = data;\n } else if (type === 'toolResponse' && data.toolResponse) {\n // For toolResponse messages, use the data as-is\n message = data;\n } else if (type === 'session.update' && data.session) {\n // For session update messages, use the data as-is\n message = data;\n } else {\n // For other messages, create the standard structure\n message = { type: type, ...data };\n }\n\n if (!this.ws || !this.connectionManager.isConnected()) {\n // Queue the message if WebSocket is not ready\n this.queue.push(message);\n this.log('Queued message:', { type, data });\n } else {\n // Send immediately if WebSocket is ready\n this.connectionManager.send(JSON.stringify(message));\n this.log('Sent message:', { type, data });\n }\n }\n\n /**\n * Equip the voice provider with tools\n * @param tools Object containing tool definitions that can be called by the voice model\n *\n * @example\n * ```typescript\n * const weatherTool = createTool({\n * id: \"getWeather\",\n * description: \"Get the current weather for a location\",\n * inputSchema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\"),\n * }),\n * execute: async (inputData) => {\n * // Fetch weather data from an API\n * const response = await fetch(\n * `https://api.weather.com?location=${encodeURIComponent(inputData.location)}`,\n * );\n * const data = await response.json();\n * return {\n * message: `The current temperature in ${inputData.location} is ${data.temperature}°F with ${data.conditions}.`,\n * };\n * },\n * });\n *\n * voice.addTools({\n * getWeather: weatherTool,\n * });\n * ```\n */\n addTools(tools: ToolsInput): void {\n this.tools = tools;\n this.log('Tools added to Gemini Live Voice', { toolCount: Object.keys(tools || {}).length });\n }\n\n /**\n * Get the current tools configured for this voice instance\n * @returns Object containing the current tools\n */\n listTools(): ToolsInput | undefined {\n return this.tools;\n }\n\n private log(message: string, ...args: unknown[]): void {\n if (this.debug) {\n console.info(`[GeminiLiveVoice] ${message}`, ...args);\n }\n }\n\n /**\n * Convert Zod schema to JSON Schema for tool parameters\n * @private\n */\n private convertZodSchemaToJsonSchema(schema: any): unknown {\n try {\n // Try to use the schema's toJSON method if available\n if (typeof schema.toJSON === 'function') {\n return schema.toJSON();\n }\n\n // Try to use the schema's _def property if available (Zod internal)\n if (schema._def) {\n return this.convertZodDefToJsonSchema(schema._def);\n }\n\n // If it's already a plain object, return as is\n if (typeof schema === 'object' && !schema.safeParse) {\n return schema;\n }\n\n // Default fallback\n return {\n type: 'object',\n properties: {},\n description: schema.description || '',\n };\n } catch (error) {\n this.log('Failed to convert Zod schema to JSON schema', { error, schema });\n return {\n type: 'object',\n properties: {},\n description: 'Schema conversion failed',\n };\n }\n }\n\n /**\n * Convert Zod definition to JSON Schema\n * @private\n */\n private convertZodDefToJsonSchema(def: any): unknown {\n switch (def.typeName) {\n case 'ZodString':\n return {\n type: 'string',\n description: def.description || '',\n };\n case 'ZodNumber':\n return {\n type: 'number',\n description: def.description || '',\n };\n case 'ZodBoolean':\n return {\n type: 'boolean',\n description: def.description || '',\n };\n case 'ZodArray':\n return {\n type: 'array',\n items: this.convertZodDefToJsonSchema(def.type._def),\n description: def.description || '',\n };\n case 'ZodObject':\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(def.shape())) {\n properties[key] = this.convertZodDefToJsonSchema((value as any)._def);\n if ((value as any)._def.typeName === 'ZodOptional') {\n // Optional field, don't add to required\n } else {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n description: def.description || '',\n };\n case 'ZodOptional':\n return this.convertZodDefToJsonSchema(def.innerType._def);\n case 'ZodEnum':\n return {\n type: 'string',\n enum: def.values,\n description: def.description || '',\n };\n default:\n return {\n type: 'object',\n properties: {},\n description: def.description || '',\n };\n }\n }\n\n /**\n * Close the connection (alias for disconnect)\n */\n close(): void {\n void this.disconnect();\n }\n\n /**\n * Trigger voice provider to respond\n */\n async answer(_options?: Record<string, unknown>): Promise<void> {\n this.validateConnectionState();\n\n // Send a signal to trigger response generation\n this.sendEvent('response.create', {});\n }\n\n /**\n * Equip the voice provider with instructions\n * @param instructions Instructions to add\n */\n addInstructions(instructions?: string): void {\n if (instructions) {\n this.options.instructions = instructions;\n this.log('Instructions added:', instructions);\n }\n }\n}\n"]}
|