Skip to content

fix(gateway): make Telegram auto-TTS provider-aware - #62040

Closed
giladbau wants to merge 1 commit into
NousResearch:mainfrom
giladbau:feat/telegram-voice-input-ogg
Closed

fix(gateway): make Telegram auto-TTS provider-aware#62040
giladbau wants to merge 1 commit into
NousResearch:mainfrom
giladbau:feat/telegram-voice-input-ogg

Conversation

@giladbau

@giladbau giladbau commented Jul 10, 2026

Copy link
Copy Markdown

What does this PR do?

Fixes Telegram auto-TTS voice replies returning MP3 audio cards instead of native Opus voice bubbles.

  • Makes the target platform explicit on both gateway auto-TTS paths, removing reliance on ambient session context.
  • Routes providers by capability: native-Opus providers generate .ogg directly; MP3/WAV-native providers use a conversion-safe intermediate before Opus conversion.
  • Preserves manual output_path behavior, command/plugin configured formats, and voice_compatible opt-in semantics.
  • Cleans up requested, converted, and partial files on both success and failure.

Closes the gap left by stale PRs #31937 and #32539.

Type of Change

  • Bug fix
  • Tests

Verification

  • Gateway suite: 269 passed
  • TTS suite: 300 passed
  • Ruff + git diff --check: clean
  • Real Gemini smoke test: .ogg output, ffprobe codec = opus

+538 / -75 lines across 6 files.

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter tool/tts Text-to-speech and transcription sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages P2 Medium — degraded but workaround exists labels Jul 10, 2026
@giladbau
giladbau force-pushed the feat/telegram-voice-input-ogg branch from 3ae1956 to 1b4a0d5 Compare July 10, 2026 14:37

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for covering both gateway auto-TTS paths and preserving command/plugin-provider behavior. The main direction addresses a current Telegram delivery bug.

Problems

  • tools/tts_tool.py:401 classifies Gemini as native Opus, but _generate_gemini_tts produces PCM/WAV and needs ffmpeg to encode a valid .ogg/Opus file (tools/tts_tool.py:1768-1810). Without ffmpeg it copies WAV bytes to the .ogg path, while the new routing later marks that path voice-compatible (tools/tts_tool.py:2467-2468). The new Gemini test stubs the generator with OGG bytes, so it does not cover the real codec path.

Suggested changes

  • Separate Gemini from native-Opus providers or explicitly model its ffmpeg dependency, and add a regression covering the no-ffmpeg/resulting-codec behavior before advertising a Telegram voice bubble.

Automated hermes-sweeper review.

Comment thread tools/tts_tool.py
"kittentts",
"piper",
})
NATIVE_OPUS_TTS_PROVIDERS = frozenset({"elevenlabs", "openai", "mistral", "gemini"})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gemini is not native Opus: _generate_gemini_tts receives raw PCM, wraps it as WAV, then uses ffmpeg for .ogg/Opus; without ffmpeg it copies WAV bytes to the .ogg path. Please model that dependency separately and add a regression for the no-ffmpeg path rather than treating Gemini as a native-Opus provider.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 11, 2026
teknium1 pushed a commit that referenced this pull request Jul 28, 2026
…bbles

Salvaged from PR #62040 (@giladbau), simplified per post-#73072 main: the
central _repair_ogg_container transcode makes an explicit .ogg output path
sufficient — no target_platform plumbing through the TTS tool needed.

