fix(gateway): keep the STT echo ledger across pending-media merges - #67281
fix(gateway): keep the STT echo ledger across pending-media merges#67281Frowtek wants to merge 1 commit into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the pending-event STT cache/echo interaction. The reported defect is present on current main: gateway/platforms/base.py:2120 deletes _gateway_pending_stt_echo_sent, while gateway/run.py:16431-16434 uses that attribute as the one-time echo guard. The count-and-tail approach addresses the merged-media prefix correctly.
Problems
- The PR also carries an unrelated
api_contentreplay hunk ingateway/run.py:852-868. Current main already has that exact code from7b3dcee928e6; it should not be bundled with this STT fix. - The tests do not cover the documented identical-transcript case. A value-based deduplication implementation could pass the added
hello/worldtest while incorrectly collapsing two separatehellovoice notes.
Suggested changes
- Drop the already-landed replay-sidecar hunk.
- Add a two-voice-note, same-transcript regression asserting two echoes.
Automated hermes-sweeper review.
| @@ -849,6 +849,23 @@ def _build_replay_entry( | |||
| providers. | |||
| """ | |||
| entry: Dict[str, Any] = {"role": role, "content": content} | |||
| # api_content sidecar (persist-what-you-send, prompt-cache stability): | |||
There was a problem hiding this comment.
This api_content replay hunk is unrelated to the STT ledger and is already present on current main at gateway/run.py:852-868 via 7b3dcee928e6. Please remove it from this PR so the salvage remains scoped to the STT fix.
_invalidate_pending_stt_cache() clears the gateway-side transcription
cache when merge_pending_message_event() folds a follow-up message into a
still-pending event, so the next transcription picks up the merged text
and attachments. It also cleared _gateway_pending_stt_echo_sent, but that
flag is not derived state — it records that the transcript was already
delivered to the user.
Dropping it makes the re-run transcription echo the earlier notes a second
time. Both merge branches are affected, including the text-only follow-up
case where no new audio arrived at all: there the cache is invalidated,
the same voice note is transcribed again (a second paid STT call) and the
same line is echoed again.
Sequence:
1. voice note arrives, interrupt monitor transcribes it and echoes
'🎙️ "hello"'
2. user sends a follow-up while the turn is still pending, so it merges
3. drain path re-transcribes and echoes '🎙️ "hello"' a second time
Keep the ledger out of the invalidation set and track it as a count of
already-echoed transcripts instead of a single boolean. A count is what
the merge case actually needs: re-running transcription over the extended
media list returns the earlier transcripts as a prefix of the new one, so
echoing only the unsent tail suppresses the repeat while still surfacing a
newly merged voice note. A count rather than a set of seen values, so two
separate notes that transcribe identically stay two distinct deliveries —
covered by test_pending_stt_merge_echoes_two_identical_transcripts.
The guard stays within the 12-line window that
test_all_gateway_transcript_echo_sends_are_gated enforces over run.py.
667aaff to
91cba28
Compare
…point Follow-up for salvaged #65023/#53020: _prepare_busy_steer_text now calls _transcribe_and_echo_pending_voice (the same helper the interrupt monitor and pending-drain paths use) instead of a private transcription+echo copy, so out-of-band voice pays one STT call per platform message and the echo respects the count-based ledger from #67281. can_steer now accepts events whose attachments are all STT-eligible voice media, completing the steer half of #58780. Adds extract_media gating tests for #44826 and the contributor mapping for chefboyrdave21.
|
Merged into main via consolidated salvage PR #73518 (merge Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage. |
…point Follow-up for salvaged NousResearch#65023/NousResearch#53020: _prepare_busy_steer_text now calls _transcribe_and_echo_pending_voice (the same helper the interrupt monitor and pending-drain paths use) instead of a private transcription+echo copy, so out-of-band voice pays one STT call per platform message and the echo respects the count-based ledger from NousResearch#67281. can_steer now accepts events whose attachments are all STT-eligible voice media, completing the steer half of NousResearch#58780. Adds extract_media gating tests for NousResearch#44826 and the contributor mapping for chefboyrdave21.
Summary
_invalidate_pending_stt_cache()(added in #67248) clears the gateway-sidetranscription cache when
merge_pending_message_event()folds a follow-upmessage into a still-pending event, so the next transcription call picks up the
merged text and attachments. That part is correct.
It also clears
_gateway_pending_stt_echo_sent. That flag is not derived state —it records that the transcript was already delivered to the user. Dropping it
makes the re-run transcription echo the earlier notes a second time.
Both merge branches are affected, including the text-only follow-up case where
no new audio arrived at all: the cache is invalidated, the same voice note is
transcribed again (a second paid STT call), and the same line is echoed again.
Reproduction
🎙️ "hello"🎙️ "hello"a second timeAgainst
origin/main, with a second voice note merging in, the user receives:Fix
Keep the ledger out of the invalidation set, and track it as a count of
already-echoed transcripts rather than a single boolean.
A count is what the merge case actually needs: re-running transcription over the
extended media list returns the earlier transcripts as a prefix of the new
list, so echoing only the unsent tail suppresses the repeat while still
surfacing a newly merged voice note. Two identical transcripts from two separate
notes stay distinct — a value-based dedup would have collapsed them.
hello,hellohellohello,hello,worldhello,worldhello,hello,hellohello,hello_gateway_pending_stt_echo_senthad exactly one reader (the echo helper itself),so replacing it with
_gateway_pending_stt_echoedis self-contained.Testing
Two regression tests added to
tests/gateway/test_telegram_voice_v0_regressions.py,driving the real
merge_pending_message_event()and echo helper:test_pending_stt_merge_does_not_re_echo_delivered_transcripttest_pending_stt_merge_echoes_only_the_newly_merged_transcriptBoth fail on
origin/mainwith the duplicate-echo symptom above and pass withthis change.
Full gateway voice/STT/pending/merge/telegram selection compared against a clean
origin/mainworktree: identical 15 pre-existing failures (network/SSL-dependentTelegram tests),
2002 -> 2004passed, no new failures.Checklist
mainand covered by a failing-before/passing-after testorigin/main)