@burdenoff/website-sdk 2026.1102.2 → 2026.1104.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +63 -8
  2. package/dist/avatar-live-view/index.d.mts +29 -5
  3. package/dist/avatar-live-view/index.d.ts +29 -5
  4. package/dist/avatar-live-view/index.js +1319 -271
  5. package/dist/avatar-live-view/index.js.map +1 -1
  6. package/dist/avatar-live-view/index.mjs +1317 -269
  7. package/dist/avatar-live-view/index.mjs.map +1 -1
  8. package/dist/{chunk-R742FS5E.js → chunk-22OT6E26.js} +61 -27
  9. package/dist/chunk-22OT6E26.js.map +1 -0
  10. package/dist/{chunk-ETI2HQEC.mjs → chunk-5JQGE3XI.mjs} +46 -14
  11. package/dist/chunk-5JQGE3XI.mjs.map +1 -0
  12. package/dist/{chunk-FQH3AJN3.js → chunk-7O2I32ZN.js} +2 -2
  13. package/dist/chunk-7O2I32ZN.js.map +1 -0
  14. package/dist/{chunk-SFT3WHN5.mjs → chunk-K3QZGJEH.mjs} +2 -2
  15. package/dist/chunk-K3QZGJEH.mjs.map +1 -0
  16. package/dist/{chunk-SK5UGG6A.js → chunk-P5GMVPR6.js} +76 -20
  17. package/dist/chunk-P5GMVPR6.js.map +1 -0
  18. package/dist/{chunk-EUPFS6MZ.mjs → chunk-SMD7MEEA.mjs} +76 -20
  19. package/dist/chunk-SMD7MEEA.mjs.map +1 -0
  20. package/dist/components/explore.d.mts +2 -2
  21. package/dist/components/explore.d.ts +2 -2
  22. package/dist/components/explore.js +14 -14
  23. package/dist/components/explore.mjs +2 -2
  24. package/dist/{explore-DUTNYUOm.d.mts → explore-BV4dRwoC.d.ts} +8 -1
  25. package/dist/{explore-DjQE7Xia.d.ts → explore-BgEeGPvY.d.mts} +8 -1
  26. package/dist/{explore-avatar-live-config-Cetx8-Zu.d.ts → explore-avatar-live-config-CAfN5eAX.d.ts} +6 -3
  27. package/dist/{explore-avatar-live-config-Bp3kQbU2.d.mts → explore-avatar-live-config-N4WhJzgS.d.mts} +6 -3
  28. package/dist/{explore-types-Bb2Ih3d8.d.mts → explore-types-Ol1Mm3dW.d.mts} +12 -1
  29. package/dist/{explore-types-Bb2Ih3d8.d.ts → explore-types-Ol1Mm3dW.d.ts} +12 -1
  30. package/dist/hooks/index.d.mts +2 -2
  31. package/dist/hooks/index.d.ts +2 -2
  32. package/dist/hooks/index.js +9 -9
  33. package/dist/hooks/index.mjs +1 -1
  34. package/dist/index.d.mts +14 -8
  35. package/dist/index.d.ts +14 -8
  36. package/dist/index.js +100 -63
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +43 -6
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/{use-explore-chat-DunjG-3p.d.ts → use-explore-chat-B3dOOvJN.d.ts} +43 -3
  41. package/dist/{use-explore-chat-zRuoAin6.d.mts → use-explore-chat-CbfohA9O.d.mts} +43 -3
  42. package/package.json +1 -1
  43. package/dist/chunk-ETI2HQEC.mjs.map +0 -1
  44. package/dist/chunk-EUPFS6MZ.mjs.map +0 -1
  45. package/dist/chunk-FQH3AJN3.js.map +0 -1
  46. package/dist/chunk-R742FS5E.js.map +0 -1
  47. package/dist/chunk-SFT3WHN5.mjs.map +0 -1
  48. package/dist/chunk-SK5UGG6A.js.map +0 -1
