import type { ConversationMetrics, RealtimeAnalyticsExport, RealtimeClientEvent, RealtimeConnectOptions, RealtimeConversation, RealtimeImageInput, RealtimeImageOptions, RealtimeServerEvent, RealtimeSessionConfig, RealtimeSessionEvents, RealtimeSessionState, RealtimeToolResult } from './types.js'; /** * A realtime voice conversation: connects a transport, runs tools, handles barge-in, reconnects, * and keeps a record of everything said. */ export declare class RealtimeSession { private readonly config; /** This session's id. */ readonly id: string; /** Provider name, for records and telemetry. */ readonly provider: string; /** The realtime model. */ readonly model: string; private readonly emitter; private readonly clock; private readonly controller; private readonly transportUnsubscribers; private readonly rawEvents; private readonly pendingCalls; private readonly pendingConfirmations; /** Tool calls running on their own, by call id, so `whenIdle()` waits for them. */ private readonly runningTools; /** Tool results being sent back to the provider. */ private readonly handlingResults; /** Woken when a running call starts waiting for a person, which `whenIdle()` then stops waiting on. */ private readonly confirmationWaiters; private readonly seenToolCalls; private readonly interruptedResponses; private readonly outbox; private readonly toolExecutor; private connectPromise?; private reconnectPromise?; private eventQueue; private conversation; private sessionState; private providerSessionId?; private activeConnection?; private pendingConnectedEvent?; private hasConnected; private manualDisconnect; private connectionStartedAt; private speechEndedAt?; private turnStartedAt?; private toolResultAt?; private firstAudioRecorded; private activeResponseId?; private activeItemId?; private outputPlaybackStartedAt?; private sessionTimeout?; /** When the last video frame was sent, to space frames out. */ private lastFrameAt?; private audioLimitTriggered; private activeConnectionCounted; private connectionSpan?; /** The lifecycle operation this session runs as, between its first connect and its disconnect. */ private ticket?; private operationSettled; /** Each turn's lifecycle operation, finished one after another. */ private turnsMetered; /** Turns admitted as they started, by response id, until they finish. */ private readonly turnTickets; /** What each finished turn cost, to estimate the next one by. */ private readonly turnCosts; /** The record's writes to the conversation store, one after another. */ private persisted; /** A conversation this session carries on, given back to the provider on its first connect. */ private resumeFrom?; constructor(config: RealtimeSessionConfig); /** The session's lifecycle state. */ get state(): RealtimeSessionState; /** The provider's session id once connected, otherwise this session's own id. */ get sessionId(): string; /** Subscribes to a session event. Returns a function that unsubscribes. */ on(event: Event, listener: (payload: RealtimeSessionEvents[Event]) => void): () => void; /** Subscribes to the next occurrence of a session event only. */ once(event: Event, listener: (payload: RealtimeSessionEvents[Event]) => void): () => void; /** A snapshot of the conversation record. */ getConversation(): RealtimeConversation; /** A snapshot of the conversation's metrics. */ getMetrics(): ConversationMetrics; /** Raw provider events retained so far, the latest `maxRawEvents` of them. */ getRawEvents(): RealtimeServerEvent[]; /** Waits until all provider events already received by the session have been normalized. */ whenIdle(): Promise; /** * Exports the conversation: the record as JSON, the provider's events, a readable transcript, or * analytics without transcripts. */ export(format: 'json'): RealtimeConversation; export(format: 'openai-events'): RealtimeServerEvent[]; export(format: 'text'): string; export(format: 'analytics'): RealtimeAnalyticsExport; /** * Connects the transport, configures the provider session, and starts enforcing the session's * limits. */ connect(options?: RealtimeConnectOptions): Promise; /** Disconnects and stops reconnecting. */ disconnect(): Promise; /** Sends a raw provider event. */ sendEvent(event: RealtimeClientEvent): void; /** Sends a chunk of microphone audio. */ sendAudio(chunk: ArrayBuffer): void; /** Adds a user text message, and by default asks the model to answer it. */ sendText(text: string, createResponse?: boolean): void; /** * Adds an image to the conversation as the user's: a photo, a screenshot, a page. With `text`, the * two go in one message, and the model answers unless `createResponse` is false. */ sendImage(image: RealtimeImageInput, options?: RealtimeImageOptions): void; /** Sends an image, and records it unless it is a frame of video. */ private sendPicture; /** * Streams one frame of video, from a camera or a shared screen: as realtime video input on a * provider that takes it, such as Gemini Live, and otherwise as an image in the conversation. A * frame sooner than `video.minIntervalMs` after the last one sent is dropped. Returns whether this * one was sent. */ sendVideoFrame(frame: ArrayBuffer | Uint8Array, mimeType?: string): boolean; /** * Commits buffered audio as a user turn, and by default asks the model to answer it. For * push-to-talk without server turn detection. */ commitAudio(createResponse?: boolean): void; /** Discards buffered audio that has not been committed. */ clearAudio(): void; /** Asks the model to respond now, optionally with response-level settings. */ createResponse(response?: Record): void; /** Changes provider session settings mid-conversation. */ updateSession(session: Record): void; /** * Stops the model speaking: cancels its response and truncates what was not heard, as configured. */ interrupt(reason?: 'barge_in' | 'manual'): void; private performInterruption; /** * Records when the first audio of a response actually started playing, which is the latency a * caller hears. Call it from your player. */ markAudioPlayed(at?: number): void; /** Answers a pending tool confirmation. Returns false when there was no such pending call. */ confirmTool(callId: string, approved: boolean): boolean; /** Runs a pending tool call yourself, for `toolExecution.mode: 'manual'`. */ executeTool(callId: string): Promise; /** Sends a tool result you produced yourself, for `toolExecution.mode: 'manual'`. */ submitToolResult(callId: string, result: unknown, error?: string): Promise; private bindTransport; private bindAbortSignal; private completeConnection; private handleRawEvent; private processProviderEvent; private applyPiiHook; private handleTransportAudio; private handleToolCall; private handleToolResult; private handleTransportDisconnected; private reconnect; private applyEvent; /** Writes the record to the conversation store, after the writes before it. */ private persistConversation; /** Reads the record a resume names by id, before the first connect. */ private loadResumed; /** Gives a new provider session what the resumed conversation said, once, before anything new. */ private replayResumed; private finishDisconnect; /** Finishes the session's lifecycle operation once: with its cost, or with the error that ended it. */ private settleOperation; private awaitConfirmation; private cleanupConfirmation; private resolveAllConfirmations; private sendProviderEvent; private flushOutbox; private assertConnected; private setState; private interruptionOptions; private effectiveSessionConfig; private withAudioDuration; private observeOutputBuffer; private finishOutputPlayback; private rememberInterruptedResponse; private recordInactiveConnection; private isLateInterruptedEvent; private retainRawEvent; private emitRaw; private emitNormalized; /** A copy of the record for each listener's event: made only when one is listening. */ private emitConversation; private emitMetrics; private telemetryEvent; private telemetryAttributes; private recordMetricEvent; private runTelemetry; /** * Adds a finished response's usage to the session's, and its estimated cost: a provider reports * each response's usage, so the session's is the sum. With a lifecycle, the turn is charged too. */ private updateUsage; /** * Admits a turn as it starts, as one lifecycle operation, `realtime.turn`: rate-limited, authorized, * and holding what the turns so far cost on average against the budget. A turn the lifecycle * refuses is cancelled before the model runs it, and the session ends. */ private beginTurn; /** Finishes a turn's operation with what it cost, once it was admitted. */ private meterTurn; /** Ends the session because the lifecycle refused a turn: past the budget, the rate limit, or authorization. */ private refuseTurn; /** The descriptor every operation of the session shares. */ private operationOf; /** The options every operation of the session starts with. */ private operationOptions; private startSessionLimit; private enforceAudioLimit; } /** Creates a realtime session from its configuration. */ export declare function createRealtimeSession(config: RealtimeSessionConfig): RealtimeSession;