mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
refactor(telegram): make typing thread-id resolver symmetric with send
Mirror _message_thread_id_for_typing() with _message_thread_id_for_send(): both now map the General forum topic (thread id "1") to None upfront. That removes the need for the retry-without-thread fallback in send_typing() entirely — if _message_thread_id_for_typing() returns a non-None value, it's a real user-created topic and falling back to the root chat is never correct. If Telegram rejects the typing action (e.g. topic deleted mid-session), we swallow it at debug level instead of bleeding the indicator into All Messages. Updates the General-topic typing regression test to assert the new single-call contract.
This commit is contained in:
parent
41545f7ec5
commit
d5357f816d
2 changed files with 21 additions and 22 deletions
|
|
@ -353,7 +353,10 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
|
||||
@classmethod
|
||||
def _message_thread_id_for_typing(cls, thread_id: Optional[str]) -> Optional[int]:
|
||||
if not thread_id:
|
||||
# Mirrors _message_thread_id_for_send: the General forum topic (thread id
|
||||
# "1") is represented as "no thread id" on the wire. User-created topics
|
||||
# keep their real id so typing stays scoped to that topic.
|
||||
if not thread_id or str(thread_id) == cls._GENERAL_TOPIC_THREAD_ID:
|
||||
return None
|
||||
return int(thread_id)
|
||||
|
||||
|
|
@ -2508,22 +2511,16 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
try:
|
||||
_typing_thread = self._metadata_thread_id(metadata)
|
||||
message_thread_id = self._message_thread_id_for_typing(_typing_thread)
|
||||
try:
|
||||
await self._bot.send_chat_action(
|
||||
chat_id=int(chat_id),
|
||||
action="typing",
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
except Exception as e:
|
||||
if message_thread_id is not None and self._is_thread_not_found_error(e):
|
||||
if str(_typing_thread) == self._GENERAL_TOPIC_THREAD_ID:
|
||||
await self._bot.send_chat_action(
|
||||
chat_id=int(chat_id),
|
||||
action="typing",
|
||||
message_thread_id=None,
|
||||
)
|
||||
else:
|
||||
raise
|
||||
# No retry-without-thread fallback here: _message_thread_id_for_typing
|
||||
# already maps the forum General topic to None, so any non-None value
|
||||
# reaching this call is a user-created topic. If Telegram rejects it
|
||||
# (e.g. topic deleted mid-session), we swallow the failure rather than
|
||||
# showing a typing indicator in the wrong chat/All Messages.
|
||||
await self._bot.send_chat_action(
|
||||
chat_id=int(chat_id),
|
||||
action="typing",
|
||||
message_thread_id=message_thread_id,
|
||||
)
|
||||
except Exception as e:
|
||||
# Typing failures are non-fatal; log at debug level only.
|
||||
logger.debug(
|
||||
|
|
|
|||
|
|
@ -159,22 +159,24 @@ async def test_send_omits_general_topic_thread_id():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_typing_retries_without_general_thread_when_not_found():
|
||||
"""Typing for forum General should fall back if Telegram rejects thread 1."""
|
||||
async def test_send_typing_general_topic_uses_none_thread_id():
|
||||
"""Typing for forum General should hit the API with message_thread_id=None directly.
|
||||
|
||||
_message_thread_id_for_typing() maps the General topic (thread id "1") to None
|
||||
the same way _message_thread_id_for_send() does, so there's no retry path — the
|
||||
first call is already correct.
|
||||
"""
|
||||
adapter = _make_adapter()
|
||||
call_log = []
|
||||
|
||||
async def mock_send_chat_action(**kwargs):
|
||||
call_log.append(dict(kwargs))
|
||||
if kwargs.get("message_thread_id") == 1:
|
||||
raise FakeBadRequest("Message thread not found")
|
||||
|
||||
adapter._bot = SimpleNamespace(send_chat_action=mock_send_chat_action)
|
||||
|
||||
await adapter.send_typing("-100123", metadata={"thread_id": "1"})
|
||||
|
||||
assert call_log == [
|
||||
{"chat_id": -100123, "action": "typing", "message_thread_id": 1},
|
||||
{"chat_id": -100123, "action": "typing", "message_thread_id": None},
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue