@convai/web-sdk 0.3.2-beta.0 → 1.0.0-beta.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.
Files changed (60) hide show
  1. package/dist/core/BlendshapeQueue.d.ts +75 -42
  2. package/dist/core/BlendshapeQueue.d.ts.map +1 -1
  3. package/dist/core/BlendshapeQueue.js +177 -103
  4. package/dist/core/BlendshapeQueue.js.map +1 -1
  5. package/dist/core/ConvaiClient.d.ts +0 -14
  6. package/dist/core/ConvaiClient.d.ts.map +1 -1
  7. package/dist/core/ConvaiClient.js +13 -24
  8. package/dist/core/ConvaiClient.js.map +1 -1
  9. package/dist/core/MessageHandler.d.ts.map +1 -1
  10. package/dist/core/MessageHandler.js +6 -3
  11. package/dist/core/MessageHandler.js.map +1 -1
  12. package/dist/core/index.d.ts +0 -1
  13. package/dist/core/index.d.ts.map +1 -1
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/types.d.ts +29 -11
  16. package/dist/core/types.d.ts.map +1 -1
  17. package/dist/lipsync-helpers/createBlendshapeQueue.d.ts +86 -0
  18. package/dist/lipsync-helpers/createBlendshapeQueue.d.ts.map +1 -0
  19. package/dist/lipsync-helpers/createBlendshapeQueue.js +126 -0
  20. package/dist/lipsync-helpers/createBlendshapeQueue.js.map +1 -0
  21. package/dist/lipsync-helpers/declarativeMapping.d.ts +93 -0
  22. package/dist/lipsync-helpers/declarativeMapping.d.ts.map +1 -0
  23. package/dist/lipsync-helpers/declarativeMapping.js +228 -0
  24. package/dist/lipsync-helpers/declarativeMapping.js.map +1 -0
  25. package/dist/lipsync-helpers/index.d.ts +9 -4
  26. package/dist/lipsync-helpers/index.d.ts.map +1 -1
  27. package/dist/lipsync-helpers/index.js +24 -12
  28. package/dist/lipsync-helpers/index.js.map +1 -1
  29. package/dist/lipsync-helpers/mappingTypes.d.ts +64 -0
  30. package/dist/lipsync-helpers/mappingTypes.d.ts.map +1 -0
  31. package/dist/lipsync-helpers/mappingTypes.js +28 -0
  32. package/dist/lipsync-helpers/mappingTypes.js.map +1 -0
  33. package/dist/lipsync-helpers/presetMappers.d.ts +24 -0
  34. package/dist/lipsync-helpers/presetMappers.d.ts.map +1 -0
  35. package/dist/lipsync-helpers/presetMappers.js +38 -0
  36. package/dist/lipsync-helpers/presetMappers.js.map +1 -0
  37. package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
  38. package/dist/react/hooks/useConvaiClient.js +0 -4
  39. package/dist/react/hooks/useConvaiClient.js.map +1 -1
  40. package/dist/types/index.d.ts +13 -0
  41. package/dist/types/index.d.ts.map +1 -1
  42. package/dist/vanilla/ConvaiWidget.d.ts +13 -6
  43. package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
  44. package/dist/vanilla/ConvaiWidget.js +108 -70
  45. package/dist/vanilla/ConvaiWidget.js.map +1 -1
  46. package/dist/vanilla/types.d.ts +29 -2
  47. package/dist/vanilla/types.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/dist/lipsync-helpers/arkitBlendshapeHelpers.d.ts +0 -80
  50. package/dist/lipsync-helpers/arkitBlendshapeHelpers.d.ts.map +0 -1
  51. package/dist/lipsync-helpers/arkitBlendshapeHelpers.js +0 -201
  52. package/dist/lipsync-helpers/arkitBlendshapeHelpers.js.map +0 -1
  53. package/dist/lipsync-helpers/arkitPhonemeReference.d.ts +0 -155
  54. package/dist/lipsync-helpers/arkitPhonemeReference.d.ts.map +0 -1
  55. package/dist/lipsync-helpers/arkitPhonemeReference.js +0 -362
  56. package/dist/lipsync-helpers/arkitPhonemeReference.js.map +0 -1
  57. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.d.ts +0 -30
  58. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.d.ts.map +0 -1
  59. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.js +0 -315
  60. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.js.map +0 -1
@@ -70,6 +70,19 @@ export interface ConvaiConfig {
70
70
  startWithAudioOn?: boolean;
71
71
  /** Enable text-to-speech audio generation (default: true) */
72
72
  ttsEnabled?: boolean;
73
+ /**
74
+ * Enable lipsync/facial animation blendshapes (default: false).
75
+ * When true, sets blendshape_provider to "neurosync".
76
+ * When false, sets blendshape_provider to "none" (no facial animation data).
77
+ */
78
+ enableLipsync?: boolean;
79
+ /** Blendshape configuration for facial animation format */
80
+ blendshapeConfig?: {
81
+ /** Format of blendshapes: "arkit" or "mha" (Meta Human Animation, default: "mha") */
82
+ format?: "arkit" | "mha";
83
+ /** Custom mapper function to transform incoming blendshapes */
84
+ customMapper?: (input: number[] | Float32Array) => Float32Array;
85
+ };
73
86
  /** Configuration for character actions and environmental context */
74
87
  actionConfig?: {
75
88
  /** List of action names the character can perform */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -10,12 +10,22 @@ import type { VanillaWidgetOptions, VanillaWidget } from "./types";
10
10
  * @param options - Widget configuration options
11
11
  * @returns VanillaWidget instance with destroy method
12
12
  *
13
- * @example
13
+ * @example Simple usage with config
14
+ * ```typescript
15
+ * import { createConvaiWidget } from '@convai/web-sdk/vanilla';
16
+ *
17
+ * const widget = createConvaiWidget(document.body, {
18
+ * apiKey: 'your-api-key',
19
+ * characterId: 'your-character-id',
20
+ * enableVideo: false
21
+ * });
22
+ * ```
23
+ *
24
+ * @example Advanced usage with client instance
14
25
  * ```typescript
15
26
  * import { ConvaiClient, createConvaiWidget } from '@convai/web-sdk/vanilla';
16
27
  *
17
- * const client = new ConvaiClient();
18
- * await client.connect({
28
+ * const client = new ConvaiClient({
19
29
  * apiKey: 'your-api-key',
20
30
  * characterId: 'your-character-id'
21
31
  * });
@@ -26,9 +36,6 @@ import type { VanillaWidgetOptions, VanillaWidget } from "./types";
26
36
  * showScreenShare: true,
27
37
  * defaultVoiceMode: true
28
38
  * });
29
- *
30
- * // Later, cleanup
31
- * widget.destroy();
32
39
  * ```
33
40
  */
34
41
  export declare function createConvaiWidget(container: HTMLElement, options: VanillaWidgetOptions): VanillaWidget;
@@ -1 +1 @@
1
- {"version":3,"file":"ConvaiWidget.d.ts","sourceRoot":"","sources":["../../src/vanilla/ConvaiWidget.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAe,MAAM,SAAS,CAAC;AAWhF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CA+7Df;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAE/D"}
1
+ {"version":3,"file":"ConvaiWidget.d.ts","sourceRoot":"","sources":["../../src/vanilla/ConvaiWidget.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAA8B,MAAM,SAAS,CAAC;AAW/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAy+Df;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAE/D"}
@@ -5,6 +5,7 @@
5
5
  import { AudioRenderer } from "./AudioRenderer";
6
6
  import { aeroTheme, injectGlobalStyles } from "./styles";
7
7
  import { Icons } from "./icons";
8
+ import { ConvaiClient } from "../core/ConvaiClient";
8
9
  /**
9
10
  * Create a Convai chat widget in the specified container
10
11
  *
@@ -12,12 +13,22 @@ import { Icons } from "./icons";
12
13
  * @param options - Widget configuration options
13
14
  * @returns VanillaWidget instance with destroy method
14
15
  *
15
- * @example
16
+ * @example Simple usage with config
17
+ * ```typescript
18
+ * import { createConvaiWidget } from '@convai/web-sdk/vanilla';
19
+ *
20
+ * const widget = createConvaiWidget(document.body, {
21
+ * apiKey: 'your-api-key',
22
+ * characterId: 'your-character-id',
23
+ * enableVideo: false
24
+ * });
25
+ * ```
26
+ *
27
+ * @example Advanced usage with client instance
16
28
  * ```typescript
17
29
  * import { ConvaiClient, createConvaiWidget } from '@convai/web-sdk/vanilla';
18
30
  *
19
- * const client = new ConvaiClient();
20
- * await client.connect({
31
+ * const client = new ConvaiClient({
21
32
  * apiKey: 'your-api-key',
22
33
  * characterId: 'your-character-id'
23
34
  * });
@@ -28,13 +39,24 @@ import { Icons } from "./icons";
28
39
  * showScreenShare: true,
29
40
  * defaultVoiceMode: true
30
41
  * });
31
- *
32
- * // Later, cleanup
33
- * widget.destroy();
34
42
  * ```
35
43
  */
36
44
  export function createConvaiWidget(container, options) {
37
- const { convaiClient, showVideo = true, showScreenShare = true, defaultVoiceMode = true } = options;
45
+ // Create client if not provided - guarantee it's defined
46
+ const client = options.convaiClient || (() => {
47
+ if (!options.apiKey || !options.characterId) {
48
+ throw new Error('Either convaiClient or (apiKey + characterId) must be provided');
49
+ }
50
+ return new ConvaiClient({
51
+ apiKey: options.apiKey,
52
+ characterId: options.characterId,
53
+ enableVideo: options.enableVideo ?? false,
54
+ startWithVideoOn: options.startWithVideoOn ?? false,
55
+ enableLipsync: options.enableLipsync ?? false,
56
+ blendshapeConfig: options.blendshapeConfig,
57
+ });
58
+ })();
59
+ const { showVideo = true, showScreenShare = true, defaultVoiceMode = true, onConnect, onDisconnect, onMessage } = options;
38
60
  // Inject global styles
39
61
  injectGlobalStyles();
40
62
  // State
@@ -69,16 +91,16 @@ export function createConvaiWidget(container, options) {
69
91
  let source = null;
70
92
  // Fetch character info - matches React useCharacterInfo hook
71
93
  const fetchCharacterInfo = async () => {
72
- if (!convaiClient.apiKey || !convaiClient.characterId)
94
+ if (!client.apiKey || !client.characterId)
73
95
  return;
74
96
  try {
75
97
  const response = await fetch("https://api.convai.com/character/get", {
76
98
  method: "POST",
77
99
  headers: {
78
100
  "Content-Type": "application/json",
79
- "CONVAI-API-KEY": convaiClient.apiKey,
101
+ "CONVAI-API-KEY": client.apiKey,
80
102
  },
81
- body: JSON.stringify({ charID: convaiClient.characterId }),
103
+ body: JSON.stringify({ charID: client.characterId }),
82
104
  });
83
105
  if (response.ok) {
84
106
  const data = await response.json();
@@ -261,8 +283,8 @@ export function createConvaiWidget(container, options) {
261
283
  if (!voiceModeOverlay)
262
284
  return;
263
285
  const bars = voiceModeOverlay.querySelectorAll(".voice-bar");
264
- const isTalking = convaiClient.state.isSpeaking;
265
- const isListening = !convaiClient.audioControls.isAudioMuted;
286
+ const isTalking = client.state.isSpeaking;
287
+ const isListening = !client.audioControls.isAudioMuted;
266
288
  const isAnimating = isListening || isTalking;
267
289
  // Update colors based on state
268
290
  bars.forEach((bar) => {
@@ -576,8 +598,8 @@ export function createConvaiWidget(container, options) {
576
598
  border: none;
577
599
  `;
578
600
  voiceExitButton.addEventListener("click", async () => {
579
- convaiClient.sendInterruptMessage();
580
- await convaiClient.audioControls.muteAudio(); // Mute on exit
601
+ client.sendInterruptMessage();
602
+ await client.audioControls.muteAudio(); // Mute on exit
581
603
  isVoiceMode = false;
582
604
  updateVoiceMode();
583
605
  });
@@ -647,8 +669,8 @@ export function createConvaiWidget(container, options) {
647
669
  }
648
670
  else {
649
671
  // Toggle Voice Mode
650
- convaiClient.sendInterruptMessage();
651
- await convaiClient.audioControls.unmuteAudio(); // Unmute on enter
672
+ client.sendInterruptMessage();
673
+ await client.audioControls.unmuteAudio(); // Unmute on enter
652
674
  isVoiceMode = true;
653
675
  updateVoiceMode();
654
676
  }
@@ -761,8 +783,9 @@ export function createConvaiWidget(container, options) {
761
783
  resetIcon.style.width = "18px";
762
784
  resetIcon.style.height = "18px";
763
785
  settingsRow.appendChild(createOption(resetIcon, "Reset", handleReset));
764
- // Video
765
- if (convaiClient.connectionType === "video" && showVideo) {
786
+ // Video - only show if connection type is video
787
+ const connectionType = client.connectionType;
788
+ if (connectionType === "video" && showVideo) {
766
789
  const videoIcon = isVideoVisible
767
790
  ? Icons.Video("md")
768
791
  : Icons.VideoOff("md");
@@ -772,9 +795,9 @@ export function createConvaiWidget(container, options) {
772
795
  videoBtn.id = "convai-settings-video-btn";
773
796
  settingsRow.appendChild(videoBtn);
774
797
  }
775
- // Screen Share
776
- if (convaiClient.connectionType === "video" && showScreenShare) {
777
- const isSharing = convaiClient.screenShareControls.isScreenShareActive;
798
+ // Screen Share - only show if connection type is video
799
+ if (connectionType === "video" && showScreenShare) {
800
+ const isSharing = client.screenShareControls.isScreenShareActive;
778
801
  const shareIcon = isSharing
779
802
  ? Icons.StopScreenShare("md")
780
803
  : Icons.ScreenShare("md");
@@ -859,7 +882,8 @@ export function createConvaiWidget(container, options) {
859
882
  resetIcon.style.height = "18px";
860
883
  settingsRow.appendChild(createOption(resetIcon, "Reset", handleReset));
861
884
  // Video - Always show if showVideo is true and connection type is video
862
- if (convaiClient.connectionType === "video" && showVideo) {
885
+ const connectionType = client.connectionType;
886
+ if (connectionType === "video" && showVideo) {
863
887
  const videoIcon = isVideoVisible
864
888
  ? Icons.Video("md")
865
889
  : Icons.VideoOff("md");
@@ -870,8 +894,8 @@ export function createConvaiWidget(container, options) {
870
894
  settingsRow.appendChild(videoBtn);
871
895
  }
872
896
  // Screen Share - Always show if showScreenShare is true and connection type is video
873
- if (convaiClient.connectionType === "video" && showScreenShare) {
874
- const isSharing = convaiClient.screenShareControls.isScreenShareActive;
897
+ if (connectionType === "video" && showScreenShare) {
898
+ const isSharing = client.screenShareControls.isScreenShareActive;
875
899
  const shareIcon = isSharing
876
900
  ? Icons.StopScreenShare("md")
877
901
  : Icons.ScreenShare("md");
@@ -957,7 +981,7 @@ export function createConvaiWidget(container, options) {
957
981
  `;
958
982
  closeButton.addEventListener("click", (e) => {
959
983
  e.stopPropagation();
960
- convaiClient.videoControls.disableVideo();
984
+ client.videoControls.disableVideo();
961
985
  });
962
986
  closeButton.addEventListener("mouseenter", () => {
963
987
  closeButton.style.transform = "scale(1.1)";
@@ -1077,9 +1101,9 @@ export function createConvaiWidget(container, options) {
1077
1101
  return;
1078
1102
  }
1079
1103
  // Connect on first click if not already connected/connecting
1080
- if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {
1104
+ if (!client.state.isConnected && !client.state.isConnecting) {
1081
1105
  try {
1082
- await convaiClient.connect();
1106
+ await client.connect();
1083
1107
  setIsOpen(true);
1084
1108
  }
1085
1109
  catch (error) {
@@ -1095,8 +1119,8 @@ export function createConvaiWidget(container, options) {
1095
1119
  setIsOpen(false);
1096
1120
  };
1097
1121
  const handleSend = () => {
1098
- if (inputValue.trim() && convaiClient.state.isConnected) {
1099
- convaiClient.sendUserTextMessage(inputValue);
1122
+ if (inputValue.trim() && client.state.isConnected) {
1123
+ client.sendUserTextMessage(inputValue);
1100
1124
  inputValue = "";
1101
1125
  inputElement.value = "";
1102
1126
  updateSendButton();
@@ -1105,8 +1129,8 @@ export function createConvaiWidget(container, options) {
1105
1129
  // Microphone toggle removed - only controlled via voice mode now
1106
1130
  const handleToggleMute = () => {
1107
1131
  isMuted = !isMuted;
1108
- if (convaiClient.room) {
1109
- const remoteParticipants = Array.from(convaiClient.room.remoteParticipants.values());
1132
+ if (client.room) {
1133
+ const remoteParticipants = Array.from(client.room.remoteParticipants.values());
1110
1134
  remoteParticipants.forEach((participant) => {
1111
1135
  participant.audioTrackPublications.forEach((publication) => {
1112
1136
  if (publication.track) {
@@ -1120,8 +1144,8 @@ export function createConvaiWidget(container, options) {
1120
1144
  const handleReset = async () => {
1121
1145
  setIsSettingsOpen(false);
1122
1146
  try {
1123
- await convaiClient.disconnect();
1124
- convaiClient.resetSession();
1147
+ await client.disconnect();
1148
+ client.resetSession();
1125
1149
  isMuted = false;
1126
1150
  isVoiceMode = false;
1127
1151
  hasEnteredDefaultVoiceMode = false;
@@ -1135,7 +1159,7 @@ export function createConvaiWidget(container, options) {
1135
1159
  };
1136
1160
  const handleDisconnect = async () => {
1137
1161
  setIsSettingsOpen(false);
1138
- await convaiClient.disconnect();
1162
+ await client.disconnect();
1139
1163
  isMuted = false;
1140
1164
  isVoiceMode = false;
1141
1165
  hasEnteredDefaultVoiceMode = false;
@@ -1144,14 +1168,14 @@ export function createConvaiWidget(container, options) {
1144
1168
  updateSendButton();
1145
1169
  };
1146
1170
  const handleToggleVideo = async () => {
1147
- if (convaiClient.connectionType !== "video")
1171
+ if (client.connectionType !== "video")
1148
1172
  return;
1149
1173
  try {
1150
1174
  if (isVideoVisible) {
1151
- await convaiClient.videoControls.disableVideo();
1175
+ await client.videoControls.disableVideo();
1152
1176
  }
1153
1177
  else {
1154
- await convaiClient.videoControls.enableVideo();
1178
+ await client.videoControls.enableVideo();
1155
1179
  }
1156
1180
  // State will be updated via event listener below
1157
1181
  }
@@ -1161,7 +1185,7 @@ export function createConvaiWidget(container, options) {
1161
1185
  };
1162
1186
  const handleToggleScreenShare = async () => {
1163
1187
  try {
1164
- await convaiClient.screenShareControls.toggleScreenShare();
1188
+ await client.screenShareControls.toggleScreenShare();
1165
1189
  // State will be updated via event listener above
1166
1190
  }
1167
1191
  catch (e) {
@@ -1190,10 +1214,10 @@ export function createConvaiWidget(container, options) {
1190
1214
  chatContent.style.transform = "scale(1)";
1191
1215
  chatContent.style.pointerEvents = "auto";
1192
1216
  // Auto-enter voice mode if defaultVoiceMode is true and not already entered
1193
- if (defaultVoiceMode && !hasEnteredDefaultVoiceMode && convaiClient.state.isConnected) {
1217
+ if (defaultVoiceMode && !hasEnteredDefaultVoiceMode && client.state.isConnected) {
1194
1218
  setTimeout(async () => {
1195
1219
  try {
1196
- await convaiClient.audioControls.unmuteAudio();
1220
+ await client.audioControls.unmuteAudio();
1197
1221
  isVoiceMode = true;
1198
1222
  hasEnteredDefaultVoiceMode = true;
1199
1223
  updateVoiceMode();
@@ -1246,15 +1270,15 @@ export function createConvaiWidget(container, options) {
1246
1270
  };
1247
1271
  const updateVideoTrack = () => {
1248
1272
  if (!floatingVideo ||
1249
- !convaiClient.room ||
1250
- !convaiClient.room.localParticipant)
1273
+ !client.room ||
1274
+ !client.room.localParticipant)
1251
1275
  return;
1252
1276
  const videoEl = floatingVideo.querySelector("#floating-video-element");
1253
1277
  const placeholder = floatingVideo.querySelector("#camera-off-placeholder");
1254
1278
  if (!videoEl || !placeholder)
1255
1279
  return;
1256
1280
  if (isVideoVisible && !isVoiceMode) {
1257
- const tracks = Array.from(convaiClient.room.localParticipant.videoTrackPublications.values());
1281
+ const tracks = Array.from(client.room.localParticipant.videoTrackPublications.values());
1258
1282
  const videoPub = tracks.find((t) => t.kind === "video");
1259
1283
  if (videoPub && videoPub.track) {
1260
1284
  videoPub.track.attach(videoEl);
@@ -1300,8 +1324,8 @@ export function createConvaiWidget(container, options) {
1300
1324
  }
1301
1325
  else {
1302
1326
  // Ensure microphone is muted when not in voice mode
1303
- if (!convaiClient.audioControls.isAudioMuted) {
1304
- await convaiClient.audioControls.muteAudio();
1327
+ if (!client.audioControls.isAudioMuted) {
1328
+ await client.audioControls.muteAudio();
1305
1329
  }
1306
1330
  // Hide Overlay
1307
1331
  if (voiceModeOverlay)
@@ -1571,16 +1595,16 @@ export function createConvaiWidget(container, options) {
1571
1595
  messageListElement.scrollTop = messageListElement.scrollHeight;
1572
1596
  };
1573
1597
  const getBotStatusColor = () => {
1574
- if (!convaiClient.state.isConnected) {
1598
+ if (!client.state.isConnected) {
1575
1599
  return { color: "#ef4444", label: "Disconnected" };
1576
1600
  }
1577
- if (convaiClient.state.isConnecting || !convaiClient.isBotReady) {
1601
+ if (client.state.isConnecting || !client.isBotReady) {
1578
1602
  return { color: "#f59e0b", label: "Connecting" };
1579
1603
  }
1580
1604
  return { color: "#10b981", label: "Connected" };
1581
1605
  };
1582
1606
  const formatMessages = () => {
1583
- const filteredMessages = convaiClient.chatMessages.filter((msg) => (msg.type === "user-transcription" ||
1607
+ const filteredMessages = client.chatMessages.filter((msg) => (msg.type === "user-transcription" ||
1584
1608
  msg.type === "user-llm-text" ||
1585
1609
  msg.type === "bot-llm-text" ||
1586
1610
  msg.type === "bot-emotion") &&
@@ -1600,10 +1624,10 @@ export function createConvaiWidget(container, options) {
1600
1624
  };
1601
1625
  // Setup event listeners for client state changes
1602
1626
  const setupClientListeners = () => {
1603
- convaiClient.on("stateChange", () => {
1627
+ client.on("stateChange", () => {
1604
1628
  updateHeader();
1605
1629
  // Update pulse animation based on connecting state
1606
- if (convaiClient.state.isConnecting) {
1630
+ if (client.state.isConnecting) {
1607
1631
  morphingContainer.style.animation =
1608
1632
  "convai-pulse 2s ease-in-out infinite";
1609
1633
  }
@@ -1611,21 +1635,21 @@ export function createConvaiWidget(container, options) {
1611
1635
  morphingContainer.style.animation = "none";
1612
1636
  }
1613
1637
  // Update speaking animation state
1614
- if (convaiClient.state.isSpeaking) {
1638
+ if (client.state.isSpeaking) {
1615
1639
  if (!startTime) {
1616
1640
  startTime = Date.now();
1617
1641
  }
1618
1642
  }
1619
1643
  else {
1620
1644
  // Reset when not speaking
1621
- if (startTime && !convaiClient.state.isSpeaking) {
1645
+ if (startTime && !client.state.isSpeaking) {
1622
1646
  startTime = 0;
1623
1647
  currentLevels = Array(40).fill(0.05);
1624
1648
  targetLevels = Array(40).fill(0.05);
1625
1649
  }
1626
1650
  }
1627
1651
  // Auto-collapse when disconnected
1628
- if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {
1652
+ if (!client.state.isConnected && !client.state.isConnecting) {
1629
1653
  if (isOpen) {
1630
1654
  setIsOpen(false);
1631
1655
  }
@@ -1637,14 +1661,14 @@ export function createConvaiWidget(container, options) {
1637
1661
  updateVoiceMode();
1638
1662
  }
1639
1663
  // Auto-enter voice mode on first connection if defaultVoiceMode is true
1640
- if (convaiClient.state.isConnected &&
1664
+ if (client.state.isConnected &&
1641
1665
  defaultVoiceMode &&
1642
1666
  isOpen &&
1643
1667
  !hasEnteredDefaultVoiceMode &&
1644
1668
  !isVoiceMode) {
1645
1669
  setTimeout(async () => {
1646
1670
  try {
1647
- await convaiClient.audioControls.unmuteAudio();
1671
+ await client.audioControls.unmuteAudio();
1648
1672
  isVoiceMode = true;
1649
1673
  hasEnteredDefaultVoiceMode = true;
1650
1674
  updateVoiceMode();
@@ -1657,7 +1681,7 @@ export function createConvaiWidget(container, options) {
1657
1681
  });
1658
1682
  // Audio state changes now only affect voice mode (microphone button removed)
1659
1683
  // Video state change listener
1660
- convaiClient.videoControls.on("videoStateChange", (videoState) => {
1684
+ client.videoControls.on("videoStateChange", (videoState) => {
1661
1685
  if (videoState.isVideoEnabled !== undefined) {
1662
1686
  isVideoVisible = videoState.isVideoEnabled;
1663
1687
  updateVoiceMode();
@@ -1684,7 +1708,7 @@ export function createConvaiWidget(container, options) {
1684
1708
  }
1685
1709
  });
1686
1710
  // Screen share state change listener
1687
- convaiClient.screenShareControls.on("screenShareStateChange", (screenShareState) => {
1711
+ client.screenShareControls.on("screenShareStateChange", (screenShareState) => {
1688
1712
  if (screenShareState.isScreenShareActive !== undefined) {
1689
1713
  const isSharing = screenShareState.isScreenShareActive;
1690
1714
  const shareBtn = document.getElementById("convai-settings-share-btn");
@@ -1710,28 +1734,41 @@ export function createConvaiWidget(container, options) {
1710
1734
  }
1711
1735
  }
1712
1736
  });
1713
- convaiClient.on("messagesChange", () => {
1737
+ client.on("messagesChange", () => {
1714
1738
  updateMessageList();
1739
+ // Call onMessage callback if provided
1740
+ if (onMessage && client.chatMessages.length > 0) {
1741
+ const lastMessage = client.chatMessages[client.chatMessages.length - 1];
1742
+ onMessage(lastMessage);
1743
+ }
1715
1744
  });
1716
1745
  // Bot ready listener - updates UI when bot becomes ready
1717
- convaiClient.on("botReady", () => {
1746
+ client.on("botReady", () => {
1718
1747
  updateHeader(); // Update header to show green status
1719
1748
  });
1720
- convaiClient.on("connect", () => {
1749
+ client.on("connect", () => {
1721
1750
  // Initialize audio renderer on connection
1722
- if (convaiClient.room && !audioRenderer) {
1723
- audioRenderer = new AudioRenderer(convaiClient.room);
1751
+ if (client.room && !audioRenderer) {
1752
+ audioRenderer = new AudioRenderer(client.room);
1724
1753
  }
1725
1754
  // Fetch character info
1726
1755
  fetchCharacterInfo();
1756
+ // Call onConnect callback if provided
1757
+ if (onConnect) {
1758
+ onConnect();
1759
+ }
1727
1760
  });
1728
- convaiClient.on("disconnect", () => {
1761
+ client.on("disconnect", () => {
1729
1762
  // Cleanup audio renderer
1730
1763
  if (audioRenderer) {
1731
1764
  audioRenderer.destroy();
1732
1765
  audioRenderer = null;
1733
1766
  }
1734
1767
  updateMessageList();
1768
+ // Call onDisconnect callback if provided
1769
+ if (onDisconnect) {
1770
+ onDisconnect();
1771
+ }
1735
1772
  });
1736
1773
  };
1737
1774
  // Initialize
@@ -1744,13 +1781,14 @@ export function createConvaiWidget(container, options) {
1744
1781
  updateVoiceMode();
1745
1782
  }
1746
1783
  // If already connected, initialize audio renderer and fetch character info
1747
- if (convaiClient.state.isConnected && convaiClient.room) {
1748
- audioRenderer = new AudioRenderer(convaiClient.room);
1784
+ if (client.state.isConnected && client.room) {
1785
+ audioRenderer = new AudioRenderer(client.room);
1749
1786
  fetchCharacterInfo();
1750
1787
  }
1751
1788
  // Return widget instance
1752
1789
  const widget = {
1753
1790
  element: rootElement,
1791
+ client: client,
1754
1792
  destroy: () => {
1755
1793
  // Cleanup audio renderer
1756
1794
  if (audioRenderer) {
@@ -1767,11 +1805,11 @@ export function createConvaiWidget(container, options) {
1767
1805
  floatingVideo.remove();
1768
1806
  }
1769
1807
  // Unsubscribe from client events
1770
- convaiClient.off("stateChange", () => { });
1771
- convaiClient.off("messagesChange", () => { });
1772
- convaiClient.off("botReady", () => { });
1773
- convaiClient.off("connect", () => { });
1774
- convaiClient.off("disconnect", () => { });
1808
+ client.off("stateChange", () => { });
1809
+ client.off("messagesChange", () => { });
1810
+ client.off("botReady", () => { });
1811
+ client.off("connect", () => { });
1812
+ client.off("disconnect", () => { });
1775
1813
  },
1776
1814
  };
1777
1815
  return widget;