From 398e62f55a69d6e17c13c8063998b6fcab557dcd Mon Sep 17 00:00:00 2001 From: Mark Pesce Date: Sat, 23 May 2026 13:55:27 +1000 Subject: [PATCH] fix(telegram): stop typing indicator from lingering after response delivery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Telegram has no native 'stop typing' API — the indicator self-expires after ~5s. The gateway's _keep_typing() loop fires send_typing() every ~2s, and a race condition causes one final refresh after the response is already delivered, keeping the indicator alive for another 5s. Add stop_typing() to TelegramAdapter using the existing _typing_paused mechanism from the base adapter. The gateway already calls stop_typing() at the right moment — this just gives Telegram an implementation that pauses the refresh loop's last tick instead of inheriting the no-op. The _typing_paused set and the _keep_typing check/finally cleanup are already in BasePlatformAdapter — no new infrastructure needed. --- gateway/platforms/telegram.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gateway/platforms/telegram.py b/gateway/platforms/telegram.py index 799a836df735..50c84a124dd8 100644 --- a/gateway/platforms/telegram.py +++ b/gateway/platforms/telegram.py @@ -3963,6 +3963,16 @@ async def send_typing(self, chat_id: str, metadata: Optional[Dict[str, Any]] = N exc_info=True, ) + async def stop_typing(self, chat_id: str) -> None: + """Suppress the last _keep_typing refresh so Telegram's 5s indicator fades naturally. + + Telegram has no native "stop typing" API — the indicator expires on its own + after ~5s. Pausing the refresh loop here prevents a final spurious + send_typing() from resetting the 5s timer after the response has already + been delivered. + """ + self._typing_paused.add(chat_id) + async def get_chat_info(self, chat_id: str) -> Dict[str, Any]: """Get information about a Telegram chat.""" if not self._bot: