@burdenoff/website-sdk 2026.1105.2 → 2026.1106.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.
package/README.md CHANGED
@@ -420,6 +420,139 @@ publishes audio, video or data, and it sends the avatar nothing to say.
420
420
  site's main bundle and the view's chunk carry none of it. On alpha, a browser
421
421
  WebSocket cannot carry Cloudflare Access service-token headers, so the
422
422
  stream needs the Access cookie for the gateway host.
423
+ - **The mic through the browser's own speech recognition (BOFF-9797 Stage C,
424
+ the operator's decision of 2026-11-05, dark).** The same `mic: true` opt-in
425
+ (default unset: no mic); the server's availability decides how the mic works.
426
+ Where the last `ok` answer carries `mic: {"mode": "browser",
427
+ "maxPressSeconds": 30}` (contract v1.6, the avatar service's
428
+ `AVATAR_WEB_MIC=browser`; read strictly: any other value is `unreadable` and
429
+ means no mic) and the consent version's words describe it (the new
430
+ `AvatarConsentCopy.micNotice`), the mic uses `SpeechRecognition` /
431
+ `webkitSpeechRecognition`, as the product assistant does: the browser's own
432
+ speech service turns the voice into text, and **nothing of a press reaches
433
+ our server**; the text goes into the box and leaves only on Send. Offered
434
+ only in a secure context with a recognizer, and never in Firefox (`Firefox/`,
435
+ `FxiOS/`: desktop Firefox gains an on-device recognizer in release 160) or
436
+ Brave (`navigator.brave`: no speech service behind its recognizer). The
437
+ gateway's stream is never offered beside a `mic` the server sent (readable or
438
+ not), nor under words that name a `micNotice`; without a `mic` it is offered
439
+ exactly as before. The first tap shows the notice the words name,
440
+ `web-mic-2026-11-21-c` (714 bytes, SHA-256 `0a15bf5d…8e06de8f`); agreement is
441
+ kept per notice version, so another version is shown again. Two new consent
442
+ versions, DRAFTS for the privacy review that no server names yet:
443
+ `web-consent-2026-11-21-c` (bot check `turnstile`, 1,761 bytes, SHA-256
444
+ `824f389a…111790db`) and `web-consent-2026-11-22-c` (bot check `off`, 1,717
445
+ bytes, SHA-256 `d84a038b…1eb6200c`), Stage D's words with the mic's sentences
446
+ added. Tap to start, tap to stop on every platform: the recognizer
447
+ (`en-IN`, one `en-US` retry on `language-not-supported`, interim results,
448
+ `continuous` except on a touch device) starts inside the tap where the
449
+ browser reports the microphone granted; otherwise the tap first opens the
450
+ microphone and releases it at once (`getUserMedia`, nothing kept or sent),
451
+ which is what raises the permission prompt on Android Chrome and iOS, and
452
+ the recognizer starts 250 ms later (the Chat dictation's mobile handling,
453
+ `use-speech-input`). The 30 s limit counts from its `onstart`, and an engine
454
+ that ends by itself (a pause, a phone's single utterance, `no-speech`) is
455
+ replaced in the same press, its words joined: at once on a computer, after
456
+ 120 ms on a touch device, after a 2 s cooldown after a throw (or, on a
457
+ computer, an instant end); only 8 instant ends in a row, or 60 recognizers
458
+ in all, end a press by itself. The last words after `stop()` are waited for
459
+ (3 s), and a tap meanwhile does nothing. A refused microphone
460
+ (`NotAllowedError`, or `not-allowed` where the microphone was not
461
+ confirmed) says it is blocked (the mic stays); a refusal right after a grant
462
+ is retried once after 350 ms; refused again, or `service-not-allowed`,
463
+ `audio-capture`, no microphone, or a second `network` in a row, it says it
464
+ can't be used here and goes for the page. Words heard before any failure are
465
+ kept. Inside a Stage D session a tap while the avatar speaks sends
466
+ `interrupt`, recording sends `listening` marks from `onstart`, never within
467
+ 5 s of the one before (at most 12 a minute, within the session's 30 turns a
468
+ minute); the mic goes the moment a question is sent and is back once its
469
+ answer has gone to the session, so the avatar never starts an answer into
470
+ an open microphone (a tap while it speaks sends `interrupt` first; how fast
471
+ the cut lands, and whether to mute the avatar locally on that tap, are open
472
+ Stage D items). What is heard and the box carry rrweb's `rr-block`/`rr-mask` (the box also `rr-ignore`), so a site's
473
+ session replay records none of it before Send, and nothing in the mic calls
474
+ the site's analytics. **Before alpha is switched on:** each of the four sites'
475
+ session replay must be off, or honour those classes, and each privacy notice
476
+ (`/privacy#live-avatar`) needs its microphone paragraph.
477
+ - **The voice conversation (BOFF-9797 Stage C2/C3, the operator's decisions of
478
+ 2026-11-06, dark).** The same `mic: true` opt-in; the server decides. Only
479
+ where the last `ok` answer's `mic` carries a pause, `{"mode": "browser",
480
+ "maxPressSeconds": 30, "pauseMs": N}` (contract v1.7, the avatar service's
481
+ `AVATAR_WEB_MIC_PAUSE_MS`; N a whole number from 2000 to 2500, read strictly,
482
+ anything else `unreadable`), under the version whose entry declares no notice
483
+ and a question sent by itself after about two seconds of silence
484
+ (`AvatarNoNoticeCopy`: `notice: "none"`, `voice: { pauseMs: 2000 }`;
485
+ `web-voice-2026-11-25-n`, typed questions, Stage B's three minutes, Stage D's
486
+ answers after the first, no bot check: alpha and prod both run it with
487
+ `AVATAR_WEB_BOT_CHECK=off`). A pause under any other version, or that version
488
+ without a pause, is no mic at all. The notice versions of the earlier
489
+ first-use dialog (`web-consent-2026-11-23-v`, `-24-v`), which no environment
490
+ ran, are retired: this SDK has no copy for them, so a server naming one gets
491
+ the tab as it was. The mic slot becomes a labelled **Talk** button: tap Talk, speak,
492
+ and the question goes through the box's own Send once no word has changed
493
+ for the pause (twice that after one word, fillers aside: "So, ragi" is one;
494
+ or after a word a sentence goes on after: "the", "of", "and", "what", "is"…,
495
+ or a filler; never sooner than 1.5 s after the recognizer listening now
496
+ started, never between two recognizers; fillers and stalls such as "um",
497
+ "okay", "hello", such words alone ("the", "what is the") and a lone pronoun
498
+ ("you") never make a question). The avatar answers aloud, and once that
499
+ answer has played out (its voice quiet for 2.5 s, nothing accepted still to
500
+ be heard, read when it would listen) the mic listens again by itself, never
501
+ while the avatar speaks (the avatar's voice coming back drops a press the
502
+ conversation started, words and all), and not with less than 20 s of the
503
+ session left (a press under way still finishes). Only a press the
504
+ conversation started by itself is checked for the avatar's own words heard
505
+ back; the visitor's own Talk is their question, whatever it repeats.
506
+ **Stop listening** stops at once (the recognizer released, its words into
507
+ the box, unsent). The session's Stop, its own end (the idle end, the three
508
+ minutes), a question past 30 s from its first word, a failure after words and
509
+ typing (after what was typed) put the words heard so far into the box the
510
+ same way; 30 s with no question ends with nothing heard; leaving the tab or
511
+ the page releases the mic and drops what it heard. None of them ever sends. A
512
+ Talk while the avatar speaks interrupts it and mutes it here in that same
513
+ tap, until its voice has been quiet for 2.5 s after the tap (counted from the
514
+ tap where it was already quiet) or the next answer is accepted; the mute
515
+ holds against the room's own unmuting (LiveKit's playback resume, from "Tap
516
+ to turn on sound" or an iPhone's page shown again, and a track attached
517
+ again); where an answer is still to be heard at the tap (the first before
518
+ any voice, or one accepted), only a voice heard after the tap, quiet for the
519
+ hold, or the next answer accepted ends it. **Nothing of consent in the tab**
520
+ (Stage C3, the operator's final decision of 2026-11-06, "nothing at all"): no
521
+ consent card, no dialog, no mic notice and no privacy text, not even the line
522
+ under the box ("Answers are AI-generated and can be wrong. Don't include
523
+ personal details." stays under every version with words, word for word);
524
+ speech processing and the question sent by itself are the site's privacy
525
+ policy's to describe. The box asking in text under the server's `limits`
526
+ refusal has no line either: every availability answer names the server's
527
+ version, a refusal's too (read leniently: `AvatarAvailability`'s refused
528
+ `consentVersion`), and the tab goes by the last version named. A refusal
529
+ that names none changes nothing, and a tab that has heard of no version yet
530
+ keeps the line.
531
+ Talk starts the recognizer and lets the avatar's sound play inside its own
532
+ tap (only the browser's own permission prompt may come first; the mic is
533
+ made ready while Talk is offered, so the recognizer can start in the tap).
534
+ A new chat's first question, spoken or typed (Talk, Send or a chip), arms
535
+ the start of its session in its own tap (single use: bound to its question,
536
+ site, locale, page, version and bot check), and the avatar answers aloud once
537
+ the answer is ready, with no Start; a start called off (Cancel, the page or
538
+ the version changed) shows Start alone, with no words. The recording
539
+ indicator, Stop listening, the session's Stop and the live avatar's "AI
540
+ avatar · not a real person" label (a label, not a notice) stay. Nothing of
541
+ consent is kept in this browser, no consent and no acceptance of anything:
542
+ the only avatar key written is the existing day's note
543
+ `boff.explore.avatarUsedOn`, at a session's start, as under every version.
544
+ The create still names the version the server named, as the contract's
545
+ token: the server must record no consent for it.
546
+ `listening` marks go only while speech is heard, so an open, silent mic keeps
547
+ no session from its idle end. Under this version the box never switches to
548
+ text on this browser's note of a session today (a visitor may have several a
549
+ day: the server's per-visitor limit decides, and its `limits` refusal still
550
+ switches the box to text); after a session, "New chat for the avatar" offers
551
+ the next one, and words heard as it ended wait in its box. **PROD waits for
552
+ the privacy/legal reviewer's approval** of this no-notice experience; should
553
+ they require a pre-use disclosure, it would be one short line under Talk, as
554
+ a version of its own (`AvatarConsentCopy` has room for another kind of
555
+ notice), never a change to this one.
423
556
  - **The answers after the first (BOFF-9797 Stage D, dark).** Only where the
424
557
  create's 201 carries `followUps: {maxAnswers, idleSeconds,
425
558
  maxAnswerWaitSeconds}` (the avatar service adds it only under its
@@ -1,6 +1,6 @@
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-BL8FTm0I.mjs';
3
+ import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-D2PGF8fG.mjs';
4
4
  import '../types-CTUJNvQu.mjs';
5
5
  import '../use-explore-chat-CbfohA9O.mjs';
6
6
  import '../explore-types-Ol1Mm3dW.mjs';
@@ -1,6 +1,6 @@
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-auLKxSzx.js';
3
+ import { E as ExplorePanelAvatarLive, a as ExploreLocale, A as AvatarConversation } from '../explore-avatar-live-config-CJstiSAN.js';
4
4
  import '../types-CTUJNvQu.js';
5
5
  import '../use-explore-chat-B3dOOvJN.js';
6
6
  import '../explore-types-Ol1Mm3dW.js';