@convai/web-sdk 1.8.0-beta.7 → 1.8.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 (106) hide show
  1. package/README.md +44 -194
  2. package/dist/core/ConvaiClient.d.ts +1 -190
  3. package/dist/core/ConvaiClient.d.ts.map +1 -1
  4. package/dist/core/ConvaiClient.js +286 -1306
  5. package/dist/core/ConvaiClient.js.map +1 -1
  6. package/dist/core/MessageHandler.d.ts +1 -19
  7. package/dist/core/MessageHandler.d.ts.map +1 -1
  8. package/dist/core/MessageHandler.js +27 -378
  9. package/dist/core/MessageHandler.js.map +1 -1
  10. package/dist/core/connectRequest.d.ts +4 -17
  11. package/dist/core/connectRequest.d.ts.map +1 -1
  12. package/dist/core/connectRequest.js +17 -28
  13. package/dist/core/connectRequest.js.map +1 -1
  14. package/dist/core/index.d.ts +1 -6
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/core/index.js +1 -7
  17. package/dist/core/index.js.map +1 -1
  18. package/dist/core/logicalTurn.d.ts +6 -4
  19. package/dist/core/logicalTurn.d.ts.map +1 -1
  20. package/dist/core/logicalTurn.js +4 -29
  21. package/dist/core/logicalTurn.js.map +1 -1
  22. package/dist/core/modelOutput.d.ts.map +1 -1
  23. package/dist/core/modelOutput.js +2 -2
  24. package/dist/core/modelOutput.js.map +1 -1
  25. package/dist/core/types.d.ts +22 -860
  26. package/dist/core/types.d.ts.map +1 -1
  27. package/dist/core/types.js.map +1 -1
  28. package/dist/embed/chat-embed-v1.js +9 -10
  29. package/dist/embed/chat-embed-v1.js.map +4 -4
  30. package/dist/react/components/ConvaiWidget.d.ts.map +1 -1
  31. package/dist/react/components/ConvaiWidget.js +1 -6
  32. package/dist/react/components/ConvaiWidget.js.map +1 -1
  33. package/dist/react/components/rtc-widget/components/AudioVisualizer.d.ts.map +1 -1
  34. package/dist/react/components/rtc-widget/components/AudioVisualizer.js +1 -28
  35. package/dist/react/components/rtc-widget/components/AudioVisualizer.js.map +1 -1
  36. package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts.map +1 -1
  37. package/dist/react/components/rtc-widget/components/MarkdownRenderer.js +44 -39
  38. package/dist/react/components/rtc-widget/components/MarkdownRenderer.js.map +1 -1
  39. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts.map +1 -1
  40. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js +49 -93
  41. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js.map +1 -1
  42. package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
  43. package/dist/react/hooks/useConvaiClient.js +2 -17
  44. package/dist/react/hooks/useConvaiClient.js.map +1 -1
  45. package/dist/react/index.d.ts +1 -1
  46. package/dist/react/index.d.ts.map +1 -1
  47. package/dist/react/index.js +1 -1
  48. package/dist/react/index.js.map +1 -1
  49. package/dist/vanilla/AudioRenderer.d.ts +1 -3
  50. package/dist/vanilla/AudioRenderer.d.ts.map +1 -1
  51. package/dist/vanilla/AudioRenderer.js +2 -8
  52. package/dist/vanilla/AudioRenderer.js.map +1 -1
  53. package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
  54. package/dist/vanilla/ConvaiWidget.js +300 -994
  55. package/dist/vanilla/ConvaiWidget.js.map +1 -1
  56. package/dist/vanilla/WidgetEventSubscriptions.d.ts +1 -1
  57. package/dist/vanilla/WidgetEventSubscriptions.d.ts.map +1 -1
  58. package/dist/vanilla/WidgetEventSubscriptions.js +0 -5
  59. package/dist/vanilla/WidgetEventSubscriptions.js.map +1 -1
  60. package/dist/vanilla/icons.d.ts.map +1 -1
  61. package/dist/vanilla/icons.js +15 -62
  62. package/dist/vanilla/icons.js.map +1 -1
  63. package/dist/vanilla/index.d.ts +2 -4
  64. package/dist/vanilla/index.d.ts.map +1 -1
  65. package/dist/vanilla/index.js +1 -3
  66. package/dist/vanilla/index.js.map +1 -1
  67. package/dist/vanilla/styles.d.ts +1 -18
  68. package/dist/vanilla/styles.d.ts.map +1 -1
  69. package/dist/vanilla/styles.js +29 -129
  70. package/dist/vanilla/styles.js.map +1 -1
  71. package/dist/vanilla/types.d.ts +0 -74
  72. package/dist/vanilla/types.d.ts.map +1 -1
  73. package/dist/vanilla/types.js.map +1 -1
  74. package/dist/version.d.ts +1 -1
  75. package/dist/version.d.ts.map +1 -1
  76. package/dist/version.js +1 -1
  77. package/dist/version.js.map +1 -1
  78. package/package.json +8 -13
  79. package/dist/core/CharacterRoster.d.ts +0 -84
  80. package/dist/core/CharacterRoster.d.ts.map +0 -1
  81. package/dist/core/CharacterRoster.js +0 -348
  82. package/dist/core/CharacterRoster.js.map +0 -1
  83. package/dist/core/CharacterVersionManager.d.ts +0 -100
  84. package/dist/core/CharacterVersionManager.d.ts.map +0 -1
  85. package/dist/core/CharacterVersionManager.js +0 -227
  86. package/dist/core/CharacterVersionManager.js.map +0 -1
  87. package/dist/core/ConvaiRoomError.d.ts +0 -48
  88. package/dist/core/ConvaiRoomError.d.ts.map +0 -1
  89. package/dist/core/ConvaiRoomError.js +0 -111
  90. package/dist/core/ConvaiRoomError.js.map +0 -1
  91. package/dist/core/SSESession.d.ts +0 -59
  92. package/dist/core/SSESession.d.ts.map +0 -1
  93. package/dist/core/SSESession.js +0 -289
  94. package/dist/core/SSESession.js.map +0 -1
  95. package/dist/core/characterReference.d.ts +0 -40
  96. package/dist/core/characterReference.d.ts.map +0 -1
  97. package/dist/core/characterReference.js +0 -72
  98. package/dist/core/characterReference.js.map +0 -1
  99. package/dist/core/rosterRequest.d.ts +0 -57
  100. package/dist/core/rosterRequest.d.ts.map +0 -1
  101. package/dist/core/rosterRequest.js +0 -210
  102. package/dist/core/rosterRequest.js.map +0 -1
  103. package/dist/utils/inlineMarkdown.d.ts +0 -38
  104. package/dist/utils/inlineMarkdown.d.ts.map +0 -1
  105. package/dist/utils/inlineMarkdown.js +0 -106
  106. package/dist/utils/inlineMarkdown.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\nimport { parseInlineMarkdown, type InlineNode } from \"../../../../utils/inlineMarkdown\";\n\ninterface MarkdownRendererProps {\n text: string;\n}\n\nconst linkStyle: React.CSSProperties = {\n color: \"#10b981\",\n textDecoration: \"underline\",\n wordBreak: \"break-all\",\n};\n\nconst mediaStyle: React.CSSProperties = {\n display: \"block\",\n maxWidth: \"100%\",\n maxHeight: 240,\n marginTop: 6,\n borderRadius: 8,\n};\n\n/** Inline preview for an image or video URL, shown under its link. */\nconst MediaPreview = ({ node }: { node: Extract<InlineNode, { kind: \"link\" }> }) => {\n if (node.media === \"image\") {\n return <img src={node.href} alt={node.label} loading=\"lazy\" style={mediaStyle} />;\n }\n if (node.media === \"video\") {\n return <video src={node.href} controls preload=\"metadata\" style={mediaStyle} />;\n }\n return null;\n};\n\nconst renderNode = (node: InlineNode, key: string): React.ReactNode => {\n switch (node.kind) {\n case \"strong\":\n return <strong key={key}>{node.text}</strong>;\n case \"em\":\n return <em key={key}>{node.text}</em>;\n case \"link\":\n return (\n <React.Fragment key={key}>\n <a href={node.href} target=\"_blank\" rel=\"noopener noreferrer\" style={linkStyle}>\n {node.label}\n </a>\n <MediaPreview node={node} />\n </React.Fragment>\n );\n case \"image\":\n return <img key={key} src={node.src} alt={node.alt} loading=\"lazy\" style={mediaStyle} />;\n default:\n return <React.Fragment key={key}>{node.text}</React.Fragment>;\n }\n};\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ text }) => {\n // Convert markdown to JSX elements\n const renderMarkdown = (input: string): React.ReactNode => {\n if (!input) return null;\n\n // Handle both actual newlines and \\n escape sequences\n // Replace literal \\n strings with actual newlines\n const normalizedText = input.replace(/\\\\n/g, '\\n');\n\n // Split by actual newlines\n const lines = normalizedText.split('\\n');\n\n return lines.map((line, lineIndex) => {\n // Bold, italic, links, images and bare URLs — see utils/inlineMarkdown.\n const processedLine = parseInlineMarkdown(line).map((node, i) =>\n renderNode(node, `${node.kind}-${lineIndex}-${i}`),\n );\n\n // Handle empty lines (creates paragraph spacing)\n if (line.trim() === \"\" && lineIndex > 0) {\n return <br key={`br-${lineIndex}`} />;\n }\n\n // Return the line with line break\n return (\n <React.Fragment key={`line-${lineIndex}`}>\n {processedLine.length > 0 ? processedLine : line}\n {lineIndex < lines.length - 1 && <br />}\n </React.Fragment>\n );\n });\n };\n\n return <div style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>{renderMarkdown(text)}</div>;\n};\n"]}
