Просмотр исходного кода

Use lazy_deps for chattolib imports (Hermes plugin requirement)

- Replace all 'from chattolib...' imports with lazy_import calls
- Required for Hermes plugin system to handle optional dependencies
- Applies to main chattolib imports, chattolib.types, and internal modules

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Liv Klumpp 1 неделя назад
Родитель
Сommit
3ed96ebcec
2 измененных файлов с 40 добавлено и 33 удалено
  1. 31 29
      adapter.py
  2. 9 4
      test_adapter.py

+ 31 - 29
adapter.py

@@ -51,26 +51,26 @@ from gateway.platforms.base import (
 )
 from gateway.config import Platform
 
-# Chattolib imports
-from chattolib import (
-    ChattoClient,
-    ChattoError,
-    ChattoAuthError,
-    ChattoConnectError,
-    ChattoRealtimeError,
-    ChattoRealtimeCloseError,
-    RealtimeConnection,
-    RealtimeEvent,
-    ServerHello,
-    stream_events,
-)
-from chattolib.types import (
-    RoomKind,
-    PresenceStatus,
-    RoomWithViewerState,
-    User,
-    Message,
-)
+# Chattolib imports (lazy loaded)
+from tools.lazy_deps import lazy_import
+
+ChattoClient = lazy_import("chattolib", "ChattoClient")
+ChattoError = lazy_import("chattolib", "ChattoError")
+ChattoAuthError = lazy_import("chattolib", "ChattoAuthError")
+ChattoConnectError = lazy_import("chattolib", "ChattoConnectError")
+ChattoRealtimeError = lazy_import("chattolib", "ChattoRealtimeError")
+ChattoRealtimeCloseError = lazy_import("chattolib", "ChattoRealtimeCloseError")
+RealtimeConnection = lazy_import("chattolib", "RealtimeConnection")
+RealtimeEvent = lazy_import("chattolib", "RealtimeEvent")
+ServerHello = lazy_import("chattolib", "ServerHello")
+stream_events = lazy_import("chattolib", "stream_events")
+
+# chattolib types
+RoomKind = lazy_import("chattolib.types", "RoomKind")
+PresenceStatus = lazy_import("chattolib.types", "PresenceStatus")
+RoomWithViewerState = lazy_import("chattolib.types", "RoomWithViewerState")
+User = lazy_import("chattolib.types", "User")
+Message = lazy_import("chattolib.types", "Message")
 
 # --------------------------------------------------------------------------- #
 # Constants
@@ -490,8 +490,8 @@ class ChattoAdapter(BasePlatformAdapter):
     async def _seed_room(self, room_id: str) -> None:
         """Seed high-water mark from the newest events so a restart doesn't replay history."""
         try:
