fix(voice): Doppel-Ausfuehrung — identischen STT-Endpoint-Text <5s deduppen
Im Auto cancelt der App-seitige No-Speech-Watchdog den conversing-Stream
vorzeitig (Whisper-Partials kommen bei Fahrgeraeusch verspaetet) und startet
passives Lauschen, waehrend die Bridge dieselbe Aeusserung parallel noch
finalisiert. Ergebnis: derselbe Befehl ("nächstes lied") wird zweimal
ausgefuehrt — aus zwei verschiedenen audioRequestIds, darum griff die
bestehende ID-Idempotenz nicht.
Text-Fenster-Dedup: identischer normalisierter Endpoint-Text innerhalb 5s
wird verworfen. Serverseitig, kein APK noetig.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3006,6 +3006,24 @@ class ARIABridge:
|
||||
if self._is_duplicate_client_msg(client_msg_id):
|
||||
return
|
||||
|
||||
# Text-Fenster-Dedup: im Auto cancelt der App-No-Speech-Watchdog den
|
||||
# Stream vorzeitig und startet passives Lauschen, waehrend die Bridge
|
||||
# dieselbe Aeusserung parallel noch finalisiert → derselbe Befehl
|
||||
# kaeme zweimal (aus ZWEI verschiedenen audioRequestIds, darum greift
|
||||
# die ID-Idempotenz oben nicht). Identischen Endpoint-Text innerhalb
|
||||
# 5s verwerfen. Genuines "nächstes, nächstes" liegt praktisch immer
|
||||
# weiter auseinander (man hoert den Wechsel erst).
|
||||
_norm_txt = " ".join(text.lower().split())
|
||||
_now_t = asyncio.get_event_loop().time()
|
||||
if (_norm_txt
|
||||
and _norm_txt == getattr(self, "_last_endpoint_norm", "")
|
||||
and (_now_t - getattr(self, "_last_endpoint_at", 0.0)) < 5.0):
|
||||
logger.info("[rvs] stt_endpoint Dupe verworfen (gleicher Text <5s): %r",
|
||||
text[:60])
|
||||
return
|
||||
self._last_endpoint_norm = _norm_txt
|
||||
self._last_endpoint_at = _now_t
|
||||
|
||||
# App-Focus aus stt_stream_start-Registry auflösen (falls die
|
||||
# App-Version die projectId noch nicht mitschickt: leer = Hauptchat).
|
||||
stream_req_id = payload.get("requestId", "") or ""
|
||||
|
||||
Reference in New Issue
Block a user