1
+ {"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\ninterface MarkdownRendererProps {\n text: string;\n}\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ text }) => {\n // Convert markdown to JSX elements\n const renderMarkdown = (input: string): React.ReactNode => {\n if (!input) return null;\n\n // Handle both actual newlines and \\n escape sequences\n // Replace literal \\n strings with actual newlines\n const normalizedText = input.replace(/\\\\n/g, '\\n');\n \n // Split by actual newlines\n const lines = normalizedText.split('\\n');\n \n return lines.map((line, lineIndex) => {\n // Process markdown within each line\n const processLine = (text: string): React.ReactNode[] => {\n const parts: React.ReactNode[] = [];\n let remaining = text;\n let keyCounter = 0;\n\n // Process bold and italic markdown\n // Bold: **text** or __text__\n // Italic: *text* or _text_\n const markdownRegex = /(\\*\\*|__)(.*?)\\1|\\*([^*]+)\\*|_([^_]+)_/g;\n let lastIndex = 0;\n let match;\n\n while ((match = markdownRegex.exec(remaining)) !== null) {\n // Add text before the match\n if (match.index > lastIndex) {\n const textBefore = remaining.substring(lastIndex, match.index);\n if (textBefore) {\n parts.push(\n <React.Fragment key={`text-${lineIndex}-${keyCounter++}`}>\n {textBefore}\n </React.Fragment>\n );\n }\n }\n\n // Determine if it's bold or italic\n if (match[1] && match[2]) {\n // Bold text (** or __)\n parts.push(\n <strong key={`bold-${lineIndex}-${keyCounter++}`}>\n {match[2]}\n </strong>\n );\n } else if (match[3]) {\n // Italic text (*)\n parts.push(\n <em key={`italic-${lineIndex}-${keyCounter++}`}>\n {match[3]}\n </em>\n );\n } else if (match[4]) {\n // Italic text (_)\n parts.push(\n <em key={`italic-${lineIndex}-${keyCounter++}`}>\n {match[4]}\n </em>\n );\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < remaining.length) {\n const textAfter = remaining.substring(lastIndex);\n if (textAfter) {\n parts.push(\n <React.Fragment key={`text-${lineIndex}-${keyCounter++}`}>\n {textAfter}\n </React.Fragment>\n );\n }\n }\n\n return parts;\n };\n\n const processedLine = processLine(line);\n\n // Handle empty lines (creates paragraph spacing)\n if (line.trim() === \"\" && lineIndex > 0) {\n return <br key={`br-${lineIndex}`} />;\n }\n\n // Return the line with line break\n return (\n <React.Fragment key={`line-${lineIndex}`}>\n {processedLine.length > 0 ? processedLine : line}\n {lineIndex < lines.length - 1 && <br />}\n </React.Fragment>\n );\n });\n };\n\n return <div style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>{renderMarkdown(text)}</div>;\n};\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceModeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,GAAI,0FAQ9B,qBAAqB,4CA6ZvB,CAAC"}
1
+ {"version":3,"file":"VoiceModeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,GAAI,0FAQ9B,qBAAqB,4CA8YvB,CAAC"}
@@ -6,91 +6,10 @@ import { iosTransitions } from "../../styles/framerConfig.js";
6
6
  import { AudioVisualizer } from "../AudioVisualizer.js";
7
7
  export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, convaiClient, characterImage, characterName = "Character", room, }) => {
8
8
  const barsCount = 40; // Number of bars for user microphone waveform
9
- // PERF: the waveform is driven OUTSIDE React. A setState per animation
10
- // frame re-rendered the whole overlay (reconcile + style recalc +
11
- // framer-motion filter retarget) ~60x/s — ~30ms main-thread tasks that
12
- // visibly juddered the host page's 3D scene whenever voice mode was
13
- // open. Levels live in a ref and the SVG paths are updated directly.
14
- const audioLevelsRef = useRef(Array(barsCount).fill(0));
15
- const waveCanvasRef = useRef(null);
9
+ const [audioLevels, setAudioLevels] = useState(Array(barsCount).fill(0));
16
10
  const analyzerRef = useRef(null);
17
11
  const animationFrameRef = useRef(undefined);
18
12
  const audioContextRef = useRef(null);
19
- // Paint the three waves onto a small canvas — no React, no SVG filters.
20
- // (The previous SVG version re-rasterized a 35px drop-shadow blur every
21
- // frame; that GPU paint alone pushed the host page to ~30fps.) Glow is
22
- // approximated with a wide low-alpha understroke, which is ~free.
23
- // Painting is THROTTLED to 30fps and skipped entirely while silent:
24
- // every canvas update forces the compositor to re-blend the whole
25
- // panel stack over the host WebGL canvas, so idle repaints are pure
26
- // waste that judders the 3D scene.
27
- const waveFrameParityRef = useRef(0);
28
- const waveWasSilentRef = useRef(false);
29
- const drawWaves = () => {
30
- waveFrameParityRef.current ^= 1;
31
- if (waveFrameParityRef.current)
32
- return; // 30fps is plenty for a waveform
33
- const canvas = waveCanvasRef.current;
34
- if (!canvas)
35
- return;
36
- {
37
- const lv = audioLevelsRef.current;
38
- let sum = 0;
39
- for (let i = 0; i < lv.length; i++)
40
- sum += lv[i];
41
- const silent = sum / lv.length < 0.012;
42
- if (silent && waveWasSilentRef.current)
43
- return; // static line already drawn
44
- waveWasSilentRef.current = silent;
45
- }
46
- const dpr = Math.min(window.devicePixelRatio || 1, 2);
47
- if (canvas.width !== 250 * dpr) {
48
- canvas.width = 250 * dpr;
49
- canvas.height = 80 * dpr;
50
- }
51
- const ctx = canvas.getContext("2d");
52
- if (!ctx)
53
- return;
54
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
55
- ctx.clearRect(0, 0, 250, 80);
56
- const audioLevels = audioLevelsRef.current;
57
- const centerY = 40;
58
- const waveWidth = 250;
59
- const segments = barsCount;
60
- const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;
61
- const waveColors = [
62
- aeroTheme.colors.convai.light,
63
- aeroTheme.colors.convai.light,
64
- "#34d399",
65
- ];
66
- ctx.lineCap = "round";
67
- ctx.lineJoin = "round";
68
- for (let waveIndex = 2; waveIndex >= 0; waveIndex--) {
69
- ctx.beginPath();
70
- for (let i = 0; i <= segments; i++) {
71
- const x = (i / segments) * waveWidth;
72
- const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));
73
- const level = audioLevels[levelIndex] || 0;
74
- const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);
75
- const baseAmplitude = avgLevel > 0.05 ? 2 + waveIndex * 1.5 : 0;
76
- const amplitude = baseAmplitude + level * (25 - baseAmplitude);
77
- const y = centerY + Math.sin(phase) * amplitude;
78
- if (i === 0)
79
- ctx.moveTo(x, y);
80
- else
81
- ctx.lineTo(x, y);
82
- }
83
- // glow understroke scaled by level, then the crisp line on top
84
- ctx.strokeStyle = waveColors[waveIndex];
85
- ctx.globalAlpha = 0.18 * (0.3 + avgLevel);
86
- ctx.lineWidth = (2.5 - waveIndex * 0.4) + 8 * avgLevel + 3;
87
- ctx.stroke();
88
- ctx.globalAlpha = 0.95 - waveIndex * 0.15;
89
- ctx.lineWidth = 2.5 - waveIndex * 0.4;
90
- ctx.stroke();
91
- }
92
- ctx.globalAlpha = 1;
93
- };
94
13
  // Setup audio analysis for USER microphone input ONLY