package/README.md CHANGED
@@ -320,7 +320,7 @@ publishes audio, video or data, and it sends the avatar nothing to say.
320
320
  what the Avatar view shows until it arrives (the same picture, and the same
321
321
  bytes in a server render or a prerendered page, as before). A site that never
322
322
  passes `avatar.live` never downloads it: its bundle grows by under a kilobyte
323
- gzipped, instead of the roughly twelve the view weighs. Your bundler needs
323
+ gzipped, instead of the roughly twenty-five the view weighs. Your bundler needs
324
324
  to split dynamic imports, as Vite, webpack and Rollup do. If the file cannot
325
325
  be fetched (offline, or a deploy has replaced it), or has not arrived after
326
326
  eight seconds, the Avatar view shows what it showed before the live avatar,
@@ -358,6 +358,36 @@ publishes audio, video or data, and it sends the avatar nothing to say.
358
358
  turning the bot check on or off is a server config change: a site needs no
359
359
  new build for it, as long as its build carries a site key for `turnstile` and
360
360
  its CSP allows Cloudflare (below).
361
+ - **The Avatar tab's own question box (web API contract v1.3, additive).** The
362
+ availability answer's `questions` says which first questions the server
363
+ reads the answer to: `"suggested"` (only the exact suggested questions, as
364
+ before) or `"any"` (a question the visitor typed too). A server older than
365
+ v1.3 sends none and is read as `suggested`; an unknown value leaves the view
366
+ as it was. Under `any`, and only with consent copy written for it (below),
367
+ the Avatar tab has a box of its own ("Ask the avatar…", at most 300
368
+ characters, text only, Enter to ask) and the panel's suggested questions as
369
+ chips. A question asked there is the first of a new chat, sent with
370
+ `surface: "AVATAR"` (the chat's own composer never sends a surface), and its
371
+ first answer is the only one the card is offered for: the card shows while
372
+ the answer is written, with **Start when ready**. That press is bound to this
373
+ conversation, its question and the answer on its way, the site, the locale,
374
+ the page and the consent version and bot check; any of them changing, Cancel,
375
+ leaving the tab, closing the panel or hiding the page calls it off with
376
+ nothing created. Once the answer is ready the view asks availability again
377
+ and checks the answer as the service will (an answer, one to sixty-four
378
+ references, no files, under fourteen minutes old), and creates the session
379
+ only if nothing differs; otherwise it shows the card for what is offered now.
380
+ A create is never sent again by itself. A conversation that is not a new
381
+ chat started in the tab (a question asked in Chat, a second question, an
382
+ answer too old) is never read and never reset by the tab: it offers **New
383
+ chat for the avatar** ("Your current chat stays in History."), and the box
384
+ appears after that tap. After the day's session (a `limits` refusal, or this
385
+ browser's own note of a session today, kept in `localStorage` as
386
+ `boff.explore.avatarUsedOn`), the box asks ordinary questions, without
387
+ `surface`, and the answer shows in the tab as text, with "Read the answer and
388
+ sources in Chat". Pass `currentPath` to `ExplorePanel` (as
389
+ `SiteAssistantDock` does) so a page change calls off a "Start when ready"
390
+ at once; without it, the window's path is checked before the create.
361
391
  - **One answer: the first, to a suggested question.** The avatar service
362
392
  accepts a conversation only when it holds exactly two messages: the first user
363
393
  message (a suggested question) and the first assistant answer, completed. The
@@ -390,10 +420,24 @@ publishes audio, video or data, and it sends the avatar nothing to say.
390
420
  limits, region, language, paused, a question the avatar cannot read) is one
391
421
  short sentence and "Continue in Chat". A network or CORS failure, or a route
392
422
  that is not there, shows the view as it was before.
