fix(gateway): handle silent audio and media producers - #65745
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Fix handles silent audio and media producers in gateway (+169 -6). Good edge case handling improvement.
Reviewed by Hermes Agent
teknium1
left a comment
There was a problem hiding this comment.
Thanks for covering real gateway edge cases. The silent-STT, producer-metadata, and failed-send premises still exist on current main (gateway/run.py:15806, 1215, and 13730).
Problems
- The new busy-session voice branch calls
adapter.send(...)before the localadapterbinding. In current main, the binding remains later in the same function atgateway/run.py:5631; the PR inserts its echo call before that point. A normal non-empty transcript with STT echo enabled therefore raises instead of reaching busy handling. The added test only exercises the empty-transcript early return.
Suggested changes
- Move/resolve the adapter lookup before the new transcription block and retain the existing absent-adapter fallback.
- Add a busy non-empty-voice test with transcript echo enabled, asserting both the echo and subsequent busy-mode behavior.
Automated hermes-sweeper review.
| event.media_urls = [] | ||
| event.media_types = [] | ||
| if self._should_echo_stt_transcripts(): | ||
| echo_meta = self._thread_metadata_for_source( |
There was a problem hiding this comment.
adapter is assigned only later in this function's normal busy-case setup. Resolve it before this STT block (and preserve the no-adapter fallback), otherwise a non-empty transcript with echo enabled raises here.
|
Vox Lockin lane 07 verification — partially superseded on main; residual gaps shipped in #78196. Probed against origin/main @ Already on main (not re-applied):
Genuine residuals still missing on main (shipped in #78196, commit 2):
This PR's head ( |
…ribution Maps the author emails of the two salvaged gateway voice commits (from NousResearch#74051 @mglavinic86 and NousResearch#65745 @dhansxd) so the check-attribution CI gate can resolve them to their GitHub identities. Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
Summary
tool_name/namewhen the paired assistanttool_callsrow is absent.SendResultvalues instead of silently ignoring them.Generic symptoms
Command-backed STT can exit successfully with an empty transcript for silence. Fresh silent voice previously reached the LLM as a quoted empty string, while silent voice received during an active turn could queue and interrupt that turn.
Post-stream media extraction also required a paired assistant tool-call row. Persisted/reconstructed tool results that retained explicit producer metadata but lost that row could therefore fail to auto-deliver valid generated media.
Security invariant
Automatic file delivery remains fail-closed: explicit tool-result metadata only identifies the producer; producer must still match
_AUTO_APPEND_MEDIA_TOOL_NAMES, and path matching plus delivery-path filtering remain unchanged. Arbitrary tools such asterminalcannot auto-deliver files.Test evidence
Strict RED observed before implementation:
tests/gateway/test_stt_config.py: 1 failed, 7 passed ('" \\n"' is None)tests/gateway/test_busy_session_ack.py: 1 failed, 26 passed (silent voice queued/interrupted)tests/gateway/test_media_extraction.py: 2 failed, 17 passed (explicittool_name/nameignored); arbitrary producer cases passedtests/gateway/test_send_voice_reply_notify.py: 1 failed, 2 passed (unsuccessful send result not logged)GREEN:
ruff format --checkwas also inspected but not used as a gate: currentgateway/run.pyand touched legacy test files are already not ruff-formatted onmain; formatting whole files would create a large unrelated diff.