From bca886c84441fae08a0135654b246e7f57d2a737 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sun, 19 Jul 2026 07:21:43 +0530 Subject: [PATCH] fix(gateway): invalidate pending STT cache when media merges into event merge_pending_message_event extends the existing event's media_urls in place when two media-bearing messages arrive in quick succession (photo bursts, consecutive voice messages). The gateway runner caches STT transcripts on the event via _gateway_pending_stt_text; if the cached event gains new media after the cache was populated, the stale transcript was returned instead of transcribing the merged attachments. Add _invalidate_pending_stt_cache() and call it from both media-merge branches in merge_pending_message_event so the next transcription call re-runs against the full merged media list. Closes the merge-race edge case identified during review of PR #61519. --- gateway/platforms/base.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index 1391395c32ff..4abe92072c68 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -2104,6 +2104,25 @@ class EphemeralReply(str): return str.__str__(self) +def _invalidate_pending_stt_cache(event: MessageEvent) -> None: + """Clear gateway-side STT cache attrs when media is merged into an event. + + ``merge_pending_message_event`` extends ``media_urls`` in place when two + media-bearing messages arrive in quick succession. The gateway runner + caches STT transcripts on the event via ``setattr`` (see + ``_transcribe_pending_audio_event_once``); if the cached event gains new + media after the cache was populated, the stale transcript must be + discarded so the next transcription call picks up the merged attachments. + """ + for attr in ( + "_gateway_pending_stt_text", + "_gateway_pending_stt_transcripts", + "_gateway_pending_stt_echo_sent", + ): + if hasattr(event, attr): + delattr(event, attr) + + def merge_pending_message_event( pending_messages: Dict[str, MessageEvent], session_key: str, @@ -2134,6 +2153,7 @@ def merge_pending_message_event( existing.media_types.extend(event.media_types) if event.text: existing.text = BasePlatformAdapter._merge_caption(existing.text, event.text) + _invalidate_pending_stt_cache(existing) return if existing_has_media or incoming_has_media: @@ -2152,6 +2172,7 @@ def merge_pending_message_event( and event.message_type != MessageType.TEXT ): existing.message_type = event.message_type + _invalidate_pending_stt_cache(existing) return if (