Skip to content

feat(gateway): per-platform suppress_text_when_voice for voice replies - #87397

Open
BBaFSE wants to merge 1 commit into
NousResearch:mainfrom
BBaFSE:feat/suppress-text-on-voice
Open

feat(gateway): per-platform suppress_text_when_voice for voice replies#87397
BBaFSE wants to merge 1 commit into
NousResearch:mainfrom
BBaFSE:feat/suppress-text-on-voice

Conversation

@BBaFSE

@BBaFSE BBaFSE commented Aug 16, 2026

Copy link
Copy Markdown

What does this PR do?

Adds an opt-in per-platform suppress_text_when_voice config flag that drops the redundant written text when a voice reply (auto-TTS speak or a MEDIA voice clip) is delivered with no other non-voice content. On platforms whose voice notes arrive as caption-less attachments (e.g. Signal), this avoids the user receiving audio and the same text twice. Default off preserves existing behavior. Also fixes a latent bug where an empty handler response could raise UnboundLocalError by reading the suppression flag before it was initialized.

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • 🐛 Bug fix (UnboundLocalError on empty responses)

Changes Made

  • gateway/config.py — added PlatformConfig.suppress_text_when_voice: bool = False (parsed from top-level or extra), serialized in to_dict.
  • gateway/platforms/base.py — extracted _should_suppress_text_on_voice() helper; wired it into _process_message_background; initialized _suppress_text = False at function top (fixes the UnboundLocalError); kept the ✅-not-❌ success handling for suppressed voice delivery.
  • cli-config.yaml.example — documented the key.
  • tests/gateway/test_suppress_text_when_voice.py — config parsing + helper logic tests.

How to Test

  1. platforms.signal.suppress_text_when_voice: true.
  2. Send a voice message on Signal that triggers a voice reply → only the voice clip, no redundant text; reaction shows ✅ not ❌.
  3. On a platform with the flag unset (default false) → text is still sent.

Checklist

  • Conventional commit message
  • PR contains only changes related to this feature
  • Tests added and passing
  • Tested on Linux (self-hosted HA1)

@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery tool/tts Text-to-speech and transcription area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 16, 2026
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

feat(gateway): per-platform suppress_text_when_voice for voice replies

  • Suppression is decided before the voice delivery outcome is known. _suppress_text is set at the point the text would be sent, but the later if _suppress_text: delivery_attempted = True; delivery_succeeded = True; processing_ok = True marks the turn successful unconditionally. If TTS generation fails or the voice send raises after suppression was decided, the user receives neither audio nor text while the processing hooks report success. Consider computing/clearing _suppress_text based on the actual voice send result (e.g. clear it when the voice delivery fails so the text fallback still goes out, and only mark success when voice actually landed).

  • Same assumption for non-voice media. _should_suppress_text_on_voice treats presence of images/local_files as "non-voice content, keep text" — but if those deliveries fail, text is still suppressed under the same "assume delivery succeeded" pattern. Minor given the first point, but the helper itself is purely presence-based.

  • Minor: to_dict always emits suppress_text_when_voice (non-optional bool defaulting False), consistent with typing_indicator/gateway_restart_notification — fine. The else: _suppress_text = False reset inside the response block correctly re-initializes per turn; good.

@BBaFSE
BBaFSE force-pushed the feat/suppress-text-on-voice branch from 9206ba7 to 2d3f202 Compare August 16, 2026 19:22
@BBaFSE

BBaFSE commented Aug 16, 2026

Copy link
Copy Markdown
Author

Fixed. Text suppression now tracks actual voice delivery. _voice_delivered_ok is set only when auto-TTS play_tts or a media voice send_voice actually succeeds; _should_suppress_text_on_voice takes that delivered flag instead of file presence; a queued MEDIA voice clip defers the text and falls back to text if the send fails; the success mask requires _suppress_text and _voice_delivered_ok. Added integration tests for voice-send failure → text fallback, voice+text failure → FAILURE, voice delivered → text suppressed + SUCCESS, and the agent-tool voice-clip path. On the non-voice media point: images/local_files stay presence-based intentionally: when they're present the helper keeps the text, so the text is the fallback if that media fails (the inverse of the voice bug, so no silent-drop case there).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages tool/tts Text-to-speech and transcription type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants