@moveo-ai/web-client 0.116.1 → 0.117.0-true.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.
@@ -6,7 +6,7 @@
6
6
 
7
7
  /*!
8
8
  *
9
- * @moveo-ai/web-client v0.116.1
9
+ * @moveo-ai/web-client v0.117.0-true.1
10
10
  * Copyright (c) Moveo.ai (TM)
11
11
  *
12
12
  */
package/dist/index.html CHANGED
@@ -11,7 +11,7 @@
11
11
  const widgetId = urlParams.get('widgetId');
12
12
 
13
13
  const script = document.createElement('script');
14
- script.src = 'iframe.min.js?12ed67fddbdcc089e8ad';
14
+ script.src = 'iframe.min.js?78472d4bc83b1ae13046';
15
15
 
16
16
  script.onload = function () {
17
17
  if (widgetId) {
@@ -4,11 +4,11 @@
4
4
 
5
5
  body::before {
6
6
  background-image: url('/public/background.svg');
7
- }</style><script src="../audio-client.min.js?12ed67fddbdcc089e8ad"></script></head><body><div class="flex flex-row flex-wrap justify-between p-[10%] pb-0 mobile:flex-col mobile:items-center mobile:p-0 mobile:pt-[75px]"><div class="w-[510px] mb-9 mobile:flex mobile:flex-col mobile:items-center mobile:w-auto mobile:min-w-0"><p class="mt-0 mb-6 text-[42px] leading-[51px] font-bold mobile:text-center mobile:text-[28px] mobile:leading-[34px]"><span class="colored text-preview-muted">Preview</span> and <span class="colored text-preview-muted">Test</span><br/>your Webchat</p><p class="mb-9 text-2xl leading-[30px] font-normal mobile:text-center mobile:text-base mobile:leading-5 mobile:w-[280px]">Moveo.ai can help you build engaging conversational applications powered by Artificial Intelligence.</p><div class="flex flex-row justify-start"><button class="action_button hidden cursor-pointer" id="open-chat-button">Open Webchat</button> <button class="action_button hidden mobile:hidden cursor-pointer" id="close-chat-button">Close Webchat</button> <button class="action_button hidden cursor-pointer" id="render-chat-button">Render Webchat</button></div></div><div class="hidden box-border flex-initial w-[512px] h-[562px] min-w-[300px] mb-16 rounded-lg border-2 border-brand-background bg-white shadow-[2px_3px_6px_rgb(104_104_104/10%)] mobile:mx-[10%] mobile:w-4/5" id="embed-chat-container"><p class="mt-[10%] mx-7 mb-0 text-base leading-6 text-center" id="embed-text">The webchat will render in the html element of your choice. Render the webchat here, in order to preview other settings.</p><div class="hidden w-full h-full" id="embed-chat"></div></div></div><script>const queryString = window.location.search;
7
+ }</style><script src="../audio-client.min.js?78472d4bc83b1ae13046"></script></head><body><div class="flex flex-row flex-wrap justify-between p-[10%] pb-0 mobile:flex-col mobile:items-center mobile:p-0 mobile:pt-[75px]"><div class="w-[510px] mb-9 mobile:flex mobile:flex-col mobile:items-center mobile:w-auto mobile:min-w-0"><p class="mt-0 mb-6 text-[42px] leading-[51px] font-bold mobile:text-center mobile:text-[28px] mobile:leading-[34px]"><span class="colored text-preview-muted">Preview</span> and <span class="colored text-preview-muted">Test</span><br/>your Webchat</p><p class="mb-9 text-2xl leading-[30px] font-normal mobile:text-center mobile:text-base mobile:leading-5 mobile:w-[280px]">Moveo.ai can help you build engaging conversational applications powered by Artificial Intelligence.</p><div class="flex flex-row justify-start"><button class="action_button hidden cursor-pointer" id="open-chat-button">Open Webchat</button> <button class="action_button hidden mobile:hidden cursor-pointer" id="close-chat-button">Close Webchat</button> <button class="action_button hidden cursor-pointer" id="render-chat-button">Render Webchat</button></div></div><div class="hidden box-border flex-initial w-[512px] h-[562px] min-w-[300px] mb-16 rounded-lg border-2 border-brand-background bg-white shadow-[2px_3px_6px_rgb(104_104_104/10%)] mobile:mx-[10%] mobile:w-4/5" id="embed-chat-container"><p class="mt-[10%] mx-7 mb-0 text-base leading-6 text-center" id="embed-text">The webchat will render in the html element of your choice. Render the webchat here, in order to preview other settings.</p><div class="hidden w-full h-full" id="embed-chat"></div></div></div><script>const queryString = window.location.search;
8
8
  const urlParams = new URLSearchParams(queryString);
9
9
 
10
10
  // Find web-client.min.js directly
11
- const webpackFiles = `../iframe.min.js?12ed67fddbdcc089e8ad,../web-client.min.js?12ed67fddbdcc089e8ad,../preview.css.min.js?12ed67fddbdcc089e8ad,../audio-client.min.js?12ed67fddbdcc089e8ad,../webrtc-client.min.js?12ed67fddbdcc089e8ad,../telnyx-client.min.js?12ed67fddbdcc089e8ad`.split(',');
11
+ const webpackFiles = `../iframe.min.js?78472d4bc83b1ae13046,../web-client.min.js?78472d4bc83b1ae13046,../preview.css.min.js?78472d4bc83b1ae13046,../audio-client.min.js?78472d4bc83b1ae13046,../webrtc-client.min.js?78472d4bc83b1ae13046,../telnyx-client.min.js?78472d4bc83b1ae13046`.split(',');
12
12
  const webClientFile = webpackFiles.find(file => file.includes('web-client.min.js'));
13
13
  const previewCssFile = webpackFiles.find(file => file.includes('preview.css.min.js'));
14
14
 
@@ -12,7 +12,7 @@
12
12
  },
