From 2bb155a9e4a3ed52365e36af8c2bbb4e65010ef8 Mon Sep 17 00:00:00 2001 From: timmy Date: Sun, 16 Aug 2026 03:56:50 +0000 Subject: [PATCH] fix: deduplicate cumulative voice results (Closes #935) --- frontend/voice-issue-capture.js | 1 + tests/test_voice_issue_capture.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/frontend/voice-issue-capture.js b/frontend/voice-issue-capture.js index b58d67a..462cd07 100644 --- a/frontend/voice-issue-capture.js +++ b/frontend/voice-issue-capture.js @@ -43,6 +43,7 @@ function createVoiceIssueCapture({ recognition.interimResults = false; recognition.onresult = event => { const finalText = Array.from(event.results || []) + .slice(event.resultIndex ?? 0) .filter(result => result.isFinal) .map(result => result[0]?.transcript || '').join(' ').replace(/\s+/g, ' ').trim(); if (finalText) { diff --git a/tests/test_voice_issue_capture.py b/tests/test_voice_issue_capture.py index 568d8f4..bf0e35e 100644 --- a/tests/test_voice_issue_capture.py +++ b/tests/test_voice_issue_capture.py @@ -157,7 +157,7 @@ const loads=[]; } -def test_multiple_final_segments_accumulate_in_one_bounded_checkpoint(): +def test_cumulative_recognition_events_append_each_new_final_segment_once(): script = f""" const {{createVoiceIssueCapture}} = require({json.dumps(str(VOICE_CAPTURE))}); class Element {{ @@ -165,6 +165,7 @@ class Element {{ addEventListener(name, callback) {{ this.listeners[name]=callback; }} click() {{ this.listeners.click?.(); }} dispatchEvent() {{}} }} +const result=(transcript,isFinal)=>Object.assign([{{transcript}}],{{isFinal}}); let recognition; class Recognition {{ constructor() {{ recognition=this; }} start() {{}} stop() {{}} abort() {{}} }} const elements=Object.fromEntries( @@ -176,8 +177,12 @@ const saved=[]; async load() {{ return ''; }}, async save(login,text) {{ saved.push(text); }}, async clear() {{}}, }}}}); await controller.ready; elements.start.click(); - recognition.onresult({{results:[Object.assign([{{transcript:'Lift outage.'}}],{{isFinal:true}})]}}); - recognition.onresult({{results:[Object.assign([{{transcript:'Elevator B is trapped.'}}],{{isFinal:true}})]}}); + const first=result('Lift outage.',true); + recognition.onresult({{resultIndex:0,results:[first]}}); + recognition.onresult({{ + resultIndex:1, + results:[first,result('Elevator B',false),result('Elevator B is trapped.',true)], + }}); await Promise.resolve(); process.stdout.write(JSON.stringify({{transcript:elements.transcript.value,saved}})); }})().catch(error=>{{console.error(error);process.exit(1);}}); -- 2.43.0