95
14
  useEffect(() => {
96
15
  if (!isActive) {
@@ -98,8 +17,7 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
98
17
  if (animationFrameRef.current) {
99
18
  cancelAnimationFrame(animationFrameRef.current);
100
19
  }
101
- audioLevelsRef.current = Array(barsCount).fill(0);
102
- drawWaves();
20
+ setAudioLevels(Array(barsCount).fill(0));
103
21
  return;
104
22
  }
105
23
  let stream = null;
@@ -132,17 +50,17 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
132
50
  const rms = Math.sqrt(sum / dataArray.length);
133
51
  // Apply some scaling and clamping
134
52
  const volume = Math.min(1, rms * 3); // Boost sensitivity
135
- // Create left-to-right wave effect — write into the ref and paint
136
- // the SVG directly (no setState: a per-frame React render here
137
- // visibly juddered the host page).
138
- const levels = audioLevelsRef.current;
139
- for (let i = 0; i < barsCount; i++) {
53
+ // Create left-to-right wave effect
54
+ const levels = Array(barsCount)
55
+ .fill(0)
56
+ .map((_, i) => {
57
+ // Progressive wave from left to right
140
58
  const position = i / barsCount; // 0 to 1 from left to right
141
59
  const wavePhase = Date.now() / 300 + position * Math.PI * 2;
142
60
  const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0
143
- levels[i] = volume * waveVariation;
144
- }
145
- drawWaves();
61
+ return volume * waveVariation;
62
+ });
63
+ setAudioLevels(levels);
146
64
  animationFrameRef.current = requestAnimationFrame(updateLevels);
147
65
  };
148
66
  updateLevels();
@@ -282,7 +200,45 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
282
200
  width: "250px",
283
201
  height: "80px",
284
202
  position: "relative",
285
- }, children: _jsx("canvas", { ref: waveCanvasRef, style: { width: "250px", height: "80px" } }) })) }), _jsxs(motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.2, ...iosTransitions.fadePop }, children: [_jsx("div", { style: {
203
+ }, children: _jsx("svg", { width: "250", height: "80", style: {
204
+ overflow: "visible",
205
+ }, children: [0, 1, 2].map((waveIndex) => {
206
+ // Calculate wave path based on audio levels
207
+ const points = [];
208
+ const centerY = 40;
209
+ const waveWidth = 250;
210
+ const segments = barsCount;
211
+ // Calculate average audio level for glow intensity
212
+ const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;
213
+ const glowIntensity = avgLevel * 35; // 0-35px glow (increased from 20)
214
+ // Green color variants for each wave
215
+ const waveColors = [
216
+ aeroTheme.colors.convai.light, // Bright green - front wave
217
+ aeroTheme.colors.convai.light, // Medium green - mid wave
218
+ "#34d399", // Medium-light green - back wave (lighter than dark)
219
+ ];
220
+ for (let i = 0; i <= segments; i++) {
221
+ const x = (i / segments) * waveWidth;
222
+ const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));
223
+ const level = audioLevels[levelIndex] || 0;
224
+ // When idle (low audio), show straight line
225
+ // When active, create waves with increased amplitude
226
+ const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);
227
+ // Only add wave motion when there's audio
228
+ // Idle: amplitude ~0 (straight line)
229
+ // Active: amplitude up to 25px (increased from 15)
230
+ const baseAmplitude = avgLevel > 0.05 ? (2 + waveIndex * 1.5) : 0;
231
+ const amplitude = baseAmplitude + level * (25 - baseAmplitude);
232
+ const y = centerY + Math.sin(phase) * amplitude;
233
+ points.push(`${x},${y}`);
234
+ }
235
+ return (_jsx(motion.path, { d: `M ${points.join(" L ")}`, fill: "none", stroke: waveColors[waveIndex], strokeWidth: 2.5 - waveIndex * 0.4, strokeLinecap: "round", strokeLinejoin: "round", opacity: 0.95 - waveIndex * 0.15, animate: {
236
+ filter: `drop-shadow(0 0 ${glowIntensity}px ${waveColors[waveIndex]}) blur(${waveIndex * 0.3}px)`,
237
+ }, transition: {
238
+ duration: 0.1,
239
+ ease: "easeOut",
240
+ } }, waveIndex));
241
+ }) }) })) }), _jsxs(motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.2, ...iosTransitions.fadePop }, children: [_jsx("div", { style: {
286
242
  fontSize: "16px",
287
243
  fontWeight: 600,
288
244
  color: aeroTheme.colors.text.primary,
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceModeOverlay.js","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { aeroTheme } from \"../../styles/theme\";\nimport { iosTransitions } from \"../../styles/framerConfig\";\nimport { AudioVisualizer } from \"../AudioVisualizer\";\nimport { Room } from \"livekit-client\";\n\ninterface VoiceModeOverlayProps {\n isActive: boolean;\n isTalking: boolean;\n /** When true (user is speaking, from server), show \"Listening...\" label */\n isListening?: boolean;\n convaiClient?: any; // Reference to convai client for audio analysis\n characterImage?: string;\n characterName?: string;\n room?: Room | null;\n}\n\nexport const VoiceModeOverlay = ({\n isActive,\n isTalking,\n isListening = false,\n convaiClient,\n characterImage,\n characterName = \"Character\",\n room,\n}: VoiceModeOverlayProps) => {\n const barsCount = 40; // Number of bars for user microphone waveform\n // PERF: the waveform is driven OUTSIDE React. A setState per animation\n // frame re-rendered the whole overlay (reconcile + style recalc +\n // framer-motion filter retarget) ~60x/s — ~30ms main-thread tasks that\n // visibly juddered the host page's 3D scene whenever voice mode was\n // open. Levels live in a ref and the SVG paths are updated directly.\n const audioLevelsRef = useRef<number[]>(Array(barsCount).fill(0));\n const waveCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const analyzerRef = useRef<AnalyserNode | null>(null);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const audioContextRef = useRef<AudioContext | null>(null);\n\n // Paint the three waves onto a small canvas — no React, no SVG filters.\n // (The previous SVG version re-rasterized a 35px drop-shadow blur every\n // frame; that GPU paint alone pushed the host page to ~30fps.) Glow is\n // approximated with a wide low-alpha understroke, which is ~free.\n // Painting is THROTTLED to 30fps and skipped entirely while silent:\n // every canvas update forces the compositor to re-blend the whole\n // panel stack over the host WebGL canvas, so idle repaints are pure\n // waste that judders the 3D scene.\n const waveFrameParityRef = useRef(0);\n const waveWasSilentRef = useRef(false);\n const drawWaves = () => {\n waveFrameParityRef.current ^= 1;\n if (waveFrameParityRef.current) return; // 30fps is plenty for a waveform\n const canvas = waveCanvasRef.current;\n if (!canvas) return;\n {\n const lv = audioLevelsRef.current;\n let sum = 0;\n for (let i = 0; i < lv.length; i++) sum += lv[i];\n const silent = sum / lv.length < 0.012;\n if (silent && waveWasSilentRef.current) return; // static line already drawn\n waveWasSilentRef.current = silent;\n }\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n if (canvas.width !== 250 * dpr) {\n canvas.width = 250 * dpr;\n canvas.height = 80 * dpr;\n }\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, 250, 80);\n const audioLevels = audioLevelsRef.current;\n const centerY = 40;\n const waveWidth = 250;\n const segments = barsCount;\n const avgLevel =\n audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;\n const waveColors = [\n aeroTheme.colors.convai.light,\n aeroTheme.colors.convai.light,\n \"#34d399\",\n ];\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n for (let waveIndex = 2; waveIndex >= 0; waveIndex--) {\n ctx.beginPath();\n for (let i = 0; i <= segments; i++) {\n const x = (i / segments) * waveWidth;\n const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));\n const level = audioLevels[levelIndex] || 0;\n const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);\n const baseAmplitude = avgLevel > 0.05 ? 2 + waveIndex * 1.5 : 0;\n const amplitude = baseAmplitude + level * (25 - baseAmplitude);\n const y = centerY + Math.sin(phase) * amplitude;\n if (i === 0) ctx.moveTo(x, y);\n else ctx.lineTo(x, y);\n }\n // glow understroke scaled by level, then the crisp line on top\n ctx.strokeStyle = waveColors[waveIndex];\n ctx.globalAlpha = 0.18 * (0.3 + avgLevel);\n ctx.lineWidth = (2.5 - waveIndex * 0.4) + 8 * avgLevel + 3;\n ctx.stroke();\n ctx.globalAlpha = 0.95 - waveIndex * 0.15;\n ctx.lineWidth = 2.5 - waveIndex * 0.4;\n ctx.stroke();\n }\n ctx.globalAlpha = 1;\n };\n\n // Setup audio analysis for USER microphone input ONLY\n useEffect(() => {\n if (!isActive) {\n // Clean up when user is not speaking\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n audioLevelsRef.current = Array(barsCount).fill(0);\n drawWaves();\n return;\n }\n\n let stream: MediaStream | null = null;\n\n const setupAudioAnalysis = async () => {\n try {\n // Get microphone stream\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n // Create audio context and analyzer\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)();\n audioContextRef.current = audioContext;\n\n const analyzer = audioContext.createAnalyser();\n analyzer.fftSize = 256; // Better resolution for time domain\n analyzer.smoothingTimeConstant = 0.7;\n analyzerRef.current = analyzer;\n\n const source = audioContext.createMediaStreamSource(stream);\n source.connect(analyzer);\n\n const dataArray = new Uint8Array(analyzer.fftSize);\n\n const updateLevels = () => {\n if (!analyzerRef.current) return;\n\n // Use time domain data (waveform) instead of frequency\n analyzer.getByteTimeDomainData(dataArray);\n\n // Calculate RMS (Root Mean Square) for volume\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n const normalized = (dataArray[i] - 128) / 128; // Center around 0\n sum += normalized * normalized;\n }\n const rms = Math.sqrt(sum / dataArray.length);\n\n // Apply some scaling and clamping\n const volume = Math.min(1, rms * 3); // Boost sensitivity\n\n // Create left-to-right wave effect — write into the ref and paint\n // the SVG directly (no setState: a per-frame React render here\n // visibly juddered the host page).\n const levels = audioLevelsRef.current;\n for (let i = 0; i < barsCount; i++) {\n const position = i / barsCount; // 0 to 1 from left to right\n const wavePhase = Date.now() / 300 + position * Math.PI * 2;\n const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0\n levels[i] = volume * waveVariation;\n }\n drawWaves();\n animationFrameRef.current = requestAnimationFrame(updateLevels);\n };\n\n updateLevels();\n } catch (error) {\n console.error(\"Error setting up audio analysis:\", error);\n }\n };\n\n setupAudioAnalysis();\n\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (audioContextRef.current) {\n audioContextRef.current.close();\n }\n };\n }, [isActive, barsCount]);\n\n const [isBotSpeaking, setIsBotSpeaking] = useState(false);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n textAlign: \"center\",\n padding: \"1rem\",\n zIndex: 10,\n pointerEvents: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2rem\",\n }}\n >\n {/* Character Avatar with Audio Visualizer */}\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n isolation: \"isolate\", // Create stacking context\n }}\n >\n {/* Audio Visualizer - positioned absolutely behind the character */}\n {room && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{\n opacity: isBotSpeaking ? 1 : 0,\n scale: isBotSpeaking ? 1 : 0.8,\n }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"absolute\",\n width: \"220px\",\n height: \"220px\",\n zIndex: -1, // Negative z-index to ensure it's behind\n pointerEvents: \"none\",\n }}\n >\n <AudioVisualizer\n room={room}\n size={220}\n color={aeroTheme.colors.convai.light}\n opacity={0.6}\n avatarRadius={110}\n barCount={48}\n onSpeakingChange={setIsBotSpeaking}\n />\n </motion.div>\n )}\n\n {/* Character Image - pops from header to center */}\n <motion.div\n key=\"center-avatar\" // Use key instead of layoutId for independent animation\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"relative\",\n zIndex: 10, // Higher z-index to be clearly on top\n borderRadius: \"50%\",\n overflow: \"visible\", // Changed to visible to show glow\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.3)\",\n background: \"white\",\n }}\n >\n {/* Animated liquid gradient - Layer 1 */}\n <motion.div\n animate={{\n rotate: [0, 360],\n scale: isBotSpeaking ? [1, 1.05, 1.02, 1.05, 1] : 1,\n }}\n transition={{\n rotate: { duration: 20, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 3, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n conic-gradient(\n from 0deg,\n ${aeroTheme.colors.convai.light}00 0%,\n ${aeroTheme.colors.convai.light}40 25%,\n ${aeroTheme.colors.convai.dark}60 50%,\n ${aeroTheme.colors.convai.light}40 75%,\n ${aeroTheme.colors.convai.light}00 100%\n )\n `,\n opacity: 0.8,\n filter: \"blur(8px)\",\n zIndex: -2,\n }}\n />\n\n {/* Animated liquid gradient - Layer 2 (counter-rotating) */}\n <motion.div\n animate={{\n rotate: [360, 0],\n scale: isBotSpeaking ? [1, 1.03, 1.06, 1.03, 1] : 1,\n }}\n transition={{\n rotate: { duration: 15, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 2.5, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n radial-gradient(\n ellipse 80% 100% at 30% 40%,\n ${aeroTheme.colors.convai.light}50,\n ${aeroTheme.colors.convai.light}30 40%,\n transparent 70%\n ),\n radial-gradient(\n ellipse 80% 100% at 70% 60%,\n ${aeroTheme.colors.convai.dark}50,\n ${aeroTheme.colors.convai.dark}30 40%,\n transparent 70%\n )\n `,\n opacity: 0.9,\n filter: \"blur(6px)\",\n zIndex: -1,\n }}\n />\n\n {/* Character container with border */}\n <div\n style={{\n position: \"relative\",\n borderRadius: \"50%\",\n overflow: \"hidden\",\n border: `3px solid rgba(255, 255, 255, 0.2)`,\n }}\n >\n {characterImage ? (\n <motion.img\n src={characterImage}\n alt={characterName}\n animate={{\n scale: isBotSpeaking ? 1.05 : 1,\n }}\n transition={{\n duration: 0.3,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"120px\",\n height: \"120px\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n ) : (\n <div\n style={{\n width: \"120px\",\n height: \"120px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"48px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 600,\n }}\n >\n {characterName[0]?.toUpperCase() || \"C\"}\n </div>\n )}\n </div>\n </motion.div>\n </div>\n\n {/* Sound Wave Lines - USER microphone ONLY */}\n <AnimatePresence>\n {isActive && (\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -20 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"250px\",\n height: \"80px\",\n position: \"relative\",\n }}\n >\n {/* Wave lines painted by drawWaves() (rAF-driven canvas) — the\n previous SVG + animated drop-shadow filter re-rasterized a\n blurred layer every frame and juddered the host page. */}\n <canvas\n ref={waveCanvasRef}\n style={{ width: \"250px\", height: \"80px\" }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Status Text */}\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.2, ...iosTransitions.fadePop }}\n >\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 600,\n color: aeroTheme.colors.text.primary,\n marginBottom: \"0.5rem\",\n }}\n >\n {isTalking\n ? `${characterName} Speaking...`\n : isListening || isActive\n ? \"Listening...\"\n : \"Voice Mode\"}\n </div>\n <div\n style={{\n fontSize: \"13px\",\n color: aeroTheme.colors.text.secondary,\n }}\n >\n {isListening || isActive || isTalking ? \"Audio active\" : \"Tap microphone to talk\"}\n </div>\n </motion.div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"VoiceModeOverlay.js","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { aeroTheme } from \"../../styles/theme\";\nimport { iosTransitions } from \"../../styles/framerConfig\";\nimport { AudioVisualizer } from \"../AudioVisualizer\";\nimport { Room } from \"livekit-client\";\n\ninterface VoiceModeOverlayProps {\n isActive: boolean;\n isTalking: boolean;\n /** When true (user is speaking, from server), show \"Listening...\" label */\n isListening?: boolean;\n convaiClient?: any; // Reference to convai client for audio analysis\n characterImage?: string;\n characterName?: string;\n room?: Room | null;\n}\n\nexport const VoiceModeOverlay = ({\n isActive,\n isTalking,\n isListening = false,\n convaiClient,\n characterImage,\n characterName = \"Character\",\n room,\n}: VoiceModeOverlayProps) => {\n const barsCount = 40; // Number of bars for user microphone waveform\n const [audioLevels, setAudioLevels] = useState<number[]>(\n Array(barsCount).fill(0) as number[],\n );\n const analyzerRef = useRef<AnalyserNode | null>(null);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const audioContextRef = useRef<AudioContext | null>(null);\n\n // Setup audio analysis for USER microphone input ONLY\n useEffect(() => {\n if (!isActive) {\n // Clean up when user is not speaking\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n setAudioLevels(Array(barsCount).fill(0));\n return;\n }\n\n let stream: MediaStream | null = null;\n\n const setupAudioAnalysis = async () => {\n try {\n // Get microphone stream\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n // Create audio context and analyzer\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)();\n audioContextRef.current = audioContext;\n\n const analyzer = audioContext.createAnalyser();\n analyzer.fftSize = 256; // Better resolution for time domain\n analyzer.smoothingTimeConstant = 0.7;\n analyzerRef.current = analyzer;\n\n const source = audioContext.createMediaStreamSource(stream);\n source.connect(analyzer);\n\n const dataArray = new Uint8Array(analyzer.fftSize);\n\n const updateLevels = () => {\n if (!analyzerRef.current) return;\n\n // Use time domain data (waveform) instead of frequency\n analyzer.getByteTimeDomainData(dataArray);\n\n // Calculate RMS (Root Mean Square) for volume\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n const normalized = (dataArray[i] - 128) / 128; // Center around 0\n sum += normalized * normalized;\n }\n const rms = Math.sqrt(sum / dataArray.length);\n\n // Apply some scaling and clamping\n const volume = Math.min(1, rms * 3); // Boost sensitivity\n\n // Create left-to-right wave effect\n const levels = Array(barsCount)\n .fill(0)\n .map((_, i) => {\n // Progressive wave from left to right\n const position = i / barsCount; // 0 to 1 from left to right\n const wavePhase = Date.now() / 300 + position * Math.PI * 2;\n const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0\n return volume * waveVariation;\n });\n\n setAudioLevels(levels);\n animationFrameRef.current = requestAnimationFrame(updateLevels);\n };\n\n updateLevels();\n } catch (error) {\n console.error(\"Error setting up audio analysis:\", error);\n }\n };\n\n setupAudioAnalysis();\n\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (audioContextRef.current) {\n audioContextRef.current.close();\n }\n };\n }, [isActive, barsCount]);\n\n const [isBotSpeaking, setIsBotSpeaking] = useState(false);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n textAlign: \"center\",\n padding: \"1rem\",\n zIndex: 10,\n pointerEvents: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2rem\",\n }}\n >\n {/* Character Avatar with Audio Visualizer */}\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n isolation: \"isolate\", // Create stacking context\n }}\n >\n {/* Audio Visualizer - positioned absolutely behind the character */}\n {room && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{\n opacity: isBotSpeaking ? 1 : 0,\n scale: isBotSpeaking ? 1 : 0.8,\n }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"absolute\",\n width: \"220px\",\n height: \"220px\",\n zIndex: -1, // Negative z-index to ensure it's behind\n pointerEvents: \"none\",\n }}\n >\n <AudioVisualizer\n room={room}\n size={220}\n color={aeroTheme.colors.convai.light}\n opacity={0.6}\n avatarRadius={110}\n barCount={48}\n onSpeakingChange={setIsBotSpeaking}\n />\n </motion.div>\n )}\n\n {/* Character Image - pops from header to center */}\n <motion.div\n key=\"center-avatar\" // Use key instead of layoutId for independent animation\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"relative\",\n zIndex: 10, // Higher z-index to be clearly on top\n borderRadius: \"50%\",\n overflow: \"visible\", // Changed to visible to show glow\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.3)\",\n background: \"white\",\n }}\n >\n {/* Animated liquid gradient - Layer 1 */}\n <motion.div\n animate={{\n rotate: [0, 360],\n scale: isBotSpeaking ? [1, 1.05, 1.02, 1.05, 1] : 1,\n }}\n transition={{\n rotate: { duration: 20, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 3, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n conic-gradient(\n from 0deg,\n ${aeroTheme.colors.convai.light}00 0%,\n ${aeroTheme.colors.convai.light}40 25%,\n ${aeroTheme.colors.convai.dark}60 50%,\n ${aeroTheme.colors.convai.light}40 75%,\n ${aeroTheme.colors.convai.light}00 100%\n )\n `,\n opacity: 0.8,\n filter: \"blur(8px)\",\n zIndex: -2,\n }}\n />\n\n {/* Animated liquid gradient - Layer 2 (counter-rotating) */}\n <motion.div\n animate={{\n rotate: [360, 0],\n scale: isBotSpeaking ? [1, 1.03, 1.06, 1.03, 1] : 1,\n }}\n transition={{\n rotate: { duration: 15, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 2.5, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n radial-gradient(\n ellipse 80% 100% at 30% 40%,\n ${aeroTheme.colors.convai.light}50,\n ${aeroTheme.colors.convai.light}30 40%,\n transparent 70%\n ),\n radial-gradient(\n ellipse 80% 100% at 70% 60%,\n ${aeroTheme.colors.convai.dark}50,\n ${aeroTheme.colors.convai.dark}30 40%,\n transparent 70%\n )\n `,\n opacity: 0.9,\n filter: \"blur(6px)\",\n zIndex: -1,\n }}\n />\n\n {/* Character container with border */}\n <div\n style={{\n position: \"relative\",\n borderRadius: \"50%\",\n overflow: \"hidden\",\n border: `3px solid rgba(255, 255, 255, 0.2)`,\n }}\n >\n {characterImage ? (\n <motion.img\n src={characterImage}\n alt={characterName}\n animate={{\n scale: isBotSpeaking ? 1.05 : 1,\n }}\n transition={{\n duration: 0.3,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"120px\",\n height: \"120px\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n ) : (\n <div\n style={{\n width: \"120px\",\n height: \"120px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"48px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 600,\n }}\n >\n {characterName[0]?.toUpperCase() || \"C\"}\n </div>\n )}\n </div>\n </motion.div>\n </div>\n\n {/* Sound Wave Lines - USER microphone ONLY */}\n <AnimatePresence>\n {isActive && (\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -20 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"250px\",\n height: \"80px\",\n position: \"relative\",\n }}\n >\n <svg\n width=\"250\"\n height=\"80\"\n style={{\n overflow: \"visible\",\n }}\n >\n {/* Generate 3 wave lines with green shades */}\n {[0, 1, 2].map((waveIndex) => {\n // Calculate wave path based on audio levels\n const points: string[] = [];\n const centerY = 40;\n const waveWidth = 250;\n const segments = barsCount;\n \n // Calculate average audio level for glow intensity\n const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;\n const glowIntensity = avgLevel * 35; // 0-35px glow (increased from 20)\n \n // Green color variants for each wave\n const waveColors = [\n aeroTheme.colors.convai.light, // Bright green - front wave\n aeroTheme.colors.convai.light, // Medium green - mid wave\n \"#34d399\", // Medium-light green - back wave (lighter than dark)\n ];\n \n for (let i = 0; i <= segments; i++) {\n const x = (i / segments) * waveWidth;\n const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));\n const level = audioLevels[levelIndex] || 0;\n \n // When idle (low audio), show straight line\n // When active, create waves with increased amplitude\n const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);\n \n // Only add wave motion when there's audio\n // Idle: amplitude ~0 (straight line)\n // Active: amplitude up to 25px (increased from 15)\n const baseAmplitude = avgLevel > 0.05 ? (2 + waveIndex * 1.5) : 0;\n const amplitude = baseAmplitude + level * (25 - baseAmplitude);\n const y = centerY + Math.sin(phase) * amplitude;\n \n points.push(`${x},${y}`);\n }\n \n return (\n <motion.path\n key={waveIndex}\n d={`M ${points.join(\" L \")}`}\n fill=\"none\"\n stroke={waveColors[waveIndex]}\n strokeWidth={2.5 - waveIndex * 0.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n opacity={0.95 - waveIndex * 0.15}\n animate={{\n filter: `drop-shadow(0 0 ${glowIntensity}px ${waveColors[waveIndex]}) blur(${waveIndex * 0.3}px)`,\n }}\n transition={{\n duration: 0.1,\n ease: \"easeOut\",\n }}\n />\n );\n })}\n </svg>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Status Text */}\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.2, ...iosTransitions.fadePop }}\n >\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 600,\n color: aeroTheme.colors.text.primary,\n marginBottom: \"0.5rem\",\n }}\n >\n {isTalking\n ? `${characterName} Speaking...`\n : isListening || isActive\n ? \"Listening...\"\n : \"Voice Mode\"}\n </div>\n <div\n style={{\n fontSize: \"13px\",\n color: aeroTheme.colors.text.secondary,\n }}\n >\n {isListening || isActive || isTalking ? \"Audio active\" : \"Tap microphone to talk\"}\n </div>\n </motion.div>\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useConvaiClient.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,YAAY,KACpB,aAAa,GAAG;IACjB,oFAAoF;IACpF,2BAA2B,EAAE,WAAW,CACtC,aAAa,CAAC,6BAA6B,CAAC,CAC7C,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAuP9B,CAAC"}
1
+ {"version":3,"file":"useConvaiClient.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,YAAY,KACpB,aAAa,GAAG;IACjB,oFAAoF;IACpF,2BAA2B,EAAE,WAAW,CACtC,aAAa,CAAC,6BAA6B,CAAC,CAC7C,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAwO9B,CAAC"}
@@ -27,10 +27,8 @@ import { ConvaiClient as CoreConvaiClient } from "../../core/index.js";
27
27
  * ```
28
28
  */
29
29
  export const useConvaiClient = (config) => {
30
- // Create client instance once. The config is handed to the client as well
31
- // as kept in the hook, so config-derived surfaces such as
32
- // `characterVersions` are usable before the first connect().
33
- const [client] = useState(() => new CoreConvaiClient(config));
30
+ // Create client instance once
31
+ const [client] = useState(() => new CoreConvaiClient());
34
32
  // React state for UI updates
35
33
  const [state, setState] = useState(client.state);
36
34
  const [activity, setActivity] = useState("Idle");
@@ -172,19 +170,8 @@ export const useConvaiClient = (config) => {
172
170
  ...(client.apiKey && { apiKey: client.apiKey }),
173
171
  ...(client.authToken && { authToken: client.authToken }),
174
172
  characterId: client.characterId,
175
- characterVersion: client.characterVersion,
176
- characterReference: client.characterReference,
177
173
  requestTraceId: client.requestTraceId,
178
174
  connect,
179
- connectWithConnectionData: client.connectWithConnectionData.bind(client),
180
- joinRoom: client.joinRoom.bind(client),
181
- appendMessage: client.appendMessage.bind(client),
182
- toggleUsageUpdates: client.toggleUsageUpdates.bind(client),
183
- setInteractionTarget: client.setInteractionTarget.bind(client),
184
- updateCharacterRoster: client.updateCharacterRoster.bind(client),
185
- roomSession: client.roomSession,
186
- characters: client.characters,
187
- activeMembershipId: client.activeMembershipId,
188
175
  connectWithPublicationGrant,
189
176
  disconnect: client.disconnect.bind(client),
190
177
  reconnect,
@@ -192,7 +179,6 @@ export const useConvaiClient = (config) => {
192
179
  room: client.room,
193
180
  sendUserTextMessage: client.sendUserTextMessage.bind(client),
194
181
  sendActionResult: client.sendActionResult.bind(client),
195
- sendActionResultAndWait: client.sendActionResultAndWait.bind(client),
196
182
  sendTriggerMessage: client.sendTriggerMessage.bind(client),
197
183
  sendInterruptMessage: client.sendInterruptMessage.bind(client),
198
184
  resetIdleTimer: client.resetIdleTimer.bind(client),
@@ -215,7 +201,6 @@ export const useConvaiClient = (config) => {
215
201
  blendshapeQueue: client.blendshapeQueue,
216
202
  conversationSessionId: client.conversationSessionId,
217
203
  memoryManager: client.memoryManager,
218
- characterVersions: client.characterVersions,
219
204
  toggleTts: client.toggleTts.bind(client),
220
205
  toggleStt: client.toggleStt.bind(client),
221
206
  uploadFile: client.uploadFile.bind(client),
@@ -1 +1 @@
1
- {"version":3,"file":"useConvaiClient.js","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQ9D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAAqB,EAWrB,EAAE;IACF,0EAA0E;IAC1E,0DAA0D;IAC1D,6DAA6D;IAC7D,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9D,6BAA6B;IAC7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAS,MAAM,CAAC,CAAC;IACzD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,MAAM,CAAC,YAAY,CACpB,CAAC;IACF,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CACxD,MAAM,CAAC,iBAAiB,CACzB,CAAC;IACF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC7D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,MAAM,CAAC,UAAU,CAAC,CAAC;IAEzE,uCAAuC;IACvC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,MAAM,CAAC,aAAa,CAAC,YAAY,CAClC,CAAC;IACF,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAClD,MAAM,CAAC,aAAa,CAAC,cAAc,CACpC,CAAC;IACF,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAC5D,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,CAC/C,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAA2B,MAAM,CAAC,CAAC;IAElE,wBAAwB;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,wBAAwB;QACxB,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC7D,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEnB,yFAAyF;YACzF,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAC1B,WAAW,CAAC,cAAc,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACjC,WAAW,CAAC,eAAe,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC/B,WAAW,CAAC,UAAU,CAAC,CAAC;YAC1B,CAAC;iBAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAChC,WAAW,CAAC,WAAW,CAAC,CAAC;YAC3B,CAAC;iBAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC/B,WAAW,CAAC,UAAU,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,WAAW,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,EAAE;YACnE,eAAe,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CACtC,yBAAyB,EACzB,CAAC,aAAa,EAAE,EAAE;YAChB,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;QAEF,2BAA2B;QAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC7D,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;YAC/C,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,mBAAmB;QACnB,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC7C,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACnD,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,WAAW,CAAC,cAAc,CAAC,CAAC;YAC5B,eAAe,CAAC,EAAE,CAAC,CAAC;YACpB,qCAAqC;YACrC,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzB,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC;QACpC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAClC,eAAe,EACf,CAAC,KAAuB,EAAE,EAAE;YAC1B,SAAS,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC,CACF,CAAC;QAEF,2CAA2C;QAC3C,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAC1D,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,uCAAuC;QACvC,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAe,EAAE,EAAE;YACtF,IAAI,UAAU,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC1C,eAAe,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uCAAuC;QACvC,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAe,EAAE,EAAE;YACtF,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAC5C,iBAAiB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,MAAM,qBAAqB,GAAG,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,gBAAqB,EAAE,EAAE;YAC9G,IAAI,gBAAgB,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;gBACvD,sBAAsB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,OAAO,GAAG,EAAE;YACV,gBAAgB,EAAE,CAAC;YACnB,mBAAmB,EAAE,CAAC;YACtB,sBAAsB,EAAE,CAAC;YACzB,aAAa,EAAE,CAAC;YAChB,aAAa,EAAE,CAAC;YAChB,YAAY,EAAE,CAAC;YACf,eAAe,EAAE,CAAC;YAClB,kBAAkB,EAAE,CAAC;YACrB,sBAAsB,EAAE,CAAC;YACzB,eAAe,EAAE,CAAC;YAClB,eAAe,EAAE,CAAC;YAClB,qBAAqB,EAAE,CAAC;YACxB,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;YAC3B,SAAS,CAAC,MAAM,EAAE,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,8DAA8D;IAC9D,MAAM,OAAO,GAAG,WAAW,CACzB,KAAK,EAAE,cAA6B,EAAE,EAAE;QACtC,MAAM,WAAW,GAAG,cAAc,IAAI,YAAY,CAAC;QAEnD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC,EACD,CAAC,MAAM,EAAE,YAAY,CAAC,CACvB,CAAC;IAEF,oCAAoC;IACpC,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;IAC3B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,2BAA2B,GAAG,WAAW,CAC7C,KAAK,EACH,WAAmB,EACnB,OAAqC,EACrC,EAAE;QACF,MAAM,MAAM,CAAC,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,wDAAwD;IACxD,OAAO;QACL,KAAK;QACL,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,sBAAsB,EAAE,MAAM,CAAC,sBAAsB;QACrD,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QACxD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO;QACP,yBAAyB,EAAE,MAAM,CAAC,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACtC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1D,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9D,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;QAChE,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,2BAA2B;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1C,SAAS;QACT,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5D,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QACtD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC;QACpE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1D,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9D,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QAClD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1D,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxD,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxD,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5D,QAAQ;QACR,YAAY;QACZ,iBAAiB;QACjB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,UAAU;QACV,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;QAC3C,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1B,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5B,0BAA0B;QAC1B,YAAY;QACZ,cAAc;QACd,mBAAmB;KACpB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { ConvaiClient as CoreConvaiClient } from \"../../core\";\nimport type {\n ConvaiConfig,\n IConvaiClient,\n ChatMessage,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\n\n/**\n * React hook wrapper for ConvaiClient\n * Main hook for managing Convai client connection and functionality.\n *\n * Provides a complete interface for connecting to Convai's AI-powered voice assistants,\n * managing real-time audio/video conversations, and handling various message types.\n *\n * @param config - Optional configuration to store for later connection\n * @returns {ConvaiClient & { activity: string; chatMessages: ChatMessage[] }} Complete client interface with connection state, methods, and message history\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * endUserId: 'user-uuid', // Optional: enables memory & analytics\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget convaiClient={convaiClient} />\n * );\n * }\n * ```\n */\nexport const useConvaiClient = (\n config?: ConvaiConfig,\n): IConvaiClient & {\n /** This hook always supplies the publication connector, unlike generic adapters. */\n connectWithPublicationGrant: NonNullable<\n IConvaiClient[\"connectWithPublicationGrant\"]\n >;\n activity: string;\n chatMessages: ChatMessage[];\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n} => {\n // Create client instance once. The config is handed to the client as well\n // as kept in the hook, so config-derived surfaces such as\n // `characterVersions` are usable before the first connect().\n const [client] = useState(() => new CoreConvaiClient(config));\n\n // React state for UI updates\n const [state, setState] = useState(client.state);\n const [activity, setActivity] = useState<string>(\"Idle\");\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>(\n client.chatMessages,\n );\n const [userTranscription, setUserTranscription] = useState<string>(\n client.userTranscription,\n );\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false);\n const [isBotReady, setIsBotReady] = useState<boolean>(client.isBotReady);\n \n // Reactive states for control managers\n const [isAudioMuted, setIsAudioMuted] = useState<boolean>(\n client.audioControls.isAudioMuted\n );\n const [isVideoEnabled, setIsVideoEnabled] = useState<boolean>(\n client.videoControls.isVideoEnabled\n );\n const [isScreenShareActive, setIsScreenShareActive] = useState<boolean>(\n client.screenShareControls.isScreenShareActive\n );\n\n // Store config if provided\n const [storedConfig] = useState<ConvaiConfig | undefined>(config);\n\n // Setup event listeners\n useEffect(() => {\n // State change listener\n const unsubStateChange = client.on(\"stateChange\", (newState) => {\n setState(newState);\n\n // Update activity based on state (priority: speaking > listening > thinking > connected)\n if (!newState.isConnected) {\n setActivity(\"Disconnected\");\n } else if (newState.isConnecting) {\n setActivity(\"Connecting...\");\n } else if (newState.isSpeaking) {\n setActivity(\"Speaking\");\n } else if (newState.isListening) {\n setActivity(\"Listening\");\n } else if (newState.isThinking) {\n setActivity(\"Thinking\");\n } else {\n setActivity(\"Connected\");\n }\n });\n\n // Messages change listener\n const unsubMessagesChange = client.on(\"messagesChange\", (messages) => {\n setChatMessages([...messages]);\n });\n\n // User transcription change listener\n const unsubUserTranscription = client.on(\n \"userTranscriptionChange\",\n (transcription) => {\n setUserTranscription(transcription);\n },\n );\n\n // Speaking change listener\n const unsubSpeaking = client.on(\"speakingChange\", (speaking) => {\n setIsSpeaking(speaking);\n });\n\n // Bot ready listener\n const unsubBotReady = client.on(\"botReady\", () => {\n setIsBotReady(true);\n setActivity(\"Connected\");\n });\n\n // Connect listener\n const unsubConnect = client.on(\"connect\", () => {\n setState(client.state);\n });\n\n // Disconnect listener\n const unsubDisconnect = client.on(\"disconnect\", () => {\n setIsBotReady(false);\n setState(client.state);\n setActivity(\"Disconnected\");\n setChatMessages([]);\n // Reset control states on disconnect\n setIsAudioMuted(true);\n setIsVideoEnabled(false);\n setIsScreenShareActive(false);\n });\n\n // WebSocket transport: play bot audio track via a hidden <audio> element\n const wsAudioEl = document.createElement(\"audio\");\n wsAudioEl.autoplay = true;\n wsAudioEl.dataset.convaiWs = \"true\";\n document.body.appendChild(wsAudioEl);\n\n const unsubBotAudioTrack = client.on(\n \"botAudioTrack\",\n (track: MediaStreamTrack) => {\n wsAudioEl.srcObject = new MediaStream([track]);\n },\n );\n\n // Disconnect listener also clears WS audio\n const unsubDisconnectWsAudio = client.on(\"disconnect\", () => {\n wsAudioEl.srcObject = null;\n });\n\n // Audio controls state change listener\n const unsubAudioState = client.audioControls.on(\"audioStateChange\", (audioState: any) => {\n if (audioState.isAudioMuted !== undefined) {\n setIsAudioMuted(audioState.isAudioMuted);\n }\n });\n\n // Video controls state change listener\n const unsubVideoState = client.videoControls.on(\"videoStateChange\", (videoState: any) => {\n if (videoState.isVideoEnabled !== undefined) {\n setIsVideoEnabled(videoState.isVideoEnabled);\n }\n });\n\n // Screen share controls state change listener\n const unsubScreenShareState = client.screenShareControls.on(\"screenShareStateChange\", (screenShareState: any) => {\n if (screenShareState.isScreenShareActive !== undefined) {\n setIsScreenShareActive(screenShareState.isScreenShareActive);\n }\n });\n\n // Cleanup listeners on unmount\n return () => {\n unsubStateChange();\n unsubMessagesChange();\n unsubUserTranscription();\n unsubSpeaking();\n unsubBotReady();\n unsubConnect();\n unsubDisconnect();\n unsubBotAudioTrack();\n unsubDisconnectWsAudio();\n unsubAudioState();\n unsubVideoState();\n unsubScreenShareState();\n wsAudioEl.srcObject = null;\n wsAudioEl.remove();\n };\n }, [client]);\n\n // Create enhanced connect function that can use stored config\n const connect = useCallback(\n async (configOverride?: ConvaiConfig) => {\n const finalConfig = configOverride || storedConfig;\n\n if (!finalConfig) {\n throw new Error(\n \"No configuration provided. Pass config to useConvaiClient() or to connect()\",\n );\n }\n\n await client.connect(finalConfig);\n },\n [client, storedConfig],\n );\n\n // Create reconnect function wrapper\n const reconnect = useCallback(async () => {\n await client.reconnect();\n }, [client]);\n\n const connectWithPublicationGrant = useCallback(\n async (\n launchToken: string,\n options?: PublishedChatConnectOptions,\n ) => {\n await client.connectWithPublicationGrant(launchToken, options);\n },\n [client],\n );\n\n // Return client interface with React-friendly additions\n return {\n state,\n connectionType: client.connectionType,\n isPublishedChatSession: client.isPublishedChatSession,\n ...(client.apiKey && { apiKey: client.apiKey }),\n ...(client.authToken && { authToken: client.authToken }),\n characterId: client.characterId,\n characterVersion: client.characterVersion,\n characterReference: client.characterReference,\n requestTraceId: client.requestTraceId,\n connect,\n connectWithConnectionData: client.connectWithConnectionData.bind(client),\n joinRoom: client.joinRoom.bind(client),\n appendMessage: client.appendMessage.bind(client),\n toggleUsageUpdates: client.toggleUsageUpdates.bind(client),\n setInteractionTarget: client.setInteractionTarget.bind(client),\n updateCharacterRoster: client.updateCharacterRoster.bind(client),\n roomSession: client.roomSession,\n characters: client.characters,\n activeMembershipId: client.activeMembershipId,\n connectWithPublicationGrant,\n disconnect: client.disconnect.bind(client),\n reconnect,\n resetSession: client.resetSession.bind(client),\n room: client.room,\n sendUserTextMessage: client.sendUserTextMessage.bind(client),\n sendActionResult: client.sendActionResult.bind(client),\n sendActionResultAndWait: client.sendActionResultAndWait.bind(client),\n sendTriggerMessage: client.sendTriggerMessage.bind(client),\n sendInterruptMessage: client.sendInterruptMessage.bind(client),\n resetIdleTimer: client.resetIdleTimer.bind(client),\n updateTemplateKeys: client.updateTemplateKeys.bind(client),\n updateDynamicInfo: client.updateDynamicInfo.bind(client),\n updateContext: client.updateContext.bind(client),\n updateEmotion: client.updateEmotion.bind(client),\n visionStatus: client.visionStatus.bind(client),\n visionTrigger: client.visionTrigger.bind(client),\n respondModeUpdate: client.respondModeUpdate.bind(client),\n updateSceneMetadata: client.updateSceneMetadata.bind(client),\n activity,\n chatMessages,\n userTranscription,\n characterSessionId: client.characterSessionId,\n isBotReady,\n audioControls: client.audioControls,\n videoControls: client.videoControls,\n screenShareControls: client.screenShareControls,\n blendshapeQueue: client.blendshapeQueue,\n conversationSessionId: client.conversationSessionId,\n memoryManager: client.memoryManager,\n characterVersions: client.characterVersions,\n toggleTts: client.toggleTts.bind(client),\n toggleStt: client.toggleStt.bind(client),\n uploadFile: client.uploadFile.bind(client),\n on: client.on.bind(client),\n off: client.off.bind(client),\n // Reactive control states\n isAudioMuted,\n isVideoEnabled,\n isScreenShareActive,\n };\n};\n"]}
1
+ {"version":3,"file":"useConvaiClient.js","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { ConvaiClient as CoreConvaiClient } from \"../../core\";\nimport type {\n ConvaiConfig,\n IConvaiClient,\n ChatMessage,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\n\n/**\n * React hook wrapper for ConvaiClient\n * Main hook for managing Convai client connection and functionality.\n *\n * Provides a complete interface for connecting to Convai's AI-powered voice assistants,\n * managing real-time audio/video conversations, and handling various message types.\n *\n * @param config - Optional configuration to store for later connection\n * @returns {ConvaiClient & { activity: string; chatMessages: ChatMessage[] }} Complete client interface with connection state, methods, and message history\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * endUserId: 'user-uuid', // Optional: enables memory & analytics\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget convaiClient={convaiClient} />\n * );\n * }\n * ```\n */\nexport const useConvaiClient = (\n config?: ConvaiConfig,\n): IConvaiClient & {\n /** This hook always supplies the publication connector, unlike generic adapters. */\n connectWithPublicationGrant: NonNullable<\n IConvaiClient[\"connectWithPublicationGrant\"]\n >;\n activity: string;\n chatMessages: ChatMessage[];\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n} => {\n // Create client instance once\n const [client] = useState(() => new CoreConvaiClient());\n\n // React state for UI updates\n const [state, setState] = useState(client.state);\n const [activity, setActivity] = useState<string>(\"Idle\");\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>(\n client.chatMessages,\n );\n const [userTranscription, setUserTranscription] = useState<string>(\n client.userTranscription,\n );\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false);\n const [isBotReady, setIsBotReady] = useState<boolean>(client.isBotReady);\n \n // Reactive states for control managers\n const [isAudioMuted, setIsAudioMuted] = useState<boolean>(\n client.audioControls.isAudioMuted\n );\n const [isVideoEnabled, setIsVideoEnabled] = useState<boolean>(\n client.videoControls.isVideoEnabled\n );\n const [isScreenShareActive, setIsScreenShareActive] = useState<boolean>(\n client.screenShareControls.isScreenShareActive\n );\n\n // Store config if provided\n const [storedConfig] = useState<ConvaiConfig | undefined>(config);\n\n // Setup event listeners\n useEffect(() => {\n // State change listener\n const unsubStateChange = client.on(\"stateChange\", (newState) => {\n setState(newState);\n\n // Update activity based on state (priority: speaking > listening > thinking > connected)\n if (!newState.isConnected) {\n setActivity(\"Disconnected\");\n } else if (newState.isConnecting) {\n setActivity(\"Connecting...\");\n } else if (newState.isSpeaking) {\n setActivity(\"Speaking\");\n } else if (newState.isListening) {\n setActivity(\"Listening\");\n } else if (newState.isThinking) {\n setActivity(\"Thinking\");\n } else {\n setActivity(\"Connected\");\n }\n });\n\n // Messages change listener\n const unsubMessagesChange = client.on(\"messagesChange\", (messages) => {\n setChatMessages([...messages]);\n });\n\n // User transcription change listener\n const unsubUserTranscription = client.on(\n \"userTranscriptionChange\",\n (transcription) => {\n setUserTranscription(transcription);\n },\n );\n\n // Speaking change listener\n const unsubSpeaking = client.on(\"speakingChange\", (speaking) => {\n setIsSpeaking(speaking);\n });\n\n // Bot ready listener\n const unsubBotReady = client.on(\"botReady\", () => {\n setIsBotReady(true);\n setActivity(\"Connected\");\n });\n\n // Connect listener\n const unsubConnect = client.on(\"connect\", () => {\n setState(client.state);\n });\n\n // Disconnect listener\n const unsubDisconnect = client.on(\"disconnect\", () => {\n setIsBotReady(false);\n setState(client.state);\n setActivity(\"Disconnected\");\n setChatMessages([]);\n // Reset control states on disconnect\n setIsAudioMuted(true);\n setIsVideoEnabled(false);\n setIsScreenShareActive(false);\n });\n\n // WebSocket transport: play bot audio track via a hidden <audio> element\n const wsAudioEl = document.createElement(\"audio\");\n wsAudioEl.autoplay = true;\n wsAudioEl.dataset.convaiWs = \"true\";\n document.body.appendChild(wsAudioEl);\n\n const unsubBotAudioTrack = client.on(\n \"botAudioTrack\",\n (track: MediaStreamTrack) => {\n wsAudioEl.srcObject = new MediaStream([track]);\n },\n );\n\n // Disconnect listener also clears WS audio\n const unsubDisconnectWsAudio = client.on(\"disconnect\", () => {\n wsAudioEl.srcObject = null;\n });\n\n // Audio controls state change listener\n const unsubAudioState = client.audioControls.on(\"audioStateChange\", (audioState: any) => {\n if (audioState.isAudioMuted !== undefined) {\n setIsAudioMuted(audioState.isAudioMuted);\n }\n });\n\n // Video controls state change listener\n const unsubVideoState = client.videoControls.on(\"videoStateChange\", (videoState: any) => {\n if (videoState.isVideoEnabled !== undefined) {\n setIsVideoEnabled(videoState.isVideoEnabled);\n }\n });\n\n // Screen share controls state change listener\n const unsubScreenShareState = client.screenShareControls.on(\"screenShareStateChange\", (screenShareState: any) => {\n if (screenShareState.isScreenShareActive !== undefined) {\n setIsScreenShareActive(screenShareState.isScreenShareActive);\n }\n });\n\n // Cleanup listeners on unmount\n return () => {\n unsubStateChange();\n unsubMessagesChange();\n unsubUserTranscription();\n unsubSpeaking();\n unsubBotReady();\n unsubConnect();\n unsubDisconnect();\n unsubBotAudioTrack();\n unsubDisconnectWsAudio();\n unsubAudioState();\n unsubVideoState();\n unsubScreenShareState();\n wsAudioEl.srcObject = null;\n wsAudioEl.remove();\n };\n }, [client]);\n\n // Create enhanced connect function that can use stored config\n const connect = useCallback(\n async (configOverride?: ConvaiConfig) => {\n const finalConfig = configOverride || storedConfig;\n\n if (!finalConfig) {\n throw new Error(\n \"No configuration provided. Pass config to useConvaiClient() or to connect()\",\n );\n }\n\n await client.connect(finalConfig);\n },\n [client, storedConfig],\n );\n\n // Create reconnect function wrapper\n const reconnect = useCallback(async () => {\n await client.reconnect();\n }, [client]);\n\n const connectWithPublicationGrant = useCallback(\n async (\n launchToken: string,\n options?: PublishedChatConnectOptions,\n ) => {\n await client.connectWithPublicationGrant(launchToken, options);\n },\n [client],\n );\n\n // Return client interface with React-friendly additions\n return {\n state,\n connectionType: client.connectionType,\n isPublishedChatSession: client.isPublishedChatSession,\n ...(client.apiKey && { apiKey: client.apiKey }),\n ...(client.authToken && { authToken: client.authToken }),\n characterId: client.characterId,\n requestTraceId: client.requestTraceId,\n connect,\n connectWithPublicationGrant,\n disconnect: client.disconnect.bind(client),\n reconnect,\n resetSession: client.resetSession.bind(client),\n room: client.room,\n sendUserTextMessage: client.sendUserTextMessage.bind(client),\n sendActionResult: client.sendActionResult.bind(client),\n sendTriggerMessage: client.sendTriggerMessage.bind(client),\n sendInterruptMessage: client.sendInterruptMessage.bind(client),\n resetIdleTimer: client.resetIdleTimer.bind(client),\n updateTemplateKeys: client.updateTemplateKeys.bind(client),\n updateDynamicInfo: client.updateDynamicInfo.bind(client),\n updateContext: client.updateContext.bind(client),\n updateEmotion: client.updateEmotion.bind(client),\n visionStatus: client.visionStatus.bind(client),\n visionTrigger: client.visionTrigger.bind(client),\n respondModeUpdate: client.respondModeUpdate.bind(client),\n updateSceneMetadata: client.updateSceneMetadata.bind(client),\n activity,\n chatMessages,\n userTranscription,\n characterSessionId: client.characterSessionId,\n isBotReady,\n audioControls: client.audioControls,\n videoControls: client.videoControls,\n screenShareControls: client.screenShareControls,\n blendshapeQueue: client.blendshapeQueue,\n conversationSessionId: client.conversationSessionId,\n memoryManager: client.memoryManager,\n toggleTts: client.toggleTts.bind(client),\n toggleStt: client.toggleStt.bind(client),\n uploadFile: client.uploadFile.bind(client),\n on: client.on.bind(client),\n off: client.off.bind(client),\n // Reactive control states\n isAudioMuted,\n isVideoEnabled,\n isScreenShareActive,\n };\n};\n"]}
@@ -3,6 +3,6 @@ export { ConvaiWidget } from './components/ConvaiWidget.js';
3
3
  export * from './hooks/index.js';
