@unisphere/models-types 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +450 -80
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,134 +1,504 @@
1
- # Unisphere - Kaltura Models
1
+ # Kaltura Avatar SDK
2
2
 
3
- ## Overview
3
+ A TypeScript SDK for integrating with Kaltura's speech-to-video (STV) avatar service.
4
4
 
5
- This repository is a **Unisphere workspace** for an experience named **Models**.
5
+ ## Features
6
6
 
7
- It contains everything you need to:
8
- - Create and publish npm / JFrog packages
9
- - Bundle and version runtime artifacts
10
- - Build and deploy applications
11
- - Develop locally and promote changes to production
7
+ - 🎭 **Simple API** - Create sessions and control avatars with just a few lines of code
8
+ - 🎥 **WebRTC Streaming** - Real-time avatar video via WHEP protocol
9
+ - 🗣️ **Text-to-Speech** - Automatic text chunking for optimal processing
10
+ - 🎵 **Audio Support** - Send audio files for avatar to speak
11
+ - 🔄 **Auto-Retry** - Built-in retry logic with exponential backoff
12
+ - 💓 **Keep-Alive** - Automatic session maintenance every 10 seconds
13
+ - 🎬 **Auto-Attach** - Optional automatic video element creation and attachment
14
+ - 🛠️ **TypeScript** - Full type safety and IntelliSense support
15
+ - 📦 **Modular** - Clean SDK-of-SDKs architecture
12
16
 
13
- The Unisphere workspace acts as the single entry point for the entire lifecycle — from local development, through CI/CD, and all the way to production deployment.
17
+ ## Installation
14
18
 
15
- To better understand the ideas behind Unisphere and how it works, read more at:
16
- https://unisphere.kaltura.com/
19
+ ```bash
20
+ npm install @unisphere/models-sdk-js
21
+ ```
17
22
 
18
- ---
23
+ ## Quick Start
19
24
 
20
- ## Prerequisites
25
+ ### Option 1: Auto-Attach Video (Recommended)
21
26
 
22
- At the moment, **deploying Unisphere experiences is available only to Kaltura employees**.
27
+ ```typescript
28
+ import { KalturaAvatarSession } from '@unisphere/models-sdk-js';
23
29
 
24
- Before doing anything else, make sure your machine is properly configured to access:
25
- - Kaltura GitHub repositories
26
- - Kaltura JFrog Artifactory registries
30
+ // 1. Create SDK instance
31
+ const session = new KalturaAvatarSession('your-api-key', {
32
+ baseUrl: 'https://api.avatar.example.com/v1/avatar-session'
33
+ });
27
34
 
28
- Follow the setup guide here:
29
- https://unisphere.kaltura.com/docs/create/kaltura-employees/setup-machine
35
+ // 2. Create session with auto-attach
36
+ // The SDK will automatically create a video element inside the container
37
+ await session.createSession({
38
+ avatarId: 'avatar-123',
39
+ voiceId: 'voice-456', // optional
40
+ videoContainerId: 'avatar-container' // ID of div element
41
+ });
30
42
 
31
- ---
43
+ // 3. Make avatar speak
44
+ await session.sayText('Hello from Kaltura Avatar!');
32
45
 
33
- ## Add the Experience to Kaltura Github Organization
46
+ // 4. End session
47
+ await session.endSession();
48
+ ```
34
49
 
35
- Before you can deploy or activate this experience, it must be registered in Github under Kaltura Organization.
50
+ ### Option 2: Manual Attach
36
51
 
37
- This step connects your Unisphere workspace to the relevant Kaltura infrastructure and enables CI/CD, deployment, and activation flows.
52
+ ```typescript
53
+ import { KalturaAvatarSession } from '@unisphere/models-sdk-js';
38
54
 
39
- Follow the guide here:
40
- https://unisphere.kaltura.com/docs/create/devops/create-github-repository
55
+ // 1. Create SDK instance
56
+ const session = new KalturaAvatarSession('your-api-key', {
57
+ baseUrl: 'https://api.avatar.example.com/v1/avatar-session'
58
+ });
41
59
 
42
- ---
60
+ // 2. Create session
61
+ await session.createSession({
62
+ avatarId: 'avatar-123',
63
+ voiceId: 'voice-456' // optional
64
+ });
43
65
 
44
- ## Create Artifacts
66
+ // 3. Attach video to container
67
+ // The SDK will create a video element inside the specified div
68
+ session.attachAvatar('avatar-container');
45
69
 
46
- Unisphere allows you to create and manage different types of artifacts, including:
47
- - Packages
48
- - Runtimes
49
- - Applications
70
+ // 4. Make avatar speak
71
+ await session.sayText('Hello from Kaltura Avatar!');
50
72
 
51
- Each artifact type has its own role in the ecosystem, but they all live and evolve together inside this workspace.
73
+ // 5. End session
74
+ await session.endSession();
75
+ ```
52
76
 
53
- Read more about creating artifacts here:
54
- https://unisphere.kaltura.com/docs/create/overview
77
+ **HTML Setup:**
55
78
 
56
- ---
79
+ ```html
80
+ <div id="avatar-container" style="width: 512px; height: 512px;"></div>
81
+ ```
57
82
 
58
- ## Deploy
83
+ ## API Reference
59
84
 
60
- To deploy **packages, applications, and runtimes**, follow the deployment guide:
61
- https://unisphere.kaltura.com/docs/create/devops/deploy
85
+ ### Constructor
62
86
 
63
- For **applications and runtimes**, deployment is only part of the process.
64
- After deployment, they must also be activated to become available in production.
87
+ ```typescript
88
+ new KalturaAvatarSession(apiKey: string, config?: AvatarConfig)
89
+ ```
65
90
 
66
- Activation guide:
67
- https://unisphere.kaltura.com/docs/create/devops/activate
91
+ **Parameters:**
92
+ - `apiKey` - Your Kaltura Avatar API key
93
+ - `config` - Optional configuration:
94
+ - `baseUrl` - Backend API URL (required for non-default endpoints)
95
+ - `iceServers` - Custom ICE servers for WebRTC (optional, defaults to backend-provided TURN servers)
96
+ - `iceTransportPolicy` - 'all' or 'relay' (default: 'all')
97
+ - `retryConfig` - Retry configuration for API calls and connections
98
+ - `logLevel` - 'debug' | 'info' | 'warn' | 'error' (default: 'info')
99
+
100
+ ### Methods
101
+
102
+ #### `createSession(options: CreateSessionOptions): Promise<void>`
103
+
104
+ Create a new avatar session and establish WebRTC connection. Optionally auto-attach video to a container.
105
+
106
+ **Options:**
107
+ - `avatarId` (required) - ID of the avatar to use
108
+ - `voiceId` (optional) - ID of the voice to use for TTS
109
+ - `videoContainerId` (optional) - ID of the div element to automatically attach video to
110
+
111
+ ```typescript
112
+ // With auto-attach
113
+ await session.createSession({
114
+ avatarId: 'avatar-123',
115
+ voiceId: 'voice-456', // optional
116
+ videoContainerId: 'avatar-container' // optional - auto-attach video
117
+ });
118
+
119
+ // Without auto-attach
120
+ await session.createSession({
121
+ avatarId: 'avatar-123',
122
+ voiceId: 'voice-456' // optional
123
+ });
124
+ ```
68
125
 
69
- ---
126
+ **Note:** When a session is created, the SDK automatically:
127
+ 1. Initializes the backend client
128
+ 2. Retrieves WHEP URL and TURN server configuration from the backend
129
+ 3. Establishes WebRTC connection
130
+ 4. Starts automatic keep-alive (every 10 seconds)
131
+ 5. Attaches video if `videoContainerId` is provided
70
132
 
