@burdenoff/website-sdk 2026.1104.4 → 2026.1105.2

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 (36) hide show
  1. package/README.md +67 -3
  2. package/dist/avatar-live/index.d.mts +2 -2
  3. package/dist/avatar-live/index.d.ts +2 -2
  4. package/dist/avatar-live/index.js +11 -1
  5. package/dist/avatar-live/index.js.map +1 -1
  6. package/dist/avatar-live/index.mjs +11 -1
  7. package/dist/avatar-live/index.mjs.map +1 -1
  8. package/dist/avatar-live-view/index.d.mts +2 -2
  9. package/dist/avatar-live-view/index.d.ts +2 -2
  10. package/dist/avatar-live-view/index.js +1059 -45
  11. package/dist/avatar-live-view/index.js.map +1 -1
  12. package/dist/avatar-live-view/index.mjs +1054 -40
  13. package/dist/avatar-live-view/index.mjs.map +1 -1
  14. package/dist/avatar-mic/index.d.mts +193 -0
  15. package/dist/avatar-mic/index.d.ts +193 -0
  16. package/dist/avatar-mic/index.js +738 -0
  17. package/dist/avatar-mic/index.js.map +1 -0
  18. package/dist/avatar-mic/index.mjs +736 -0
  19. package/dist/avatar-mic/index.mjs.map +1 -0
  20. package/dist/{chunk-7MSB3EUI.mjs → chunk-MVNN6LLO.mjs} +4 -3
  21. package/dist/chunk-MVNN6LLO.mjs.map +1 -0
  22. package/dist/{chunk-WSEQ2I6I.js → chunk-XIZE37IB.js} +4 -3
  23. package/dist/chunk-XIZE37IB.js.map +1 -0
  24. package/dist/{explore-avatar-live-config-B6_p0q1c.d.mts → explore-avatar-live-config-BL8FTm0I.d.mts} +9 -1
  25. package/dist/{explore-avatar-live-config-DRpS-mqQ.d.ts → explore-avatar-live-config-auLKxSzx.d.ts} +9 -1
  26. package/dist/index.d.mts +9 -4
  27. package/dist/index.d.ts +9 -4
  28. package/dist/index.js +9 -7
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.mjs +5 -3
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/{types-CXqaLlNB.d.mts → types-CTUJNvQu.d.mts} +10 -0
  33. package/dist/{types-CXqaLlNB.d.ts → types-CTUJNvQu.d.ts} +10 -0
  34. package/package.json +1 -1
  35. package/dist/chunk-7MSB3EUI.mjs.map +0 -1
  36. package/dist/chunk-WSEQ2I6I.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/avatar-mic/capture-worklet.ts","../../src/avatar-mic/mic-capture.ts","../../src/avatar-mic/stt-stream.ts","../../src/avatar-mic/press.ts"],"names":["__publicField"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * BOFF-9797 (Stage C). The AudioWorklet that turns the microphone into 16 kHz PCM, for the Avatar tab's mic.\n *\n * **Ported, not shared.** A copy of `src/shared/assistant/voice/handsfree/captureWorklet.ts` in Algoshred/fe-libs at\n * {@link CAPTURE_WORKLET_PORTED_FROM} (blob `bcf5f754`): the website SDK cannot depend on fe-libs, and this folder\n * imports nothing outside itself. {@link CAPTURE_WORKLET_SOURCE} is that file's string byte for byte (its SHA-256 is\n * pinned by `capture-worklet.test.ts`, which also runs fe-libs' own checks against it), so a fix there is a fix to copy\n * here, and a drift fails the test.\n *\n * A worklet module is loaded from a URL, and this package cannot assume a bundler that emits a second entry file for\n * it, so the processor is a SOURCE STRING that `mic-capture.ts` loads through a Blob URL. It has no imports and no\n * access to this file's scope; everything it needs is inside the string.\n *\n * What it does, per render quantum (128 samples at the device rate):\n * - input 0 is the microphone. (Input 1 is fe-libs' playback reference bus; the website creates none, so the worklet\n * meters it as silence: `refDb` about -90.);\n * - the microphone is decimated to 16 kHz with a windowed-sinc low-pass (cutoff 7.2 kHz). Forcing `sampleRate: 16000`\n * on the context is not reliable across browsers, so the context runs at the device rate;\n * - 320-sample (20 ms) frames are posted as s16le with their RMS (dBFS), zero-crossing rate and the reference RMS.\n *\n * The input buffer is preallocated; nothing is allocated per quantum.\n */\n\n/** Where this file was ported from: Algoshred/fe-libs, at this commit of its `main`. */\nexport const CAPTURE_WORKLET_PORTED_FROM =\n \"fe-libs@5ad67543179abb4d8b8f6151c3d9347584802494\";\n\n/** Samples per frame at 16 kHz: 20 ms. */\nexport const CAPTURE_FRAME_SAMPLES = 320;\nexport const CAPTURE_SAMPLE_RATE = 16000;\nexport const CAPTURE_FRAME_MS = 20;\nexport const CAPTURE_PROCESSOR_NAME = \"boff-handsfree-capture\";\n\n/** What the worklet posts for each frame. */\nexport interface CaptureFrameMessage {\n /** s16le mono 16 kHz, `CAPTURE_FRAME_SAMPLES` samples. */\n pcm: ArrayBuffer;\n /** Microphone level over the frame, dBFS. */\n rmsDb: number;\n /** Reference-bus level over the same samples, dBFS (about -90 when silent, as it always is here). */\n refDb: number;\n /** Zero crossings per sample. */\n zcr: number;\n /** AudioContext time at the end of the frame, seconds. */\n ctxTime: number;\n seq: number;\n}\n\nexport const CAPTURE_WORKLET_SOURCE = `\n\"use strict\";\nconst FRAME = ${CAPTURE_FRAME_SAMPLES};\nclass BoffHandsfreeCapture extends AudioWorkletProcessor {\n constructor() {\n super();\n this.step = sampleRate / ${CAPTURE_SAMPLE_RATE};\n this.half = 6 * this.step;\n this.fc = 7200 / sampleRate;\n this.buf = new Float32Array(Math.ceil(this.half * 2) + 4096);\n this.len = 0;\n this.pos = 0;\n this.frame = new Float32Array(FRAME);\n this.n = 0;\n this.seq = 0;\n this.refEnergy = 0;\n this.refCount = 0;\n this.stopped = false;\n this.port.onmessage = (e) => { if (e.data && e.data.type === \"stop\") this.stopped = true; };\n }\n tap(d) {\n const x = 2 * this.fc * d;\n const s = x === 0 ? 1 : Math.sin(Math.PI * x) / (Math.PI * x);\n return 2 * this.fc * s * 0.5 * (1 + Math.cos(Math.PI * d / this.half));\n }\n emit() {\n const pcm = new Int16Array(FRAME);\n let energy = 0;\n let crossings = 0;\n for (let i = 0; i < FRAME; i++) {\n const v = Math.max(-1, Math.min(1, this.frame[i]));\n pcm[i] = Math.round(v * 32767);\n energy += v * v;\n if (i > 0 && (v >= 0) !== (this.frame[i - 1] >= 0)) crossings++;\n }\n const refMean = this.refCount > 0 ? this.refEnergy / this.refCount : 0;\n this.port.postMessage({\n pcm: pcm.buffer,\n rmsDb: 10 * Math.log10(energy / FRAME + 1e-9),\n refDb: 10 * Math.log10(refMean + 1e-9),\n zcr: crossings / FRAME,\n ctxTime: currentTime,\n seq: this.seq++,\n }, [pcm.buffer]);\n this.n = 0;\n this.refEnergy = 0;\n this.refCount = 0;\n }\n process(inputs) {\n if (this.stopped) return false;\n const mic = inputs[0] && inputs[0][0];\n if (!mic) return true;\n const ref = inputs[1] && inputs[1][0];\n if (ref) { for (let i = 0; i < ref.length; i++) this.refEnergy += ref[i] * ref[i]; }\n this.refCount += mic.length;\n if (this.len + mic.length > this.buf.length) {\n const grown = new Float32Array((this.len + mic.length) * 2);\n grown.set(this.buf.subarray(0, this.len));\n this.buf = grown;\n }\n this.buf.set(mic, this.len);\n this.len += mic.length;\n while (this.pos + this.half < this.len) {\n const from = Math.max(0, Math.ceil(this.pos - this.half));\n const to = Math.floor(this.pos + this.half);\n let acc = 0;\n for (let i = from; i <= to; i++) acc += this.buf[i] * this.tap(i - this.pos);\n this.frame[this.n++] = acc;\n this.pos += this.step;\n if (this.n === FRAME) this.emit();\n }\n const drop = Math.max(0, Math.floor(this.pos - this.half));\n if (drop > 0) {\n this.buf.copyWithin(0, drop, this.len);\n this.len -= drop;\n this.pos -= drop;\n }\n return true;\n }\n}\nregisterProcessor(\"${CAPTURE_PROCESSOR_NAME}\", BoffHandsfreeCapture);\n`;\n","/**\n * BOFF-9797 (Stage C). The Avatar tab's own microphone capture: `getUserMedia`, through the capture worklet\n * (`capture-worklet.ts`), into 16 kHz PCM frames.\n *\n * **Ported, not shared.** From `src/shared/assistant/voice/handsfree/micCapture.ts` in Algoshred/fe-libs at the\n * commit `capture-worklet.ts` names (`CAPTURE_WORKLET_PORTED_FROM`; blob `8486c630`), with one difference: fe-libs\n * routes everything its assistant plays into the worklet's second input (its playback reference, for barge-in), and the\n * website plays nothing through this context (the avatar's voice is the room's own audio element, and the mic is\n * offered only while no session plays), so no reference bus is made and the worklet has the microphone as its only\n * input. `looksLikeHeadset`, which only fe-libs' barge-in reads, is not ported. `capture-worklet.test.ts` holds the\n * parity tests.\n *\n * It opens `getUserMedia` with echo cancellation, noise suppression and auto gain on. Constraints are plain `true`,\n * never `{ exact }`: `exact` throws OverconstrainedError on handsets that cannot honour one. The settings the browser\n * actually applied are read back (`track.getSettings()`), because some Android handsets report `true` and apply nothing.\n *\n * `stop()` stops the track (the browser's recording indicator goes), disconnects the graph and closes the context. The\n * caller does that the moment a press ends, whichever way it ends; `pagehide` does it too, whatever the caller does.\n */\nimport {\n CAPTURE_PROCESSOR_NAME,\n CAPTURE_WORKLET_SOURCE,\n type CaptureFrameMessage,\n} from \"./capture-worklet\";\n\nexport interface MicCaptureHandle {\n context: AudioContext;\n micSource: MediaStreamAudioSourceNode;\n track: MediaStreamTrack;\n /** What the browser reports it applied. */\n settings: MediaTrackSettings;\n /** Stop everything and release the microphone. Safe to call more than once. */\n stop(): void;\n}\n\nexport type MicCaptureFailure = \"unsupported\" | \"not-allowed\" | \"unavailable\";\n\nexport class MicCaptureError extends Error {\n constructor(readonly reason: MicCaptureFailure) {\n super(`mic capture failed: ${reason}`);\n this.name = \"MicCaptureError\";\n }\n}\n\nexport const CAPTURE_CONSTRAINTS: MediaStreamConstraints = {\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: 1,\n },\n};\n\nexport function isMicCaptureSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n typeof navigator.mediaDevices?.getUserMedia === \"function\" &&\n typeof AudioContext !== \"undefined\" &&\n typeof AudioWorkletNode !== \"undefined\"\n );\n}\n\n/**\n * Open the microphone and call `onFrame` with every 20 ms frame until `stop()`. Rejects with a {@link MicCaptureError}:\n * `not-allowed` when the visitor (or the browser, or the page's permissions policy) refuses the microphone,\n * `unsupported` where there is no way to capture, `unavailable` for anything else (no device, a device in use).\n */\nexport async function startMicCapture(\n onFrame: (frame: CaptureFrameMessage) => void,\n): Promise<MicCaptureHandle> {\n if (!isMicCaptureSupported()) throw new MicCaptureError(\"unsupported\");\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia(CAPTURE_CONSTRAINTS);\n } catch (cause) {\n const name = cause instanceof DOMException ? cause.name : \"\";\n throw new MicCaptureError(\n name === \"NotAllowedError\" || name === \"SecurityError\"\n ? \"not-allowed\"\n : \"unavailable\",\n );\n }\n const track = stream.getAudioTracks()[0];\n if (!track) {\n stream.getTracks().forEach((t) => t.stop());\n throw new MicCaptureError(\"unavailable\");\n }\n const context = new AudioContext({ latencyHint: \"interactive\" });\n const release = (): void => {\n stream.getTracks().forEach((t) => t.stop());\n };\n try {\n await context.resume();\n const url = URL.createObjectURL(\n new Blob([CAPTURE_WORKLET_SOURCE], { type: \"text/javascript\" }),\n );\n try {\n await context.audioWorklet.addModule(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n const node = new AudioWorkletNode(context, CAPTURE_PROCESSOR_NAME, {\n numberOfInputs: 1,\n numberOfOutputs: 0,\n });\n node.port.onmessage = (event: MessageEvent<CaptureFrameMessage>) =>\n onFrame(event.data);\n const micSource = context.createMediaStreamSource(stream);\n micSource.connect(node, 0, 0);\n\n let stopped = false;\n const onPageHide = (): void => handle.stop();\n const handle: MicCaptureHandle = {\n context,\n micSource,\n track,\n settings: track.getSettings(),\n stop() {\n if (stopped) return;\n stopped = true;\n window.removeEventListener(\"pagehide\", onPageHide);\n node.port.onmessage = null;\n try {\n node.port.postMessage({ type: \"stop\" });\n micSource.disconnect();\n } catch {\n // already torn down\n }\n release();\n void context.close().catch(() => undefined);\n },\n };\n window.addEventListener(\"pagehide\", onPageHide);\n return handle;\n } catch (cause) {\n release();\n void context.close().catch(() => undefined);\n throw cause instanceof MicCaptureError\n ? cause\n : new MicCaptureError(\"unavailable\");\n }\n}\n","/**\n * BOFF-9797 (Stage C). The wire protocol of the website speech-to-text stream, as the Avatar tab's mic speaks it.\n *\n * The route is the global gateway's `GET /api/web-avatar/v1/stt/stream` (WebSocket, Algoshred/global-public-gateway\n * `src/web-stt-proxy.ts`), on the SDK's gateway, which relays to the existing speech service's website path\n * (Algoshred/global-speech-svc `src/speech/stt/protocol.ts`, `/api/stt/v1/web/stream`):\n *\n * subprotocols `boff.web-stt.v1` and `offer.<token>`: the token an availability answer carried (`stt.token`), never\n * in the URL; the gateway lifts it out before the handshake completes, so it is never echoed back.\n *\n * client -> {t:'config', v:1, utteranceId, epoch, langs:['en-IN'], sampleRate:16000, encoding:'s16le', notice}\n * binary s16le mono 16 kHz frames\n * {t:'end', utteranceId} | {t:'cancel', utteranceId}\n * server -> {t:'ready'} | {t:'pong'} | {t:'eou'|'done', utteranceId, epoch}\n * {t:'partial'|'final', utteranceId, epoch, seq, text, lang}\n * {t:'error', code, retryable, utteranceId?, detail?}\n * close codes: 4400 malformed (the mic notice too: `notice-version`), 4401 auth (any refused upgrade, the offer\n * included), 4403 origin, 4408 idle, 4413 frame too large, 4429 quota or rate, 4500 upstream, 4503 unavailable.\n *\n * **Ported, not shared.** The protocol part of `src/shared/assistant/voice/handsfree/backendStreamTransport.ts` in\n * Algoshred/fe-libs at the commit `capture-worklet.ts` names (`CAPTURE_WORKLET_PORTED_FROM`; blob `461a0706`): how\n * frames are chunked under the gateway's frame cap ({@link chunkFrames}), how a server message is read\n * ({@link readServerMessage} keeps fe-libs' checks), the close-code table ({@link CLOSE_CODE_ERRORS}) and the socket\n * seam ({@link SocketLike}). What differs is the route and its credential (the website offer, not a signed-in token),\n * the `notice` field each press names, `en-IN` only, and one connection a press: the transport's reconnects and\n * keep-alive are not ported, because nothing here holds a connection open between presses (the server's website\n * streams are a few at once, for every visitor together). `stt-stream.test.ts` holds the parity tests.\n */\n\n/** The one subprotocol the website route selects. */\nexport const WEB_STT_SUBPROTOCOL = \"boff.web-stt.v1\";\n/** The offered-subprotocol entry that carries the availability answer's token: `offer.<token>`. */\nconst OFFER_PREFIX = \"offer.\";\n/** Under the web branch's base (`/api/web-avatar/v1`). */\nconst STREAM_PATH = \"/stt/stream\";\n/** The speech service's website path takes `en-IN` only. */\nexport const WEB_STT_LANGUAGES: readonly string[] = [\"en-IN\"];\n/** What a subprotocol entry may hold (and the gateway's own token check): a WebSocket token, nothing else. */\nconst TOKEN_CHARS = /^[A-Za-z0-9._~-]{1,4096}$/;\n/** The speech service's utterance ids and notice versions. */\nconst UTTERANCE_ID = /^[A-Za-z0-9._-]{1,64}$/;\nconst NOTICE_VERSION = /^[A-Za-z0-9._-]{1,32}$/;\nconst LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/** The gateway's frame cap is 8 KB; stay well under it. (fe-libs' value.) */\nexport const MAX_SEND_BYTES = 6400;\n\n/** What the mic needs of a WebSocket; {@link openBrowserSocket} adapts the browser's. (fe-libs' seam.) */\nexport interface SocketLike {\n readonly readyState: number;\n send(data: string | ArrayBufferLike | ArrayBufferView): void;\n close(code?: number): void;\n listen(handlers: SocketHandlers): void;\n}\n\nexport interface SocketHandlers {\n open(): void;\n message(data: unknown): void;\n close(code: number): void;\n error(): void;\n}\n\nexport const SOCKET_OPEN = 1;\n\n/** The error codes the client tells apart. (fe-libs' `SttErrorCode`, less what only its transport selection reads.) */\nexport type WebSttErrorCode = \"auth\" | \"quota\" | \"upstream\" | \"closed\";\n\n/** A close with no error frame before it, read as fe-libs reads it. */\nexport const CLOSE_CODE_ERRORS: Readonly<\n Record<number, { code: WebSttErrorCode; retryable: boolean }>\n> = {\n 4400: { code: \"upstream\", retryable: false },\n 4401: { code: \"auth\", retryable: false },\n 4403: { code: \"auth\", retryable: false },\n 4408: { code: \"closed\", retryable: true },\n 4413: { code: \"upstream\", retryable: false },\n 4429: { code: \"quota\", retryable: false },\n 4500: { code: \"upstream\", retryable: true },\n 4503: { code: \"upstream\", retryable: true },\n};\n\n/** The in-band refusal of an upgrade: the client asks availability again and tries once more. */\nexport const CLOSE_AUTH = 4401;\n\n/**\n * The stream's URL on the web branch's `base` (`avatarApiBase` of the SDK's gateway, `https://…/api/web-avatar/v1`):\n * `wss:` for `https:`, and `ws:` only for `http:` on this machine (local development). Null for anything else.\n */\nexport function webSttUrl(base: string): string | null {\n let url: URL;\n try {\n url = new URL(`${base}${STREAM_PATH}`);\n } catch {\n return null;\n }\n if (url.protocol === \"https:\") url.protocol = \"wss:\";\n else if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n url.protocol = \"ws:\";\n } else {\n return null;\n }\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n}\n\n/** Whether `token` can travel as a subprotocol entry. */\nexport function isOfferToken(token: string): boolean {\n return TOKEN_CHARS.test(token);\n}\n\n/** The subprotocols a connection offers: ours, then the token. */\nexport function webSttSubprotocols(token: string): string[] {\n return [WEB_STT_SUBPROTOCOL, `${OFFER_PREFIX}${token}`];\n}\n\n/** Whether `value` is an utterance id the speech service takes. */\nexport function isUtteranceId(value: string): boolean {\n return UTTERANCE_ID.test(value);\n}\n\n/** Whether `value` is a notice version the speech service takes. */\nexport function isNoticeVersion(value: string): boolean {\n return NOTICE_VERSION.test(value);\n}\n\n/** One press's `config` frame: the speech service's protocol v1, plus the mic notice the visitor saw. */\nexport function configFrame(press: {\n utteranceId: string;\n epoch: number;\n notice: string;\n}): string {\n return JSON.stringify({\n t: \"config\",\n v: 1,\n utteranceId: press.utteranceId,\n epoch: press.epoch,\n langs: [...WEB_STT_LANGUAGES],\n sampleRate: 16000,\n encoding: \"s16le\",\n notice: press.notice,\n });\n}\n\n/** Flush and finalise the press: the visitor tapped to stop, or the limit came. */\nexport function endFrame(utteranceId: string): string {\n return JSON.stringify({ t: \"end\", utteranceId });\n}\n\n/** Drop the press upstream and stop paying for it: superseded, or the visitor left. */\nexport function cancelFrame(utteranceId: string): string {\n return JSON.stringify({ t: \"cancel\", utteranceId });\n}\n\n/** Concatenate frames into chunks of at most `MAX_SEND_BYTES`. (fe-libs' function.) */\nexport function chunkFrames(frames: readonly Int16Array[]): Int16Array[] {\n const perChunk = Math.floor(MAX_SEND_BYTES / 2);\n const out: Int16Array[] = [];\n let current: number[] = [];\n const flush = (): void => {\n if (current.length > 0) out.push(Int16Array.from(current));\n current = [];\n };\n for (const frame of frames) {\n for (const sample of frame) {\n current.push(sample);\n if (current.length === perChunk) flush();\n }\n }\n flush();\n return out;\n}\n\n/** What the server says, read: anything else is not a message the mic acts on. */\nexport type WebSttServerMessage =\n | { t: \"ready\" }\n | {\n t: \"partial\" | \"final\";\n utteranceId: string;\n epoch: number;\n text: string;\n }\n | { t: \"done\"; utteranceId: string; epoch: number }\n | {\n t: \"error\";\n code: string;\n retryable: boolean;\n /** The press it ends; null for the connection as a whole (a refused upgrade, say). */\n utteranceId: string | null;\n detail: string | null;\n };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Read one frame from the server: a text frame of JSON, as fe-libs reads it (a partial or final needs its text, its\n * utterance and its epoch; an error's code is kept as said, and only `retryable: true` is retryable). `pong` and `eou`\n * need nothing here (the visitor taps to stop), and neither does anything else: null.\n */\nexport function readServerMessage(data: unknown): WebSttServerMessage | null {\n if (typeof data !== \"string\") return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n return null;\n }\n if (!isRecord(parsed)) return null;\n const { t, utteranceId, epoch, text } = parsed;\n if (t === \"ready\") return { t };\n if (t === \"partial\" || t === \"final\") {\n if (\n typeof text !== \"string\" ||\n typeof utteranceId !== \"string\" ||\n typeof epoch !== \"number\"\n ) {\n return null;\n }\n return { t, utteranceId, epoch, text };\n }\n if (t === \"done\") {\n if (typeof utteranceId !== \"string\" || typeof epoch !== \"number\") {\n return null;\n }\n return { t, utteranceId, epoch };\n }\n if (t === \"error\") {\n return {\n t,\n code: typeof parsed.code === \"string\" ? parsed.code : \"upstream\",\n retryable: parsed.retryable === true,\n utteranceId: typeof utteranceId === \"string\" ? utteranceId : null,\n detail: typeof parsed.detail === \"string\" ? parsed.detail : null,\n };\n }\n return null;\n}\n\n/** The browser's WebSocket behind {@link SocketLike}. Throws as `new WebSocket` does (a protocol it cannot offer). */\nexport function openBrowserSocket(\n url: string,\n protocols: string[],\n): SocketLike {\n const socket = new WebSocket(url, protocols);\n socket.binaryType = \"arraybuffer\";\n return {\n get readyState() {\n return socket.readyState;\n },\n send: (data) => socket.send(data),\n close: (code) => socket.close(code),\n listen(handlers) {\n socket.onopen = () => handlers.open();\n socket.onmessage = (event: MessageEvent<unknown>) =>\n handlers.message(event.data);\n socket.onclose = (event: CloseEvent) => handlers.close(event.code);\n socket.onerror = () => handlers.error();\n },\n };\n}\n","/**\n * BOFF-9797 (Stage C). The Avatar tab's mic, one press at a time: tap to start, tap to stop, thirty seconds at most.\n *\n * A press, in order:\n *\n * 1. **The microphone opens** (`startMicCapture`: the browser's permission prompt the first time). Meanwhile the offer\n * is made ready: the token the last availability answer carried while it is fresh, else a new one, asked for now.\n * 2. **The stream connects**, once the microphone is live (never while a permission prompt is up, so no stream is held\n * open for a visitor who has not decided): `boff.web-stt.v1` and `offer.<token>`. A refused upgrade (4401) asks\n * availability again and tries once more, never twice.\n * 3. **The server says it is ready**: the press's `config` (its utterance id, its epoch, `en-IN`, and the mic notice the\n * visitor saw), then up to {@link PRE_ROLL_MS} of what the microphone heard while the stream connected, then every\n * frame as it comes. Listening, from here: what has been heard so far is reported as it is recognised.\n * 4. **The recording stops**: the visitor's tap, or {@link MAX_PRESS_MS} (counted both on the clock and in audio sent),\n * or the speech service's own limit. The microphone is released at once; `end`, and the last of the text.\n * 5. **The text is final** (`done`): reported once, for the view to put in the box. Nothing is ever sent for the\n * visitor: the text goes nowhere else.\n *\n * **Released on every way out.** The microphone's track is stopped the moment the recording stops, and also when the\n * press fails, is cancelled (`cancel()`: the view going, the page hidden, the Chat tab) or superseded (a new press while\n * one is still finishing: `cancel` for the old one, so it stops being paid for, and its text is never reported). A\n * microphone that opens after its press has gone is closed as it opens. The stream is closed whenever no press needs\n * it: one connection serves a press and the press that supersedes it, and no other.\n */\nimport {\n CAPTURE_SAMPLE_RATE,\n type CaptureFrameMessage,\n} from \"./capture-worklet\";\nimport {\n MicCaptureError,\n startMicCapture,\n type MicCaptureHandle,\n} from \"./mic-capture\";\nimport {\n CLOSE_AUTH,\n CLOSE_CODE_ERRORS,\n SOCKET_OPEN,\n cancelFrame,\n chunkFrames,\n configFrame,\n endFrame,\n isNoticeVersion,\n isOfferToken,\n isUtteranceId,\n openBrowserSocket,\n readServerMessage,\n webSttSubprotocols,\n webSttUrl,\n type SocketLike,\n} from \"./stt-stream\";\n\nimport type {\n AvatarMic,\n AvatarMicFailure,\n AvatarMicOffer,\n AvatarMicOptions,\n AvatarMicState,\n} from \"./types\";\n\n/** The longest press: the speech service's ceiling for a website press (`AVATAR_WEB_STT_MAX_SECONDS`, 30 at most). */\nexport const MAX_PRESS_MS = 30_000;\n/** Audio kept while the stream connects, and sent once it is ready: for a visitor who starts speaking a moment early. */\nexport const PRE_ROLL_MS = 1_000;\n/** How long the stream may take, once the microphone is live, to say it is ready. */\nexport const READY_TIMEOUT_MS = 10_000;\n/** After the recording stops, how long the last of the text may take: past the speech service's own final timeout. */\nexport const FINAL_WAIT_MS = 12_000;\n/** How long an offer opens a stream for (the gateway's `WEB_STT_OFFER_TTL_MS`). */\nexport const OFFER_TTL_MS = 120_000;\n/** An offer is used only this far before it expires, so it does not expire on its way. */\nconst OFFER_MARGIN_MS = 5_000;\n/** How far the gateway's clock may sit from this browser's before its `expiresAt` is not used. */\nconst CLOCK_TOLERANCE_MS = 5_000;\n\nconst IDLE: AvatarMicState = { name: \"idle\" };\n\n/**\n * Until when (this browser's clock) an offer is used: its `expiresAt` when this browser's clock agrees with the\n * gateway's, else {@link OFFER_TTL_MS} from when it came; never longer than that, and less a margin either way.\n */\nexport function offerFreshUntil(offer: AvatarMicOffer): number {\n const ahead = offer.expiresAt - offer.receivedAt;\n const life =\n ahead > 0 && ahead <= OFFER_TTL_MS + CLOCK_TOLERANCE_MS\n ? Math.min(ahead, OFFER_TTL_MS)\n : OFFER_TTL_MS;\n return offer.receivedAt + life - OFFER_MARGIN_MS;\n}\n\n/**\n * Why a refusal or an error ends a press, from what the server said: the code, whether it is retryable, its detail.\n * The mic notice of another version, a refused offer and a pause (the website avatar's kill key) are `unavailable`; a\n * spent limit is `limit`; a busy stream, or counters that cannot be read just now, `busy`.\n */\nexport function failureOf(\n code: string,\n retryable: boolean,\n detail: string | null,\n): AvatarMicFailure {\n if (detail === \"notice-version\") return \"unavailable\";\n switch (code) {\n case \"quota\":\n return \"limit\";\n case \"auth\":\n return \"unavailable\";\n case \"busy\":\n return retryable ? \"busy\" : \"unavailable\";\n default:\n return \"failed\";\n }\n}\n\n/** Why a close with no error frame before it ends a press (fe-libs' table, {@link CLOSE_CODE_ERRORS}). */\nfunction failureOfClose(code: number): AvatarMicFailure {\n const known = CLOSE_CODE_ERRORS[code];\n if (known === undefined) return \"failed\";\n return failureOf(known.code, known.retryable, null);\n}\n\n/** A random utterance id, `web-` and 32 hex digits or a UUID; null where the browser has no random source. */\nfunction randomUtteranceId(): string | null {\n const crypto = globalThis.crypto;\n if (typeof crypto?.randomUUID === \"function\") {\n return `web-${crypto.randomUUID()}`;\n }\n if (typeof crypto?.getRandomValues !== \"function\") return null;\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n return `web-${Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\n/** What a press needs from the browser. The browser's own by default; a test hands in fakes. */\nexport interface AvatarMicSeams {\n createSocket: (url: string, protocols: string[]) => SocketLike;\n startCapture: (\n onFrame: (frame: CaptureFrameMessage) => void,\n ) => Promise<Pick<MicCaptureHandle, \"stop\">>;\n newUtteranceId: () => string | null;\n}\n\nconst BROWSER: AvatarMicSeams = {\n createSocket: openBrowserSocket,\n startCapture: startMicCapture,\n newUtteranceId: randomUtteranceId,\n};\n\ntype Timer = ReturnType<typeof setTimeout>;\n\ninterface Press {\n epoch: number;\n utteranceId: string;\n stage: \"starting\" | \"listening\" | \"finishing\" | \"ended\";\n /** The microphone, once it is live and until it is released. */\n capture: Pick<MicCaptureHandle, \"stop\"> | null;\n /** What the microphone heard while the stream connected, oldest first. */\n preRoll: Int16Array[];\n preRollMs: number;\n /** Audio sent, in milliseconds: the pre-roll and every frame since. */\n sentMs: number;\n startedAt: number;\n finals: string[];\n partial: string;\n limit: boolean;\n /** A connection of its own was opened for it (a superseding press may start on the one it inherited). */\n ownConnection: boolean;\n /** It has asked availability for a new offer after a refused upgrade: the one retry. */\n retried: boolean;\n readyTimer: Timer | null;\n limitTimer: Timer | null;\n finalTimer: Timer | null;\n}\n\ninterface Connection {\n socket: SocketLike;\n /** The server said it is ready: the upgrade was taken. */\n ready: boolean;\n /** The last error frame that named no press: what a refused upgrade said before its close. */\n refusal: { code: string; retryable: boolean; detail: string | null } | null;\n}\n\n/** The mic of one Avatar tab. See the file's comment for what a press does. */\nexport function createAvatarMic(\n options: AvatarMicOptions,\n seams: Partial<AvatarMicSeams> = {},\n): AvatarMic {\n const { createSocket, startCapture, newUtteranceId } = {\n ...BROWSER,\n ...seams,\n };\n let press: Press | null = null;\n let connection: Connection | null = null;\n let epoch = 0;\n let state: AvatarMicState = IDLE;\n\n const report = (next: AvatarMicState): void => {\n state = next;\n options.onState(next);\n };\n\n /** What has been heard: the final text, and the words still being recognised after it. */\n const heard = (p: Press): string =>\n [...p.finals, p.partial].filter((part) => part !== \"\").join(\" \");\n const finalText = (p: Press): string => p.finals.join(\" \");\n\n const show = (p: Press): void => {\n if (p.stage === \"listening\") {\n report({\n name: \"listening\",\n epoch: p.epoch,\n startedAt: p.startedAt,\n text: heard(p),\n });\n } else if (p.stage === \"finishing\") {\n report({\n name: \"finishing\",\n epoch: p.epoch,\n text: heard(p),\n limit: p.limit,\n });\n }\n };\n\n const send = (data: string | ArrayBufferView): void => {\n const socket = connection?.socket;\n if (socket && socket.readyState === SOCKET_OPEN) socket.send(data);\n };\n\n const closeConnection = (): void => {\n const closing = connection;\n connection = null;\n try {\n closing?.socket.close(1000);\n } catch {\n // already closed\n }\n };\n\n const clearTimers = (p: Press): void => {\n for (const timer of [p.readyTimer, p.limitTimer, p.finalTimer]) {\n if (timer !== null) clearTimeout(timer);\n }\n p.readyTimer = null;\n p.limitTimer = null;\n p.finalTimer = null;\n };\n\n /** Stop the microphone's track: the browser's recording indicator goes. */\n const release = (p: Press): void => {\n const capture = p.capture;\n p.capture = null;\n p.preRoll = [];\n p.preRollMs = 0;\n try {\n capture?.stop();\n } catch {\n // already stopped\n }\n };\n\n /** The press is over, one way or another: released, its timers cleared, its connection closed, and `next` said. */\n const settle = (p: Press, next: AvatarMicState): void => {\n if (p.stage === \"ended\") return;\n p.stage = \"ended\";\n release(p);\n clearTimers(p);\n if (press === p) press = null;\n closeConnection();\n report(next);\n };\n\n const fail = (p: Press, reason: AvatarMicFailure): void =>\n settle(p, { name: \"failed\", epoch: p.epoch, reason, text: finalText(p) });\n\n const complete = (p: Press): void =>\n settle(p, {\n name: \"done\",\n epoch: p.epoch,\n text: finalText(p),\n limit: p.limit,\n });\n\n /** The recording stops: the microphone goes now, and the last of the text is waited for. */\n const stopRecording = (p: Press, limit: boolean, withEnd: boolean): void => {\n if (p.stage !== \"listening\") return;\n release(p);\n if (p.limitTimer !== null) clearTimeout(p.limitTimer);\n p.limitTimer = null;\n p.stage = \"finishing\";\n p.limit = limit;\n if (withEnd) send(endFrame(p.utteranceId));\n p.finalTimer = setTimeout(() => {\n p.finalTimer = null;\n if (press !== p || p.stage !== \"finishing\") return;\n if (p.finals.length > 0) complete(p);\n else fail(p, \"failed\");\n }, FINAL_WAIT_MS);\n show(p);\n };\n\n /** The stream is ready and the microphone live: the press's config, its pre-roll, and from here every frame. */\n const begin = (p: Press): void => {\n if (p.stage !== \"starting\" || p.capture === null) return;\n if (p.readyTimer !== null) clearTimeout(p.readyTimer);\n p.readyTimer = null;\n send(\n configFrame({\n utteranceId: p.utteranceId,\n epoch: p.epoch,\n notice: options.notice,\n }),\n );\n for (const chunk of chunkFrames(p.preRoll)) send(chunk);\n p.sentMs += p.preRollMs;\n p.preRoll = [];\n p.preRollMs = 0;\n p.stage = \"listening\";\n p.startedAt = Date.now();\n p.limitTimer = setTimeout(() => {\n p.limitTimer = null;\n if (press === p) stopRecording(p, true, true);\n }, MAX_PRESS_MS);\n show(p);\n };\n\n const onFrame = (p: Press, frame: CaptureFrameMessage): void => {\n if (press !== p) return;\n const pcm = new Int16Array(frame.pcm);\n const ms = (pcm.length * 1000) / CAPTURE_SAMPLE_RATE;\n if (p.stage === \"starting\") {\n p.preRoll.push(pcm);\n p.preRollMs += ms;\n while (p.preRollMs > PRE_ROLL_MS) {\n const oldest = p.preRoll.shift();\n if (oldest === undefined) break;\n p.preRollMs -= (oldest.length * 1000) / CAPTURE_SAMPLE_RATE;\n }\n return;\n }\n if (p.stage !== \"listening\") return;\n if (p.sentMs + ms > MAX_PRESS_MS) {\n stopRecording(p, true, true);\n return;\n }\n send(pcm);\n p.sentMs += ms;\n };\n\n /** An error frame that names the press. */\n const onPressError = (\n p: Press,\n error: { code: string; retryable: boolean; detail: string | null },\n ): void => {\n if (error.code === \"bad-frame\" && error.detail === \"utterance-too-long\") {\n // The speech service's own limit: it finalises what it took, and the text follows.\n stopRecording(p, true, false);\n return;\n }\n if (error.code === \"timeout\") {\n // The speech service ended the press (no audio, a gap, or no final in time): what it finalised stands.\n if (p.finals.length > 0) complete(p);\n else fail(p, \"failed\");\n return;\n }\n fail(p, failureOf(error.code, error.retryable, error.detail));\n };\n\n const onMessage = (data: unknown): void => {\n const message = readServerMessage(data);\n if (message === null || connection === null) return;\n const p = press;\n if (message.t === \"ready\") {\n connection.ready = true;\n if (p !== null) begin(p);\n return;\n }\n if (message.t === \"error\" && message.utteranceId === null) {\n connection.refusal = {\n code: message.code,\n retryable: message.retryable,\n detail: message.detail,\n };\n return;\n }\n // Only the press under way: a superseded one's late words are never shown.\n if (p === null || p.stage === \"ended\") return;\n if (message.utteranceId !== p.utteranceId) return;\n switch (message.t) {\n case \"partial\":\n if (message.epoch !== p.epoch) return;\n p.partial = message.text.trim();\n show(p);\n return;\n case \"final\": {\n if (message.epoch !== p.epoch) return;\n const text = message.text.trim();\n if (text !== \"\") p.finals.push(text);\n p.partial = \"\";\n show(p);\n return;\n }\n case \"done\":\n if (message.epoch !== p.epoch) return;\n complete(p);\n return;\n case \"error\":\n onPressError(p, message);\n return;\n }\n };\n\n const onClose = (closed: Connection, code: number): void => {\n connection = null;\n const p = press;\n if (p === null || p.stage === \"ended\") return;\n if (p.stage === \"starting\") {\n if (closed.ready && !p.ownConnection) {\n // The connection it inherited from the press it superseded went before it began: one of its own, once its\n // microphone is live (until then, the microphone opening connects it).\n if (p.capture !== null) connect(p);\n return;\n }\n if (!closed.ready && !p.retried && code === CLOSE_AUTH) {\n // A refused upgrade (any failed check is 4401: the offer expired, or is for another visitor, site or country\n // by now). Availability again, once. A refused origin (4403) is not one a new offer changes.\n p.retried = true;\n connect(p);\n return;\n }\n }\n if (p.stage === \"finishing\" && p.finals.length > 0) {\n complete(p);\n return;\n }\n const refusal = closed.refusal;\n fail(\n p,\n refusal === null\n ? failureOfClose(code)\n : failureOf(refusal.code, refusal.retryable, refusal.detail),\n );\n };\n\n /**\n * The offer this press connects with: the one held while it is fresh, else (and always for the retry) a new one; null\n * when availability answers without one. Rejects when availability gave no answer.\n */\n const offerFor = async (p: Press): Promise<AvatarMicOffer | null> => {\n const held = options.offer();\n if (!p.retried && held !== null && Date.now() < offerFreshUntil(held)) {\n return held;\n }\n return await options.refreshOffer();\n };\n\n const open = (p: Press, token: string): void => {\n const url = webSttUrl(options.base);\n if (url === null || !isOfferToken(token)) {\n fail(p, \"unavailable\");\n return;\n }\n let socket: SocketLike;\n try {\n socket = createSocket(url, webSttSubprotocols(token));\n } catch {\n fail(p, \"failed\");\n return;\n }\n const opened: Connection = { socket, ready: false, refusal: null };\n connection = opened;\n p.ownConnection = true;\n socket.listen({\n // The server's `ready` is what begins the press; a close always follows an error.\n open: () => undefined,\n error: () => undefined,\n message: (data) => {\n if (connection === opened) onMessage(data);\n },\n close: (code) => {\n if (connection === opened) onClose(opened, code);\n },\n });\n };\n\n /** Connect the press, its microphone being live: on the connection it inherited when that is ready, else its own. */\n function connect(p: Press): void {\n if (connection !== null) {\n if (connection.ready) begin(p);\n return;\n }\n if (p.readyTimer !== null) clearTimeout(p.readyTimer);\n p.readyTimer = setTimeout(() => {\n p.readyTimer = null;\n if (press === p && p.stage === \"starting\") fail(p, \"failed\");\n }, READY_TIMEOUT_MS);\n const waiting = (): boolean =>\n press === p && p.stage === \"starting\" && connection === null;\n void offerFor(p).then(\n (offer) => {\n if (!waiting()) return;\n if (offer === null) {\n fail(p, \"unavailable\");\n return;\n }\n open(p, offer.token);\n },\n () => {\n // No answer (the network, or its deadline) is no refusal: the press fails, and the next one may try again.\n if (waiting()) fail(p, \"failed\");\n },\n );\n }\n\n const cancel = (): void => {\n const p = press;\n press = null;\n if (p !== null && p.stage !== \"ended\") {\n if (p.stage === \"listening\" || p.stage === \"finishing\") {\n send(cancelFrame(p.utteranceId));\n }\n p.stage = \"ended\";\n release(p);\n clearTimers(p);\n }\n closeConnection();\n if (state.name !== \"idle\") report(IDLE);\n };\n\n const start = (): void => {\n const current = press;\n if (\n current !== null &&\n (current.stage === \"starting\" || current.stage === \"listening\")\n ) {\n return;\n }\n if (current !== null && current.stage === \"finishing\") {\n // Superseded: cancelled upstream, so it stops being paid for, and never reported. Its connection carries on.\n send(cancelFrame(current.utteranceId));\n current.stage = \"ended\";\n release(current);\n clearTimers(current);\n press = null;\n }\n epoch += 1;\n const utteranceId = newUtteranceId();\n if (\n utteranceId === null ||\n !isUtteranceId(utteranceId) ||\n !isNoticeVersion(options.notice)\n ) {\n closeConnection();\n report({ name: \"failed\", epoch, reason: \"unsupported\", text: \"\" });\n return;\n }\n const p: Press = {\n epoch,\n utteranceId,\n stage: \"starting\",\n capture: null,\n preRoll: [],\n preRollMs: 0,\n sentMs: 0,\n startedAt: 0,\n finals: [],\n partial: \"\",\n limit: false,\n ownConnection: false,\n retried: false,\n readyTimer: null,\n limitTimer: null,\n finalTimer: null,\n };\n press = p;\n report({ name: \"starting\", epoch });\n let capturing: Promise<Pick<MicCaptureHandle, \"stop\">>;\n try {\n capturing = startCapture((frame) => onFrame(p, frame));\n } catch (error) {\n capturing = Promise.reject(error);\n }\n capturing.then(\n (capture) => {\n if (press !== p || p.stage !== \"starting\") {\n // Its press has gone while the microphone opened: closed as it opens.\n try {\n capture.stop();\n } catch {\n // already stopped\n }\n return;\n }\n p.capture = capture;\n connect(p);\n },\n (error: unknown) => {\n if (press !== p || p.stage !== \"starting\") return;\n fail(\n p,\n error instanceof MicCaptureError && error.reason === \"not-allowed\"\n ? \"denied\"\n : \"unsupported\",\n );\n },\n );\n };\n\n return {\n start,\n stop() {\n const p = press;\n if (p === null) return;\n if (p.stage === \"starting\") cancel();\n else stopRecording(p, false, true);\n },\n cancel,\n state: () => state,\n };\n}\n"]}