-            from chattolib._pb.chatto.api.v1 import room_service_pb2
-            from chattolib._transport import pb_to_dict
+            room_service_pb2 = lazy_import("chattolib._pb.chatto.api.v1", "room_service_pb2")
+            pb_to_dict = lazy_import("chattolib._transport", "pb_to_dict")
             
             resp = await self._chatto_client.services.rooms.get_room_events(
                 room_service_pb2.GetRoomEventsRequest(room_id=room_id),
@@ -650,7 +650,8 @@ class ChattoAdapter(BasePlatformAdapter):
         try:
             # event.payload is a RealtimeProjectionEvent protobuf message
             # We need to convert it to the dict format that _handle_projection_event expects
-            from chattolib._transport import pb_to_dict
+            from tools.lazy_deps import lazy_import
+            pb_to_dict = lazy_import("chattolib._transport", "pb_to_dict")
             
             pe_dict = pb_to_dict(event.payload)
             
@@ -722,7 +723,7 @@ class ChattoAdapter(BasePlatformAdapter):
         _handle_transient_event.
         """
         try:
-            from chattolib._transport import pb_to_dict
+            pb_to_dict = lazy_import("chattolib._transport", "pb_to_dict")
             
             # Build envelope dict based on event kind
             envelope = {
@@ -957,10 +958,13 @@ class ChattoAdapter(BasePlatformAdapter):
         """
         self._mark_seen(room_id, event_id)
         try:
+            # Import all required protobuf modules
+            thread_service_pb2 = lazy_import("chattolib._pb.chatto.api.v1", "thread_service_pb2")
+            room_service_pb2 = lazy_import("chattolib._pb.chatto.api.v1", "room_service_pb2")
+            pb_to_dict = lazy_import("chattolib._transport", "pb_to_dict")
+            
             if thread_root_event_id:
                 # Thread reply — use GetThreadEvents
-                from chattolib._pb.chatto.api.v1 import thread_service_pb2
-                from chattolib._transport import pb_to_dict
                 resp = await self._chatto_client.services.threads.get_thread_events(
                     thread_service_pb2.GetThreadEventsRequest(
                         room_id=room_id,
@@ -971,8 +975,6 @@ class ChattoAdapter(BasePlatformAdapter):
                 data = pb_to_dict(resp)
             else:
                 # Regular room message — use GetRoomEvents
-                from chattolib._pb.chatto.api.v1 import room_service_pb2
-                from chattolib._transport import pb_to_dict
                 resp = await self._chatto_client.services.rooms.get_room_events(
                     room_service_pb2.GetRoomEventsRequest(room_id=room_id),
                     headers=self._chatto_client._headers(),
@@ -2055,7 +2057,7 @@ async def _standalone_send(
     """Out-of-process send for cron delivery (no live adapter needed)."""
     try:
         # Create a temporary client for standalone sending
-        from chattolib import ChattoClient
+        # Use the lazy-imported ChattoClient
         client = ChattoClient(base_url=base_url)
         await client.login(login=login, password=password)
         

+ 9 - 4
test_adapter.py

@@ -22,6 +22,9 @@ from collections import OrderedDict
 import pytest
 import pytest_asyncio
 
+# Lazy imports for chattolib (required by Hermes plugin system)
+from tools.lazy_deps import lazy_import
+
 # -- Path setup --
 sys.path.insert(0, "/opt/hermes")
 sys.path.insert(0, "/root/.hermes/plugins/platforms/chatto")
@@ -295,7 +298,8 @@ class TestUserLookup:
         return adapter
 
     async def test_get_user_calls_chattolib(self, adapter):
-        from chattolib.types import User, GetUserResponse
+        User = lazy_import("chattolib.types", "User")
+        GetUserResponse = lazy_import("chattolib.types", "GetUserResponse")
         mock_user = User(id="user-1", login="testuser", display_name="Test User")
         adapter._chatto_client.get_user.return_value = GetUserResponse(user=mock_user)
         result = await adapter.get_user("user-1")
@@ -304,7 +308,8 @@ class TestUserLookup:
         assert result["login"] == "testuser"
 
     async def test_get_user_caching(self, adapter):
-        from chattolib.types import User, GetUserResponse
+        User = lazy_import("chattolib.types", "User")
+        GetUserResponse = lazy_import("chattolib.types", "GetUserResponse")
         mock_user = User(id="user-1", login="testuser", display_name="Test User")
         adapter._chatto_client.get_user.return_value = GetUserResponse(user=mock_user)
         result1 = await adapter.get_user("user-1")
@@ -376,7 +381,7 @@ class TestRoomOperations:
         return adapter
 
     async def test_create_room(self, adapter):
-        from chattolib.types import Room
+        Room = lazy_import("chattolib.types", "Room")
         mock_room = Room(id="room-123", name="Test Room", kind="ROOM_KIND_GROUP",
                         description="", archived=False, group_id="", universal=True)
         adapter._chatto_client.create_room.return_value = mock_room
@@ -385,7 +390,7 @@ class TestRoomOperations:
         adapter._chatto_client.create_room.assert_called_once()
 
     async def test_start_dm(self, adapter):
-        from chattolib.types import Room
+        Room = lazy_import("chattolib.types", "Room")
         mock_room = Room(id="dm-123", name="DM with user", kind="ROOM_KIND_DM",
                         description="", archived=False, group_id="", universal=False)
         adapter._chatto_client.start_dm.return_value = mock_room