71
- ## Local Development
133
+ #### `attachAvatar(containerId: string): void`
72
134
 
73
- Unisphere provides a structured local development flow that mirrors production as closely as possible, while still keeping things fast and developer-friendly.
135
+ Attach avatar video to a container div by creating a video element inside it. If a video element already exists in the container, it will be reused.
74
136
 
75
- This includes:
76
- - Local builds
77
- - Watching and rebuilding artifacts
78
- - Running applications in isolation or as part of a larger workspace
137
+ **Parameters:**
138
+ - `containerId` - ID of the div element to attach video to
79
139
 
80
- Read more about local development here:
81
- https://unisphere.kaltura.com/docs/create/local-development
140
+ ```typescript
141
+ // The SDK will create/find a video element inside this div
142
+ session.attachAvatar('avatar-container');
143
+ ```
82
144
 
83
- ---
145
+ **HTML:**
146
+ ```html
147
+ <div id="avatar-container" style="width: 512px; height: 512px;">
148
+ <!-- Video element will be created here automatically -->
149
+ </div>
150
+ ```
84
151
 
85
- ## Available Commands
152
+ **Note:** The created video element will have:
153
+ - `autoplay` and `playsinline` attributes
154
+ - Width and height set to 100%
155
+ - Appropriate styling for fullscreen display within the container
86
156
 
87
- This workspace exposes a small set of opinionated commands to help you explore, validate, and manage the experience.
157
+ #### `sayText(text: string): Promise<void>`
88
158
 
89
- ### Start
90
- Lists all available commands for each artifact in the experience, including how to build and serve runtimes, and how to spawn applications.
159
+ Send text for the avatar to speak. Text is automatically chunked into 3-word segments.
91
160
 
92
- ```bash
93
- npm run start
161
+ ```typescript
162
+ await session.sayText('Hello, how are you doing today?');
163
+ // Internally split into: ['Hello, how are', 'you doing today']
94
164
  ```
95
165
 
166
+ #### `say(mp3File: File | Blob): Promise<void>`
96
167
 
97
- ### Info
98
- Displays information about the current workspace, including detected artifacts, configuration, and environment details.
168
+ Send audio file for the avatar to speak.
99
169
 
100
- ```bash
101
- npm run info
170
+ ```typescript
171
+ const audioFile = new File([audioBlob], 'speech.mp3', { type: 'audio/mpeg' });
172
+ await session.say(audioFile);
102
173
  ```
103
174
 
104
- ### Check
105
- Validates the workspace setup and verifies that all required artifacts and configurations are in place.
175
+ #### `interrupt(): Promise<void>`
106
176
 
107
- ```bash
108
- npm run check
177
+ Interrupt the avatar's current speech.
178
+
179
+ ```typescript
180
+ await session.interrupt();
109
181
  ```
110
182
 
111
- ### Reset
112
- Resets the workspace to a clean state. Useful when experimenting or when local state becomes inconsistent.
183
+ #### `endSession(): Promise<void>`
113
184
 
114
- ```bash
115
- npm run reset
185
+ End the session and cleanup resources. This will:
186
+ - Stop the automatic keep-alive interval
187
+ - Disconnect the WebRTC connection
188
+ - End the session on the backend
189
+ - Clean up all resources
190
+
191
+ ```typescript
192
+ await session.endSession();
116
193
  ```
117
194
 