4
4
  export * from '../core/types.js';
5
5
  export { getDisconnectReasonMessage } from '../core/types.js';
6
- export { ActionResultAckError, ConvaiClient } from '../core/index.js';
6
+ export { ConvaiClient } from '../core/index.js';
7
7
  export { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,cAAc,SAAS,CAAC;AAGxB,cAAc,eAAe,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG7D,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,cAAc,SAAS,CAAC;AAGxB,cAAc,eAAe,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
@@ -9,7 +9,7 @@ export * from '../core/types.js';
9
9
  // Re-export helper functions explicitly
10
10
  export { getDisconnectReasonMessage } from '../core/types.js';
11
11
  // Re-export core client for advanced usage
12
- export { ActionResultAckError, ConvaiClient } from '../core/index.js';
12
+ export { ConvaiClient } from '../core/index.js';
13
13
  // Re-export LiveKit components for convenience (backward compatible)
14
14
  export { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';
15
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,wCAAwC;AACxC,cAAc,SAAS,CAAC;AAExB,uCAAuC;AACvC,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE7D,qEAAqE;AACrE,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["// Main hook (backward compatible)\nexport { useConvaiClient } from './hooks/useConvaiClient';\n\n// Components\nexport { ConvaiWidget } from './components/ConvaiWidget';\n\n// Additional hooks (for advanced usage)\nexport * from './hooks';\n\n// Re-export core types for convenience\nexport * from '../core/types';\n\n// Re-export helper functions explicitly\nexport { getDisconnectReasonMessage } from '../core/types';\n\n// Re-export core client for advanced usage\nexport { ActionResultAckError, ConvaiClient } from '../core';\n\n// Re-export LiveKit components for convenience (backward compatible)\nexport { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,wCAAwC;AACxC,cAAc,SAAS,CAAC;AAExB,uCAAuC;AACvC,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,qEAAqE;AACrE,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["// Main hook (backward compatible)\nexport { useConvaiClient } from './hooks/useConvaiClient';\n\n// Components\nexport { ConvaiWidget } from './components/ConvaiWidget';\n\n// Additional hooks (for advanced usage)\nexport * from './hooks';\n\n// Re-export core types for convenience\nexport * from '../core/types';\n\n// Re-export helper functions explicitly\nexport { getDisconnectReasonMessage } from '../core/types';\n\n// Re-export core client for advanced usage\nexport { ConvaiClient } from '../core';\n\n// Re-export LiveKit components for convenience (backward compatible)\nexport { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';\n\n"]}
@@ -13,9 +13,7 @@ export declare class AudioRenderer {
13
13
  private boundHandleTrackSubscribed;
14
14
  private boundHandleTrackUnsubscribed;
15
15
  private boundHandleParticipantDisconnected;
16
- constructor(room: Room, options?: {
17
- container?: HTMLElement;
18
- });
16
+ constructor(room: Room);
19
17
  /**
20
18
  * Setup event listeners for room events
21
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AudioRenderer.d.ts","sourceRoot":"","sources":["../../src/vanilla/AudioRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwD,MAAM,gBAAgB,CAAC;AAG5F;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAA+B;IAGpD,OAAO,CAAC,0BAA0B,CAAM;IACxC,OAAO,CAAC,4BAA4B,CAAM;IAC1C,OAAO,CAAC,kCAAkC,CAAM;gBAEpC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,WAAW,CAAA;KAAE;IAmB7D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAMrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe,CAAiC;IAExD;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IASnD,oBAAoB,IAAI,IAAI;IAS5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAmBhB"}
1
+ {"version":3,"file":"AudioRenderer.d.ts","sourceRoot":"","sources":["../../src/vanilla/AudioRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwD,MAAM,gBAAgB,CAAC;AAG5F;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAA+B;IAGpD,OAAO,CAAC,0BAA0B,CAAM;IACxC,OAAO,CAAC,4BAA4B,CAAM;IAC1C,OAAO,CAAC,kCAAkC,CAAM;gBAEpC,IAAI,EAAE,IAAI;IAmBtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAMrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe,CAAiC;IAExD;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IASnD,oBAAoB,IAAI,IAAI;IAS5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAmBhB"}
@@ -6,7 +6,7 @@ import { logger } from '../utils/logger.js';
6
6
  * This replaces React's RoomAudioRenderer for vanilla implementations
7
7
  */
8
8
  export class AudioRenderer {
9
- constructor(room, options) {
9
+ constructor(room) {
10
10
  this.audioElements = new Map();
11
11
  this.livekitTracks = new Map(); // Store track references
12
12
  this._wsAudioElement = null;
@@ -20,7 +20,7 @@ export class AudioRenderer {
20
20
  this.container = document.createElement('div');
21
21
  this.container.id = `convai-audio-renderer-${this.rendererId}`;
22
22
  this.container.style.display = 'none';
23
- (options?.container ?? document.body).appendChild(this.container);
23
+ document.body.appendChild(this.container);
24
24
  this.setupEventListeners();
25
25
  this.attachExistingTracks();
26
26
  }
@@ -84,12 +84,6 @@ export class AudioRenderer {
84
84
  // Create audio element
85
85
  const audioElement = document.createElement('audio');
86
86
  audioElement.id = `audio-${trackSid}`;
87
- // Expose who owns this element, so a host page can find a member's
88
- // audio by identity (`character:{membershipId}` in a roster room).
89
- audioElement.dataset.participantIdentity = participant.identity;
90
- if (participant.identity.startsWith('character:')) {
91
- audioElement.dataset.membershipId = participant.identity.slice('character:'.length);
92
- }
93
87
  audioElement.autoplay = true;
94
88
  // Direct track attachment - play audio immediately
95
89
  track.attach(audioElement);