13
13
  },
14
14
  },
15
- };</script><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet"/><script defer="defer" src="/webrtc-client.min.js"></script></head><body><div id="preview-content" class="relative min-h-screen font-sans text-slate-900 antialiased"><main class="relative z-10 flex min-h-screen items-start md:items-center"><section class="mx-auto flex w-full max-w-6xl flex-col gap-12 px-6 py-16 pb-32 md:flex-row md:items-start md:px-12 md:pb-16 lg:gap-16"><header class="max-w-2xl space-y-6 text-center md:text-left"><h1 class="text-4xl font-semibold leading-tight sm:text-5xl">Preview and test<br class="hidden sm:block"/>your WebRTC voice integration</h1><p class="text-lg text-slate-600 sm:text-xl">Click the widget button at the bottom right to start a test call and try your AI Agent with native WebRTC voice.</p><div id="status" class="text-sm font-medium"></div></header><div class="flex-1"><div id="transcript-log" class="hidden max-h-[60vh] w-full overflow-y-auto rounded-xl border border-slate-200 bg-white/80 p-4 font-mono text-sm shadow-sm backdrop-blur md:max-h-[70vh]"><h3 class="mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400">Live Transcript</h3><div id="transcript-entries" class="space-y-2 pb-24"></div></div></div></section></main></div><script>localStorage.debug = 'moveo:webrtc:*';
15
+ };</script><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet"/><script src="https://cdn.jsdelivr.net/npm/marked@18.0.9/lib/marked.umd.js"></script><script src="https://cdn.jsdelivr.net/npm/dompurify@3.4.13/dist/purify.min.js"></script><script defer="defer" src="/webrtc-client.min.js"></script></head><body><div id="preview-content" class="relative min-h-screen font-sans text-slate-900 antialiased"><main class="relative z-10 flex min-h-screen items-start md:items-center"><section class="mx-auto flex w-full max-w-6xl flex-col gap-12 px-6 py-16 pb-32 md:flex-row md:items-start md:px-12 md:pb-16 lg:gap-16"><header class="max-w-2xl space-y-6 text-center md:text-left"><h1 class="text-4xl font-semibold leading-tight sm:text-5xl">Preview and test<br class="hidden sm:block"/>your WebRTC voice integration</h1><p class="text-lg text-slate-600 sm:text-xl">Click the widget button at the bottom right to start a test call and try your AI Agent with native WebRTC voice.</p><div id="status" class="text-sm font-medium"></div></header><div class="flex-1"><div id="transcript-log" class="hidden max-h-[60vh] w-full overflow-y-auto rounded-xl border border-slate-200 bg-white/80 p-4 font-mono text-sm shadow-sm backdrop-blur md:max-h-[70vh]"><h3 class="mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400">Live Transcript</h3><div id="transcript-entries" class="space-y-2 pb-24"></div></div></div></section></main></div><script>localStorage.debug = 'moveo:webrtc:*';
16
16
 