195
+ ### State Management
196
+
197
+ #### `getSessionId(): string | null`
198
+
199
+ Get the current session ID.
200
+
201
+ ```typescript
202
+ const sessionId = session.getSessionId();
203
+ console.log('Session ID:', sessionId);
204
+ ```
205
+
206
+ #### `getSessionState(): SessionState`
207
+
208
+ Get current session state.
209
+
210
+ ```typescript
211
+ const state = session.getSessionState();
212
+ // States: IDLE, CREATING, READY, ENDED, ERROR
213
+ ```
214
+
215
+ #### `getConnectionState(): ConnectionState`
216
+
217
+ Get current WebRTC connection state.
218
+
219
+ ```typescript
220
+ const connState = session.getConnectionState();
221
+ // States: DISCONNECTED, CONNECTING, CONNECTED, FAILED, CLOSED
222
+ ```
223
+
224
+ ### Events
225
+
226
+ #### `on(event: SessionEvent, callback: Function): void`
118
227
 
119
- ---
228
+ Register event handlers.
229
+
230
+ ```typescript
231
+ // State changes
232
+ session.on('stateChange', (state: SessionState) => {
233
+ console.log('Session state:', state);
234
+ });
235
+
236
+ // Connection changes
237
+ session.on('connectionChange', (state: ConnectionState) => {
238
+ console.log('Connection state:', state);
239
+ });
240
+
241
+ // Errors
242
+ session.on('error', (error: AvatarError) => {
243
+ console.error('Error:', error.message, error.code);
244
+ });
245
+ ```
246
+
247
+ ## Complete Example
248
+
249
+ ```typescript
250
+ import {
251
+ KalturaAvatarSession,
252
+ SessionState,
253
+ ConnectionState,
254
+ AvatarError,
255
+ } from '@unisphere/models-sdk-js';
256
+
257
+ async function runAvatarDemo() {
258
+ // Create SDK instance with custom config
259
+ const session = new KalturaAvatarSession('your-api-key', {
260
+ baseUrl: 'https://api.avatar.example.com/v1/avatar-session',
261
+ logLevel: 'info',
262
+ retryConfig: {
263
+ maxAttempts: 3,
264
+ initialDelayMs: 500,
265
+ maxDelayMs: 5000,
266
+ backoffMultiplier: 2,
267
+ },
268
+ });
269
+
270
+ // Setup event listeners
271
+ session.on('stateChange', (state: SessionState) => {
272
+ console.log('Session state changed:', state);
273
+ });
274
+
275
+ session.on('connectionChange', (state: ConnectionState) => {
276
+ console.log('Connection state changed:', state);
277
+ });
278
+
279
+ session.on('error', (error: AvatarError) => {
280
+ console.error('SDK Error:', error.message);
281
+ });
282
+
283
+ try {
284
+ // Create session with auto-attach
285
+ console.log('Creating session...');
286
+ await session.createSession({
287
+ avatarId: 'avatar-123',
288
+ voiceId: 'voice-456',
289
+ videoContainerId: 'avatar-container' // Auto-attach to div
290
+ });
291
+
292
+ // Session is now ready, keep-alive started automatically
293
+ console.log('Session ID:', session.getSessionId());
294
+ console.log('Session State:', session.getSessionState());
295
+ console.log('Connection State:', session.getConnectionState());
296
+
297
+ // Say some text (automatically chunked)
298
+ await session.sayText('Welcome to Kaltura Avatar! How can I help you today?');
299
+
300
+ // Wait for user interaction...
301
+ await new Promise(resolve => setTimeout(resolve, 5000));
302
+
303
+ // Interrupt if needed
304
+ await session.interrupt();
305
+
306
+ // Say something else
307
+ await session.sayText('Thanks for trying the Kaltura Avatar SDK!');
308
+
309
+ // Wait before ending
310
+ await new Promise(resolve => setTimeout(resolve, 3000));
311
+
312
+ // End session (automatically stops keep-alive)
313
+ await session.endSession();
314
+ console.log('Session ended successfully');
315
+
316
+ } catch (error) {
317
+ if (error instanceof AvatarError) {
318
+ console.error('Avatar Error:', error.code, error.message);
319
+ } else {
320
+ console.error('Unexpected error:', error);
321
+ }
322
+ }
323
+ }
324
+
325
+ // HTML: <div id="avatar-container" style="width: 512px; height: 512px;"></div>
326
+ runAvatarDemo();
327
+ ```
328
+
329
+ ## Architecture
330
+
331
+ The SDK follows an "SDK of SDKs" pattern with clean separation of concerns:
332
+
333
+ ```
334
+ KalturaAvatarSession (Public API)
335
+ ├── AvatarControlSDK (HTTP/JWT)
336
+ │ ├── Session lifecycle (create, init, end)
337
+ │ ├── Avatar control (sayText, say, interrupt)
338
+ │ └── Keep-alive management
339
+ └── AvatarRTCSDK (WebRTC)
340
+ ├── SignalingManager (WHEP protocol)
341
+ └── PeerConnectionManager (RTCPeerConnection)
342
+ ```
343
+
344
+ ### Session Initialization Flow
345
+
346
+ 1. **Create Session** - Establishes backend session and receives JWT token
347
+ 2. **Init Client** - Retrieves WHEP URL and TURN server configuration from backend
348
+ 3. **Initialize RTC SDK** - Creates RTC SDK with backend-provided configuration
349
+ 4. **Connect WebRTC** - Establishes WHEP connection using backend-provided endpoint
350
+ 5. **Start Keep-Alive** - Automatically sends keep-alive every 10 seconds
351
+ 6. **Auto-Attach (optional)** - Creates video element if `videoContainerId` provided
352
+
353
+ ### Benefits
354
+
355
+ - **Separation of Concerns** - Each layer has a single responsibility
356
+ - **Backend-Managed ICE Servers** - TURN configuration provided by backend, not client
357
+ - **Automatic Keep-Alive** - Session maintenance handled automatically
358
+ - **Testability** - Mock and test each layer independently
359
+ - **Extensibility** - Easy to add new features or swap implementations
360
+ - **Maintainability** - Clear boundaries and good TypeScript typing
361
+
362
+ ## Advanced Usage
363
+
364
+ ### Custom ICE Servers (Override Backend)
365
+
366
+ By default, ICE servers (TURN configuration) are provided by the backend during `initClient`. However, you can override them:
367
+
368
+ ```typescript
369
+ const session = new KalturaAvatarSession('your-api-key', {
370
+ baseUrl: 'https://api.avatar.example.com/v1/avatar-session',
371
+ // Override backend-provided ICE servers
372
+ iceServers: [
373
+ { urls: 'stun:stun.example.com:19302' },
374
+ {
375
+ urls: ['turn:turn.example.com:80', 'turn:turn.example.com:443'],
376
+ username: 'user',
377
+ credential: 'pass',
378
+ },
379
+ ],
380
+ iceTransportPolicy: 'relay', // Force TURN only
381
+ });
382
+ ```
383
+
384
+ **Note:** The SDK will fall back to your custom ICE servers only if the backend doesn't provide them.
385
+
386
+ ### Using Individual SDKs
387
+
388
+ For advanced use cases, you can use the underlying SDKs directly:
389
+
390
+ ```typescript
391
+ import {
392
+ AvatarControlSDK,
393
+ AvatarRTCSDK,
394
+ } from '@unisphere/models-sdk-js';
395
+
396
+ // HTTP control
397
+ const controlSDK = new AvatarControlSDK({
398
+ baseUrl: 'http://localhost:6100/v1/avatar-session',
399
+ apiKey: 'your-api-key',
400
+ logLevel: 'debug',
401
+ });
402
+
403
+ // Create session
404
+ const createRes = await controlSDK.createSession({
405
+ avatarId: 'avatar-123',
406
+ voiceId: 'voice-456',
407
+ });
408
+
409
+ // Initialize client to get WHEP URL and TURN servers
410
+ const initRes = await controlSDK.initClient(createRes.sessionId);
411
+
412
+ // WebRTC - initialized with backend-provided config
413
+ const rtcSDK = new AvatarRTCSDK({
414
+ whepUrl: initRes.whepUrl,
415
+ iceServers: [{
416
+ urls: [
417
+ `turn:${initRes.turn.url}:80?transport=udp`,
418
+ `turn:${initRes.turn.url}:443?transport=udp`,
419
+ `turn:${initRes.turn.url}:80?transport=tcp`,
420
+ ],
421
+ username: initRes.turn.username,
422
+ credential: initRes.turn.credential,
423
+ }],
424
+ });
425
+
426
+ await rtcSDK.connect();
427
+ ```
428
+
429
+ ### Keep-Alive Management
430
+
431
+ The SDK automatically sends keep-alive signals to the backend every 10 seconds once a session is created. This ensures:
432
+ - Session remains active
433
+ - Backend doesn't terminate idle sessions
434
+ - Resources are properly maintained
435
+
436
+ ```typescript
437
+ // Keep-alive is started automatically when session is READY
438
+ await session.createSession({
439
+ avatarId: 'avatar-123',
440
+ videoContainerId: 'avatar-container'
441
+ });
442
+ // Keep-alive now running every 10 seconds
443
+
444
+ // Keep-alive is stopped automatically when session ends
445
+ await session.endSession();
446
+ // Keep-alive stopped
447
+ ```
448
+
449
+ **Configuration:**
450
+
451
+ The keep-alive interval is set to 10 seconds and cannot be configured. If you need to manually manage keep-alive, use the `AvatarControlSDK` directly:
452
+
453
+ ```typescript
454
+ import { AvatarControlSDK } from '@unisphere/models-sdk-js';
455
+
456
+ const controlSDK = new AvatarControlSDK({
457
+ baseUrl: 'https://api.avatar.example.com/v1/avatar-session',
458
+ apiKey: 'your-api-key',
459
+ });
460
+
461
+ // Manual keep-alive
462
+ await controlSDK.keepAlive(sessionId);
463
+ ```
464
+
465
+ ## Error Handling
466
+
467
+ All errors are instances of `AvatarError` with a specific error code:
468
+
469
+ ```typescript
470
+ try {
471
+ await session.sayText('Hello');
472
+ } catch (error) {
473
+ if (error instanceof AvatarError) {
474
+ switch (error.code) {
475
+ case AvatarErrorCode.INVALID_STATE:
476
+ console.log('Wrong state - create session first');
477
+ break;
478
+ case AvatarErrorCode.API_REQUEST_FAILED:
479
+ console.log('API request failed - check network');
480
+ break;
481
+ case AvatarErrorCode.RTC_CONNECTION_FAILED:
482
+ console.log('WebRTC connection failed');
483
+ break;
484
+ default:
485
+ console.log('Error:', error.message);
486
+ }
487
+ }
488
+ }
489
+ ```
120
490
 
121
- ## Next Steps
491
+ ## Browser Support
122
492
 
123
- If this is your first time working with Unisphere, a great next step is to **create a runtime with a playground**.
493
+ - Chrome/Edge 80+
494
+ - Firefox 75+
495
+ - Safari 14+
496
+ - Requires WebRTC support
124
497
 
125
- Follow the Hello World walkthrough here:
126
- [https://unisphere.kaltura.com/docs/create/overview](https://unisphere.kaltura.com/docs/create/overview)
498
+ ## License
127
499
 
128
- The walkthrough will guide you through:
500
+ AGPL-3.0
129
501
 
130
- * Creating your first runtime
131
- * Running it locally with a playground
132
- * Understanding how runtimes, packages, and applications connect together
502
+ ## Support
133
503
 
134
- This will give you a strong foundation for building and evolving the experience over time.
504
+ For issues and questions, please visit our [GitHub repository](https://github.com/kaltura/models).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unisphere/models-types",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "author": "kaltura",
5
5
  "private": false,
6
6
  "license": "AGPL-3.0",