Explorar o código

ok, find in_reply_to

Paul Klumpp hai 1 semana
pai
achega
6ac51d2a8e
Modificáronse 2 ficheiros con 33 adicións e 35 borrados
  1. 32 34
      adapter.py
  2. 1 1
      platform_config.py

+ 32 - 34
adapter.py

@@ -12,6 +12,7 @@ including both outbound messaging and realtime WebSocket connections.
 
 from __future__ import annotations
 
+from builtins import ImportError
 import random
 
 from gateway.platforms.helpers import MessageDeduplicator
@@ -673,13 +674,14 @@ class ChattoAdapter(BasePlatformAdapter):
         except RuntimeError:
             logger.warning("Chatto: chattolib event loop aborted - no client available")
             return
-    
-        logger.info("Chatto WS: 'message_posted' event_payload:%s", payload)
+        logger.info("Chatto WS: 'message_posted' payload:%s", payload)
 
         message = await payload.fetch_message(client=client)
         if message is None or message.deleted_at:
             return
         message_body = message.body or ""
+        logger.info("message: %s", message)
+
         attachments = list(message.attachments or [])
         # A message carrying only an image/PDF has an empty body — dropping it
         # here is what made attachments sent to Hermes disappear silently.
@@ -749,13 +751,13 @@ class ChattoAdapter(BasePlatformAdapter):
                 await self.add_reaction(message.room_id, message.id, "🫥")
             return
 
-        # Thread anchoring — if the incoming message is inside a thread, we
+        # Thread anchoring — if the incoming message is inside a Chatto thread, we
         # keep that thread by default; otherwise leave thread_id unset so
         # replies land at the root.
-        thread_id = payload.thread_root_event_id or None
-        if not thread_id and room_kind != RoomKind.DM and self.chatto_config.auto_thread.value:
+        thread_id = payload.thread_root_event_id or None # we could also take "payload.room_id" but then, we're in a thread already.
+        if not thread_id and room_kind != RoomKind.DM:
             thread_id = message.id
-            
+
         source = self.build_source(
             chat_id=payload.room_id,
             chat_name=self._room_names.get(message.room_id),
@@ -767,37 +769,33 @@ class ChattoAdapter(BasePlatformAdapter):
             role_authorized=True,
         )
 
-        msg_type = MessageType.COMMAND if (message_body.lstrip().startswith("/")) else MessageType.TEXT
-
-        my_body = message_body.lstrip() if msg_type == MessageType.COMMAND else message_body
+        # prepare a MessageEvent
+        message_event = MessageEvent(
+            text=message_body,
+            source=source,
+            message_id=message.id,
+            timestamp=message.created_at or datetime.now(timezone.utc),
+            raw_message=message,
+            reply_to_message_id=message.in_reply_to,
+        )
+        if message_event.is_command():
+            message_event.message_type = MessageType.COMMAND
 
         # Attachments — download and hand the local cache paths to the gateway,
         # which runs vision enrichment / document extraction off media_urls.
-        media_urls, media_types, media_kinds = await self._cache_attachments(
+        message_event.media_urls, message_event.media_types, media_kinds = await self._cache_attachments(
             payload.room_id, attachments,
         )
-        if media_kinds and msg_type != MessageType.COMMAND:
+        if media_kinds:
             # Same precedence as the Teams/Signal adapters: document-context
             # injection gates strictly on DOCUMENT, image handling keys off the
             # per-path image/* MIME regardless of message_type.
-            msg_type = self._message_type_for_media_kinds(media_kinds)
+            message_event.message_type = self._message_type_for_media_kinds(media_kinds)
+        else:
+            message_event.message_type = MessageType.TEXT
 
-        message_event = MessageEvent(
-            text=my_body,
-            source=source,
-            message_id=message.id,
-            message_type=msg_type,
-            media_urls=media_urls,
-            media_types=media_types,
-            timestamp=message.created_at or datetime.now(timezone.utc),
-            raw_message=message,
-            reply_to_message_id=message.id,
-            reply_to_text=message_body,
-            reply_to_author_id=user.id,
-            reply_to_author_name=user.login,
-        )
-        logger.info("Chatto: Dispatching MessageEvent to Hermes: %s", message_event)
 
+        logger.info("Chatto: Dispatching MessageEvent to Hermes: %s", message_event)
         await self.handle_message(message_event)
         return
 
@@ -1934,9 +1932,9 @@ class ChattoAdapter(BasePlatformAdapter):
 # ---------------------------------------------------------------------------
 
 async def hermes_standalone_sender_fn(
-    pconfig,
-    chat_id,
-    message,
+    pconfig: PlatformConfig,
+    chat_id: str,
+    message: str,
     *,
     thread_id=None,
     media_files=None,
@@ -1974,14 +1972,14 @@ async def hermes_standalone_sender_fn(
     try:
         kwargs: Dict[str, Any] = {}
         if chatto_config.auto_thread.value and thread_id:
-            kwargs["in_reply_to"] = thread_id
+            kwargs["thread_root_event_id"] = thread_id
         if media_files and media_files.get("attachment_asset_ids"):
             kwargs["attachment_asset_ids"] = list(media_files["attachment_asset_ids"])
         try:
             posted = await client.post_message(chat_id, message, **kwargs)
         except Exception as exc:
             return SendResult(success=False, error=str(exc))
-        return SendResult(success=True, message_id=getattr(posted, "id", "") or None)
+        return SendResult(success=True, message_id=posted.id, raw_response=posted)
     finally:
         try:
             await client.close()
@@ -2019,7 +2017,7 @@ def hermes_check_fn() -> bool:
     """Check if Chatto is configured and dependencies are available.
     Add real logic?! Or just .. there are no dependencies.. always return true. Really. Docs suck."""
     try:
-        import chattolib.client  # noqa: F401 — vendored dependency probe
+        from .vendor.common.chattolib import client  # noqa: F401 — vendored dependency probe
         return True
     except ImportError:
         return False
@@ -2100,7 +2098,7 @@ def hermes_env_enablement_fn() -> Optional[dict]:
     # Seed keys must be the config.yaml "extra" keys (config_key), NOT the env
     # var names — ChattoConfiguration reads extra[config_key].
     seed: Dict[str, Any] = {
-        ChattoConfiguration.base_url.config_key: (
+        ChattoConfiguration.base_url.field_name: (
             os.getenv(ChattoConfiguration.base_url.env_name) or ChattoClient.DEFAULT_BASE_URL
         ).strip(),
     }

+ 1 - 1
platform_config.py

@@ -27,7 +27,7 @@ import utils
 # own modules import each other absolutely ("from chattolib.x import y").
 # Importing it relatively as well would load a *second* copy of every module
 # under a different name, so isinstance() checks across the two would fail.
-from chattolib.client import ChattoClient
+from chattolib import ChattoClient
 
 logger = logging.getLogger(__name__)