@sessioniq/client-sdk
v0.5.3
Published
SessionIQ Client SDK allows you to record and interact with your users' sessions.
Readme
SessionIQ Client SDK (@sessioniq/client-sdk)
Overview
The SessionIQ Client SDK is a lightweight JavaScript library for recording user sessions in your web application. It captures events, uploads them securely to the SessionIQ backend, facilitates triggering server-side analysis, allows adding textual context notes to specific sessions, and receives real-time updates about analysis progress and AI chat via a Supabase connection.
Key Features:
- Easy Integration: Simple API to initialize and control recording.
- Session Recording: Captures DOM changes, user interactions, console logs, network requests, and more (powered by
@sessioniq/coreinternally). - Secure Upload: Transmits recorded data securely to your configured SessionIQ backend using short-lived tokens.
- Dynamic Loading: Core recording logic is loaded dynamically only when needed, keeping the initial bundle size small.
- Server-Side Analysis: All heavy analysis, including AI processing, happens on the backend, not in the user's browser.
- Real-time Updates: Uses Supabase Realtime to receive analysis status updates and AI chat messages.
- Chat Context Management: Allows adding simple text notes (e.g., user observations) to a specific session ID via the
addChatContextmethod. This context can then be used by the backend AI during chat interactions related to that session. - Event-Driven: Provides hooks to listen for SDK events (initialization, recording status, errors, real-time updates).
Installation
# Using npm (or pnpm or yarn)
npm install @sessioniq/client-sdkBasic Usage
Here's a simple example of how to initialize and use the SDK:
import { SessionIQSdk } from "@sessioniq/client-sdk";
// 1. Create an instance
const sdk = new SessionIQSdk();
// 2. Initialize the SDK (asynchronously)
async function initialize() {
try {
await sdk.init({
clientId: "YOUR_CLIENT_ID", // Replace with your actual Client ID
baseUrl: "https://api.sessioniq.ai/api/v1", // Optional: Replace if self-hosting
logLevel: "info", // Optional: Set desired log level
userIdentifier: "[email protected]", // Optional: Identifier for the user (e.g., email)
// autoStartRecording: true, // Optional: To start recording engine & agent snapshots automatically
});
console.log("SessionIQ SDK Initialized!");
// 3. Add event listeners (optional)
sdk.addListener("recording:started", (p) =>
console.log(`Recording started. Checkpoint ID: ${p.checkpointId}`)
);
sdk.addListener("recording:stopped", (p) =>
console.log(
`Recording stopped. Checkpoint ID: ${p.checkpointId}, Events: ${p.eventCount}`
)
);
sdk.addListener(
"snapshotGenerated",
(
p // NEW EVENT
) =>
console.log(
`Snapshot for agent ${p.triggeringAgentId} generated with ${p.snapshotEvents.length} events.`
)
);
sdk.addListener("error", (p) =>
console.error(`SDK Error (${p.context}):`, p.error)
);
sdk.addListener("analysis:update", (payload) => {
console.log("Received analysis update:", payload);
// Handle analysis status updates (e.g., update UI)
});
sdk.addListener("chat:update", (payload) => {
console.log("Received chat update:", payload);
// Handle chat messages from AI
});
// 4. Subscribe to real-time updates (optional)
// The listener callback provided here is an alternative to the 'analysis:update' and 'chat:update' events
// sdk.subscribeToAnalysis((message) => {
// console.log("Realtime message:", message);
// });
} catch (error) {
console.error("Failed to initialize SessionIQ SDK:", error);
}
}
initialize();
// --- Example Usage (call these when needed, e.g., via button clicks) ---
// Start a manual recording checkpoint
// const checkpointId = await sdk.startCheckpoint({ // UPDATED METHOD
// autoStopAfterMs: 30000, // Optional: Stop this checkpoint after 30 seconds
// maxEvents: 1000, // Optional: Stop this checkpoint after 1000 events
// id: "my-custom-checkpoint-id", // Optional: Specify a custom ID
// });
// console.log("Started checkpoint with ID:", checkpointId);
// Stop the current manual recording checkpoint (automatically uploads events)
// sdk.stopCheckpoint(); // UPDATED METHOD
// Trigger analysis for the current session
// sdk.analyzeSession();
// Trigger analysis for a specific session
// sdk.analyzeSession("some_other_session_id");
// Send a chat message to an agent for the current session
// (Requires recording to be active to get current session ID)
// const currentSession = sdk.getCurrentSessionId();
// if (currentSession) {
// sdk.sendChatMessage("agent:trace-pilot", "Can you explain this error?", "optional-thread-id-123");
// }
// Add a context note to a specific session
// sdk.addChatContext("some_session_id", { note: "User reported confusion here." });
// Get enabled agents (e.g., to populate a dropdown)
// const agents = sdk.getEnabledAgents();
// console.log("Enabled Agents:", agents);
// Remember to call destroy on cleanup
// sdk.destroy();Configuration
clientId(Required): Your unique project identifier obtained from the SessionIQ dashboard.baseUrl(Optional): The base URL of your self-hosted or cloud SessionIQ API endpoint (e.g.,https://api.sessioniq.ai). Defaults tohttps://api.sessioniq.ai/api/v1.logLevel(Optional): Sets the minimum log level ('debug', 'info', 'warn', 'error', 'silent'). Defaults to'info'.userIdentifier(Optional): An identifier for the user (e.g., email). This can be used by the backend to associate the session with a known user, potentially influencing chat token generation.autoStartRecording(Optional): Iftrue, the core recording engine and agent snapshotting capabilities are started automatically after successful initialization. Defaults tofalse.
Real-time Updates
The SDK utilizes a Supabase Realtime channel (configured automatically via the backend) to deliver asynchronous updates about session analysis progress and AI chat interactions. Use the subscribeToAnalysis(callback) method to listen for these updates. The callback function will receive a payload object. Check the event field within the payload (e.g., 'analysis_status', 'chat_updates') to determine the type of update and handle the specific payload structure accordingly. Listen locally for the analysis:update and chat:update events emitted by the SDK for easier handling.
API Reference
new SessionIQSdk(): Creates a new SDK instance.async init(options: SdkInitOptions): Initializes the SDK, fetches configuration from the backend, and sets up the Supabase connection. Ifoptions.autoStartRecordingis true, the core recording engine and agent snapshotting capabilities are started. Options includeclientId,baseUrl(optional),logLevel(optional),userIdentifier(optional), andautoStartRecording(optional). Emitsinit:successorinit:error.async startCheckpoint(options?: { autoStopAfterMs?: number; maxEvents?: number; id?: string; }): Promise<string | void>: Starts a manual recording checkpoint. Returns a Promise that resolves with the checkpoint ID (or void if an error occurs internally). Emitsrecording:started.stopCheckpoint(): Stops the currently active manual recording checkpoint and triggers background upload of captured events. Emitsrecording:stoppedand potentiallyevents:upload:*events.async analyzeSession(sessionId?: string): Triggers the backend analysis for the specified session ID (or the current session if none is provided). Returns a confirmation message. Progress delivered via real-time updates (listened to viasubscribeToAnalysisand emitted locally asanalysis:update).async sendChatMessage(agentId: string, message: string, threadId?: string): Sends a message to the specified agent for the currently active recording session. An optionalthreadIdcan be provided to group messages into a specific conversation thread. Requires an active session (getCurrentSessionId()must return an ID). Emitschat:message:sent. AI response is delivered via the real-time subscription (listened to viasubscribeToAnalysisand emitted locally aschat:update).async addChatContext(sessionId: string, context: SdkChatContextAddPayload): Adds a textual context note (and optional payload) to a specific session ID on the backend via an API call. Requires a valid Chat Token (fetched during init). Thecontextobject should conform toSdkChatContextAddPayload(typically{ note?: string; payload?: any }). Emitschat:context:add.subscribeToAnalysis(callback: (message: { event: string, payload: any }) => void): RealtimeChannel | null: Subscribes to the Supabase Realtime channel for broadcast events (analysis_status,chat_updates). Returns the channel instance or null. Use the SDK'sanalysis:updateandchat:updateevents for easier handling. Emitsrealtime:subscribedorrealtime:error.unsubscribeFromAnalysis(): Unsubscribes from the Supabase Realtime channel. Emitsrealtime:unsubscribed.getCurrentSessionId(): string | null: Returns the ID of the current active recording session, if any.getEnabledAgents(): EnabledAgent[]: Returns the list of agents configured and enabled for the project.identifyUser(userId: string, details?: Record<string, any>): Associates a user ID and optional details with the current session. Records a custom event internally.recordCustomEvent(name: string, payload?: any): Records a custom application event.addListener(eventType: keyof SdkEventMap, listener): Adds a listener for local SDK events. SeeSdkEventMapbelow for the full list.removeListener(eventType: keyof SdkEventMap, listener): Removes a listener for local SDK events.destroy(): Stops recording, unsubscribes from real-time updates, removes all listeners, and cleans up resources. Important: Call this when your application or relevant component unmounts to prevent memory leaks, especially in Single Page Applications (SPAs).
Events (SdkEventMap)
Listen to these events using sdk.addListener():
init:success: SDK initialized successfully. Payload:{ config: SdkConfigResponse }.init:error: SDK initialization failed. Payload:{ error: Error }.recording:started: A manual recording checkpoint has started. Payload:{ checkpointId: string }.recording:stopped: A manual recording checkpoint has stopped. Payload:{ checkpointId: string; eventCount: number }.snapshotGenerated: An agent-triggered snapshot has been generated. Payload:{ triggeringAgentId: string; triggeringEvent?: RRWebEventWithTime; snapshotEvents: RRWebEventWithTime[] }.checkpointCompleted: A manual recording checkpoint is completed and its data is available. Payload:{ checkpointId: string; events: RRWebEventWithTime[]; }.events:upload:start: Event upload process initiated. Payload:{ eventCount: number; uploadType: 'checkpoint' | 'snapshot' }.events:upload:success: Events uploaded successfully. Payload:{ uploadType: 'checkpoint' | 'snapshot' }.events:upload:error: Event upload failed. Payload:{ error: Error; uploadType: 'checkpoint' | 'snapshot'; context?: string }.realtime:subscribed: Successfully subscribed to the Supabase channel. Payload:{ channel: string }.realtime:error: Error related to the Supabase channel subscription. Payload:{ channel: string; status: string; error: Error }.realtime:unsubscribed: Successfully unsubscribed from the Supabase channel. Payload:{ channel: string }.analysis:update: Received a real-time status update about analysis progress from the backend via Supabase. Payload structure depends on the specific status update sent by the backend (e.g.,{ status: 'starting' | 'agent_running' | 'agent_completed' | 'analyzed' | 'failed', sessionId: string, agentId?: string, message?: string, reports?: any[], error?: string }).chat:update: Received a real-time chat-related update from the backend via Supabase (e.g., AI response, error). Payload structure depends on the specific update sent by the backend (e.g.,{ status: 'completed' | 'error', sessionId: string, agentId: string, threadId?: string, response?: string, error?: string }).chat:message:sent: A chat message was successfully submitted to the API viasendChatMessage. Payload:{ agentId: string; message: string; threadId?: string }.chat:context:add: A chat context note was successfully submitted to the API viaaddChatContext. Payload:{ note?: string; payload?: any }.tokens:refreshed: SDK tokens have been successfully refreshed. Payload:{ config: SdkConfigResponse }.tokens:refresh_error: An error occurred while trying to refresh SDK tokens. Payload:{ error: Error }.error: A general SDK error occurred. Payload:{ context: string; error: Error; [key: string]: any }. Provide context indicates the operation that failed (e.g., 'startRecording', 'init').
