feat(telegram): skip-STT audio path + 2GB cap via local Bot API server
Two coordinated changes that unblock downstream audio pipelines (diarization, custom transcription, archival) on attachments larger than the public Bot API's 20MB getFile ceiling. - `stt.enabled: false` no longer drops voice/audio with a generic "transcription disabled" note. The gateway probes the cached file's duration (wave → mutagen → ffprobe ladder) and surfaces `[The user sent a voice message: <abs path> (duration: M:SS)]` to the agent so a skill or tool can pick up the raw file. The previous placeholder is replaced rather than appended when present. - `platforms.telegram.extra.base_url` set → adapter auto-lifts its document size cap from 20MB to 2GB (the local telegram-bot-api `--local` ceiling) and the "too large" reply reports the active limit dynamically. No new config knob; presence of `base_url` is the opt-in. - `platforms.telegram.extra.local_mode: true` wires `Application.builder().local_mode(True)` on the python-telegram-bot builder. PTB then reads files from disk instead of HTTP, which is required when telegram-bot-api runs in `--local` mode (the server returns absolute filesystem paths, not `/file/bot...` URLs). - gateway/run.py: rewrites the `stt.enabled: false` branch of `_enrich_message_with_transcription`. New `_format_duration` + `_probe_audio_duration` helpers. - gateway/platforms/telegram.py: `_max_doc_bytes` instance attribute derived from `extra.base_url`; `local_mode` builder wiring; dynamic "too large" message. - tests/gateway/test_stt_config.py: covers path-surfacing with and without an existing user message, and placeholder replacement. - tests/gateway/test_telegram_max_doc_bytes.py: 3 cases — default 20MB without base_url, 2GB when set, empty-string base_url keeps default. - website/docs/user-guide/messaging/telegram.md: new "Skipping STT" subsection under Voice Messages and a full "Large Files (>20MB) via Local Bot API Server" walkthrough (api_id/api_hash, docker-compose, one-time `logOut` migration, `platforms.telegram.extra` config, the `local_mode` disk-access requirement, the silent HTTP-fallback 404). - website/docs/user-guide/features/voice-mode.md: documents the `stt.enabled` knob in the config reference. - `pytest tests/gateway/test_telegram_max_doc_bytes.py tests/gateway/test_stt_config.py` → 9/9 passing. - Verified end-to-end on a live deployment: gateway log shows `Using custom Telegram base_url: http://...` and `Using Telegram local_mode (read files from disk)` on startup; voice messages above 20MB cache to disk and surface their path to the agent. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -439,6 +439,14 @@ class TelegramAdapter(BasePlatformAdapter):
|
||||
self._dm_topic_chat_ids: Set[str] = {
|
||||
str(e["chat_id"]) for e in self._dm_topics_config if "chat_id" in e
|
||||
}
|
||||
# Document size cap. Telegram's public Bot API caps getFile at 20MB; a
|
||||
# locally-hosted telegram-bot-api server (configured via extra.base_url)
|
||||
# raises that to 2GB, so the presence of base_url is the opt-in.
|
||||
self._max_doc_bytes: int = (
|
||||
2 * 1024 * 1024 * 1024
|
||||
if self.config.extra.get("base_url")
|
||||
else 20 * 1024 * 1024
|
||||
)
|
||||
# Interactive model picker state per chat
|
||||
self._model_picker_state: Dict[str, dict] = {}
|
||||
# Approval button state: message_id → session_key
|
||||
@@ -1315,6 +1323,14 @@ class TelegramAdapter(BasePlatformAdapter):
|
||||
"[%s] Using custom Telegram base_url: %s",
|
||||
self.name, custom_base_url,
|
||||
)
|
||||
# In local-mode telegram-bot-api, file_path is an absolute path on the
|
||||
# server's filesystem rather than a relative HTTP path. PTB needs
|
||||
# local_mode=True so download_*() reads from disk instead of issuing
|
||||
# an HTTP GET that would 404. Requires that the same path is
|
||||
# readable by the Hermes process (shared mount, same machine, etc.).
|
||||
if self.config.extra.get("local_mode"):
|
||||
builder = builder.local_mode(True)
|
||||
logger.info("[%s] Using Telegram local_mode (read files from disk)", self.name)
|
||||
|
||||
# PTB defaults (pool_timeout=1s) are too aggressive on flaky networks and
|
||||
# can trigger "Pool timeout: All connections in the connection pool are occupied"
|
||||
@@ -4894,11 +4910,11 @@ class TelegramAdapter(BasePlatformAdapter):
|
||||
|
||||
# Check file size early so image documents cannot bypass the
|
||||
# document size limit by taking the image path.
|
||||
MAX_DOC_BYTES = 20 * 1024 * 1024
|
||||
if not doc.file_size or doc.file_size > MAX_DOC_BYTES:
|
||||
if not doc.file_size or doc.file_size > self._max_doc_bytes:
|
||||
limit_mb = self._max_doc_bytes // (1024 * 1024)
|
||||
event.text = (
|
||||
"The document is too large or its size could not be verified. "
|
||||
"Maximum: 20 MB."
|
||||
f"Maximum: {limit_mb} MB."
|
||||
)
|
||||
logger.info("[Telegram] Document too large: %s bytes", doc.file_size)
|
||||
await self.handle_message(event)
|
||||
|
||||
Reference in New Issue
Block a user