@burdenoff/website-sdk 2026.1104.2 → 2026.1104.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -494,6 +494,27 @@ publishes audio, video or data, and it sends the avatar nothing to say.
494
494
  chat started in the Avatar tab, provided it passes the speech checks, whether
495
495
  you chose a suggested question or typed your own", and the visitor is told
496
496
  not to put personal details in a typed question.
497
+ `web-consent-2026-11-12-b` (bot check `turnstile`, 1,010 bytes, SHA-256
498
+ `e8f4495d1e7f179b16de86c1eba0d2528623afb088f904f100e54523ad350c8c`) and
499
+ `web-consent-2026-11-13-b` (bot check `off`, 966 bytes, SHA-256
500
+ `4c88c229da1331ebe0f7e6e32f425612071efb2e4cf01ece813ed827ea8fc174`) are the
501
+ same two with only the timing sentence changed, for the server's Stage B
502
+ sessions of up to three minutes: "It reads for up to three minutes; if an
503
+ answer is longer, it reads the first part, says so, and the full answer stays
504
+ in Chat."
505
+ - **A part-read answer.** Where the server speaks only the first part of an
506
+ answer because the whole of it does not fit the session (the create
507
+ answer's `excerpt: true`, web API contract v1.4, only under the server's
508
+ `AVATAR_WEB_SIZE_BY_AUDIO`), the status line says "The avatar reads the
509
+ first part of this answer. The full answer is in Chat." (key `excerpt`) while
510
+ the avatar speaks, in place of "The avatar is speaking.". The layout is the
511
+ same. Without the field, or with any value but `true`, nothing changes.
512
+ - **Session length.** The countdown and the room's timers follow the server's
513
+ `endsAt` for each session, up to the availability answer's
514
+ `maxSessionSeconds` (three minutes under Stage B); an `endsAt` this
515
+ browser's clock cannot place within that is counted down from
516
+ `maxSessionSeconds` on the browser's own clock. Nothing in the view assumes a
517
+ minute.
497
518
  - **How a session ended.** When the worker leaves, the server closes the room,
498
519
  or the session's time runs out with the room still open, the view says only
499
520
  "The live avatar has ended." (key `finished`). The browser
@@ -121,7 +121,8 @@ function readCreated(body) {
121
121
  endSecret,
122
122
  endsAt,
123
123
  join: { livekitUrl, participantToken, workerIdentity },
124
- captions: { locale, text }
124
+ captions: { locale, text },
125
+ excerpt: body.excerpt === true
125
126
  }
126
127
  };
127
128
  }
@@ -294,6 +295,7 @@ var EN = {
294
295
  failed: "The live avatar couldn't start.",
295
296
  interrupted: "The live avatar stopped early.",
296
297
  answerInChat: "The full answer is in Chat.",
298
+ excerpt: "The avatar reads the first part of this answer. The full answer is in Chat.",
297
299
  backToChat: "Back to Chat",
298
300
  busy: "The live avatar is busy right now. Please try again in a few minutes.",
299
301
  limits: "The live avatar has reached its limit for now. Please try again later.",
@@ -351,6 +353,8 @@ var ZH = {
351
353
  failed: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u65E0\u6CD5\u542F\u52A8\u3002",
352
354
  interrupted: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u63D0\u524D\u505C\u6B62\u4E86\u3002",
353
355
  answerInChat: "\u5B8C\u6574\u56DE\u7B54\u5728\u804A\u5929\u4E2D\u3002",
356
+ // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
357
+ 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",
354
358
  backToChat: "\u8FD4\u56DE\u804A\u5929",
355
359
  busy: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u76EE\u524D\u7E41\u5FD9\uFF0C\u8BF7\u51E0\u5206\u949F\u540E\u518D\u8BD5\u3002",
356
360
  limits: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u6682\u65F6\u5DF2\u8FBE\u5230\u4F7F\u7528\u4E0A\u9650\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",
@@ -410,6 +414,8 @@ var HI = {
410
414
  failed: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u0936\u0941\u0930\u0942 \u0928\u0939\u0940\u0902 \u0939\u094B \u0938\u0915\u093E\u0964",
411
415
  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",
412
416
  answerInChat: "\u092A\u0942\u0930\u093E \u0909\u0924\u094D\u0924\u0930 \u091A\u0948\u091F \u092E\u0947\u0902 \u0939\u0948\u0964",
417
+ // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
418
+ 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",
413
419
  backToChat: "\u091A\u0948\u091F \u092A\u0930 \u0935\u093E\u092A\u0938 \u091C\u093E\u090F\u0901",
414
420
  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",
415
421
  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",
@@ -469,6 +475,8 @@ var ES = {
469
475
  failed: "No se pudo iniciar el avatar en vivo.",
470
476
  interrupted: "El avatar en vivo se detuvo antes de tiempo.",
471
477
  answerInChat: "La respuesta completa est\xE1 en el chat.",
478
+ // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
479
+ excerpt: "El avatar lee la primera parte de esta respuesta. La respuesta completa est\xE1 en el chat.",
472
480
  backToChat: "Volver al chat",
473
481
  busy: "El avatar en vivo est\xE1 ocupado en este momento. Vuelve a intentarlo en unos minutos.",
474
482
  limits: "El avatar en vivo ha alcanzado su l\xEDmite por ahora. Vuelve a intentarlo m\xE1s tarde.",
@@ -528,6 +536,8 @@ var AR = {
528
536
  failed: "\u062A\u0639\u0630\u0651\u0631 \u0628\u062F\u0621 \u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631.",
529
537
  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.",
530
538
  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.",
539
+ // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
540
+ 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.",
531
541
  backToChat: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u062F\u0631\u062F\u0634\u0629",
532
542
  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.",
533
543
  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.",
@@ -587,6 +597,8 @@ var TA = {
587
597
  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.",
588
598
  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.",
589
599
  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.",
600
+ // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).
601
+ 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.",
590
602
  backToChat: "\u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC1\u0BAE\u0BCD\u0BAA\u0BC1",
591
603
  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.",
592
604
  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.",
@@ -734,6 +746,42 @@ var CONSENT = /* @__PURE__ */ new Map([
734
746
  questions: "any"
735
747
  }
736
748
  }
749
+ ],
750
+ [
751
+ // Stage B (operator decision 2026-11-04): web-consent-2026-11-05 with only its timing sentence changed. A session
752
+ // lasts up to three minutes, sized by the server to the answer's audio; an answer longer than that is read in part,
753
+ // which the avatar says and the Avatar tab notes (`excerpt`), and the full answer stays in Chat. A cap still
754
+ // applies, so the words never say every answer is read whole (gitops docs/avatar-web/en-web-consent-2026-11-12-b.txt).
755
+ "web-consent-2026-11-12-b",
756
+ {
757
+ en: {
758
+ title: "Live AI avatar (beta)",
759
+ introProduct: null,
760
+ 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.",
761
+ 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.",
762
+ 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.",
763
+ privacyLink: "How we handle this",
764
+ botCheck: "turnstile",
765
+ questions: "any"
766
+ }
767
+ }
768
+ ],
769
+ [
770
+ // The words of web-consent-2026-11-12-b without "When you start, Cloudflare checks for bots.", for a server that runs
771
+ // no bot check (gitops docs/avatar-web/en-web-consent-2026-11-13-b.txt).
772
+ "web-consent-2026-11-13-b",
773
+ {
774
+ en: {
775
+ title: "Live AI avatar (beta)",
776
+ introProduct: null,
777
+ 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.",
778
+ 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.",
779
+ 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.",
780
+ privacyLink: "How we handle this",
781
+ botCheck: "off",
782
+ questions: "any"
783
+ }
784
+ }
737
785
  ]
738
786
  ]);
739
787
  function avatarConsentCopy(version, locale) {
@@ -1303,7 +1351,11 @@ function AvatarLiveView({
1303
1351
  setNow(received);
1304
1352
  go({
1305
1353
  name: "pending",
1306
- session: { endsAt, captions: session.captions }
1354
+ session: {
1355
+ endsAt,
1356
+ captions: session.captions,
1357
+ excerpt: session.excerpt
1358
+ }
1307
1359
  });
1308
1360
  },
1309
1361
  [go]
@@ -2125,6 +2177,7 @@ function AvatarLiveView({
2125
2177
  ]
2126
2178
  }
2127
2179
  );
2180
+ const speakingLine = (session) => session.excerpt ? S.excerpt : S.speaking;
2128
2181
  const liveBody = (session) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2129
2182
  /* @__PURE__ */ jsxRuntime.jsx(
2130
2183
  "section",
@@ -2338,7 +2391,7 @@ function AvatarLiveView({
2338
2391
  break;
2339
2392
  case "pending":
2340
2393
  case "live":
2341
- status = phase.name === "live" ? S.speaking : S.connecting;
2394
+ status = phase.name === "live" ? speakingLine(phase.session) : S.connecting;
2342
2395
  top2 = badge;
2343
2396
  media2 = liveMedia(phase.name === "live");
2344
2397
  body2 = liveBody(phase.session);
@@ -2464,7 +2517,7 @@ function AvatarLiveView({
2464
2517
  "bot-check": S.botCheck,
2465
2518
  creating: S.connecting,
2466
2519
  pending: S.connecting,
2467
- live: S.speaking,
2520
+ live: phase.name === "live" ? speakingLine(phase.session) : "",
2468
2521
  ended: phase.name === "ended" ? S[phase.how] : ""
2469
2522
  };
2470
2523
  const outcome = phase.name === "needs-answer" || phase.name === "refused" || phase.name === "ended";