Events
Event Registration Timing
Callbacks can be registered at any time, before or after init(). However, to receive status changes during init() (CONNECTING, SOCKET_CONNECTED, etc.), register onStatus before calling init().
- Only one callback per type can be registered; the latest registration overwrites the previous one.
- Callbacks are preserved after
destroy(), so you don't need to re-register them on re-initialization.
onSignal(callback)
Receives signals from the server.
js
SDK.onSignal((data) => {
console.log(data.signal, data.payload);
});jsx
useEffect(() => {
window.KlleonSDK.onSignal((data) => {
console.log(data.signal, data.payload);
});
}, []);Callback Parameters
| Field | Type | Required | Description |
|---|---|---|---|
signal | string | Yes | Signal type |
payload | object | No | Additional data per signal |
id | string | Yes | Signal UUID |
type | string | Yes | "SESSION" | "INPUT" | "OUTPUT" |
Key Signals
Conversation Flow
| Signal | Description | payload |
|---|---|---|
RESPONSE_TEXT | Avatar response text | { text: string, language: string } |
STT_RESULT | Speech recognition result | { text: string } |
RESPONSE_PREPARING | Preparing response (just before LLM request) | - |
RESPONSE_STARTED | Response started | - |
RESPONSE_ENDED | Response completed | - |
USER_SPEECH_STARTED | Speech segment started within STT session (mic already on) | - |
USER_SPEECH_STOPPED | Speech segment ended within STT session (mic still on) | - |
ERROR | Server error (session maintained) | { type: "STT_ERROR" | "LLM_ERROR" | ... } |
REJECTED | Input rejected (session maintained) | { type: "STT_EMPTY" | "MODERATION" | ... } |
Session Management
| Signal | Description | payload |
|---|---|---|
MATCH_WAITING | Waiting for match (for loading UI) | - |
SESSION_ENDED | Session ended normally | - |
SESSION_TIMED_OUT | Session timeout | - |
TIME_EXHAUSTED | Usage time exhausted | - |
QUOTA_EXCEEDED | Concurrent connection quota exceeded | - |
SUSPEND_WARNED | Long idle warning | - |
onStatus(callback)
Receives SDK connection status changes.
js
SDK.onStatus((status) => {
console.log('Status:', status);
if (status === 'CONNECTED_FINISH') {
console.log('Avatar ready');
}
});jsx
const [status, setStatus] = useState('IDLE');
useEffect(() => {
window.KlleonSDK.onStatus((s) => setStatus(s));
}, []);onError(callback)
Receives SDK internal errors and server errors.
js
SDK.onError((error) => {
console.error(error.code, error.message);
});jsx
useEffect(() => {
window.KlleonSDK.onError((error) => {
console.error(error.code, error.message);
});
}, []);Callback Parameters
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Error code |
message | string | No | Detailed message |
Error Code Details
Initialization Errors (on init failure)
| Code | Trigger | message example |
|---|---|---|
SOCKET_FAILED | SDK key validation failure or WebSocket connection failure | "Failed to connect: ..." |
STREAMING_FAILED | Streaming connection failure | "Failed to connect streaming: ..." |
On init failure,
onErroris not called. Sinceinit()throws anError, handle it withtry/catch.
Runtime Errors (during active connection)
| Code | Trigger | message example |
|---|---|---|
SOCKET_DISCONNECTED_UNEXPECTEDLY | WebSocket error occurred | "WebSocket disconnected unexpectedly" |
STREAMING_FAILED | Remote track subscription failure | "Failed to subscribe to remote track" |
STREAMING_DISCONNECTED_UNEXPECTEDLY | Streaming abnormal termination | "Streaming disconnected: NETWORK_ERROR" |
Server Errors
| Code | Trigger | message example |
|---|---|---|
SERVER_ERROR | SERVER_ERROR signal received from server | Server message or "SERVER_ERROR" |
WORKER_DISCONNECTED | Server connection termination signal received | "WORKER_DISCONNECTED" |
Event Registration Example
js
const SDK = window.KlleonSDK;
SDK.onStatus((status) => console.log('Status:', status));
SDK.onSignal((data) => {
if (data.signal === 'RESPONSE_TEXT') {
console.log('Avatar:', data.payload.text);
}
});
SDK.onError((error) => {
console.error(`[${error.code}] ${error.message}`);
});
SDK.init({
sdk_key: 'YOUR_SDK_KEY',
avatar_id: 'YOUR_AVATAR_ID',
}).catch((e) => console.error(e.message));jsx
import { useEffect, useRef } from 'react';
function App() {
const initialized = useRef(false);
useEffect(() => {
const SDK = window.KlleonSDK;
SDK.onStatus((status) => console.log('Status:', status));
SDK.onSignal((data) => {
if (data.signal === 'RESPONSE_TEXT') {
console.log('Avatar:', data.payload.text);
}
});
SDK.onError((error) => {
console.error(`[${error.code}] ${error.message}`);
});
SDK.init({
sdk_key: 'YOUR_SDK_KEY',
avatar_id: 'YOUR_AVATAR_ID',
})
.then(() => { initialized.current = true; })
.catch((e) => console.error(e.message));
return () => {
if (initialized.current) SDK.destroy();
};
}, []);
return <avatar-container style={{ width: 400, height: 600 }} />;
}