Root cause (class-level): both gateway auto-TTS delivery call sites relied
on the TTS tool reading HERMES_SESSION_PLATFORM to pick Ogg/Opus vs MP3,
but that contextvar is cleared by _clear_session_env before the base
adapter's post-handler auto-TTS block runs, so want_opus was always False
on that path → MP3 → Telegram sent an audio attachment instead of a native
voice bubble (#57049, #36685). The runner's _send_voice_reply had the
sibling bug: it hardcoded .ogg for Telegram only, leaving Matrix and
Feishu runner voice replies as MP3 (#14841, #45557).

Fix: new build_auto_tts_output_path(platform) in gateway/platforms/base.py
hands an explicit .ogg temp path when the platform is in the TTS tool's
OPUS_VOICE_PLATFORMS set (single source of truth — telegram/matrix/feishu/
whatsapp/signal), .mp3 otherwise. Used by BOTH delivery call sites:
- BasePlatformAdapter auto-TTS block (also honors the tool's success flag
  and cleans up requested + returned paths)
- GatewayRunner._send_voice_reply (replaces the telegram-only ternary)

Fixes #57049
Fixes #36685
Refs #14841 #45557
teknium1 pushed a commit that referenced this pull request Jul 28, 2026
…bbles

Salvaged from PR #62040 (@giladbau), simplified per post-#73072 main: the
central _repair_ogg_container transcode makes an explicit .ogg output path
sufficient — no target_platform plumbing through the TTS tool needed.

Root cause (class-level): both gateway auto-TTS delivery call sites relied
on the TTS tool reading HERMES_SESSION_PLATFORM to pick Ogg/Opus vs MP3,
but that contextvar is cleared by _clear_session_env before the base
adapter's post-handler auto-TTS block runs, so want_opus was always False
on that path → MP3 → Telegram sent an audio attachment instead of a native
voice bubble (#57049, #36685). The runner's _send_voice_reply had the
sibling bug: it hardcoded .ogg for Telegram only, leaving Matrix and
Feishu runner voice replies as MP3 (#14841, #45557).

Fix: new build_auto_tts_output_path(platform) in gateway/platforms/base.py
hands an explicit .ogg temp path when the platform is in the TTS tool's
OPUS_VOICE_PLATFORMS set (single source of truth — telegram/matrix/feishu/
whatsapp/signal), .mp3 otherwise. Used by BOTH delivery call sites:
- BasePlatformAdapter auto-TTS block (also honors the tool's success flag
  and cleans up requested + returned paths)
- GatewayRunner._send_voice_reply (replaces the telegram-only ternary)

Fixes #57049
Fixes #36685
Refs #14841 #45557
@teknium1

Copy link
Copy Markdown
Contributor

Merged into main via consolidated salvage PR #73508 (merge f440a44753). Your platform-aware explicit auto-TTS output path — fixing the cleared-contextvar root cause — was cherry-picked with your authorship (simplified post-#73072: the central container repair does the transcode).

Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage.

randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…bbles

Salvaged from PR NousResearch#62040 (@giladbau), simplified per post-NousResearch#73072 main: the
central _repair_ogg_container transcode makes an explicit .ogg output path
sufficient — no target_platform plumbing through the TTS tool needed.

Root cause (class-level): both gateway auto-TTS delivery call sites relied
on the TTS tool reading HERMES_SESSION_PLATFORM to pick Ogg/Opus vs MP3,
but that contextvar is cleared by _clear_session_env before the base
adapter's post-handler auto-TTS block runs, so want_opus was always False
on that path → MP3 → Telegram sent an audio attachment instead of a native
voice bubble (NousResearch#57049, NousResearch#36685). The runner's _send_voice_reply had the
sibling bug: it hardcoded .ogg for Telegram only, leaving Matrix and
Feishu runner voice replies as MP3 (NousResearch#14841, NousResearch#45557).

Fix: new build_auto_tts_output_path(platform) in gateway/platforms/base.py
hands an explicit .ogg temp path when the platform is in the TTS tool's
OPUS_VOICE_PLATFORMS set (single source of truth — telegram/matrix/feishu/
whatsapp/signal), .mp3 otherwise. Used by BOTH delivery call sites:
- BasePlatformAdapter auto-TTS block (also honors the tool's success flag
  and cleans up requested + returned paths)
- GatewayRunner._send_voice_reply (replaces the telegram-only ternary)

Fixes NousResearch#57049
Fixes NousResearch#36685
Refs NousResearch#14841 NousResearch#45557
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 platform/telegram Telegram bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform 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/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants