mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
fix: refresh stale Telegram DM topic threads
(cherry picked from commit 26b87057ad)
This commit is contained in:
parent
dcd504cea4
commit
c394e7919d
5 changed files with 202 additions and 14 deletions
|
|
@ -44,6 +44,25 @@ def _looks_like_int(value: Optional[str]) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def _send_result_failed(result: Any) -> bool:
|
||||
if isinstance(result, dict):
|
||||
return result.get("success") is False
|
||||
return getattr(result, "success", True) is False
|
||||
|
||||
|
||||
def _send_result_error(result: Any) -> Optional[str]:
|
||||
if isinstance(result, dict):
|
||||
error = result.get("error")
|
||||
else:
|
||||
error = getattr(result, "error", None)
|
||||
return str(error) if error else None
|
||||
|
||||
|
||||
def _is_thread_not_found_delivery_error(result: Any) -> bool:
|
||||
error = _send_result_error(result)
|
||||
return bool(error and "thread not found" in error.lower())
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeliveryTarget:
|
||||
"""
|
||||
|
|
@ -268,6 +287,8 @@ class DeliveryRouter:
|
|||
)
|
||||
|
||||
send_metadata = dict(metadata or {})
|
||||
is_named_telegram_private_topic = False
|
||||
named_telegram_private_topic_name: Optional[str] = None
|
||||
if target.thread_id:
|
||||
has_explicit_direct_topic = (
|
||||
"direct_messages_topic_id" in send_metadata
|
||||
|
|
@ -283,6 +304,7 @@ class DeliveryRouter:
|
|||
and not has_explicit_direct_topic
|
||||
)
|
||||
if is_named_telegram_private_topic:
|
||||
named_telegram_private_topic_name = target_thread_id
|
||||
ensure_dm_topic = getattr(adapter, "ensure_dm_topic", None)
|
||||
if ensure_dm_topic is None:
|
||||
raise RuntimeError(
|
||||
|
|
@ -318,8 +340,37 @@ class DeliveryRouter:
|
|||
elif "thread_id" not in send_metadata and "message_thread_id" not in send_metadata and not has_explicit_direct_topic:
|
||||
send_metadata["thread_id"] = target_thread_id
|
||||
result = await adapter.send(target.chat_id, content, metadata=send_metadata or None)
|
||||
if getattr(result, "success", True) is False:
|
||||
raise RuntimeError(getattr(result, "error", None) or f"{target.platform.value} delivery failed")
|
||||
if _send_result_failed(result):
|
||||
if (
|
||||
is_named_telegram_private_topic
|
||||
and named_telegram_private_topic_name
|
||||
and _is_thread_not_found_delivery_error(result)
|
||||
):
|
||||
ensure_dm_topic = getattr(adapter, "ensure_dm_topic", None)
|
||||
if ensure_dm_topic is None:
|
||||
raise RuntimeError(
|
||||
"Telegram adapter cannot refresh named private DM topics"
|
||||
)
|
||||
try:
|
||||
refreshed_thread_id = await ensure_dm_topic(
|
||||
target.chat_id,
|
||||
named_telegram_private_topic_name,
|
||||
force_create=True,
|
||||
)
|
||||
except TypeError:
|
||||
refreshed_thread_id = await ensure_dm_topic(
|
||||
target.chat_id,
|
||||
named_telegram_private_topic_name,
|
||||
)
|
||||
if not refreshed_thread_id:
|
||||
raise RuntimeError(
|
||||
f"Failed to refresh Telegram private DM topic '{named_telegram_private_topic_name}'"
|
||||
)
|
||||
send_metadata["thread_id"] = str(refreshed_thread_id)
|
||||
send_metadata["telegram_dm_topic_created_for_send"] = True
|
||||
result = await adapter.send(target.chat_id, content, metadata=send_metadata or None)
|
||||
if _send_result_failed(result):
|
||||
raise RuntimeError(_send_result_error(result) or f"{target.platform.value} delivery failed")
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1192,7 +1192,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
thread_id = await self._create_dm_topic(chat_id_int, name=name)
|
||||
return str(thread_id) if thread_id else None
|
||||
|
||||
async def ensure_dm_topic(self, chat_id: str, topic_name: str) -> Optional[str]:
|
||||
async def ensure_dm_topic(self, chat_id: str, topic_name: str, force_create: bool = False) -> Optional[str]:
|
||||
"""Return a private DM topic thread id, creating and persisting it if needed."""
|
||||
name = str(topic_name or "").strip()
|
||||
if not name:
|
||||
|
|
@ -1204,7 +1204,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
|
||||
cache_key = f"{chat_id_int}:{name}"
|
||||
cached = self._dm_topics.get(cache_key)
|
||||
if cached:
|
||||
if cached and not force_create:
|
||||
return str(cached)
|
||||
|
||||
topic_conf: Optional[Dict[str, Any]] = None
|
||||
|
|
@ -1219,7 +1219,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
break
|
||||
break
|
||||
|
||||
if topic_conf and topic_conf.get("thread_id"):
|
||||
if topic_conf and topic_conf.get("thread_id") and not force_create:
|
||||
thread_id = int(topic_conf["thread_id"])
|
||||
self._dm_topics[cache_key] = thread_id
|
||||
return str(thread_id)
|
||||
|
|
@ -1242,7 +1242,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
|
||||
topic_conf["thread_id"] = thread_id
|
||||
self._dm_topics[cache_key] = int(thread_id)
|
||||
self._persist_dm_topic_thread_id(chat_id_int, name, int(thread_id))
|
||||
self._persist_dm_topic_thread_id(chat_id_int, name, int(thread_id), replace_existing=force_create)
|
||||
return str(thread_id)
|
||||
|
||||
async def rename_dm_topic(
|
||||
|
|
@ -1268,7 +1268,13 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
self.name, chat_id, thread_id, name,
|
||||
)
|
||||
|
||||
def _persist_dm_topic_thread_id(self, chat_id: int, topic_name: str, thread_id: int) -> None:
|
||||
def _persist_dm_topic_thread_id(
|
||||
self,
|
||||
chat_id: int,
|
||||
topic_name: str,
|
||||
thread_id: int,
|
||||
replace_existing: bool = False,
|
||||
) -> None:
|
||||
"""Save a newly created thread_id back into config.yaml so it persists across restarts."""
|
||||
try:
|
||||
from hermes_constants import get_hermes_home
|
||||
|
|
@ -1301,9 +1307,10 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
matching_chat_entry = chat_entry
|
||||
for t in chat_entry.setdefault("topics", []):
|
||||
if t.get("name") == topic_name:
|
||||
if not t.get("thread_id"):
|
||||
t["thread_id"] = thread_id
|
||||
changed = True
|
||||
if replace_existing or not t.get("thread_id"):
|
||||
if t.get("thread_id") != thread_id:
|
||||
t["thread_id"] = thread_id
|
||||
changed = True
|
||||
break
|
||||
else:
|
||||
chat_entry.setdefault("topics", []).append(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue