diff --git a/gateway/platforms/feishu_comment_rules.py b/gateway/platforms/feishu_comment_rules.py index 6ddd4776db..054ef95698 100644 --- a/gateway/platforms/feishu_comment_rules.py +++ b/gateway/platforms/feishu_comment_rules.py @@ -11,21 +11,26 @@ from __future__ import annotations import json import logging -import os import time from dataclasses import dataclass, field from pathlib import Path from typing import Any, Dict, Optional +from hermes_constants import get_hermes_home + logger = logging.getLogger(__name__) # --------------------------------------------------------------------------- # Paths # --------------------------------------------------------------------------- +# +# Uses the canonical ``get_hermes_home()`` helper (HERMES_HOME-aware and +# profile-safe). Resolved at import time; this module is lazy-imported by +# the Feishu comment event handler, which runs long after profile overrides +# have been applied, so freezing paths here is safe. -_HERMES_HOME = Path(os.environ.get("HERMES_HOME", os.path.expanduser("~/.hermes"))) -RULES_FILE = _HERMES_HOME / "feishu_comment_rules.json" -PAIRING_FILE = _HERMES_HOME / "feishu_comment_pairing.json" +RULES_FILE = get_hermes_home() / "feishu_comment_rules.json" +PAIRING_FILE = get_hermes_home() / "feishu_comment_pairing.json" # --------------------------------------------------------------------------- # Data models diff --git a/scripts/release.py b/scripts/release.py index 464620d97e..8fd6dfc18a 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -76,6 +76,7 @@ AUTHOR_MAP = { "Asunfly@users.noreply.github.com": "Asunfly", # contributors (manual mapping from git names) "ahmedsherif95@gmail.com": "asheriif", + "liujinkun@bytedance.com": "liujinkun2025", "dmayhem93@gmail.com": "dmahan93", "samherring99@gmail.com": "samherring99", "desaiaum08@gmail.com": "Aum08Desai", diff --git a/tests/gateway/test_feishu.py b/tests/gateway/test_feishu.py index c5a6d8a550..661e37ec1a 100644 --- a/tests/gateway/test_feishu.py +++ b/tests/gateway/test_feishu.py @@ -601,6 +601,10 @@ class TestAdapterBehavior(unittest.TestCase): calls.append("message_recalled") return self + def register_p2_customized_event(self, event_key, _handler): + calls.append(f"customized:{event_key}") + return self + def build(self): calls.append("build") return "handler" @@ -628,6 +632,7 @@ class TestAdapterBehavior(unittest.TestCase): "bot_deleted", "p2p_chat_entered", "message_recalled", + "customized:drive.notice.comment_add_v1", "build", ], ) diff --git a/tools/feishu_doc_tool.py b/tools/feishu_doc_tool.py index 110501db7f..f334b915e9 100644 --- a/tools/feishu_doc_tool.py +++ b/tools/feishu_doc_tool.py @@ -4,7 +4,6 @@ Provides ``feishu_doc_read`` for reading document content as plain text. Uses the same lazy-import + BaseRequest pattern as feishu_comment.py. """ -import asyncio import json import logging import threading @@ -85,13 +84,9 @@ def _handle_feishu_doc_read(args: dict, **kwargs) -> str: .build() ) - try: - response = asyncio.get_event_loop().run_until_complete( - asyncio.to_thread(client.request, request) - ) - except RuntimeError: - # No running event loop -- call synchronously - response = client.request(request) + # Tool handlers run synchronously in a worker thread (no running event + # loop), so call the blocking lark client directly. + response = client.request(request) code = getattr(response, "code", None) if code != 0: diff --git a/tools/feishu_drive_tool.py b/tools/feishu_drive_tool.py index b62876b9c7..5742acf058 100644 --- a/tools/feishu_drive_tool.py +++ b/tools/feishu_drive_tool.py @@ -5,7 +5,6 @@ Uses the same lazy-import + BaseRequest pattern as feishu_comment.py. The lark client is injected per-thread by the comment event handler. """ -import asyncio import json import logging import threading @@ -59,12 +58,9 @@ def _do_request(client, method, uri, paths=None, queries=None, body=None): request = builder.build() - try: - response = asyncio.get_event_loop().run_until_complete( - asyncio.to_thread(client.request, request) - ) - except RuntimeError: - response = client.request(request) + # Tool handlers run synchronously in a worker thread (no running event + # loop), so call the blocking lark client directly. + response = client.request(request) code = getattr(response, "code", None) msg = getattr(response, "msg", "")