diff --git a/src/helpers/whisperVadConfig.js b/src/helpers/whisperVadConfig.js index 8cbc72901..fab62c4bc 100644 --- a/src/helpers/whisperVadConfig.js +++ b/src/helpers/whisperVadConfig.js @@ -6,8 +6,10 @@ const VAD_LIMITS = Object.freeze(LIMITS); function clampVadField(key, value) { const fallback = DEFAULTS[key]; const n = value === null || value === undefined || value === "" ? fallback : Number(value); - if (!Number.isFinite(n)) return fallback; - const { min, max, round } = LIMITS[key]; + if (!Number.isFinite(n)) return fallback !== undefined ? fallback : value; + const limit = LIMITS[key]; + if (!limit) return n; + const { min, max, round } = limit; const clamped = Math.min(max, Math.max(min, n)); return round ? Math.round(clamped) : clamped; } @@ -26,9 +28,14 @@ function resolveContextSileroEnabled(settings = {}, context = "dictation") { // leave Whisper decoding near-silence seeded with the dictionary prompt, which // replaces the transcript with dictionary words (#1454). Long-form contexts // (notes, meetings) keep VAD to skip extended silence. - if (context === "dictation") return settings?.dictationSileroEnabled === true; - if (context === "noteRecording") return settings?.noteRecordingSileroEnabled !== false; - if (context === "meeting") return settings?.meetingSileroEnabled !== false; + const normalizedContext = + typeof context === "string" ? context.trim().toLowerCase() : "dictation"; + + if (normalizedContext === "dictation") return settings?.dictationSileroEnabled === true; + if (normalizedContext === "noterecording" || normalizedContext === "note_recording") { + return settings?.noteRecordingSileroEnabled !== false; + } + if (normalizedContext === "meeting") return settings?.meetingSileroEnabled !== false; return true; } diff --git a/test/helpers/whisperVadConfig.test.js b/test/helpers/whisperVadConfig.test.js index f3fa5f225..9b7164935 100644 --- a/test/helpers/whisperVadConfig.test.js +++ b/test/helpers/whisperVadConfig.test.js @@ -47,3 +47,20 @@ test("resolveContextSileroEnabled defaults dictation off, other contexts on", as assert.equal(resolveContextSileroEnabled({}, "noteRecording"), true); assert.equal(resolveContextSileroEnabled({}, "meeting"), true); }); + +test("clampVadField handles unknown keys safely without throwing", async () => { + const { clampVadField } = await import("../../src/helpers/whisperVadConfig.js"); + assert.equal(clampVadField("unknownField", 42), 42); + assert.equal(clampVadField(null, 42), 42); +}); + +test("resolveContextSileroEnabled normalizes casing and whitespace in context", async () => { + const { resolveContextSileroEnabled } = await import("../../src/helpers/whisperVadConfig.js"); + assert.equal(resolveContextSileroEnabled({}, " DICTATION "), false); + assert.equal(resolveContextSileroEnabled({}, "NoteRecording"), true); + assert.equal(resolveContextSileroEnabled({}, " MEETING "), true); + assert.equal( + resolveContextSileroEnabled({ dictationSileroEnabled: true }, "Dictation"), + true + ); +});