17
17
  const statusNode = document.getElementById('status');
18
18
  const transcriptLog = document.getElementById('transcript-log');
@@ -28,6 +28,33 @@
28
28
  statusNode.textContent = message;
29
29
  };
30
30
 
31
+ const escapeHtml = (text) =>
32
+ String(text).replace(
33
+ /[&<>"']/g,
34
+ (char) =>
35
+ ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[char]
36
+ );
37
+
38
+ // Mirrors the widget caption pipeline (marked + DOMPurify) so a markdown
39
+ // link reads as a link here too. parseInline keeps the turn on one line.
40
+ const renderRich = (text) => {
41
+ if (!window.marked?.parseInline || !window.DOMPurify?.sanitize) {
42
+ return escapeHtml(text);
43
+ }
44
+ return window.DOMPurify.sanitize(
45
+ window.marked.parseInline(String(text), { gfm: true, breaks: true })
46
+ );
47
+ };
48
+
49
+ const setEntry = (entry, html) => {
50
+ entry.innerHTML = html;
51
+ entry.querySelectorAll('a').forEach((link) => {
52
+ link.target = '_blank';
53
+ link.rel = 'noopener noreferrer';
54
+ link.className = 'text-moveo-primary underline';
55
+ });
56
+ };
57
+
31
58
  const addTranscript = (speaker, text) => {
32
59
  if (!transcriptEntries || !transcriptLog) return;
33
60
  transcriptLog.classList.remove('hidden');
@@ -35,7 +62,10 @@
35
62
  const entry = document.createElement('div');
36
63
  const label = speaker === 'user' ? '🎤 You' : '🤖 Agent';
37
64
  const color = speaker === 'user' ? 'text-sky-600' : 'text-emerald-600';
38
- entry.innerHTML = `<span class="font-semibold ${color}">${label}:</span> ${text}`;
65
+ setEntry(
66
+ entry,
67
+ `<span class="font-semibold ${color}">${label}:</span> ${renderRich(text)}`
68
+ );
39
69
  transcriptEntries.appendChild(entry);
40
70
  transcriptLog.scrollTop = transcriptLog.scrollHeight;
41
71
  };
@@ -110,8 +140,10 @@
110
140
  transcriptEntries.appendChild(entry);
111
141
  brainEntries[reqId] = entry;
112
142
  }
113
- entry.innerHTML =
114
- `<span class="font-semibold text-emerald-600">🤖 Agent:</span> ${data.text}`;
143
+ setEntry(
144
+ entry,
145
+ `<span class="font-semibold text-emerald-600">🤖 Agent:</span> ${renderRich(data.text)}`
146
+ );
115
147
  transcriptLog.scrollTop = transcriptLog.scrollHeight;
116
148
  });
117
149
 
@@ -124,9 +156,13 @@
124
156
  if (!entry) return;
125
157
  const heard = ('heardText' in data && data.heardText) || '';
126
158
  const unheard = ('unheardText' in data && data.unheardText) || '';
127
- entry.innerHTML =
128
- `<span class="font-semibold text-emerald-600">🤖 Agent:</span> ${heard}` +
129
- (unheard ? ` <span class="text-slate-400 line-through">${unheard}</span>` : '');
159
+ setEntry(
160
+ entry,
161
+ `<span class="font-semibold text-emerald-600">🤖 Agent:</span> ${renderRich(heard)}` +
162
+ (unheard
163
+ ? ` <span class="text-slate-400 line-through">${renderRich(unheard)}</span>`
164
+ : '')
165
+ );
130
166
  transcriptLog.scrollTop = transcriptLog.scrollHeight;
131
167
  });
132
168
 
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  *
3
- * @moveo-ai/web-client v0.116.1
3
+ * @moveo-ai/web-client v0.117.0-true.1
4
4
  * Copyright (c) Moveo.ai (TM)
5
5
  *
6
6
  */