Skip to main content
View as Markdown

State Management - Agentic Avatars SDK

State Management​

Learn how to track and respond to avatar session states and connection states.

Session States​

The avatar session progresses through several states:

IDLE -> CREATING -> READY -> ENDED
|
ERROR

State Definitions​

StateDescription
IDLEInitial state, no session created yet
CREATINGSession is being created (API calls in progress)
READYSession is ready, avatar can be controlled
ENDEDSession has been ended
ERRORAn error occurred during session creation or use

Checking Current State​

const state = session.getSessionState();
console.log('Current state:', state);

if (state === 'READY') {
// Safe to call sayText, interrupt, etc.
}

Listening to State Changes​

session.on('stateChange', (state) => {
console.log('State changed to:', state);

switch (state) {
case 'IDLE':
console.log('Session not started');
break;
case 'CREATING':
console.log('Creating session...');
break;
case 'READY':
console.log('Avatar ready!');
break;
case 'ENDED':
console.log('Session ended');
break;
case 'ERROR':
console.log('Error occurred');
break;
}
});

Connection States​

WebRTC connection states track the streaming connection:

DISCONNECTED -> CONNECTING -> CONNECTED
| |
FAILED CLOSED

State Definitions​

StateDescription
DISCONNECTEDNo WebRTC connection
CONNECTINGWebRTC connection in progress
CONNECTEDWebRTC streaming active
FAILEDWebRTC connection failed
CLOSEDWebRTC connection closed

Checking Connection State​

const connState = session.getConnectionState();
console.log('Connection state:', connState);

if (connState === 'CONNECTED') {
// Video is streaming
}

Listening to Connection Changes​

session.on('connectionChange', (state) => {
console.log('Connection state:', state);

switch (state) {
case 'DISCONNECTED':
console.log('Not connected');
break;
case 'CONNECTING':
console.log('Connecting...');
break;
case 'CONNECTED':
console.log('Streaming!');
break;
case 'FAILED':
console.log('Connection failed');
break;
case 'CLOSED':
console.log('Connection closed');
break;
}
});

Complete State Management Example​

import { KalturaAvatarSession } from '@unisphere/models-sdk-js';

const session = new KalturaAvatarSession({
apiKey: 'your-api-key',
baseUrl: 'https://api.avatar.us.kaltura.ai/',
});

// UI elements
const statusEl = document.getElementById('status');
const videoContainer = document.getElementById('avatar-container');

// Session state management
session.on('stateChange', (state) => {
statusEl.textContent = `Session: ${state}`;

switch (state) {
case 'CREATING':
statusEl.className = 'status-creating';
break;
case 'READY':
statusEl.className = 'status-ready';
enableControls();
break;
case 'ENDED':
statusEl.className = 'status-ended';
disableControls();
break;
case 'ERROR':
statusEl.className = 'status-error';
disableControls();
break;
}
});

// Connection state management
session.on('connectionChange', (state) => {
const connStatusEl = document.getElementById('conn-status');
connStatusEl.textContent = `Connection: ${state}`;

switch (state) {
case 'CONNECTING':
videoContainer.classList.add('loading');
break;
case 'CONNECTED':
videoContainer.classList.remove('loading');
videoContainer.classList.add('streaming');
break;
case 'FAILED':
videoContainer.classList.add('error');
alert('Connection failed. Please refresh.');
break;
}
});

// Error handling
session.on('error', (error) => {
console.error('Error:', error.code, error.message);
document.getElementById('error-msg').textContent = error.message;
});

function enableControls() {
document.querySelectorAll('button').forEach((btn) => {
btn.disabled = false;
});
}

function disableControls() {
document.querySelectorAll('button').forEach((btn) => {
btn.disabled = true;
});
}

Best Practices​

1. Wait for READY State​

Only call control methods when session is READY:

async function safelySpeak(text) {
if (session.getSessionState() !== 'READY') {
console.warn('Session not ready');
return;
}
await session.sayText(text);
}

2. Handle State Transitions​

Update UI based on state changes:

session.on('stateChange', (state) => {
// Update button states
document.getElementById('start-btn').disabled = state !== 'IDLE';
document.getElementById('speak-btn').disabled = state !== 'READY';
document.getElementById('end-btn').disabled = state !== 'READY';
});

3. Monitor Connection Quality​

session.on('connectionChange', (state) => {
if (state === 'FAILED') {
// Try to reconnect or show error
showReconnectOption();
}
});

Next Steps​