@maximai/maxim-js
Version:
Maxim AI JS SDK. Visit https://getmaxim.ai for more info.
149 lines (148 loc) • 5 kB
TypeScript
import type { MaximLogger } from "../logger";
import { MaximRealtimeHeaders } from "./realtime/types";
import { OpenAIRealtimeWS } from "openai/realtime/ws";
export type { MaximRealtimeHeaders } from "./realtime/types";
export declare class MaximOpenAIRealtimeWrapper {
private realtimeClient;
private logger;
private state;
private boundHandlers;
private containerManager;
private eventQueue;
private originalSend;
private modelParametersToIgnore;
constructor(realtimeClient: OpenAIRealtimeWS, logger: MaximLogger, headers?: MaximRealtimeHeaders);
/**
* Attach event listeners to the realtime client.
*/
private attachEventListeners;
/**
* Wrap the send method to intercept client events like input_audio_buffer.append.
*/
private wrapSendMethod;
/**
* Handle client events being sent to the server.
* Events are queued and processed sequentially to prevent race conditions.
*/
private handleClientEvent;
/**
* Handle input_audio_buffer.append events to capture user audio.
*/
private handleInputAudioBufferAppend;
/**
* Handle realtime events and log to Maxim.
* Events are queued and processed sequentially to prevent race conditions.
*/
private handleEvent;
/**
* Get or create the session container.
*/
private getOrCreateSession;
/**
* Get the current trace container.
*/
private getCurrentTraceContainer;
/**
* Create a new trace for an interaction using ContainerManager.
*/
private createTrace;
/**
* Finalize the trace and clean up state.
* This handles ending the trace, session, and resetting all relevant state.
*/
private finalizeTrace;
/**
* Handle session.created event.
*/
private handleSessionCreated;
/**
* Handle session.updated event.
*/
private handleSessionUpdated;
/**
* Handle conversation.item.added event.
* - conversation.item.added: Server sends when audio buffer is committed (user speaks)
* // Using this event instead of conversation.item.created because this event gets called once after the message is committed,
*/
private handleConversationItemAdded;
/**
* Handle conversation.item.deleted event.
*/
private handleConversationItemDeleted;
/**
* Handle response.created event.
*/
private handleResponseCreated;
/**
* Handle response.output_audio.delta event.
*/
private handleResponseOutputAudioDelta;
/**
* Handle response.function_call_arguments.delta event.
*/
private handleFunctionCallArgumentsDelta;
/**
* Handle response.function_call_arguments.done event.
*/
private handleFunctionCallArgumentsDone;
/**
* Handle conversation.item.input_audio_transcription.completed event.
* This runs asynchronously - it updates existing generations without blocking the main flow.
*/
private handleInputAudioTranscriptionCompleted;
/**
* Handle response.done event.
* No longer waits for transcription - processes immediately.
* Transcription updates are handled asynchronously in handleInputAudioTranscriptionCompleted.
*/
private handleResponseDone;
/**
* Handle error event.
*/
private handleError;
/**
* Cleanup and detach event listeners.
* Call this when you're done with the wrapper.
* Returns a promise that resolves when the queue is drained.
*/
cleanup(): Promise<void>;
/**
* Wait for the event queue to drain.
* Useful for ensuring all pending events are processed before cleanup.
*/
waitForQueueDrain(): Promise<void>;
/**
* Get the current session ID.
*/
get sessionId(): string;
/**
* Get the underlying realtime client.
*/
get client(): any;
}
/**
* Helper function to wrap an OpenAI Realtime client with Maxim logging.
*
* @param realtimeClient - The OpenAI Realtime client (OpenAIRealtimeWS or OpenAIRealtimeWebSocket)
* @param logger - The MaximLogger instance
* @param headers - Optional headers for session/generation metadata
* @returns A wrapped client that logs to Maxim
*
* @example
* ```typescript
* import { OpenAIRealtimeWS } from 'openai/realtime/ws';
* import { Maxim } from '@maximai/maxim-js';
* import { wrapOpenAIRealtime } from '@maximai/maxim-js/openai';
*
* const maxim = new Maxim({ apiKey: process.env.MAXIM_API_KEY });
* const logger = await maxim.logger({ id: 'my-app' });
*
* const rt = new OpenAIRealtimeWS({ model: 'gpt-4o-realtime-preview' });
* const wrapper = wrapOpenAIRealtime(rt, logger, {
* 'maxim-session-name': 'Voice Assistant Session'
* });
*
* // Use rt normally - all events are automatically logged
* ```
*/
export declare function wrapOpenAIRealtime(realtimeClient: OpenAIRealtimeWS, logger: MaximLogger, headers?: MaximRealtimeHeaders): MaximOpenAIRealtimeWrapper;