393
- - **Ending.** Stop, switching to Chat, closing the panel, hiding the page, and
394
- the live avatar going off under a session (the panel's locale changing to one
423
+ - **Ending.** Stop, closing the panel, leaving the page (`pagehide`), and the
424
+ live avatar going off under a session (the panel's locale changing to one
395
425
  whose strings have not been reviewed) all end the session with a `keepalive`
396
- request and leave the room. The end is a simple CORS request: its body is a
426
+ request and leave the room. Once the create has been sent (connecting,
427
+ joining, speaking), switching to the Chat tab (or pressing Continue in Chat)
428
+ and hiding the page (another browser tab, another app) do **not** end it: the
429
+ Avatar pane is only hidden, the room's video and audio stay attached, and the
430
+ avatar speaks to the end the server planned for it, which a hidden page
431
+ cannot extend. Coming back to the Avatar tab shows the session as it is, with
432
+ the countdown to the server's end, and asks nothing again. Before the create,
433
+ nothing paid exists, so the Chat tab still calls off an availability check, a
434
+ "Start when ready" and a bot check, and a hidden page still calls off a
435
+ "Start when ready" and returns a bot check to the consent card, all with
436
+ nothing created. While a session is created, joined or played, Chat's own
437
+ read-aloud and dictation are held (`ExplorePage`'s `voiceHold`): a reading
438
+ under way stops, and both controls stay where they are, `aria-disabled`, with
439
+ the avatar's status line as their title, until the session ends; nothing in
440
+ Chat ends the session. The end is a simple CORS request: its body is a
397
441
  string and the SDK sets no `content-type`, so the browser sends it as
398
442
  `text/plain;charset=UTF-8` (which the gateway accepts for this route), and on
399
443
  production nothing else is added, so no preflight has to complete while the
@@ -416,7 +460,16 @@ publishes audio, video or data, and it sends the avatar nothing to say.
416
460
  version that says so, or the view stays as it was.
417
461
  `web-consent-2026-10-31` (which names the product, "a suggested Healthy Bowl
418
462
  question") and `web-consent-2026-11` stay, unchanged, for servers that still
419
- name them.
463
+ name them. Each version also says which questions its words describe, and the
464
+ card is shown only where the server's `questions` is the same.
465
+ `web-consent-2026-11-05` (bot check `turnstile`, 904 bytes, SHA-256
466
+ `75e7e6e84d68bba35ccb208151e2e9e20c69efac2896b17b1d2f1cda46d0bb9f`) and
467
+ `web-consent-2026-11-06` (bot check `off`, 860 bytes, SHA-256
468
+ `f5a673f6c325fe2032f59a561169f5ad8b8598d615e78abbe7b65314e4e6f7bd`) are the
469
+ versions for `questions: "any"`: the avatar reads "the first answer in a new
470
+ chat started in the Avatar tab, provided it passes the speech checks, whether
471
+ you chose a suggested question or typed your own", and the visitor is told
472
+ not to put personal details in a typed question.
420
473
  - **How a session ended.** When the worker leaves, the server closes the room,
421
474
  or the session's time runs out with the room still open, the view says only
422
475
  "The live avatar has ended." (key `finished`). The browser
@@ -471,9 +524,11 @@ publishes audio, video or data, and it sends the avatar nothing to say.
471
524
  of the same host for the validation check.
472
525
  - **Not verified in this package.** Every test here uses fakes: nothing reaches
473
526
  Turnstile, the gateway, the avatar service or the media room. Left to the
474
- alpha test: real playback on iPhone Safari and Android Chrome; that
475
- `page_hide` ends actually arrive from those browsers; and that the receive-only
476
- token has `canPublish=false` and `canPublishData=false`, and a worker RPC
527
+ alpha test: real playback on iPhone Safari and Android Chrome; that the voice
528
+ keeps playing behind the Chat tab and in a background browser tab there (a
529
+ browser may suspend it; the server still ends the session at its planned
530
+ end); that `page_hide` ends actually arrive from those browsers; and that the
531
+ receive-only token has `canPublish=false` and `canPublishData=false`, and a worker RPC
477
532
  addressed to the viewer is dropped without disconnecting it (the media client
478
533
  answers incoming RPC requests on its own, so "never publishes" holds only as
479
534
  far as the token's permissions do).
@@ -1,14 +1,19 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-Bp3kQbU2.mjs';
3
+ import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-N4WhJzgS.mjs';
4
4
  import '../types-CndbmBK-.mjs';
5
- import '../use-explore-chat-zRuoAin6.mjs';
6
- import '../explore-types-Bb2Ih3d8.mjs';
5
+ import '../use-explore-chat-CbfohA9O.mjs';
6
+ import '../explore-types-Ol1Mm3dW.mjs';
7
7
 
8
8
  interface AvatarLiveViewProps {
9
9
  live: ExplorePanelAvatarLive;
10
10
  /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */
11
11
  active: boolean;
12
+ /**
13
+ * The panel is open, whichever tab it shows. With `active` it tells the Chat tab (open, not active: the pane is only
14
+ * hidden, and a session under way keeps playing) from the panel closing (not open: what is under way ends).
15
+ */
16
+ open: boolean;
12
17
  locale: ExploreLocale;
13
18
  /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */
14
19
  productName: string | null;
@@ -19,8 +24,18 @@ interface AvatarLiveViewProps {
19
24
  };
20
25
  /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */
21
26
  fallback: ReactNode;
22
- /** Back to the Chat tab. Leaving the Avatar tab ends a session, like any other way out of it. */
27
+ /**
28
+ * Back to the Chat tab. Like the Chat tab itself, it calls off a start that has not been sent yet, and leaves a
29
+ * session under way speaking.
30
+ */
23
31
  onContinueInChat: () => void;
32
+ /**
33
+ * Told whenever the avatar's voice starts or stops being the page's: its status line while a session is being
34
+ * created, joined or played ("Connecting to the live avatar…", "The avatar is speaking."), and null otherwise (and
35
+ * when the view goes). The panel holds Chat's own read-aloud and dictation meanwhile, so the page never speaks in two
36
+ * voices and the microphone never takes down the avatar's.
37
+ */
38
+ onVoiceHold?: (line: string | null) => void;
24
39
  /** "Continue in Chat" in the panel's language: the panel's own word for it, so this chunk carries none of the panel's. */
25
40
  continueInChat: string;
26
41
  /**
@@ -28,6 +43,15 @@ interface AvatarLiveViewProps {
28
43
  * `reset`, as the chat's own New chat button does, then the Chat tab) where this conversation can never be read.
29
44
  */
30
45
  newChat: string;
46
+ /** "Send" and "Try asking" in the panel's language, for the Avatar tab's own question box. */
47
+ send: string;
48
+ tryAsking: string;
49
+ /** The suggested questions the chat view shows: the box's chips. */
50
+ prompts: readonly string[];
51
+ /** No precise pointer: the box is not focused by itself, so the keyboard does not cover the view. */
52
+ touchFirst: boolean;
53
+ /** The host router's path, when it has one: a "Start when ready" is called off when it changes. */
54
+ currentPath: string | undefined;
31
55
  /**
32
56
  * Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a
33
57
  * read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was. Decided by
@@ -42,6 +66,6 @@ interface AvatarLiveViewProps {
42
66
  /** The panel's conversation, null when there is no provider. */
43
67
  conversation: AvatarConversation | null;
44
68
  }
45
- declare function AvatarLiveView({ live, active, locale, productName, still, fallback, onContinueInChat, continueInChat, newChat, off, base, headers, conversation, }: AvatarLiveViewProps): react.JSX.Element;
69
+ declare function AvatarLiveView({ live, active, open, locale, productName, still, fallback, onContinueInChat, onVoiceHold, continueInChat, newChat, send, tryAsking, prompts, touchFirst, currentPath, off, base, headers, conversation, }: AvatarLiveViewProps): react.JSX.Element;
46
70
 
47
71
  export { AvatarLiveView, type AvatarLiveViewProps };
@@ -1,14 +1,19 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-Cetx8-Zu.js';
3
+ import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-CAfN5eAX.js';
4
4
  import '../types-CndbmBK-.js';
5
- import '../use-explore-chat-DunjG-3p.js';
6
- import '../explore-types-Bb2Ih3d8.js';
5
+ import '../use-explore-chat-B3dOOvJN.js';
6
+ import '../explore-types-Ol1Mm3dW.js';
7
7
 
8
8
  interface AvatarLiveViewProps {
9
9
  live: ExplorePanelAvatarLive;
10
10
  /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */
11
11
  active: boolean;
12
+ /**
13
+ * The panel is open, whichever tab it shows. With `active` it tells the Chat tab (open, not active: the pane is only
14
+ * hidden, and a session under way keeps playing) from the panel closing (not open: what is under way ends).
15
+ */
16
+ open: boolean;
12
17
  locale: ExploreLocale;
13
18
  /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */
14
19
  productName: string | null;
@@ -19,8 +24,18 @@ interface AvatarLiveViewProps {
19
24
  };
20
25
  /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */
21
26
  fallback: ReactNode;
22
- /** Back to the Chat tab. Leaving the Avatar tab ends a session, like any other way out of it. */
27
+ /**
28
+ * Back to the Chat tab. Like the Chat tab itself, it calls off a start that has not been sent yet, and leaves a
29
+ * session under way speaking.
30
+ */
23
31
  onContinueInChat: () => void;
32
+ /**
33
+ * Told whenever the avatar's voice starts or stops being the page's: its status line while a session is being
34
+ * created, joined or played ("Connecting to the live avatar…", "The avatar is speaking."), and null otherwise (and
35
+ * when the view goes). The panel holds Chat's own read-aloud and dictation meanwhile, so the page never speaks in two
36
+ * voices and the microphone never takes down the avatar's.
37
+ */
38
+ onVoiceHold?: (line: string | null) => void;
24
39
  /** "Continue in Chat" in the panel's language: the panel's own word for it, so this chunk carries none of the panel's. */
25
40
  continueInChat: string;
26
41
  /**
@@ -28,6 +43,15 @@ interface AvatarLiveViewProps {
28
43
  * `reset`, as the chat's own New chat button does, then the Chat tab) where this conversation can never be read.
29
44
  */
30
45
  newChat: string;
46
+ /** "Send" and "Try asking" in the panel's language, for the Avatar tab's own question box. */
47
+ send: string;
48
+ tryAsking: string;
49
+ /** The suggested questions the chat view shows: the box's chips. */
50
+ prompts: readonly string[];
51
+ /** No precise pointer: the box is not focused by itself, so the keyboard does not cover the view. */
52
+ touchFirst: boolean;
53
+ /** The host router's path, when it has one: a "Start when ready" is called off when it changes. */
54
+ currentPath: string | undefined;
31
55
  /**
32
56
  * Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a
33
57
  * read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was. Decided by
@@ -42,6 +66,6 @@ interface AvatarLiveViewProps {
42
66
  /** The panel's conversation, null when there is no provider. */
43
67
  conversation: AvatarConversation | null;
44
68
  }
45
- declare function AvatarLiveView({ live, active, locale, productName, still, fallback, onContinueInChat, continueInChat, newChat, off, base, headers, conversation, }: AvatarLiveViewProps): react.JSX.Element;
69
+ declare function AvatarLiveView({ live, active, open, locale, productName, still, fallback, onContinueInChat, onVoiceHold, continueInChat, newChat, send, tryAsking, prompts, touchFirst, currentPath, off, base, headers, conversation, }: AvatarLiveViewProps): react.JSX.Element;
46
70
 
47
71
  export { AvatarLiveView, type AvatarLiveViewProps };