Skip to content

fix(gateway): preserve voice_only semantics for text input - #73938

Merged
teknium1 merged 1 commit into
NousResearch:mainfrom
juanmartitegui:fix/voice-only-text-regression
Jul 30, 2026
Merged

fix(gateway): preserve voice_only semantics for text input#73938
teknium1 merged 1 commit into
NousResearch:mainfrom
juanmartitegui:fix/voice-only-text-regression

Conversation

@juanmartitegui

Copy link
Copy Markdown
Contributor

Summary

  • Keep explicit chat-level voice modes (all, voice_only, off) authoritative over the adapter/global auto-TTS fallback.
  • Prevent voice_only chats from speaking normal text-input replies after the mode is synced into the adapter as an auto-TTS opt-in.
  • Preserve global voice.auto_tts behavior for chats with no explicit voice mode.

Root cause

The runner gate added in #73508 used voice_mode != "off" and adapter_auto_tts as a broad fallback. /voice on stores voice_only and also enables auto-TTS for that chat in the adapter, so adapter_auto_tts is True for both text and voice input. That widened voice_only into the equivalent of all.

The fallback should apply only when no explicit chat mode exists. An explicit voice_only mode should continue to require voice input.

Regression test

The existing voice_only gate test now includes the real adapter state produced by mode synchronization (_should_auto_tts_for_chat(...) == True). It fails on current main for text input and passes with this fix, while still confirming streamed voice input is spoken.

Validation

235 passed, 5 pre-existing RuntimeWarnings
ruff: all checks passed
python compile: passed
git diff --check: passed

Focused suites:

  • tests/gateway/test_auto_voice_reply_format.py
  • tests/gateway/test_voice_command.py
  • tests/gateway/test_base_auto_tts_output_format.py
  • tests/gateway/test_telegram_voice_v0_regressions.py

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery tool/tts Text-to-speech and transcription P2 Medium — degraded but workaround exists sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 29, 2026
@GodsBoy

GodsBoy commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Independent reproduction and local runtime verification

I reproduced this regression on a live Telegram gateway and applied this PR's production fix as a temporary local patch.

Reproduction

The chat had an explicit persisted mode of:

{
  "telegram:<redacted>": "voice_only"
}

Global voice.auto_tts was false.

On unpatched current Hermes, sending typed text still produced both the normal text reply and an unwanted TTS voice reply. The adapter reports auto-TTS enabled for the chat after the persisted voice_only mode is synchronised, so this condition widened voice_only into effectively all:

or (voice_mode != "off" and adapter_auto_tts)

Local fix applied

I applied the gate from this PR to the current gateway/run.py:

or (voice_mode is None and adapter_auto_tts)

I also carried the focused regression test, adapted only to its current location in tests/gateway/test_auto_voice_reply_format.py.

Verification

After applying the patch and restarting the gateway:

  • Gateway restarted successfully and remained active.
  • Typed Telegram input produced text only, with no voice attachment.
  • Explicit voice_only remained persisted for the chat.
  • The global auto-TTS fallback for chats with no explicit mode remained covered.
  • Focused gateway suites: 81 passed, 7 skipped.
  • Ruff on the two changed files: all checks passed.
  • Python compilation: passed.
  • git diff --check: passed.
  • Reapplying the local patch was idempotent and changed no files.

Focused suites run:

tests/gateway/test_auto_voice_reply_format.py
tests/gateway/test_voice_command.py
tests/gateway/test_base_auto_tts_output_format.py
tests/gateway/test_telegram_voice_v0_regressions.py

This confirms the PR fixes the reported regression in a real Telegram runtime, not only in an isolated unit test.

Current GitHub state

The PR workflow did not fail its tests. The CI run is currently recorded as action_required, so the fork workflow requires maintainer approval before substantive checks can execute:

https://github.com/NousResearch/hermes-agent/actions/runs/30428499647

The PR has since become conflicting with current main, so it also needs a refresh. The fix itself is still applicable to the current runner code and is working locally as described above.

Runtime media evidence

The repaired proof clip below shows the full regression sequence on Telegram: voice mode is enabled, typed text is sent, and Hermes responds with both a voice attachment and a text reply.

Telegram voice_only regression: typed text receives both voice and text

Open the 22-second MP4 proof clip

The clip is silent and trimmed to the relevant interaction. The original recording was retained separately.

@teknium1
teknium1 force-pushed the fix/voice-only-text-regression branch from 55f5f7a to 01b3727 Compare July 30, 2026 06:33
@teknium1
teknium1 merged commit 0bf471d into NousResearch:main Jul 30, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages tool/tts Text-to-speech and transcription type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants