@burdenoff/website-sdk 2026.1104.2 → 2026.1104.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -4
- package/dist/avatar-live-view/index.js +124 -46
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +123 -45
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/{chunk-5JQGE3XI.mjs → chunk-7HE33NBS.mjs} +4 -111
- package/dist/chunk-7HE33NBS.mjs.map +1 -0
- package/dist/chunk-JZS6FQT6.mjs +127 -0
- package/dist/chunk-JZS6FQT6.mjs.map +1 -0
- package/dist/{chunk-22OT6E26.js → chunk-MBVXDFVC.js} +18 -127
- package/dist/chunk-MBVXDFVC.js.map +1 -0
- package/dist/chunk-N7E6Z2GF.js +132 -0
- package/dist/chunk-N7E6Z2GF.js.map +1 -0
- package/dist/components/explore.d.mts +1 -1
- package/dist/components/explore.d.ts +1 -1
- package/dist/components/explore.js +20 -20
- package/dist/components/explore.mjs +2 -2
- package/dist/{explore-BV4dRwoC.d.ts → explore-Dfru4j4m.d.ts} +45 -31
- package/dist/{explore-BgEeGPvY.d.mts → explore-ei8uoko9.d.mts} +45 -31
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +61 -61
- package/dist/index.mjs +4 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-22OT6E26.js.map +0 -1
- package/dist/chunk-5JQGE3XI.mjs.map +0 -1
- package/dist/chunk-O4GS3XPZ.js +0 -10
- package/dist/chunk-O4GS3XPZ.js.map +0 -1
- package/dist/chunk-TT3MHN42.mjs +0 -8
- package/dist/chunk-TT3MHN42.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { turnstileSiteKeyOf, isAvatarLiveLocaleReviewed, isAvatarSite, isAvatarVersion } from '../chunk-7MSB3EUI.mjs';
|
|
2
|
-
import { fill } from '../chunk-
|
|
2
|
+
import { answerDisplayText, fill } from '../chunk-JZS6FQT6.mjs';
|
|
3
3
|
import { cn } from '../chunk-R7G6TWIS.mjs';
|
|
4
4
|
import '../chunk-VNS5WDWO.mjs';
|
|
5
5
|
import { useId, useState, useRef, useCallback, useEffect } from 'react';
|
|
@@ -119,7 +119,8 @@ function readCreated(body) {
|
|
|
119
119
|
endSecret,
|
|
120
120
|
endsAt,
|
|
121
121
|
join: { livekitUrl, participantToken, workerIdentity },
|
|
122
|
-
captions: { locale, text }
|
|
122
|
+
captions: { locale, text },
|
|
123
|
+
excerpt: body.excerpt === true
|
|
123
124
|
}
|
|
124
125
|
};
|
|
125
126
|
}
|
|
@@ -179,7 +180,7 @@ async function requestAvailability(target) {
|
|
|
179
180
|
timer.done();
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
|
-
|
|
183
|
+
function requestCreate(target) {
|
|
183
184
|
const { body } = target;
|
|
184
185
|
const payload = JSON.stringify({
|
|
185
186
|
site: body.site,
|
|
@@ -189,27 +190,45 @@ async function requestCreate(target) {
|
|
|
189
190
|
consentVersion: body.consentVersion,
|
|
190
191
|
manifestVersion: body.manifestVersion
|
|
191
192
|
});
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
193
|
+
const controller = new AbortController();
|
|
194
|
+
let answered = false;
|
|
195
|
+
const answer = (async () => {
|
|
196
|
+
try {
|
|
197
|
+
const response = await fetch(`${target.base}/sessions`, {
|
|
198
|
+
method: "POST",
|
|
199
|
+
credentials: "omit",
|
|
200
|
+
cache: "no-store",
|
|
201
|
+
headers: {
|
|
202
|
+
...target.headers,
|
|
203
|
+
"Content-Type": "application/json",
|
|
204
|
+
"Idempotency-Key": target.idempotencyKey,
|
|
205
|
+
...target.botToken === void 0 ? {} : { "x-web-avatar-bot-token": target.botToken }
|
|
206
|
+
},
|
|
207
|
+
body: payload,
|
|
208
|
+
signal: controller.signal
|
|
209
|
+
});
|
|
210
|
+
answered = true;
|
|
211
|
+
return readCreate(response.status, await readJson(response));
|
|
212
|
+
} catch {
|
|
213
|
+
return FAILED;
|
|
214
|
+
}
|
|
215
|
+
})();
|
|
216
|
+
return new Promise((resolve) => {
|
|
217
|
+
let late = false;
|
|
218
|
+
const timer = setTimeout(() => {
|
|
219
|
+
late = true;
|
|
220
|
+
if (!answered) controller.abort();
|
|
221
|
+
resolve(FAILED);
|
|
222
|
+
}, CREATE_TIMEOUT_MS);
|
|
223
|
+
void answer.then((result) => {
|
|
224
|
+
if (late) {
|
|
225
|
+
target.onLate?.(result);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
resolve(result);
|
|
206
230
|
});
|
|
207
|
-
|
|
208
|
-
} catch {
|
|
209
|
-
return INERT;
|
|
210
|
-
} finally {
|
|
211
|
-
timer.done();
|
|
212
|
-
}
|
|
231
|
+
});
|
|
213
232
|
}
|
|
214
233
|
function sendEnd(target) {
|
|
215
234
|
try {
|
|
@@ -292,6 +311,7 @@ var EN = {
|
|
|
292
311
|
failed: "The live avatar couldn't start.",
|
|
293
312
|
interrupted: "The live avatar stopped early.",
|
|
294
313
|
answerInChat: "The full answer is in Chat.",
|
|
314
|
+
excerpt: "The avatar reads the first part of this answer. The full answer is in Chat.",
|
|
295
315
|
backToChat: "Back to Chat",
|
|
296
316
|
busy: "The live avatar is busy right now. Please try again in a few minutes.",
|
|
297
317
|
limits: "The live avatar has reached its limit for now. Please try again later.",
|
|
@@ -349,6 +369,8 @@ var ZH = {
|
|
|
349
369
|
failed: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u65E0\u6CD5\u542F\u52A8\u3002",
|
|
350
370
|
interrupted: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u63D0\u524D\u505C\u6B62\u4E86\u3002",
|
|
351
371
|
answerInChat: "\u5B8C\u6574\u56DE\u7B54\u5728\u804A\u5929\u4E2D\u3002",
|
|
372
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
|
|
373
|
+
excerpt: "\u865A\u62DF\u5F62\u8C61\u6717\u8BFB\u8FD9\u4E2A\u56DE\u7B54\u7684\u7B2C\u4E00\u90E8\u5206\u3002\u5B8C\u6574\u56DE\u7B54\u5728\u804A\u5929\u4E2D\u3002",
|
|
352
374
|
backToChat: "\u8FD4\u56DE\u804A\u5929",
|
|
353
375
|
busy: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u76EE\u524D\u7E41\u5FD9\uFF0C\u8BF7\u51E0\u5206\u949F\u540E\u518D\u8BD5\u3002",
|
|
354
376
|
limits: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u6682\u65F6\u5DF2\u8FBE\u5230\u4F7F\u7528\u4E0A\u9650\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",
|
|
@@ -408,6 +430,8 @@ var HI = {
|
|
|
408
430
|
failed: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0936\u0941\u0930\u0942 \u0928\u0939\u0940\u0902 \u0939\u094B \u0938\u0915\u093E\u0964",
|
|
409
431
|
interrupted: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u092C\u0940\u091A \u092E\u0947\u0902 \u0939\u0940 \u0930\u0941\u0915 \u0917\u092F\u093E\u0964",
|
|
410
432
|
answerInChat: "\u092A\u0942\u0930\u093E \u0909\u0924\u094D\u0924\u0930 \u091A\u0948\u091F \u092E\u0947\u0902 \u0939\u0948\u0964",
|
|
433
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
|
|
434
|
+
excerpt: "\u0905\u0935\u0924\u093E\u0930 \u0907\u0938 \u0909\u0924\u094D\u0924\u0930 \u0915\u093E \u092A\u0939\u0932\u093E \u092D\u093E\u0917 \u092A\u0922\u093C\u0924\u093E \u0939\u0948\u0964 \u092A\u0942\u0930\u093E \u0909\u0924\u094D\u0924\u0930 \u091A\u0948\u091F \u092E\u0947\u0902 \u0939\u0948\u0964",
|
|
411
435
|
backToChat: "\u091A\u0948\u091F \u092A\u0930 \u0935\u093E\u092A\u0938 \u091C\u093E\u090F\u0901",
|
|
412
436
|
busy: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0905\u092D\u0940 \u0935\u094D\u092F\u0938\u094D\u0924 \u0939\u0948\u0964 \u0915\u0943\u092A\u092F\u093E \u0915\u0941\u091B \u092E\u093F\u0928\u091F \u092C\u093E\u0926 \u092B\u093F\u0930 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0947\u0902\u0964",
|
|
413
437
|
limits: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0905\u092D\u0940 \u0905\u092A\u0928\u0940 \u0938\u0940\u092E\u093E \u0924\u0915 \u092A\u0939\u0941\u0901\u091A \u0917\u092F\u093E \u0939\u0948\u0964 \u0915\u0943\u092A\u092F\u093E \u092C\u093E\u0926 \u092E\u0947\u0902 \u092B\u093F\u0930 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0947\u0902\u0964",
|
|
@@ -467,6 +491,8 @@ var ES = {
|
|
|
467
491
|
failed: "No se pudo iniciar el avatar en vivo.",
|
|
468
492
|
interrupted: "El avatar en vivo se detuvo antes de tiempo.",
|
|
469
493
|
answerInChat: "La respuesta completa est\xE1 en el chat.",
|
|
494
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
|
|
495
|
+
excerpt: "El avatar lee la primera parte de esta respuesta. La respuesta completa est\xE1 en el chat.",
|
|
470
496
|
backToChat: "Volver al chat",
|
|
471
497
|
busy: "El avatar en vivo est\xE1 ocupado en este momento. Vuelve a intentarlo en unos minutos.",
|
|
472
498
|
limits: "El avatar en vivo ha alcanzado su l\xEDmite por ahora. Vuelve a intentarlo m\xE1s tarde.",
|
|
@@ -526,6 +552,8 @@ var AR = {
|
|
|
526
552
|
failed: "\u062A\u0639\u0630\u0651\u0631 \u0628\u062F\u0621 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631.",
|
|
527
553
|
interrupted: "\u062A\u0648\u0642\u0641 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u0642\u0628\u0644 \u0623\u0646 \u064A\u0646\u062A\u0647\u064A.",
|
|
528
554
|
answerInChat: "\u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0643\u0627\u0645\u0644\u0629 \u0645\u0648\u062C\u0648\u062F\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629.",
|
|
555
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
|
|
556
|
+
excerpt: "\u064A\u0642\u0631\u0623 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u062C\u0632\u0621 \u0627\u0644\u0623\u0648\u0644 \u0645\u0646 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629. \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0643\u0627\u0645\u0644\u0629 \u0645\u0648\u062C\u0648\u062F\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629.",
|
|
529
557
|
backToChat: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u062F\u0631\u062F\u0634\u0629",
|
|
530
558
|
busy: "\u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u0645\u0634\u063A\u0648\u0644 \u0627\u0644\u0622\u0646. \u064A\u064F\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649 \u0628\u0639\u062F \u0628\u0636\u0639 \u062F\u0642\u0627\u0626\u0642.",
|
|
531
559
|
limits: "\u0628\u0644\u063A \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u062D\u062F\u0651\u0647 \u0641\u064A \u0627\u0644\u0648\u0642\u062A \u0627\u0644\u062D\u0627\u0644\u064A. \u064A\u064F\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0644\u0627\u062D\u0642\u064B\u0627.",
|
|
@@ -585,6 +613,8 @@ var TA = {
|
|
|
585
613
|
failed: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
|
|
586
614
|
interrupted: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B87\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BC7\u0BAF\u0BC7 \u0BA8\u0BBF\u0BA9\u0BCD\u0BB1\u0BC1\u0BB5\u0BBF\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
|
|
587
615
|
answerInChat: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
|
|
616
|
+
// TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
|
|
617
|
+
excerpt: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BBF\u0BA9\u0BCD \u0BAE\u0BC1\u0BA4\u0BB2\u0BCD \u0BAA\u0B95\u0BC1\u0BA4\u0BBF\u0BAF\u0BC8\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF\u0B95\u0BCD\u0B95\u0BBF\u0BB1\u0BA4\u0BC1. \u0BAE\u0BC1\u0BB4\u0BC1\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
|
|
588
618
|
backToChat: "\u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC1\u0BAE\u0BCD\u0BAA\u0BC1",
|
|
589
619
|
busy: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0B87\u0BAA\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0BB5\u0BC7\u0BB1\u0BC1 \u0BAA\u0BAF\u0BA9\u0BCD\u0BAA\u0BBE\u0B9F\u0BCD\u0B9F\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1. \u0B9A\u0BBF\u0BB2 \u0BA8\u0BBF\u0BAE\u0BBF\u0B9F\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0BAF\u0BB2\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
590
620
|
limits: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BA4\u0BB1\u0BCD\u0BAA\u0BCB\u0BA4\u0BC8\u0B95\u0BCD\u0B95\u0BC1\u0BA4\u0BCD \u0BA4\u0BA9\u0BCD \u0BB5\u0BB0\u0BAE\u0BCD\u0BAA\u0BC8 \u0B8E\u0B9F\u0BCD\u0B9F\u0BBF\u0BB5\u0BBF\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1. \u0BAA\u0BBF\u0BB1\u0B95\u0BC1 \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0BAF\u0BB2\u0BB5\u0BC1\u0BAE\u0BCD.",
|
|
@@ -732,6 +762,42 @@ var CONSENT = /* @__PURE__ */ new Map([
|
|
|
732
762
|
questions: "any"
|
|
733
763
|
}
|
|
734
764
|
}
|
|
765
|
+
],
|
|
766
|
+
[
|
|
767
|
+
// Stage B (operator decision 2026-11-04): web-consent-2026-11-05 with only its timing sentence changed. A session
|
|
768
|
+
// lasts up to three minutes, sized by the server to the answer's audio; an answer longer than that is read in part,
|
|
769
|
+
// which the avatar says and the Avatar tab notes (`excerpt`), and the full answer stays in Chat. A cap still
|
|
770
|
+
// applies, so the words never say every answer is read whole (gitops docs/avatar-web/en-web-consent-2026-11-12-b.txt).
|
|
771
|
+
"web-consent-2026-11-12-b",
|
|
772
|
+
{
|
|
773
|
+
en: {
|
|
774
|
+
title: "Live AI avatar (beta)",
|
|
775
|
+
introProduct: null,
|
|
776
|
+
intro: "This is an AI avatar, not a real person. It reads aloud the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. It reads for up to three minutes; if an answer is longer, it reads the first part, says so, and the full answer stays in Chat. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.",
|
|
777
|
+
processing: "When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
778
|
+
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
779
|
+
privacyLink: "How we handle this",
|
|
780
|
+
botCheck: "turnstile",
|
|
781
|
+
questions: "any"
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
],
|
|
785
|
+
[
|
|
786
|
+
// The words of web-consent-2026-11-12-b without "When you start, Cloudflare checks for bots.", for a server that runs
|
|
787
|
+
// no bot check (gitops docs/avatar-web/en-web-consent-2026-11-13-b.txt).
|
|
788
|
+
"web-consent-2026-11-13-b",
|
|
789
|
+
{
|
|
790
|
+
en: {
|
|
791
|
+
title: "Live AI avatar (beta)",
|
|
792
|
+
introProduct: null,
|
|
793
|
+
intro: "This is an AI avatar, not a real person. It reads aloud the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. It reads for up to three minutes; if an answer is longer, it reads the first part, says so, and the full answer stays in Chat. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.",
|
|
794
|
+
processing: "The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.",
|
|
795
|
+
storage: "Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.",
|
|
796
|
+
privacyLink: "How we handle this",
|
|
797
|
+
botCheck: "off",
|
|
798
|
+
questions: "any"
|
|
799
|
+
}
|
|
800
|
+
}
|
|
735
801
|
]
|
|
736
802
|
]);
|
|
737
803
|
function avatarConsentCopy(version, locale) {
|
|
@@ -1301,27 +1367,31 @@ function AvatarLiveView({
|
|
|
1301
1367
|
setNow(received);
|
|
1302
1368
|
go({
|
|
1303
1369
|
name: "pending",
|
|
1304
|
-
session: {
|
|
1370
|
+
session: {
|
|
1371
|
+
endsAt,
|
|
1372
|
+
captions: session.captions,
|
|
1373
|
+
excerpt: session.excerpt
|
|
1374
|
+
}
|
|
1305
1375
|
});
|
|
1306
1376
|
},
|
|
1307
1377
|
[go]
|
|
1308
1378
|
);
|
|
1309
1379
|
const settle = useCallback(
|
|
1310
|
-
(result,
|
|
1380
|
+
(result, givenUp, context) => {
|
|
1311
1381
|
const created = result.kind === "created" ? {
|
|
1312
1382
|
sessionId: result.session.sessionId,
|
|
1313
1383
|
secret: result.session.endSecret
|
|
1314
1384
|
} : result.kind === "unusable" ? { sessionId: result.sessionId, secret: result.endSecret } : null;
|
|
1315
1385
|
const claimed = created !== null || result.kind === "refused" && result.reason === "answer_claimed";
|
|
1316
1386
|
if (claimed) claimedRef.current.add(context.messageId);
|
|
1317
|
-
if (
|
|
1387
|
+
if (givenUp !== null) {
|
|
1318
1388
|
if (created !== null) {
|
|
1319
1389
|
sendEnd({
|
|
1320
1390
|
base: context.base,
|
|
1321
1391
|
headers: context.headers,
|
|
1322
1392
|
sessionId: created.sessionId,
|
|
1323
1393
|
secret: created.secret,
|
|
1324
|
-
reason:
|
|
1394
|
+
reason: givenUp
|
|
1325
1395
|
});
|
|
1326
1396
|
}
|
|
1327
1397
|
const shown2 = phaseRef.current;
|
|
@@ -1430,21 +1500,21 @@ function AvatarLiveView({
|
|
|
1430
1500
|
return;
|
|
1431
1501
|
}
|
|
1432
1502
|
if (turnstile !== null) go({ name: "creating" });
|
|
1503
|
+
const context = { module: loaded, offer, messageId, base: base2, headers: headers2 };
|
|
1433
1504
|
const result = await requestCreate({
|
|
1434
1505
|
base: base2,
|
|
1435
1506
|
headers: headers2,
|
|
1436
1507
|
idempotencyKey,
|
|
1437
1508
|
botToken,
|
|
1438
|
-
body: body2
|
|
1509
|
+
body: body2,
|
|
1510
|
+
// An answer past the deadline, after the view has said the live avatar couldn't start: a session it made is
|
|
1511
|
+
// ended at once with its own secret, and never joined. The reason is the visitor's own where they gave the
|
|
1512
|
+
// start up first, else `client_error`. It reads `run` and never writes it, so the deadline's `failed` below is
|
|
1513
|
+
// shown whichever of the two is handled first.
|
|
1514
|
+
onLate: (late) => settle(late, run.cancelled ?? "client_error", context)
|
|
1439
1515
|
});
|
|
1440
1516
|
if (startRef.current === run) startRef.current = null;
|
|
1441
|
-
settle(result, run,
|
|
1442
|
-
module: loaded,
|
|
1443
|
-
offer,
|
|
1444
|
-
messageId,
|
|
1445
|
-
base: base2,
|
|
1446
|
-
headers: headers2
|
|
1447
|
-
});
|
|
1517
|
+
settle(result, run.cancelled, context);
|
|
1448
1518
|
})();
|
|
1449
1519
|
},
|
|
1450
1520
|
[exchangeNow, go, reoffer, settle]
|
|
@@ -2123,6 +2193,7 @@ function AvatarLiveView({
|
|
|
2123
2193
|
]
|
|
2124
2194
|
}
|
|
2125
2195
|
);
|
|
2196
|
+
const speakingLine = (session) => session.excerpt ? S.excerpt : S.speaking;
|
|
2126
2197
|
const liveBody = (session) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2127
2198
|
/* @__PURE__ */ jsx(
|
|
2128
2199
|
"section",
|
|
@@ -2222,14 +2293,21 @@ function AvatarLiveView({
|
|
|
2222
2293
|
children: lastQuestion.content
|
|
2223
2294
|
}
|
|
2224
2295
|
),
|
|
2225
|
-
lastAnswer === void 0 ? unanswered === "waiting" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : unanswered === "failed" ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) : null : lastAnswer.status === "PENDING" || lastAnswer.status === "RUNNING" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : lastAnswer.status === "FAILED" ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) :
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2296
|
+
lastAnswer === void 0 ? unanswered === "waiting" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : unanswered === "failed" ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) : null : lastAnswer.status === "PENDING" || lastAnswer.status === "RUNNING" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: activity ?? S.gettingAnswer }) : lastAnswer.status === "FAILED" ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: S.answerFailed }) : (
|
|
2297
|
+
// The answer's words, not its markdown: `content` is written for the chat's renderer, and shown as it is
|
|
2298
|
+
// here a link reads `[label](https://…)`. In its spoken form, as the chat's read-aloud says it: a link is its
|
|
2299
|
+
// label (the address is in Chat, one tap away), a table its rows, and the markers of emphasis, headings,
|
|
2300
|
+
// quotes and list items go (`answerDisplayText`). The words are the ones the chat shows, citation markers
|
|
2301
|
+
// included, which the sources in Chat answer to.
|
|
2302
|
+
/* @__PURE__ */ jsx(
|
|
2303
|
+
"p",
|
|
2304
|
+
{
|
|
2305
|
+
"data-boff-explore": "avatar-live-text-answer",
|
|
2306
|
+
dir: "auto",
|
|
2307
|
+
className: "line-clamp-6 w-full max-w-sm whitespace-pre-wrap break-words text-start text-sm",
|
|
2308
|
+
children: answerDisplayText(lastAnswer.content)
|
|
2309
|
+
}
|
|
2310
|
+
)
|
|
2233
2311
|
)
|
|
2234
2312
|
] });
|
|
2235
2313
|
const ended = phase.name === "ended";
|
|
@@ -2336,7 +2414,7 @@ function AvatarLiveView({
|
|
|
2336
2414
|
break;
|
|
2337
2415
|
case "pending":
|
|
2338
2416
|
case "live":
|
|
2339
|
-
status = phase.name === "live" ?
|
|
2417
|
+
status = phase.name === "live" ? speakingLine(phase.session) : S.connecting;
|
|
2340
2418
|
top2 = badge;
|
|
2341
2419
|
media2 = liveMedia(phase.name === "live");
|
|
2342
2420
|
body2 = liveBody(phase.session);
|
|
@@ -2462,7 +2540,7 @@ function AvatarLiveView({
|
|
|
2462
2540
|
"bot-check": S.botCheck,
|
|
2463
2541
|
creating: S.connecting,
|
|
2464
2542
|
pending: S.connecting,
|
|
2465
|
-
live:
|
|
2543
|
+
live: phase.name === "live" ? speakingLine(phase.session) : "",
|
|
2466
2544
|
ended: phase.name === "ended" ? S[phase.how] : ""
|
|
2467
2545
|
};
|
|
2468
2546
|
const outcome = phase.name === "needs-answer" || phase.name === "refused" || phase.name === "ended";
|