@kaltura-sdk/avatars 1.14.1 → 1.15.1

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.
package/README.md CHANGED
@@ -1 +1,47 @@
1
- # Unisphere Genie - Package Avatars
1
+ # @kaltura-sdk/avatars
2
+
3
+ Core implementation of `AvatarClientManager` — the state machine-driven client for Kaltura's conversational avatar. Runs on `xstate` + `@unisphere/core` reactive stores; owns the whole connection lifecycle (RTC session, chat, captions, screen share, tap-to-talk, client tools, Kaltura context).
4
+
5
+ For a framework-free, CDN-loadable build, use [`@kaltura-sdk/avatars-esm`](../avatars-esm) — it re-exports this package.
6
+
7
+ ## Usage
8
+
9
+ ```ts
10
+ import { AvatarClientManager } from '@kaltura-sdk/avatars';
11
+
12
+ const manager = new AvatarClientManager({
13
+ actions: { showNotification }, // optional, defaults to a noop
14
+ debugMode: true, // optional, default false
15
+ logger, // optional — UnisphereLoggerType, defaults to an internal 'avatar-client' logger
16
+ runtimeSettings, // AvatarRuntimeSettings
17
+ kalturaAnalyticsService, // optional, no-ops if omitted
18
+ pubSubService, // optional, no-ops if omitted
19
+ registerDeveloperTools: (actor) => {}, // optional, e.g. xstate inspector
20
+ videoContainerId: 'avatar-video', // optional — auto-joins STV once castMode is "webrtc"
21
+ });
22
+
23
+ manager.connectionStatus.onChanges((status) => console.log(status));
24
+ manager.connect({ dynamicVariables, kickOffPhrase });
25
+ manager.disconnect();
26
+ manager.stop(); // full teardown, unsubscribes everything
27
+ ```
28
+
29
+ `connect()`/`disconnect()` are sync (fire-and-forget) — read outcomes off the reactive stores (`connectionStatus`, `castMode`, `disconnectData`, etc).
30
+
31
+ ## API surface
32
+
33
+ - **Lifecycle**: `connect()`, `disconnect()`, `reconnect()`, `stop()`, `connectionStatus`, `playerUrl`, `sessionId`, `castMode`, `turnServerURL`, `disconnectData`
34
+ - **Pause/resume**: `pause()`, `resume()`, `pauseAfterSpeaking()`, `isPaused`
35
+ - **Chat & content**: `askViaText()`, `chatLog`, `content`, `setLocalContent()`, `clearContent()`, `agentData`
36
+ - **Screen share**: `startScreenShare()`, `stopScreenShare()`, `screenShareInfo`
37
+ - **Tap-to-talk**: `tapToTalkStart()`, `tapToTalkEnd()`, `toggleTapToTalkMode()`, `tapToTalkInfo`
38
+ - **Captions**: `captions` (state + `toggle`/`setReplacements`/`setFilter`)
39
+ - **Kaltura context**: `kalturaContext`, `toggleKalturaContext()`, `updateDynamicVariables()`
40
+ - **Client tools**: `registerClientTools()`, `unregisterClientTools()`, `registeredClientTools`, `clientToolCallLog`
41
+ - **Session metadata**: `threadId`, `setExternalThreadId()`, `isPreviewMode`, `contextSelectorVisible`, `features`, `agentPreviewUrl`, `agentPreviewImageUrl`, `serverUrl`
42
+ - **RTC/device passthrough**: `audioState`, `audioVolumeLevel`, `devicesList`, `joinSTV()`, `leaveSTV()`, `changeDevice()`, `toggleMuteAudio()`
43
+ - **Player events**: `onPlayerReady()`, `onPlayerError()`
44
+
45
+ All getters return `@unisphere/core` reactive stores (`.consumer`, subscribe via `.onChanges`).
46
+
47
+ `connection` is a deprecated back-compat facade kept only for consumers not yet migrated to the manager's own getters/methods.
package/index.esm.js CHANGED
@@ -7608,6 +7608,9 @@ const connectingState = {
7608
7608
  },
