@mieweb/ui 0.6.1-dev.165 → 0.6.1-dev.166

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 (43) hide show
  1. package/dist/brands/index.cjs +7 -7
  2. package/dist/brands/index.js +2 -2
  3. package/dist/{chunk-NBD236EH.js → chunk-5O23GUS3.js} +15 -2
  4. package/dist/chunk-5O23GUS3.js.map +1 -0
  5. package/dist/chunk-6I7IDZ4A.js +51 -0
  6. package/dist/chunk-6I7IDZ4A.js.map +1 -0
  7. package/dist/{chunk-Z6NRP4Z5.cjs → chunk-JWTCEWQ4.cjs} +2 -2
  8. package/dist/{chunk-Z6NRP4Z5.cjs.map → chunk-JWTCEWQ4.cjs.map} +1 -1
  9. package/dist/{chunk-Y65SK5Y2.cjs → chunk-MJ7YITLN.cjs} +2 -2
  10. package/dist/{chunk-Y65SK5Y2.cjs.map → chunk-MJ7YITLN.cjs.map} +1 -1
  11. package/dist/{chunk-R6PBBPU3.js → chunk-TXRQQMG5.js} +2 -2
  12. package/dist/{chunk-R6PBBPU3.js.map → chunk-TXRQQMG5.js.map} +1 -1
  13. package/dist/chunk-UVSODK6V.cjs +53 -0
  14. package/dist/chunk-UVSODK6V.cjs.map +1 -0
  15. package/dist/{chunk-YYDW3ZZS.cjs → chunk-W5B3VQUQ.cjs} +15 -2
  16. package/dist/chunk-W5B3VQUQ.cjs.map +1 -0
  17. package/dist/{chunk-NSLR3B7K.js → chunk-XVF472GT.js} +2 -2
  18. package/dist/{chunk-NSLR3B7K.js.map → chunk-XVF472GT.js.map} +1 -1
  19. package/dist/components/Markdown/index.cjs +10 -10
  20. package/dist/components/Markdown/index.js +2 -2
  21. package/dist/components/Skeleton/index.d.cts +1 -1
  22. package/dist/components/Skeleton/index.d.ts +1 -1
  23. package/dist/hey-buddy-CLUVAY2X.cjs +1133 -0
  24. package/dist/hey-buddy-CLUVAY2X.cjs.map +1 -0
  25. package/dist/hey-buddy-NMSWZ4TN.js +1131 -0
  26. package/dist/hey-buddy-NMSWZ4TN.js.map +1 -0
  27. package/dist/index.cjs +4345 -542
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +786 -1
  30. package/dist/index.d.ts +786 -1
  31. package/dist/index.js +4321 -569
  32. package/dist/index.js.map +1 -1
  33. package/dist/speaker-verify-5GTWAN5Y.cjs +357 -0
  34. package/dist/speaker-verify-5GTWAN5Y.cjs.map +1 -0
  35. package/dist/speaker-verify-R67P433H.js +355 -0
  36. package/dist/speaker-verify-R67P433H.js.map +1 -0
  37. package/dist/styles/init.css +5 -0
  38. package/dist/styles.css +1 -1
  39. package/dist/tailwind-preset.cjs +4 -4
  40. package/dist/tailwind-preset.js +1 -1
  41. package/package.json +2 -1
  42. package/dist/chunk-NBD236EH.js.map +0 -1
  43. package/dist/chunk-YYDW3ZZS.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AI/HeyOzwell/WakeWord/lib/helpers.js","../src/components/AI/HeyOzwell/WakeWord/lib/onnx.js","../src/components/AI/HeyOzwell/WakeWord/lib/audio.js","../src/components/AI/HeyOzwell/WakeWord/lib/models/base.js","../src/components/AI/HeyOzwell/WakeWord/lib/models/vad.js","../src/components/AI/HeyOzwell/WakeWord/lib/models/mel-spectrogram.js","../src/components/AI/HeyOzwell/WakeWord/lib/models/speech-embedding.js","../src/components/AI/HeyOzwell/WakeWord/lib/models/wake-word.js","../src/components/AI/HeyOzwell/WakeWord/lib/hey-buddy.js"],"names":[],"mappings":"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","file":"hey-buddy-NMSWZ4TN.js","sourcesContent":["/**\n * Check if an object is 'empty'.\n *\n * @param {*} o The object to check.\n * @returns {boolean} True if the object is empty.\n */\nexport let isEmpty = (o) => {\n return (\n o === null ||\n o === undefined ||\n o === '' ||\n o === 'null' ||\n (Array.isArray(o) && o.length === 0) ||\n (typeof o === 'object' &&\n o.constructor.name === 'Object' &&\n Object.getOwnPropertyNames(o).length === 0)\n );\n};\n\n/**\n * Returns a promise that resolves after a given number of milliseconds.\n */\nexport let sleep = (ms) => {\n return new Promise(resolve => setTimeout(resolve, ms));\n};\n","/** @module onnx */\nimport { sleep } from \"./helpers.js\";\n\nlet initialized = false, initError = null, Tensor, InferenceSession;\n\nif (typeof ort !== \"undefined\") {\n initialized = true;\n Tensor = ort.Tensor;\n InferenceSession = ort.InferenceSession;\n} else {\n // onnxruntime-web is a real dependency here, so let the bundler resolve it.\n // (The original also had a local-file fallback \"./onnxruntime-web/ort.mjs\" that Vite can't\n // resolve at build time — removed; not needed when the package is installed.)\n import(\"onnxruntime-web\").then((module) => {\n try {\n // The engine's .wasm files aren't served by the bundler, so fetch them from the CDN\n // matching the installed version — but ONLY if a host hasn't already configured wasmPaths\n // (so a strict-CSP / self-hosting host can point it at its own copy). Force single-threaded —\n // localhost has no COOP/COEP headers, so the threaded build (SharedArrayBuffer) can't load.\n if (!module.env.wasm.wasmPaths) {\n const v = (module.env && module.env.versions && module.env.versions.web) || \"\";\n module.env.wasm.wasmPaths = \"https://cdn.jsdelivr.net/npm/onnxruntime-web\" + (v ? \"@\" + v : \"\") + \"/dist/\";\n }\n module.env.wasm.numThreads = 1;\n } catch (e) { /* fall back to engine defaults */ }\n initialized = true;\n Tensor = module.Tensor;\n InferenceSession = module.InferenceSession;\n }).catch((e) => {\n // Surface a load failure (CSP/network/missing dep) instead of spinning forever below.\n initError = e instanceof Error ? e : new Error(String(e));\n });\n}\n\n/**\n * Wrapper for ONNX Runtime Web API.\n */\nexport class ONNX {\n /**\n * Wait for the ONNX Runtime Web API to be initialized.\n * @returns {Promise<void>} A promise that resolves when the ONNX Runtime Web API is initialized.\n */\n static async waitForInitialization() {\n while (!initialized) {\n if (initError) throw new Error(\"ONNX Runtime Web failed to load: \" + initError.message);\n await sleep(10);\n }\n }\n\n /**\n * Create a new tensor.\n * @param {string} dtype The data type of the tensor.\n * @param {Array<number>} data The data of the tensor.\n * @param {Array<number>} dims The dimensions of the tensor.\n * @returns {Promise<Tensor>} A promise that resolves to a new tensor.\n */\n static async createTensor(dtype, data, dims) {\n await ONNX.waitForInitialization();\n return new Tensor(dtype, data, dims);\n }\n\n /**\n * Create a new inference session.\n * @param {ArrayBuffer} model The model to load.\n * @param {Object} [options] The options for the inference session.\n * @returns {Promise<InferenceSession>} A promise that resolves to a new inference session.\n */\n static async createInferenceSession(model, options = {}) {\n await ONNX.waitForInitialization();\n return await InferenceSession.create(model, options);\n }\n}\n\n// Wait for the ONNX Runtime Web API to be initialized, then replace the static methods.\n// The static methods can still potentially be used, depending on the order of execution.\n// This only saves a cycle or two, but it's better than nothing.\nONNX.waitForInitialization().then(() => {\n ONNX.createTensor = (dtype, data, dims) => new Tensor(dtype, data, dims);\n ONNX.createInferenceSession = (model, options = {}) => InferenceSession.create(model, options);\n}).catch(() => {\n // Initialization can fail (CSP / offline / dynamic-import error). Swallow it here so it doesn't become\n // an unhandled rejection at load — the static methods await waitForInitialization() and surface the\n // real error to actual callers.\n});\n","/** @module audio */\n// Minified worklet code\nconst workletName = \"hey-buddy\";\nconst workletBlob = new Blob([`(()=>{class t extends AudioWorkletProcessor{constructor(t){super(t),this.targetSampleRate=t.processorOptions.targetSampleRate,this.inputBuffer=new Float32Array(this.inputFrameSize),this.inputBufferSize=0,this.outputBuffer=new Float32Array(this.targetFrameSize)}get inputFrameSize(){return Math.round(sampleRate/50)}get targetFrameSize(){return Math.round(this.targetSampleRate/50)}async flush(){const t=sampleRate/this.targetSampleRate;this.outputBuffer.fill(0);for(let e=0;e<this.targetFrameSize;e++){const i=e*t,r=Math.floor(i),s=Math.min(r+1,this.inputFrameSize-1),u=i-r;this.outputBuffer[e]=this.inputBuffer[r]*(1-u)+this.inputBuffer[s]*u}await this.port.postMessage(this.outputBuffer)}pushAudio(t){const e=t.length,i=this.inputFrameSize-this.inputBufferSize;if(e<i)return this.inputBuffer.set(t,this.inputBufferSize),void(this.inputBufferSize+=e);this.inputBuffer.set(t.subarray(0,i),this.inputBufferSize),this.flush(),this.inputBufferSize=0,this.pushAudio(t.subarray(i))}process(t,e,i){return this.pushAudio(t[0][0]),!0}}registerProcessor(\"${workletName}\",t)})();`], {type: \"application/javascript\"});\nconst workletUrl = URL.createObjectURL(workletBlob);\n\n/**\n * A class that batches audio samples and calls a callback with the batch.\n */\nexport class AudioBatcher {\n /**\n * @param {number} batchSeconds - The number of seconds to batch.\n * @param {number} batchIntervalSeconds - The number of seconds to wait before calling the callback.\n * @param {number} targetSampleRate - The target sample rate of the worklet.\n */\n constructor(\n batchSeconds=2.0,\n batchIntervalSeconds=0.05, // 50ms\n targetSampleRate=16000,\n ) {\n this.initialized = false;\n this.initError = null;\n this.callbacks = [];\n this.batchSeconds = batchSeconds;\n this.batchIntervalSeconds = batchIntervalSeconds;\n this.batchIntervalCount = 0;\n this.targetSampleRate = targetSampleRate;\n this.buffer = new Float32Array(this.batchSamples);\n this.buffer.fill(0);\n // initialize() is async (getUserMedia + worklet addModule); catch so a denied mic / failed\n // worklet surfaces as a stored error instead of an unhandled promise rejection.\n this.initialize().catch((e) => {\n this.initError = e;\n console.error(\"[AudioBatcher] initialization failed\", e);\n });\n }\n\n /**\n * The number of samples in a batch.\n * @type {number}\n */\n get batchSamples() {\n return Math.floor(this.batchSeconds * this.targetSampleRate);\n }\n\n /**\n * The number of samples in a batch interval.\n * @type {number}\n */\n get batchIntervalSamples() {\n return Math.floor(this.batchIntervalSeconds * this.targetSampleRate);\n }\n\n /**\n * Clears the buffer.\n */\n clearBuffer() {\n this.buffer.fill(0);\n }\n\n /**\n * Pushes new audio samples into the buffer.\n * @param {Float32Array} data - The new audio samples.\n */\n push(data) {\n const dataLength = data.length;\n if (dataLength >= this.buffer.length) {\n // Chunk larger than the ring buffer — keep only its most recent samples (a plain shift+append\n // would compute a negative offset and throw, permanently breaking the detector).\n this.buffer.set(data.subarray(dataLength - this.buffer.length));\n } else {\n // Shift the buffer back by this much\n this.buffer.set(this.buffer.subarray(dataLength));\n // Append the new data\n this.buffer.set(data, this.buffer.length - dataLength);\n }\n this.batchIntervalCount += dataLength;\n // If we have enough samples, call the callbacks and reset the interval count\n if (this.batchIntervalCount >= this.batchIntervalSamples) {\n this.callbacks.forEach(callback => callback(this.buffer));\n this.batchIntervalCount = 0;\n }\n }\n\n /**\n * Adds a callback to be called with each batch.\n * @param {Function} callback - The callback to add.\n */\n onBatch(callback) {\n this.callbacks.push(callback);\n }\n\n /**\n * Removes a callback from the list of callbacks.\n * @param {Function} callback - The callback to remove.\n */\n offBatch(callback) {\n this.callbacks = this.callbacks.filter(c => c !== callback);\n }\n\n /**\n * Initializes the audio batcher.\n */\n async initialize() {\n if (this.initialized) {\n return;\n }\n // KEEP the browser's audio DSP ON. We tried turning it off (for voiceprint consistency across rooms)\n // but it badly hurt RECALL — without noise-suppression/auto-gain the model needs loud/clear speech to\n // fire (normal-volume \"hey ozwell\" wouldn't even enroll). The DSP cleans+levels the speech so the\n // model fires at normal volume. The cross-environment voiceprint drift is handled the right way:\n // RE-ENROLL in the environment you use (proven to restore ~0.9 scores) / multi-condition enrollment.\n this.stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n channelCount: 1,\n echoCancellation: true,\n autoGainControl: true,\n noiseSuppression: true,\n }\n });\n this.audioContext = new AudioContext();\n this.audioContext.resume().catch(() => {}); // may start suspended under autoplay policy\n this.sourceNode = new MediaStreamAudioSourceNode(\n this.audioContext,\n { mediaStream: this.stream }\n );\n this.workerNode = await AudioNode.create(\n this.audioContext,\n this.targetSampleRate,\n );\n this.sourceNode.connect(this.workerNode.worker);\n this.workerNode.worker.port.onmessage = (event) => {\n this.push(event.data);\n }\n this.clearBuffer();\n this.initialized = true;\n }\n}\n\n/**\n * A class that wraps an AudioWorkletNode.\n */\nexport class AudioNode {\n /**\n * @param {AudioContext} context - The audio context.\n * @param {AudioWorkletNode} worker - The audio worklet node.\n */\n constructor(context, worker) {\n this.context = context;\n this.worker = worker;\n }\n\n /**\n * Creates an AudioNode.\n * @param {AudioContext} context - The audio context.\n * @param {number} targetSampleRate - The target sample rate of the worklet.\n * @returns {Promise<AudioNode>} The created AudioNode.\n */\n static async create(context, targetSampleRate) {\n await context.audioWorklet.addModule(workletUrl);\n const workletOptions = {\n processorOptions: {\n targetSampleRate: targetSampleRate,\n }\n };\n const worker = new AudioWorkletNode(context, workletName, workletOptions);\n return new AudioNode(context, worker);\n }\n}\n","/** @module models/base */\nimport { ONNX } from \"../onnx.js\";\nimport { getModelBytes } from \"../opfs.js\";\n\n/**\n * Base class for ONNX models\n */\nexport class ONNXModel {\n /**\n * Constructor\n * @param {string} modelPath - Path to the ONNX model\n * @param {Object} options - Options\n */\n constructor(\n modelPath,\n power = 0,\n webnn = 1,\n webgpu = 2,\n webgl = 3,\n wasm = 4,\n ) {\n this.modelPath = modelPath;\n this.session = null;\n this.loadError = null;\n this.duration = 0.0; // EMA duration\n this.ema = 0.1; // EMA coefficient\n this.lastTime = 0.0; // Last time the model was run\n this.webnn = webnn;\n this.webgpu = webgpu;\n this.webgl = webgl;\n this.wasm = wasm;\n // 0 for default, -1 for low power, 1 for high power\n this.power = power;\n // Track the load so failures surface (an unhandled rejection here would leave `session` null and\n // hang waitUntilLoaded()/run() forever). waitUntilLoaded() awaits this and rethrows the error.\n this.loadPromise = this.load().catch((e) => {\n this.loadError = e;\n console.warn(\"[ONNXModel] load failed:\", e);\n });\n }\n\n /**\n * Get the power preference\n * @returns {string} - Power preference\n */\n get powerPreference() {\n switch (this.power) {\n case -1:\n return \"low-power\";\n case 1:\n return \"high-performance\";\n default:\n return \"default\";\n }\n }\n\n /**\n * Get the execution providers\n * @returns {Array} - Execution providers\n */\n get executionProviders() {\n const providerIndexes = [];\n if (Number.isInteger(this.webnn)) {\n providerIndexes.push([{\n name: \"webnn\",\n device: \"gpu\",\n powerPreference: this.powerPreference,\n }, this.webnn]);\n }\n if (Number.isInteger(this.webgpu)) {\n providerIndexes.push([\"webgpu\", this.webgpu]);\n }\n if (Number.isInteger(this.webgl)) {\n providerIndexes.push([\"webgl\", this.webgl]);\n }\n if (Number.isInteger(this.wasm)) {\n providerIndexes.push([\"wasm\", this.wasm]);\n }\n providerIndexes.sort((a, b) => a[1] - b[1]);\n return providerIndexes.map((providerIndex) => providerIndex[0]);\n }\n\n /**\n * Get the session options\n * @returns {Object} - Session options\n * @see https://onnxruntime.ai/docs/tutorials/web/env-flags-and-session-options.html#session-options\n */\n get sessionOptions() {\n // Intentionally wasm-only. The webnn/webgpu/webgl preferences computed in `executionProviders`\n // broke inference in this pipeline, so they're deliberately NOT applied here (the getter is kept\n // for reference / future investigation). This is the working configuration, not an oversight.\n return {\n executionProviders: [\"wasm\"],\n };\n }\n\n /**\n * Initialize the model\n */\n async load() {\n // Model files live in OPFS (app-private, offline, versioned) per the storage breakdown — fetch the\n // bytes ourselves (OPFS-first, network on miss) and hand ORT the bytes instead of the URL.\n const bytes = await getModelBytes(this.modelPath);\n this.session = await ONNX.createInferenceSession(bytes, this.sessionOptions);\n }\n\n /**\n * Waits until the model is loaded\n */\n async waitUntilLoaded() {\n await this.loadPromise;\n if (this.loadError) throw this.loadError; // fail fast instead of spinning forever on a load failure\n }\n\n /**\n * Execute the model\n * @param {Mixed} input - Input data\n * @returns {Promise} - Promise that resolves with the output of the model\n * @throws {Error} - If the method is not implemented\n */\n async execute(input) {\n throw new Error(\"Not Implemented\");\n }\n\n /**\n * Run the model\n * @param {Mixed} input - Input data\n * @returns {Promise} - Promise that resolves with the output of the model\n */\n async run(input) {\n await this.waitUntilLoaded();\n const currentTime = new Date().getTime();\n const result = await this.execute(input);\n const executionDuration = new Date().getTime() - currentTime;\n // Update EMA\n if (this.duration === 0.0) {\n this.duration = executionDuration;\n } else {\n this.duration = (1.0 - this.ema) * this.duration + this.ema * executionDuration;\n }\n this.lastTime = currentTime;\n return result;\n }\n}\n","/** @module models/vad */\nimport { ONNX } from \"../onnx.js\";\nimport { ONNXModel } from \"./base.js\";\n\n/**\n * Silero VAD model\n * @extends ONNXModel\n */\nexport class SileroVAD extends ONNXModel {\n /**\n * Constructor\n * @param {string} modelPath - Path to the ONNX model\n * @param {number} sampleRate - Sample rate of the input audio\n * @param {number} speechVadThreshold - Threshold for speech detection (default: 0.65)\n * @param {number} silenceVadThreshold - Threshold for silence detection (default: 0.4)\n * @param {number} silentFramesCount - Number of silent frames to consider speech ended (default: 10)\n */\n constructor(\n modelPath = \"/pretrained/silero-vad.onnx\",\n sampleRate = 16000,\n speechVadThreshold = 0.65,\n silenceVadThreshold = 0.4,\n silentFramesCount = 10,\n power = 0,\n webnn = 1,\n webgpu = 2,\n webgl = 3,\n wasm = 4,\n ) {\n super(\n modelPath,\n power,\n webnn,\n webgpu,\n webgl,\n wasm,\n );\n this.sampleRate = sampleRate || 16000;\n this.speechVadThreshold = speechVadThreshold;\n this.silenceVadThreshold = silenceVadThreshold;\n this.silentFramesCount = silentFramesCount;\n this.silentFrames = 0;\n this.isSpeaking = false;\n }\n\n /**\n * Test the model\n * @param {boolean} debug - If true, log the result to the console\n * @throws {Error} - If the model fails the test\n */\n async test(debug = false) {\n let result = await this.run(new Float32Array(16000).fill(0));\n if (!isNaN(result) && 0.0 <= result && result <= 1.0) {\n if (debug) {\n console.log(`VAD model OK, executed in ${this.duration} ms`);\n }\n } else {\n throw new Error(`VAD model failed - got ${result}`);\n }\n }\n\n /**\n * Execute the model\n * @param {Float32Array} input - Input data\n * @returns {Promise} - Promise that resolves with the output of the model, which is a single float\n * @throws {Error} - If the input data is not a Float32Array\n */\n async execute(input) {\n if (this.h === undefined || this.c === undefined || this.sr === undefined) {\n this.sr = await ONNX.createTensor(\"int64\", [this.sampleRate], [1]);\n this.h = await ONNX.createTensor(\"float32\", (new Array(128)).fill(0), [2, 1, 64]);\n this.c = await ONNX.createTensor(\"float32\", (new Array(128)).fill(0), [2, 1, 64]);\n }\n const inputTensor = await ONNX.createTensor(\"float32\", input, [1, input.length]);\n const output = await this.session.run({\n input: inputTensor,\n h: this.h,\n c: this.c,\n sr: this.sr,\n });\n this.c = output.cn;\n this.h = output.hn;\n return output.output.data[0];\n }\n\n /**\n * Determines if speech is present in the audio, with debouncing logic so a brief pause between\n * words doesn't split one utterance into two: if speech is followed by a short silence and then\n * more speech, the whole span (including the gap) is still treated as speech.\n *\n * @param {Float32Array} audio - Audio data to check for speech\n * @returns {Promise<Object>} - Promise that resolves with an object containing:\n * - isSpeaking: boolean - true if speech is detected, false otherwise\n * - probability: number - the raw VAD probability score (0-1)\n */\n async hasSpeechAudio(audio) {\n // Run VAD on the audio\n const speechProbability = await this.run(audio);\n const hasSpeech = speechProbability > this.speechVadThreshold;\n const hasSilence = speechProbability < this.silenceVadThreshold;\n let justStoppedSpeaking = false;\n let justStartedSpeaking = false;\n \n // Update speech state with debouncing\n if (!hasSpeech) {\n if (hasSilence) {\n this.silentFrames += 1;\n \n if (this.isSpeaking && this.silentFrames > this.silentFramesCount) {\n this.isSpeaking = false;\n justStoppedSpeaking = true;\n }\n }\n } else {\n this.silentFrames = 0;\n if(!this.isSpeaking){\n this.isSpeaking = true;\n justStartedSpeaking = true;\n }\n }\n \n // Return both the speech state and the probability\n return {\n isSpeaking: this.isSpeaking,\n speechProbability,\n justStoppedSpeaking,\n justStartedSpeaking\n };\n }\n}","/** @module models/mel-spectrogram */\nimport { ONNX } from \"../onnx.js\";\nimport { ONNXModel } from \"./base.js\";\n\n/**\n * Mel spectrogram model\n * @extends ONNXModel\n */\nexport class MelSpectrogram extends ONNXModel {\n /**\n * Constructor\n * @param {string} modelPath - Path to the ONNX model\n */\n constructor(\n modelPath = \"/pretrained/mel-spectrogram.onnx\",\n power = 0,\n webnn = 1,\n webgpu = 2,\n webgl = 3,\n wasm = 4,\n ) {\n super(\n modelPath,\n power,\n webnn,\n webgpu,\n webgl,\n wasm,\n );\n }\n\n /**\n * Test the model\n * @param {boolean} debug - If true, print debug information\n * @throws {Error} - If the model fails the test\n */\n async test(debug = false) {\n let result = await this.run(new Float32Array(12640).fill(1.0));\n if (result.dims.length === 4 && \n result.dims[2] === 76 &&\n result.dims[3] === 32\n ) {\n if (debug) {\n console.log(`Mel spectrogram model OK, executed in ${this.duration} ms`);\n }\n } else {\n throw new Error(\"Mel spectrogram model failed\");\n }\n }\n\n /**\n * Execute the model\n * @param {Float32Array} input - Input data\n * @returns {Promise} - Promise that resolves with the output of the model, which is a 2D array\n * @throws {Error} - If the input data is not a Float32Array\n */\n async execute(input) {\n // SCALE FIX (MIE 2026-06-09): peak-normalize each buffer to match training\n // (heybuddy/embeddings.py divides each clip by its peak). Without this, the browser\n // feeds un-normalized audio and the model separates by loudness, not content.\n let peak = 0;\n for (let i = 0; i < input.length; i++) {\n const a = Math.abs(input[i]);\n if (a > peak) peak = a;\n }\n if (peak > 1e-5) {\n const normed = new Float32Array(input.length);\n for (let i = 0; i < input.length; i++) normed[i] = input[i] / peak;\n input = normed;\n }\n const inputTensor = await ONNX.createTensor(\n \"float32\",\n input,\n [1, input.length]\n );\n const output = await this.session.run({ input: inputTensor });\n // Rescale in place — this runs every frame on the wake pipeline, so mutate the output buffer\n // instead of allocating a new array per call (.map).\n const data = output.output.data;\n for (let i = 0; i < data.length; i++) data[i] = data[i] / 10.0 + 2.0;\n return await ONNX.createTensor(\"float32\", data, output.output.dims);\n }\n}\n","/** @module models/speech-embedding */\nimport { ONNX } from \"../onnx.js\";\nimport { ONNXModel } from \"./base.js\";\nimport { MelSpectrogram } from \"./mel-spectrogram.js\";\n\n/**\n * Speech Embedding model\n * get the embeddings from a mel spectrogram\n * @extends ONNXModel\n */\nexport class SpeechEmbedding extends ONNXModel {\n /**\n * Constructor\n * @param {string} modelPath - Path to the ONNX model\n * @param {MelSpectrogram} spectrogramModel - Mel spectrogram model\n * @param {number} spectrogramMelBins - Number of Mel bins for the Mel spectrogram model\n * @param {number} embeddingDim - Dimension of the embeddings\n * @param {number} windowSize - Size of the window\n * @param {number} windowStride - Stride of the window\n */\n constructor(\n modelPath,\n embeddingDim = 96,\n windowSize = 76,\n windowStride = 8,\n power = 0,\n webnn = 1,\n webgpu = 2,\n webgl = 3,\n wasm = 4,\n ) {\n super(\n modelPath,\n power,\n webnn,\n webgpu,\n webgl,\n wasm\n );\n this.embeddingDim = embeddingDim;\n this.windowSize = windowSize;\n this.windowStride = windowStride;\n }\n\n /** \n * Test the model\n * @param {boolean} debug - Debug mode\n * @throws {Error} - If the model fails the test\n */\n async test(debug = false) {\n const melTensor = await ONNX.createTensor(\n \"float32\",\n new Float32Array(100 * 32), // already zero-initialized\n [100, 32]\n );\n let result = await this.run(melTensor);\n if (result.dims.length === 2 && \n result.dims[0] === 4 &&\n result.dims[1] === 96\n ) {\n if (debug) {\n console.log(`Speech embedding model OK, executed in ${this.duration} ms`);\n }\n } else {\n console.error(\"Unexpected speech embedding result\", result);\n throw new Error(\"Speech embedding model failed\");\n }\n }\n\n /**\n * Extracts speech embeddings from a mel spectrogram output\n * \n * This function takes the output from a mel spectrogram model, creates an ONNX tensor\n * with the appropriate dimensions, and runs it through the speech embedding model to\n * generate embeddings that can be used for wake word detection.\n * \n * @param {Object} melSpectogramOutput - The output tensor from a mel spectrogram model\n * @param {Float32Array} melSpectogramOutput.data - The raw data from the mel spectrogram\n * @param {Array<number>} melSpectogramOutput.dims - The dimensions of the mel spectrogram output\n * @returns {Promise<Object>} - A promise that resolves to an ONNX tensor containing the speech embeddings\n */\n async getEmbeddingFromMelSpectrogramOutput(melSpectogramOutput){\n const spectogramBuffer = await ONNX.createTensor(\n \"float32\",\n melSpectogramOutput.data,\n melSpectogramOutput.dims.slice(2)\n );\n\n return this.run(spectogramBuffer);\n }\n\n /**\n * Execute the model\n * @param {Float32Array} input - Input data\n * @returns {Promise} - Promise that resolves with the output of the model, which is a 2D array\n * @throws {Error} - If the input data is not a Float32Array\n */\n async execute(spectrograms) {\n const [numFrames, melBins] = spectrograms.dims;\n if (numFrames < this.windowSize) {\n throw new Error(`Audio is too short to process - require ${this.windowSize} samples, got ${numFrames}`);\n }\n // Calculate the number of batches\n const numTruncatedFrames = numFrames - (numFrames - this.windowSize) % this.windowStride;\n const numBatches = (numTruncatedFrames - this.windowSize) / this.windowStride + 1;\n\n // Create buffer for output\n const embeddings = await ONNX.createTensor(\n \"float32\",\n (new Array(numBatches * this.embeddingDim)).fill(0),\n [numBatches, this.embeddingDim]\n );\n\n // Iterate through windows\n const windowBatches = [];\n for (\n let windowStart = 0;\n windowStart < numTruncatedFrames - this.windowSize + this.windowStride;\n windowStart += this.windowStride\n ) {\n const windowEnd = windowStart + this.windowSize;\n const windowTensor = await ONNX.createTensor(\n \"float32\",\n spectrograms.data.slice(windowStart * melBins, windowEnd * melBins),\n [this.windowSize, melBins, 1]\n );\n windowBatches.push([windowStart, windowEnd, windowTensor]);\n }\n\n // Restack windows into a single tensor\n const stackedWindowTensor = await ONNX.createTensor(\n \"float32\",\n new Float32Array(numBatches * this.windowSize * melBins),\n [numBatches, this.windowSize, melBins, 1]\n );\n for (let i = 0; i < numBatches; i++) {\n stackedWindowTensor.data.set(windowBatches[i][2].data, i * this.windowSize * melBins);\n }\n\n // Execute the model\n // TODO: Determine why this takes so much longer in the browser than it does in python\n const output = await this.session.run({ input_1: stackedWindowTensor });\n\n for (let i = 0; i < numBatches; i++) {\n embeddings.data.set(\n output.conv2d_19.data.slice(\n i * this.embeddingDim,\n (i + 1) * this.embeddingDim\n ),\n i * this.embeddingDim\n );\n }\n return embeddings;\n }\n}\n","/** @module models/wake-word */\nimport { ONNX } from \"../onnx.js\";\nimport { ONNXModel } from \"./base.js\";\n\n/**\n * Wake Word model\n * @extends ONNXModel\n */\nexport class WakeWord extends ONNXModel {\n /**\n * Constructor\n * @param {string} modelPath - Path to the ONNX model\n * @param {number} threshold - Threshold for wake word detection (default: 0.5)\n */\n constructor(\n modelPath,\n threshold,\n power = 0,\n webnn = 1,\n webgpu = 2,\n webgl = 3,\n wasm = 4\n ) {\n super(modelPath, power, webnn, webgpu, webgl, wasm);\n this.threshold = threshold;\n }\n\n /**\n * Test the model\n * @param {boolean} debug - Whether to log debug messages\n * @throws {Error} - If the model test fails\n */\n async test(debug = false) {\n const embeddings = await ONNX.createTensor(\n \"float32\",\n new Float32Array(16*96).fill(0),\n [1, 16, 96]\n );\n const output = await this.run(embeddings);\n if (0.0 <= output && output <= 1.0) {\n if (debug) {\n console.log(`Wake Word model OK, executed in ${this.duration} ms`);\n }\n } else {\n throw new Error(`Wake Word model test failed - expected 0 <= x <= 1, got ${output}`);\n }\n }\n\n /**\n * Execute the model\n * @param {Float32Array} embeddings - Input embeddings\n * @returns {Promise} - Promise that resolves with the output of the model, which is a single float\n * @throws {Error} - If the input data is not a Float32Array\n */\n async execute(embeddings) {\n const input = {};\n if (embeddings.dims.length === 3) {\n input.input = embeddings;\n } else {\n input.input = await ONNX.createTensor(\n \"float32\",\n embeddings.data,\n [1, embeddings.dims[0], embeddings.dims[1]]\n );\n }\n const output = await this.session.run(input);\n return output.output.data[0] * 1;\n }\n\n /**\n * Check if the wake word is detected based on the threshold\n * @param {Float32Array} embeddings - Input embeddings\n * @returns {Promise<Object>} - Promise that resolves with an object containing probability and detected status\n */\n async checkWakeWordCalled(embeddings) {\n const probability = await this.run(embeddings);\n\n // Live base-threshold override for tuning without a rebuild: window.__baseThr can be a number\n // (all phrases) or a {name: thr} map. Falls back to the configured per-word threshold.\n let thr = this.threshold;\n const ov = (typeof window !== \"undefined\") ? window.__baseThr : undefined;\n if (typeof ov === \"number\") thr = ov;\n else if (ov && this.name && typeof ov[this.name] === \"number\") thr = ov[this.name];\n\n return {\n probability,\n detected: probability >= thr\n };\n }\n\n /**\n * Run wake word detection on audio.\n * @param {Float32Array} embeddings - Input embeddings\n * @returns {Promise} - Promise that resolves when wake word detection is complete.\n */\n async checkWakeWordPresent(embeddings) {\n return await this.execute(embeddings);\n }\n}\n","/** @module hey-buddy */\nimport { ONNX } from \"./onnx.js\";\nimport { AudioBatcher } from \"./audio.js\";\nimport {\n SileroVAD,\n SpeechEmbedding,\n MelSpectrogram,\n WakeWord\n} from \"./models.js\";\n\n/**\n * Combines an array of embedding buffers into a single embedding tensor.\n *\n * @async\n * @function\n * @param {Float32Array[]} embeddingBufferArray - An array of embedding buffers, where each buffer is a Float32Array.\n * @param {number} numFramesPerEmbedding - The number of frames per embedding.\n * @param {number} embeddingDim - The dimensionality of each embedding.\n * @returns {Promise<Object>} A promise that resolves to an ONNX tensor containing the combined embeddings.\n */\nasync function embeddingBufferArrayToEmbedding(embeddingBufferArray, numFramesPerEmbedding, embeddingDim){\n // Create empty buffer of the right size\n const combinedEmptyData = new Float32Array(numFramesPerEmbedding * embeddingBufferArray.length * embeddingDim);\n \n // Create tensor with the empty buffer\n const embeddingBuffer = await ONNX.createTensor(\n \"float32\",\n combinedEmptyData,\n [numFramesPerEmbedding * embeddingBufferArray.length, embeddingDim]\n );\n\n // Fill the buffer with data\n for (let i = 0; i < embeddingBufferArray.length; i++) {\n const embedding = embeddingBufferArray[i];\n embeddingBuffer.data.set(embedding.data, i * numFramesPerEmbedding * embeddingDim);\n }\n return embeddingBuffer;\n}\n\n/**\n * HeyBuddy class for running wake word detection.\n */\nexport class HeyBuddy {\n /**\n * Create a HeyBuddy instance.\n * @param {Object} [options] - Options object.\n * @param {number} [options.positiveVadThreshold=0.5] - VAD threshold for speech.\n * @param {number} [options.negativeVadThreshold=0.25] - VAD threshold for silence.\n * @param {number} [options.negativeVadCount=8] - Number of negative VADs to trigger silence.\n * @param {number} [options.wakeWordThreads=4] - Number of threads for wake word detection.\n * @param {number} [options.wakeWordThreshold=0.5] - Wake word detection threshold.\n * @param {string|string[]} [options.modelPath=\"/models/hey-buddy.onnx\"] - Path to wake word model.\n * @param {string} [options.vadModelPath=\"/pretrained/silero-vad.onnx\"] - Path to VAD model.\n * @param {string} [options.embeddingModelPath=\"/pretrained/speech-embedding.onnx\"] - Path to speech embedding model.\n * @param {string} [options.spectrogramModelPath=\"/pretrained/mel-spectrogram.onnx\"] - Path to mel spectrogram model.\n * @param {number} [options.batchSeconds=1.08] - Number of seconds per batch.\n * @param {number} [options.batchIntervalSeconds=0.12] - Number of seconds between batches.\n * @param {number} [options.targetSampleRate=16000] - Target sample rate for audio.\n * @param {number} [options.spectrogramMelBins=32] - Number of mel bins for spectrogram.\n * @param {number} [options.embeddingDim=96] - Dimension of speech embedding.\n * @param {number} [options.embeddingWindowSize=76] - Window size for speech embedding.\n * @param {number} [options.embeddingWindowStride=8] - Window stride for speech embedding.\n */\n constructor (options) {\n options = options || {};\n // Get options or use defaults for runtime\n this.debug = options.debug || false;\n options.positiveVadThreshold = options.positiveVadThreshold || 0.65;\n options.negativeVadThreshold = options.negativeVadThreshold || 0.4;\n options.negativeVadCount = options.negativeVadCount || 8;\n this.wakeWordThreads = options.wakeWordThreads || 4;\n this.wakeWordThreshold = options.wakeWordThreshold || 0.5;\n // Per-word thresholds (keyed by model file name, e.g. \"hey-ozwell\"); falls back to wakeWordThreshold.\n this.wakeWordThresholds = options.wakeWordThresholds || {};\n this.wakeWordInterval = options.wakeWordInterval || 2.0; // How often a wake word can be uttered\n\n // Get options or use defaults for models\n const modelPath = options.modelPath || \"/models/hey-buddy.onnx\";\n const modelArray = Array.isArray(modelPath) ? modelPath : [modelPath];\n const vadModelPath = options.vadModelPath || \"/pretrained/silero-vad.onnx\";\n const embeddingModelPath = options.embeddingModelPath || \"/pretrained/speech-embedding.onnx\";\n const spectrogramModelPath = options.spectrogramModelPath || \"/pretrained/mel-spectrogram.onnx\";\n const batchSeconds = options.batchSeconds || 1.08; // 1080ms * 16khz = 17280 samples\n const batchIntervalSeconds = options.batchIntervalSeconds || 0.12; // 120ms * 16khz = 1920 samples\n const targetSampleRate = options.targetSampleRate || 16000;\n const spectrogramMelBins = options.spectrogramMelBins || 32;\n const embeddingDim = options.embeddingDim || 96;\n const embeddingWindowSize = options.embeddingWindowSize || 76;\n const embeddingWindowStride = options.embeddingWindowStride || 8;\n const wakeWordEmbeddingFrames = options.wakeWordEmbeddingFrames || 16;\n\n // Initialize shared models\n this.vad = new SileroVAD(vadModelPath, targetSampleRate, options.positiveVadThreshold, options.negativeVadThreshold, options.negativeVadCount);\n this.vad.test(this.debug).catch((e) => console.warn(\"[HeyBuddy] vad.test failed\", e));\n\n this.spectrogram = new MelSpectrogram(spectrogramModelPath);\n this.spectrogram.test(this.debug).catch((e) => console.warn(\"[HeyBuddy] spectrogram.test failed\", e));\n this.spectrogramMelBins = spectrogramMelBins;\n\n this.embedding = new SpeechEmbedding(\n embeddingModelPath,\n embeddingDim,\n embeddingWindowSize,\n embeddingWindowStride,\n );\n this.embedding.test(this.debug).catch((e) => console.warn(\"[HeyBuddy] embedding.test failed\", e));\n this.embeddingDim = embeddingDim;\n this.embeddingWindowSize = embeddingWindowSize;\n this.embeddingWindowStride = embeddingWindowStride;\n this.embeddingBuffer = null;\n this.embeddingBufferArray = []\n\n // --- Voiceprint (per-user enrollment) layer ---\n // Stored voiceprints keyed by wake-word name; each is an array of Float32Array\n // (each a flattened [16x96] embedding window captured during enrollment). At\n // runtime we cosine-match the live embedding window against these.\n this.voiceprints = {};\n this.voiceprintThreshold = options.voiceprintThreshold ?? 0.85;\n this.voiceprintThresholds = options.voiceprintThresholds || {};\n // The voiceprint may only BOOST a phrase the general model already weakly hears, never\n // fire one it hears nothing of — this stops enrolling a DIFFERENT phrase (\"hey doug\").\n this.voiceprintGate = options.voiceprintGate ?? 0.3;\n this.embeddingMean = null; // running \"common-mode\" embedding, subtracted before cosine\n // RECALL use of the voiceprint (amplify a weak model fire). Default on for back-compat;\n // set false to use the voiceprint for PRECISION only (reject false fires in runWakeGate).\n this.voiceprintRecall = options.voiceprintRecall ?? true;\n // Debounce: require a phrase to clear its threshold for N CONSECUTIVE frames before firing.\n // Real wakes sustain (~4-9 frames in the browser pipeline); conversational false fires are brief\n // 1-2 frame spikes — so this cuts false fires ~30x at ~1pt recall cost (measured browser-faithful).\n // N=1 = off (legacy single-frame). Live-tunable via window.__debounceFrames.\n this.debounceFrames = options.debounceFrames ?? 1;\n this._consec = {}; // per-phrase consecutive-detected-frame counter\n this.lastWakeProb = 0; // peak fire confidence frozen at the last wake (the base level)\n this._peakProb = {}; // per-phrase peak probability within the current detection run\n this._peakEmb = {}; // per-phrase embedding window at that peak frame (used for the voiceprint)\n // The [16x96] embedding window at the moment a wake last fired — so the gate (runWakeGate)\n // and enrollment can reuse the exact window the model scored, no recompute.\n this.lastWakeEmbedding = null;\n\n // Initialize wake word models\n this.wakeWords = {};\n this.wakeWordTimes = {};\n this.wakeWordEmbeddingFrames = wakeWordEmbeddingFrames;\n for (let model of modelArray) {\n let modelName = model.split(\"/\").pop().split(\".\")[0];\n let modelThreshold = this.wakeWordThresholds[modelName] ?? this.wakeWordThreshold;\n this.wakeWords[modelName] = new WakeWord(model, modelThreshold);\n this.wakeWords[modelName].name = modelName; // for per-phrase window.__baseThr override\n this.wakeWords[modelName].test(this.debug).catch((e) => console.warn(`[HeyBuddy] ${modelName}.test failed`, e));\n }\n\n // Initialize state\n this.recording = false;\n this.audioBuffer = null;\n this.frameIntervalEma = 0;\n this.frameIntervalEmaWeight = 0.1;\n this.frameTimeEma = 0;\n this.frameTimeEmaWeight = 0.1;\n\n this.speechStartCallbacks = [];\n this.speechEndCallbacks = [];\n this.recordingCallbacks = [];\n this.processedCallbacks = [];\n this.detectedCallbacks = [];\n\n // Initialize batcher and add callback\n this.batcher = new AudioBatcher(\n batchSeconds,\n batchIntervalSeconds,\n targetSampleRate\n );\n this.batcher.onBatch((batch) => this.process(batch));\n }\n\n /**\n * Set a user's enrolled voiceprint for a wake word.\n * @param {string} name - Wake-word name (e.g. \"hey-ozwell\").\n * @param {Float32Array[]} vectors - Flattened embedding windows captured at enrollment.\n */\n setVoiceprint(name, vectors) { this.voiceprints[name] = vectors || []; }\n clearVoiceprint(name) { delete this.voiceprints[name]; }\n hasVoiceprint(name) {\n return Array.isArray(this.voiceprints[name]) && this.voiceprints[name].length > 0;\n }\n\n /**\n * Max cosine similarity between a live embedding window and the stored voiceprint set.\n * Cosine compares DIRECTION not magnitude, so it ignores loudness and keys on what the\n * sound actually is. Returns 0..1 (1 = near-identical).\n */\n voiceprintSimilarity(name, liveVec) {\n const set = this.voiceprints[name];\n if (!Array.isArray(set) || set.length === 0 || !liveVec) return 0;\n const mean = this.embeddingMean; // subtract the common-mode so cosine reflects CONTENT\n let best = -1; // allow negative (poor-match) scores through, don't floor them at 0\n for (const ref of set) {\n let dot = 0, na = 0, nb = 0;\n const n = Math.min(ref.length, liveVec.length);\n for (let i = 0; i < n; i++) {\n const a = mean ? ref[i] - mean[i] : ref[i];\n const b = mean ? liveVec[i] - mean[i] : liveVec[i];\n dot += a * b; na += a * a; nb += b * b;\n }\n if (na > 0 && nb > 0) { const s = dot / (Math.sqrt(na) * Math.sqrt(nb)); if (s > best) best = s; }\n }\n return best;\n }\n\n /**\n * Gets the names of wake words, chunked for threaded wake word detection.\n * @returns {string[][]} - Names of wake words.\n */\n get chunkedWakeWords() {\n return Object.keys(this.wakeWords).reduce((carry, name, i) => {\n const chunkIndex = Math.floor(i / this.wakeWordThreads);\n if (!carry[chunkIndex]) {\n carry[chunkIndex] = [];\n }\n carry[chunkIndex].push(name);\n return carry;\n }, []);\n }\n\n /**\n * Add a callback for when a wake word is detected.\n * @param {string|string[]} names - Name of wake word.\n * @param {Function} callback - Callback function.\n */\n onDetected(names, callback) {\n this.detectedCallbacks.push({names, callback});\n }\n\n /**\n * Add a callback for processed data.\n * @param {Function} callback - Callback function.\n */\n onProcessed(callback) {\n this.processedCallbacks.push(callback);\n }\n\n /**\n * Add a callback for speech start.\n * @param {Function} callback - Callback function.\n */\n onSpeechStart(callback) {\n this.speechStartCallbacks.push(callback);\n }\n\n /**\n * Add a callback for speech end.\n * @param {Function} callback - Callback function.\n */\n onSpeechEnd(callback) {\n this.speechEndCallbacks.push(callback);\n }\n\n /**\n * Add a callback for recording.\n * @param {Function} callback - Callback function.\n */\n onRecording(callback) {\n this.recordingCallbacks.push(callback);\n }\n\n /**\n * Trigger speech start event.\n */\n speechStart() {\n if (this.debug) {\n console.log(\"Speech start\");\n }\n for (let callback of this.speechStartCallbacks) {\n callback();\n }\n }\n\n /**\n * Trigger speech end event.\n */\n speechEnd() {\n if (this.debug) {\n console.log(\"Speech end\");\n }\n for (let callback of this.speechEndCallbacks) {\n callback();\n }\n if (this.recording) {\n this.dispatchRecording();\n this.recording = false;\n }\n }\n\n /**\n * Dispatch recording to all recording callbacks.\n */ \n dispatchRecording() {\n if (this.audioBuffer === null) {\n console.error(\"No recording to dispatch\");\n return;\n }\n if (this.debug) {\n const recordingLength = this.audioBuffer.length;\n const recordedDuration = recordingLength / this.batcher.targetSampleRate;\n console.log(`Dispatching recording with ${recordingLength} frames (${recordedDuration} s)`);\n }\n for (let callback of this.recordingCallbacks) {\n callback(this.audioBuffer);\n }\n this.audioBuffer = null;\n }\n\n /**\n * Trigger wake word detection event.\n * @param {string} name - Name of wake word.\n */\n wakeWordDetected(name) {\n const now = Date.now();\n if (this.wakeWordTimes[name] && (now - this.wakeWordTimes[name]) < this.wakeWordInterval * 1000) {\n return;\n }\n if (this.debug) {\n console.log(\"Wake word detected:\", name);\n }\n this.recording = true;\n this.wakeWordTimes[name] = now;\n // How long the phrase was, from its detection run. `_consec[name]` = consecutive detected frames up\n // to this fire; each frame is one batch interval (~120ms), so this ≈ the spoken phrase's duration.\n // Purely additive readout (detection logic unchanged) — consumers use it to trim the phrase off the\n // recorded audio without relying on a silent pause before it.\n const frameSec = (this.batcher && this.batcher.batchIntervalSamples && this.batcher.targetSampleRate)\n ? this.batcher.batchIntervalSamples / this.batcher.targetSampleRate : 0.12;\n this.lastWakeDurationSec = (this._consec[name] || 0) * frameSec;\n // FREEZE the wake embedding at THIS fire moment = the peak of the current detection run up to the\n // fire. Captured ONCE per fire (this runs after the interval guard above), so it can't drift to\n // later low-confidence frames during the recording tail — that drift collapsed the gate/enrollment\n // cosine (esp. with a low base threshold, where weak frames keep counting as \"detected\").\n // Enrollment and the runtime gate both read this same frozen value -> their cosines stay comparable.\n this.lastWakeEmbedding = (this._peakEmb && this._peakEmb[name])\n ? this._peakEmb[name]\n : ((this.embeddingBuffer && this.embeddingBuffer.data) ? Float32Array.from(this.embeddingBuffer.data) : null);\n // freeze the peak fire confidence too (the live prob spikes then drops, so reading it later is stale)\n this.lastWakeProb = (this._peakProb && this._peakProb[name]) ? this._peakProb[name] : 0;\n\n for (let {names, callback} of this.detectedCallbacks) {\n if (Array.isArray(names) && names.includes(name) || names === name) {\n callback();\n }\n }\n }\n\n /**\n * Trigger processed event.\n * @param {Object} data - Processed data.\n */\n processed(data) {\n for (let callback of this.processedCallbacks) {\n callback(data);\n }\n }\n\n /**\n * Runs wake word detection on a subset of wake words.\n * @param {string[]} wakeWordNames - Names of wake words to check.\n * @returns {Promise} - Promise that resolves when wake word detection is complete.\n */\n async checkWakeWordSubset(wakeWordNames) {\n return await Promise.all(\n wakeWordNames.map(name => this.wakeWords[name].checkWakeWordCalled(this.embeddingBuffer))\n );\n }\n\n /**\n * Run wake word detection on audio.\n * @returns {Promise} - Promise that resolves when wake word detection is complete.\n */\n async checkWakeWords() {\n const returnMap = {};\n for (let nameChunk of this.chunkedWakeWords) {\n const wakeWordsCalled = await this.checkWakeWordSubset(nameChunk);\n for (let i = 0; i < nameChunk.length; i++) {\n const name = nameChunk[i];\n const wordCalled = wakeWordsCalled[i];\n returnMap[name] = wordCalled;\n }\n }\n // Winner-take-all (MIE 2026-06-09): the two phrases share the word \"ozwell\" and can\n // co-fire on a single utterance. Since start/stop are mutually exclusive, when more than\n // one wake word crosses its threshold in the same window, fire ONLY the most CONFIDENT one\n // (highest raw probability). NOTE: do NOT compare by margin (prob - threshold) — that biases\n // toward the lower-threshold word (ozwell-done @0.5 out-margins hey-ozwell @0.8 even when you\n // clearly said \"hey ozwell\"). Raw probability is the correct comparison here.\n // Voiceprint layer: cosine-match the live embedding window against each phrase's\n // enrolled voiceprint. Attach the score (for graphing) and use it as a FALLBACK so a\n // user the general model is weak on (e.g. their accent) still triggers on a match.\n const liveVec = this.embeddingBuffer ? this.embeddingBuffer.data : null;\n for (let name in returnMap) {\n returnMap[name].voiceprintSim = this.hasVoiceprint(name)\n ? this.voiceprintSimilarity(name, liveVec) : 0;\n }\n\n // Debounce + PEAK-CAPTURE (per phrase). Track consecutive detected frames (debounce), AND the\n // PEAK-confidence embedding within the current run — so the voiceprint is captured at the\n // best-aligned frame, not wherever debounce happens to commit. Critical for SHORT phrases like\n // \"hey ozwell\": the debounce-fire frame can land on the tail (low/variable cosine), but the peak\n // frame is the real phrase moment (consistent cosine).\n for (let name in returnMap) {\n if (returnMap[name].detected) {\n this._consec[name] = (this._consec[name] || 0) + 1;\n if (returnMap[name].probability > (this._peakProb[name] || 0) && this.embeddingBuffer && this.embeddingBuffer.data) {\n this._peakProb[name] = returnMap[name].probability;\n this._peakEmb[name] = Float32Array.from(this.embeddingBuffer.data);\n }\n } else {\n this._consec[name] = 0; this._peakProb[name] = 0; this._peakEmb[name] = null;\n }\n }\n // Per-phrase debounce: window.__debounceFrames (number) overrides all; else this.debounceFrames may\n // be a number (global) or a {phrase: N} object (per-phrase). Short phrases need a lower N.\n const minRunFor = (name) => {\n if (typeof window.__debounceFrames === \"number\") return window.__debounceFrames;\n if (this.debounceFrames && typeof this.debounceFrames === \"object\") return this.debounceFrames[name] ?? 1;\n return this.debounceFrames || 1;\n };\n // Model winner-take-all (highest raw probability among phrases that have cleared their debounce).\n let best = null;\n for (let name in returnMap) {\n if (returnMap[name].detected && this._consec[name] >= minRunFor(name)) {\n const prob = returnMap[name].probability;\n if (best === null || prob > best.prob) {\n best = { name, prob };\n }\n }\n }\n if (best !== null) {\n // NOTE: lastWakeEmbedding is captured (frozen) INSIDE wakeWordDetected, once per fire, from the\n // run's peak — NOT here every frame (that drifted to later low-confidence frames -> bad cosine).\n this.wakeWordDetected(best.name);\n } else if (this.voiceprintRecall) {\n // RECALL (optional): general model fired nothing -> fall back to the strongest voiceprint\n // match. Off by default in this build — the voiceprint is used for PRECISION (reject) instead.\n let vbest = null;\n for (let name in returnMap) {\n const sim = returnMap[name].voiceprintSim;\n const vt = this.voiceprintThresholds[name] ?? this.voiceprintThreshold;\n // GATE: require the model to at least weakly hear THIS phrase, so the voiceprint\n // can only amplify the real wake word — not fire a different one (\"hey doug\").\n const modelLit = returnMap[name].probability >= this.voiceprintGate;\n if (sim >= vt && modelLit && (vbest === null || sim > vbest.sim)) vbest = { name, sim };\n }\n if (vbest !== null) {\n this.wakeWordDetected(vbest.name);\n }\n }\n return returnMap;\n }\n\n /**\n * Process audio batch.\n * @param {Float32Array} audio - Audio samples.\n */\n async process(audio) {\n // Start timer\n this.frameStart = (new Date()).getTime();\n\n if (this.frameEnd !== undefined && this.frameEnd !== null) {\n this.frameInterval = this.frameStart - this.frameEnd;\n } else {\n this.frameInterval = 0;\n }\n if (this.frameIntervalEma === 0) {\n this.frameIntervalEma = this.frameInterval;\n } else {\n this.frameIntervalEma = this.frameIntervalEma * (1 - this.frameIntervalEmaWeight) + this.frameInterval * this.frameIntervalEmaWeight;\n }\n\n // Get the last batch of samples\n const lastBatch = audio.subarray(audio.length - this.batcher.batchIntervalSamples);\n\n // Calculate the spectrogram for this buffer, assert it is exactly one window\n const spectrograms = await this.spectrogram.run(audio);\n const embedding = await this.embedding.getEmbeddingFromMelSpectrogramOutput(spectrograms);\n const numFramesPerEmbedding = embedding.dims[0];\n const maxEmbeddings = this.wakeWordEmbeddingFrames/numFramesPerEmbedding;\n\n\n // We want to run it via a \"window\" of audio samples at a time\n // so we add a new element, remove the first element, then analyze the new section of audio\n // (or rather audio embeddings) to see if the voice keyword is detected there\n this.embeddingBufferArray.push(embedding);\n if (this.embeddingBufferArray.length > maxEmbeddings) this.embeddingBufferArray.shift();\n\n this.embeddingBuffer = await embeddingBufferArrayToEmbedding(this.embeddingBufferArray, numFramesPerEmbedding, this.embeddingDim);\n\n const {isSpeaking, speechProbability, justStoppedSpeaking, justStartedSpeaking} = await this.vad.hasSpeechAudio(lastBatch);\n\n // Running BACKGROUND mean embedding, updated ONLY during non-speech so it stays an\n // ambient baseline and can't get contaminated by the phrase you're testing. We\n // subtract it in voiceprintSimilarity so cosine reflects content, not the shared\n // common-mode that otherwise pins every comparison near 0.9.\n if (!isSpeaking && this.embeddingBuffer && this.embeddingBuffer.data) {\n const d = this.embeddingBuffer.data;\n if (!this.embeddingMean || this.embeddingMean.length !== d.length) this.embeddingMean = Float32Array.from(d);\n else for (let i = 0; i < d.length; i++) this.embeddingMean[i] += 0.02 * (d[i] - this.embeddingMean[i]);\n }\n\n if(justStartedSpeaking) this.speechStart();\n if(justStoppedSpeaking) this.speechEnd();\n\n if (isSpeaking && this.embeddingBuffer.dims[0] === this.wakeWordEmbeddingFrames && !this._wakeBusy) {\n // If we're listening, run wake word detection. Guard against OVERLAPPING runs — if a wake\n // inference takes longer than the frame interval, the next frame would call run() on a\n // still-busy session → \"Session already started\". The guard skips those frames safely.\n this._wakeBusy = true;\n let wakeWordsCalled;\n try { wakeWordsCalled = await this.checkWakeWords(); }\n finally { this._wakeBusy = false; }\n // Trigger callbacks with processed data\n this.processed({\n listening: true,\n recording: this.recording,\n speech: {probability: speechProbability, active: isSpeaking},\n wakeWords: wakeWordsCalled,\n // Live [16x96] embedding window (flattened) — what enrollment captures and\n // what the voiceprint layer matches against. Present only while listening.\n embedding: this.embeddingBuffer ? this.embeddingBuffer.data : null\n });\n } else {\n // Trigger callbacks right away if we're not listening\n this.processed({\n listening: false,\n recording: this.recording,\n speech: {probability: speechProbability, active: isSpeaking},\n wakeWords: Object.entries(this.wakeWords).reduce(\n (carry, [name, model]) => {\n carry[name] = {\n probability: 0.0,\n active: false\n };\n return carry;\n },\n {}\n ),\n embedding: this.embeddingBuffer ? this.embeddingBuffer.data : null\n });\n }\n\n // If we're recording, append audio to buffer\n if (this.recording) {\n if (this.audioBuffer === null) {\n this.audioBuffer = new Float32Array(audio.length);\n this.audioBuffer.set(audio);\n } else {\n const concatenated = new Float32Array(this.audioBuffer.length + lastBatch.length);\n concatenated.set(this.audioBuffer);\n concatenated.set(lastBatch, this.audioBuffer.length);\n this.audioBuffer = concatenated;\n }\n }\n\n // Stop timer\n this.frameEnd = (new Date()).getTime();\n this.frameTime = this.frameEnd - this.frameStart;\n if (this.frameTimeEma === 0) {\n this.frameTimeEma = this.frameTime;\n } else {\n this.frameTimeEma = this.frameTimeEma * (1 - this.frameTimeEmaWeight) + this.frameTime * this.frameTimeEmaWeight;\n }\n }\n};\n\nif (typeof window !== \"undefined\") {\n window.HeyBuddy = HeyBuddy;\n}"]}