import { VowelRoute, VowelVoiceConfig } from '../types'; import { ToolContext, ToolManager } from './ToolManager'; import { AudioManager } from './AudioManager'; import { EnhancedVADManager } from './EnhancedVADManager'; import { TypingSoundManager } from './TypingSoundManager'; import { VoiceSessionState } from './StateManager'; import { RealtimeProvider } from '../providers/RealtimeProvider'; import { ProviderType } from '../types/providers'; /** * Message handler callback */ export type MessageHandler = (message: any) => void | Promise; /** * Status update callback */ export type StatusUpdateHandler = (status: string) => void; interface DisconnectOptions { closeReason?: string; notifyClose?: boolean; preserveHibernated?: boolean; } /** * Session configuration options */ export interface SessionConfig { /** Legacy alias for the top-level token issuer identifier. */ appId?: string; /** Preferred top-level token issuer identifier. */ apiKey?: string; /** Available routes */ routes: VowelRoute[]; /** Tool manager for executing tools */ toolManager: ToolManager; /** Audio manager for audio handling */ audioManager: AudioManager; /** @deprecated Prefer `_voiceConfig`. */ voiceConfig?: VowelVoiceConfig; /** Hidden runtime configuration bag for provider-specific overrides. */ _voiceConfig?: VowelVoiceConfig; language?: string; initialGreetingPrompt?: string; turnDetectionPreset?: 'aggressive' | 'balanced' | 'conservative'; /** Custom system instructions for the AI agent */ instructions?: string; /** * @deprecated Use 'instructions' instead * Legacy alias for instructions (backward compatibility) */ systemInstructionOverride?: string; /** Message handler callback */ onMessage?: MessageHandler; /** Status update callback */ onStatusUpdate?: StatusUpdateHandler; /** Connection opened callback */ onOpen?: () => void; /** Connection closed callback */ onClose?: (reason: string) => void; /** Error callback */ onError?: (error: string) => void; /** Custom Convex platform URL (base URL) */ convexUrl?: string; /** Custom token endpoint URL */ tokenEndpoint?: string; /** Custom token provider function */ tokenProvider?: (request: { appId?: string; apiKey?: string; identifier?: string; origin: string; config: any; }) => Promise<{ tokenName: string; model: string; provider: ProviderType; expiresAt: string; systemInstructions?: string; }>; /** User speaking state change callback */ onUserSpeakingChange?: (isSpeaking: boolean) => void; /** AI thinking state change callback */ onAIThinkingChange?: (isThinking: boolean) => void; /** Tool execution state change callback */ onToolExecutingChange?: (isExecuting: boolean) => void; /** AI speaking state change callback (already handled by AudioManager) */ onAISpeakingChange?: (isSpeaking: boolean) => void; /** Typing sound manager instance */ typingSoundManager?: TypingSoundManager; /** Transcript event callback (for caption system) */ onTranscriptEvent?: (event: { type: 'delta' | 'done'; text: string; role: 'user' | 'assistant'; responseId?: string; itemId?: string; }) => void; /** Hibernation state change callback */ onHibernationChange?: (isHibernated: boolean) => void; } /** * Session Manager class * Manages realtime voice session lifecycle (multi-provider) */ export declare class SessionManager { private config; private provider; private vadManager; private enhancedVADManager; private isAIThinking; private isToolExecuting; private isResponseInProgress; private isHibernated; private userStoppedSpeakingTime; private thinkingInitiatedBySpeech; private toolInitiatedThinkingTimeout; private TOOL_THINKING_TIMEOUT_MS; private totalStepCount; private maxSteps; private hasReachedStepLimit; private toolFailureCount; private maxToolFailures; private processedResponseIds; private processedResponseDoneIds; private readonly MAX_PROCESSED_RESPONSE_IDS; private activeResponseId; private cancelledResponseIds; private assistantAudioWatchdogTimeout; private readonly ASSISTANT_AUDIO_WATCHDOG_MS; private initTimings; private currentContext; private baseInstructions; private initialGreetingTimeout; private idleHibernateTimeout; private isClientSpeechActive; private isServerSpeechActive; private isAssistantAudioActive; private managedCloseReason; private suppressProviderClose; private isInitializingSession; private providerLifecycleId; private getHiddenVoiceConfig; constructor(config: SessionConfig); /** * Update tool execution state * @param isExecuting - New tool execution state */ private updateToolExecutingState; /** * Update AI thinking state and trigger typing sounds * @param isThinking - New thinking state * @param initiatedBySpeech - Whether thinking was initiated by speech_stopped (default: false) */ private updateThinkingState; /** * Fetch token from HTTP endpoint * * This replaces the Convex action call with a direct HTTP request * to the Vowel platform API endpoint. * * @param params - Request parameters * @param endpoint - Custom endpoint URL (optional, uses default if not provided) * @returns Token response */ private fetchToken; /** * Check if session is active */ isActive(): boolean; /** * Get the underlying provider */ getProvider(): RealtimeProvider | null; /** * Get default model for a given provider */ private getDefaultModelForProvider; private clearPendingInitialGreeting; private getClientIdleHibernateTimeoutMs; private clearIdleHibernateTimer; private refreshIdleHibernateTimer; private hasActiveSessionWork; private updateIdleHibernateTimer; private setClientSpeechActive; private setServerSpeechActive; private setAssistantAudioActive; private refreshAssistantAudioWatchdog; private clearAssistantAudioWatchdog; private isStaleProviderCallback; private hibernateForIdleTimeout; private scheduleHostedInitialGreeting; /** * Log comprehensive initialization timing breakdown */ private logInitializationTimings; /** * Handle tool calls from Gemini */ private handleToolCalls; /** * Handle normalized messages from realtime provider */ private handleProviderMessage; private shouldIgnoreAudioForResponse; /** * Handle tool call from provider with retry logic and step limiting */ private handleProviderToolCall; /** * Handle messages from Gemini Live session (LEGACY - kept for reference, not used) * @deprecated Use handleProviderMessage() instead */ /** * Connect to Gemini Live session * * @param toolContext - Tool execution context * @param restoreState - Optional state to restore (injects conversation history into system prompt) * @param initialContext - Optional initial context object to include in system prompt */ connect(toolContext: ToolContext, restoreState?: Partial, initialContext?: Record | null): Promise; /** * Disconnect from session and reset state */ disconnect(options?: DisconnectOptions): Promise; /** * Pause VAD (for session pause) */ pauseVAD(): void; /** * Resume VAD (for session resume) */ resumeVAD(): void; /** * Get EnhancedVADManager instance (for AudioManager to pass frames) */ getEnhancedVADManager(): EnhancedVADManager | null; /** * Update configuration (for dynamic updates) */ updateConfig(updates: Partial): void; /** * Send a text notification to the AI without user speech input * This allows programmatic triggering of AI responses for app events * * @param eventDetails - Description of the event that occurred, or abstract JSON payload * @param context - Optional context object to provide additional information * * @example * ```ts * // Notify AI about a timer expiry * await sessionManager.notifyEvent('Timer expired - 5 minutes are up!'); * * // Notify with additional context * await sessionManager.notifyEvent( * 'New message received', * { from: 'John', preview: 'Hello!' } * ); * ``` */ notifyEvent(eventDetails: any, context?: Record): Promise; /** * Send raw text input to the AI * Lower-level method for custom text-based interactions * * @param text - Text to send to the AI * * @example * ```ts * await sessionManager.sendText('What products are on sale?'); * ``` */ sendText(text: string): Promise; /** * Send an image to the AI for processing * Enables multimodal interactions where the AI can see and respond to images * * @param imageUrl - URL or data URI of the image to send * * @example * ```ts * // Send an image URL * await sessionManager.sendImage('https://example.com/product.jpg'); * * // Send a data URI * await sessionManager.sendImage('data:image/png;base64,iVBORw0KGgo...'); * ``` */ sendImage(imageUrl: string): Promise; /** * Update dynamic context and send session.update if connected. * Context is stringified, wrapped in tags and appended to system prompt. * * @param context - Context object to append to system prompt. Use null to clear. */ updateContext(context: Record | null): void; /** * Build system instructions with context appended. * Context is stringified, wrapped in tags and appended to base instructions. * If context is already present in base instructions (from initial context in token request), * it will be replaced with the current context. * * @returns Complete system instructions with context */ private buildInstructionsWithContext; /** * Send session.update event via provider to update session configuration. * * @param updates - Session configuration updates (e.g., instructions) */ private sendSessionUpdate; } export {}; //# sourceMappingURL=SessionManager.d.ts.map