7609
7609
  on: {
7610
7610
  [AvatarConnectionMachineEventTypes.ServerReadyReceived]: [{
7611
+ guard: 'shouldAutoJoinSTVPlayer',
7612
+ target: 'joiningSTVPlayer'
7613
+ }, {
7611
7614
  guard: 'shouldWaitPlayerReadyState',
7612
7615
  target: 'waitingPlayerReadyState'
7613
7616
  }, {
@@ -7615,6 +7618,39 @@ const connectingState = {
7615
7618
  }]
7616
7619
  }
7617
7620
  },
7621
+ joiningSTVPlayer: {
7622
+ invoke: {
7623
+ id: 'joinSTVPlayer',
7624
+ src: 'joinSTVPlayer',
7625
+ input: ({
7626
+ context
7627
+ }) => ({
7628
+ logger: context.logger,
7629
+ // videoContainerId presence is enforced by the shouldAutoJoinSTVPlayer guard
7630
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
7631
+ videoContainerId: context.externalInfo.videoContainerId,
7632
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
7633
+ sessionId: context.sessionId,
7634
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
7635
+ webrtcUrl: context.webrtcUrl
7636
+ }),
7637
+ onDone: {
7638
+ target: 'delayingBeforeConnect'
7639
+ },
7640
+ onError: {
7641
+ actions: {
7642
+ type: 'setDisconnectData',
7643
+ params: ({
7644
+ event
7645
+ }) => ({
7646
+ reason: DisconnectReasons.PlayerConnectionFailed,
7647
+ error: event.error
7648
+ })
7649
+ },
7650
+ target: 'error'
7651
+ }
7652
+ }
7653
+ },
7618
7654
  waitingPlayerReadyState: {
7619
7655
  invoke: {
7620
7656
  src: 'onPlayerReadyState',
@@ -19464,12 +19500,52 @@ const onPlayerReadyState = fromCallback(({
19464
19500
  });
19465
19501
  });
19466
19502
 
19503
+ /**
19504
+ * Auto-join the STV (webrtc) video stream into a caller-provided container
19505
+ * element, on behalf of consumers that configured `videoContainerId` on the
19506
+ * `AvatarClientManager` constructor instead of managing joinSTV/leaveSTV
19507
+ * themselves (e.g. avatar-react's STVPlayer keeps doing that manually and
19508
+ * never reaches this actor — see `shouldAutoJoinSTVPlayer`).
19509
+ *
19510
+ * Resolves once the STV peer connection is established (mirrors the
19511
+ * `onConnected` callback consumers pass to `joinSTV` directly), not merely
19512
+ * once WebRTC signaling completes.
19513
+ */
19514
+ const joinSTVPlayer = fromPromise(_a => __awaiter(void 0, [_a], void 0, function* ({
19515
+ input
19516
+ }) {
19517
+ const {
19518
+ logger,
19519
+ videoContainerId,
19520
+ sessionId,
19521
+ webrtcUrl
19522
+ } = input;
19523
+ logger.log('Auto-joining STV player...', {
19524
+ data: {
19525
+ videoContainerId,
19526
+ sessionId
19527
+ }
19528
+ });
19529
+ yield new Promise((resolve, reject) => {
19530
+ avatarRTCClientManager.joinSTV(videoContainerId, sessionId, webrtcUrl, () => {
19531
+ logger.log('STV player auto-joined and connected');
19532
+ resolve();
19533
+ }).catch(reject);
19534
+ });
19535
+ }));
19536
+
19467
19537
  const shouldWaitPlayerReadyState = ({
19468
19538
  context
19469
19539
  }) => {
19470
19540
  return context.externalInfo.waitPlayerReadyState === true;
19471
19541
  };
19472
19542
 
19543
+ const shouldAutoJoinSTVPlayer = ({
19544
+ context
19545
+ }) => {
19546
+ return context.castMode === 'webrtc' && !!context.externalInfo.videoContainerId;
19547
+ };
19548
+
19473
19549
  const setContentData = assign$1(({
19474
19550
  context,
19475
19551
  event
@@ -23290,6 +23366,7 @@ const avatarConnectionMachine = setup({
23290
23366
  onConversationEnded,
23291
23367
  onError,
23292
23368
  onPlayerReadyState,
23369
+ joinSTVPlayer,
23293
23370
  onAgentTalking,
23294
23371
  onAgentRawText,
23295
23372
  onConversationTimeWarning,
@@ -23318,6 +23395,7 @@ const avatarConnectionMachine = setup({
23318
23395
  hasMoreRecoveryRetries,
23319
23396
  justExceededRecoveryRetries,
23320
23397
  shouldWaitPlayerReadyState,
23398
+ shouldAutoJoinSTVPlayer,
23321
23399
  shouldDisconnect,
23322
23400
  shouldWaitBeforePurge,
23323
23401
  shouldCreateWebsocketConnection,
@@ -23356,6 +23434,7 @@ const avatarConnectionMachine = setup({
23356
23434
  debugMode: input.debugMode,
23357
23435
  level: (_b = input.level) !== null && _b !== void 0 ? _b : 'published',
23358
23436
  waitPlayerReadyState: (_c = input.waitPlayerReadyState) !== null && _c !== void 0 ? _c : true,
23437
+ videoContainerId: input.videoContainerId,
23359
23438
  kaltura: input.runtimeSettings.kaltura,
23360
23439
  features: Object.assign(Object.assign({}, input.runtimeSettings.features), {
23361
23440
  kickOffPhrase: (_d = input.kickOffPhrase) !== null && _d !== void 0 ? _d : (_e = input.runtimeSettings.features) === null || _e === void 0 ? void 0 : _e.kickOffPhrase
@@ -23551,6 +23630,11 @@ const noopPubSubService = {
23551
23630
  // noop
23552
23631
  }
23553
23632
  };
23633
+ const noopAvatarClientManagerActions = {
23634
+ showNotification: () => {
23635
+ // noop
23636
+ }
23637
+ };
23554
23638
  /**
23555
23639
  * Avatar-domain manager on top of the generic `ActorManager` engine: owns
23556
23640
  * the `avatarConnectionMachine` actor and exposes it as reactive stores +
@@ -23561,6 +23645,7 @@ const noopPubSubService = {
23561
23645
  */
23562
23646
  class AvatarClientManager extends ActorManager {
23563
23647
  constructor(_config) {
23648
+ var _a;
23564
23649
  super();
23565
23650
  this._config = _config;
23566
23651
  // keep separate from other subscriptions since we don't want to stop when disconnect only when stop called
@@ -23711,7 +23796,7 @@ class AvatarClientManager extends ActorManager {
23711
23796
  this._contextSelectorVisible = new TinyDataStore({
23712
23797
  initialValue: true
23713
23798
  });
23714
- this._logger = this._config.logger;
23799
+ this._logger = (_a = this._config.logger) !== null && _a !== void 0 ? _a : avatarClientLoggerFactory.getOrCreateLogger('service', 'avatar-client');
23715
23800
  if (this._config.runtimeSettings.features) {
23716
23801
  this._features.setData(() => this._config.runtimeSettings.features);
23717
23802
  }
@@ -23923,7 +24008,7 @@ class AvatarClientManager extends ActorManager {
23923
24008
  return this._agentData.consumer;
23924
24009
  }
23925
24010
  connect(options) {
23926
- var _a, _b, _c, _d, _e;
24011
+ var _a, _b, _c, _d, _e, _f, _g;
23927
24012
  this._lastConnectOptions = options;
23928
24013
  this._onThreadIdChange = options === null || options === void 0 ? void 0 : options.onThreadIdChange;
23929
24014
  if (this._connection.getData()) {
@@ -23941,26 +24026,27 @@ class AvatarClientManager extends ActorManager {
23941
24026
  input: Object.assign({
23942
24027
  connectionId,
23943
24028
  logger: this._logger,
23944
- debugMode: this._config.debugMode,
23945
- kalturaAnalyticsService: (_a = this._config.kalturaAnalyticsService) !== null && _a !== void 0 ? _a : noopKalturaAnalyticsService,
23946
- pubSubService: (_b = this._config.pubSubService) !== null && _b !== void 0 ? _b : noopPubSubService,
24029
+ debugMode: (_a = this._config.debugMode) !== null && _a !== void 0 ? _a : false,
24030
+ kalturaAnalyticsService: (_b = this._config.kalturaAnalyticsService) !== null && _b !== void 0 ? _b : noopKalturaAnalyticsService,
24031
+ pubSubService: (_c = this._config.pubSubService) !== null && _c !== void 0 ? _c : noopPubSubService,
23947
24032
  externalActions: {
23948
- showNotification: this._config.actions.showNotification
24033
+ showNotification: ((_d = this._config.actions) !== null && _d !== void 0 ? _d : noopAvatarClientManagerActions).showNotification
23949
24034
  },
23950
24035
  runtimeSettings: this._config.runtimeSettings,
24036
+ videoContainerId: this._config.videoContainerId,
23951
24037
  isInitialKalturaContextActive: this._isKalturaContextActive,
23952
24038
  dynamicVariables: options === null || options === void 0 ? void 0 : options.dynamicVariables,
23953
24039
  kickOffPhrase: options === null || options === void 0 ? void 0 : options.kickOffPhrase,
23954
24040
  clientToolsRegistry: this._clientToolsRegistry,
23955
24041
  getClientToolHandler: this._getClientToolHandler
23956
- }, ((_c = options === null || options === void 0 ? void 0 : options.context) === null || _c === void 0 ? void 0 : _c.type) === 'thread' && {
24042
+ }, ((_e = options === null || options === void 0 ? void 0 : options.context) === null || _e === void 0 ? void 0 : _e.type) === 'thread' && {
23957
24043
  threadId: options.context.threadId,
23958
24044
  messageId: options.context.messageId
23959
24045
  })
23960
24046
  });
23961
24047
  this._logsInitialized = false;
23962
24048
  this._setupActorSync(actor);
23963
- (_e = (_d = this._config).registerDeveloperTools) === null || _e === void 0 ? void 0 : _e.call(_d, actor);
24049
+ (_g = (_f = this._config).registerDeveloperTools) === null || _g === void 0 ? void 0 : _g.call(_f, actor);
23964
24050
  actor.start();
23965
24051
  }
23966
24052
  disconnect() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaltura-sdk/avatars",
3
- "version": "1.14.1",
3
+ "version": "1.15.1",
4
4
  "author": "kaltura",
5
5
  "license": "AGPL-3.0",
6
6
  "repository": {
@@ -58,14 +58,16 @@ export declare class AvatarClientManager extends ActorManager<AvatarConnectionAc
58
58
  private readonly _isPreviewMode;
59
59
  private readonly _contextSelectorVisible;
60
60
  constructor(_config: {
61
- actions: AvatarClientManagerActions;
62
- debugMode: boolean;
63
- logger: UnisphereLoggerType;
61
+ actions?: AvatarClientManagerActions;
62
+ debugMode?: boolean;
63
+ logger?: UnisphereLoggerType;
64
64
  kalturaAnalyticsService?: KalturaAnalyticsServiceType;
65
65
  pubSubService?: PubSubServiceType;
66
66
  runtimeSettings: AvatarRuntimeSettings;
67
67
  /** Optional hook for wiring up devtools/machine-inspector logging; left unset outside the Unisphere widget host. */
68
68
  registerDeveloperTools?: (actor: AvatarConnectionActor) => void;
69
+ /** DOM element id of a container div the SDK should inject its `<video>` element into and auto-join the STV stream against, once castMode is 'webrtc'. Omit to keep managing joinSTV/leaveSTV externally (e.g. avatar-react's STVPlayer). */
70
+ videoContainerId?: string;
69
71
  });
70
72
  protected _syncDerivedState(snapshot: ConnectionSnapshot): void;
71
73
  protected _isTerminalSnapshot(snapshot: ConnectionSnapshot): boolean;
@@ -0,0 +1,22 @@
1
+ import { UnisphereLoggerType } from '@unisphere/core';
2
+ /**
3
+ * Input parameters for the joinSTVPlayer actor
4
+ */
5
+ export interface JoinSTVPlayerInput {
6
+ logger: UnisphereLoggerType;
7
+ videoContainerId: string;
8
+ sessionId: string;
9
+ webrtcUrl: string;
10
+ }
11
+ /**
12
+ * Auto-join the STV (webrtc) video stream into a caller-provided container
13
+ * element, on behalf of consumers that configured `videoContainerId` on the
14
+ * `AvatarClientManager` constructor instead of managing joinSTV/leaveSTV
15
+ * themselves (e.g. avatar-react's STVPlayer keeps doing that manually and
16
+ * never reaches this actor — see `shouldAutoJoinSTVPlayer`).
17
+ *
18
+ * Resolves once the STV peer connection is established (mirrors the
19
+ * `onConnected` callback consumers pass to `joinSTV` directly), not merely
20
+ * once WebRTC signaling completes.
21
+ */
22
+ export declare const joinSTVPlayer: import("xstate").PromiseActorLogic<void, JoinSTVPlayerInput, import("xstate").EventObject>;
@@ -37,7 +37,7 @@ export declare const avatarConnectionMachine: import("xstate").StateMachine<Avat
37
37
  logger: import("@unisphere/core").UnisphereLoggerType;
38
38
  }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").CallbackActorLogic<import("./types").PlayerReadyEvent, {
39
39
  logger: import("@unisphere/core").UnisphereLoggerType;
40
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").CallbackActorLogic<import("./types").AgentStartedTalkingReceivedEvent | import("./types").AgentFinishedTalkingReceivedEvent, {
40
+ }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, import("./actors/join-stv-player").JoinSTVPlayerInput, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").CallbackActorLogic<import("./types").AgentStartedTalkingReceivedEvent | import("./types").AgentFinishedTalkingReceivedEvent, {
41
41
  logger: import("@unisphere/core").UnisphereLoggerType;
42
42
  }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").CallbackActorLogic<import("./types").AgentRawTextMessageCompletedEvent, {
43
43
  logger: import("@unisphere/core").UnisphereLoggerType;
@@ -175,6 +175,10 @@ export declare const avatarConnectionMachine: import("xstate").StateMachine<Avat
175
175
  logger: import("@unisphere/core").UnisphereLoggerType;
176
176
  }, import("xstate").EventObject>;
177
177
  id: string | undefined;
178
+ } | {
179
+ src: "joinSTVPlayer";
180
+ logic: import("xstate").PromiseActorLogic<void, import("./actors/join-stv-player").JoinSTVPlayerInput, import("xstate").EventObject>;
181
+ id: string | undefined;
178
182
  } | {
179
183
  src: "onAgentTalking";
180
184
  logic: import("xstate").CallbackActorLogic<import("./types").AgentStartedTalkingReceivedEvent | import("./types").AgentFinishedTalkingReceivedEvent, {
@@ -546,6 +550,9 @@ export declare const avatarConnectionMachine: import("xstate").StateMachine<Avat
546
550
  } | {
547
551
  type: "shouldWaitPlayerReadyState";
548
552
  params: unknown;
553
+ } | {
554
+ type: "shouldAutoJoinSTVPlayer";
555
+ params: unknown;
549
556
  } | {
550
557
  type: "shouldDisconnect";
551
558
  params: unknown;
@@ -594,7 +601,7 @@ export declare const avatarConnectionMachine: import("xstate").StateMachine<Avat
594
601
  }, never, "error" | "devicePermissionsDenied" | {
595
602
  preparing: "done" | "resolvingConfig" | "gettingUserAgentData" | "retryingConfig";
596
603
  } | {
597
- connecting: "error" | "done" | "initializingRTCSession" | "gettingUserMedia" | "connectingWebsocket" | "waitingServerConnect" | "creatingSession" | "waitingForAgent" | "reconnectingFromExpiry" | "waitingServerReady" | "waitingPlayerReadyState" | "connectingToASR" | "delayingBeforeConnect" | {
604
+ connecting: "error" | "done" | "initializingRTCSession" | "gettingUserMedia" | "connectingWebsocket" | "waitingServerConnect" | "creatingSession" | "waitingForAgent" | "reconnectingFromExpiry" | "waitingServerReady" | "joiningSTVPlayer" | "waitingPlayerReadyState" | "connectingToASR" | "delayingBeforeConnect" | {
598
605
  joiningRoom: {
599
606
  waitingClientConfiguration: "done" | "waiting";
600
607
  waitingJoinComplete: "done" | "waiting";
@@ -665,6 +672,7 @@ export declare const avatarConnectionMachine: import("xstate").StateMachine<Avat
665
672
  reconnectingFromExpiry: {};
666
673
  waitingForAgent: {};
667
674
  waitingServerReady: {};
675
+ joiningSTVPlayer: {};
668
676
  waitingPlayerReadyState: {};
669
677
  delayingBeforeConnect: {};
670
678
  connectingToASR: {};
@@ -0,0 +1,4 @@
1
+ import { AvatarConnectionMachineContext } from '../types';
2
+ export declare const shouldAutoJoinSTVPlayer: ({ context, }: {
3
+ context: AvatarConnectionMachineContext;
4
+ }) => boolean;
@@ -317,6 +317,9 @@ export declare const connectingState: {
317
317
  };
318
318
  on: {
319
319
  ServerReadyReceived: ({
320
+ guard: "shouldAutoJoinSTVPlayer";
321
+ target: string;
322
+ } | {
320
323
  guard: "shouldWaitPlayerReadyState";
321
324
  target: string;
322
325
  } | {
@@ -325,6 +328,37 @@ export declare const connectingState: {
325
328
  })[];
326
329
  };
327
330
  };
331
+ joiningSTVPlayer: {
332
+ invoke: {
333
+ id: string;
334
+ src: "joinSTVPlayer";
335
+ input: ({ context }: {
336
+ context: import("../types").AvatarConnectionMachineContext;
337
+ event: import("../types").AvatarConnectionMachineEvents;
338
+ self: import("xstate").ActorRef<import("xstate").MachineSnapshot<import("../types").AvatarConnectionMachineContext, import("../types").AvatarConnectionMachineEvents, Record<string, import("xstate").AnyActorRef>, import("xstate").StateValue, string, unknown, any, any>, import("../types").AvatarConnectionMachineEvents, import("xstate").AnyEventObject>;
339
+ }) => {
340
+ logger: import("@unisphere/core").UnisphereLoggerType;
341
+ videoContainerId: string;
342
+ sessionId: string;
343
+ webrtcUrl: string;
344
+ };
345
+ onDone: {
346
+ target: string;
347
+ };
348
+ onError: {
349
+ actions: {
350
+ type: "setDisconnectData";
351
+ params: ({ event }: {
352
+ event: ErrorActorEvent;
353
+ }) => {
354
+ reason: DisconnectReasons;
355
+ error: Error;
356
+ };
357
+ };
358
+ target: string;
359
+ };
360
+ };
361
+ };
328
362
  waitingPlayerReadyState: {
329
363
  invoke: {
330
364
  src: "onPlayerReadyState";
@@ -20,6 +20,7 @@ export interface AvatarConnectionMachineContext {
20
20
  debugMode: boolean;
21
21
  level: string;
22
22
  waitPlayerReadyState: boolean;
23
+ videoContainerId?: string;
23
24
  kaltura: {
24
25
  ks: string;
25
26
  context?: ChatContext;
@@ -20,6 +20,8 @@ export interface AvatarConnectionMachineInput {
20
20
  stickyId?: string;
21
21
  level?: string;
22
22
  waitPlayerReadyState?: boolean;
23
+ /** DOM element id of a container div the SDK should inject its `<video>` element into and auto-join the STV stream against, once castMode is 'webrtc'. Omit to keep managing joinSTV/leaveSTV externally (e.g. avatar-react's STVPlayer). */
24
+ videoContainerId?: string;
23
25
  isInitialKalturaContextActive?: boolean;
24
26
  threadId?: string;
25
27
  messageId?: string;