fix(feishu-comment): use get_hermes_home(); drop dead asyncio wrapper; AUTHOR_MAP

Follow-up polish on top of the cherry-picked #11023 commit.

- feishu_comment_rules.py: replace import-time "~/.hermes" expanduser fallback
  with get_hermes_home() from hermes_constants (canonical, profile-safe).
- tools/feishu_doc_tool.py, tools/feishu_drive_tool.py: drop the
  asyncio.get_event_loop().run_until_complete(asyncio.to_thread(...)) dance.
  Tool handlers run synchronously in a worker thread with no running loop, so
  the RuntimeError branch was always the one that executed. Calls client.request
  directly now. Unused asyncio import removed.
- tests/gateway/test_feishu.py: add register_p2_customized_event to the mock
  EventDispatcher builder so the existing adapter test matches the new handler
  registration for drive.notice.comment_add_v1.
- scripts/release.py: map liujinkun@bytedance.com -> liujinkun2025 for
  contributor attribution on release notes.
This commit is contained in:
Teknium 2026-04-17 19:03:37 -07:00 committed by Teknium
parent 85cdb04bd4
commit b449a0e049
5 changed files with 21 additions and 19 deletions

View file

@ -11,21 +11,26 @@ from __future__ import annotations
import json import json
import logging import logging
import os
import time import time
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from hermes_constants import get_hermes_home
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Paths # 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 = get_hermes_home() / "feishu_comment_rules.json"
RULES_FILE = _HERMES_HOME / "feishu_comment_rules.json" PAIRING_FILE = get_hermes_home() / "feishu_comment_pairing.json"
PAIRING_FILE = _HERMES_HOME / "feishu_comment_pairing.json"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Data models # Data models

View file

@ -76,6 +76,7 @@ AUTHOR_MAP = {
"Asunfly@users.noreply.github.com": "Asunfly", "Asunfly@users.noreply.github.com": "Asunfly",
# contributors (manual mapping from git names) # contributors (manual mapping from git names)
"ahmedsherif95@gmail.com": "asheriif", "ahmedsherif95@gmail.com": "asheriif",
"liujinkun@bytedance.com": "liujinkun2025",
"dmayhem93@gmail.com": "dmahan93", "dmayhem93@gmail.com": "dmahan93",
"samherring99@gmail.com": "samherring99", "samherring99@gmail.com": "samherring99",
"desaiaum08@gmail.com": "Aum08Desai", "desaiaum08@gmail.com": "Aum08Desai",

View file

@ -601,6 +601,10 @@ class TestAdapterBehavior(unittest.TestCase):
calls.append("message_recalled") calls.append("message_recalled")
return self return self
def register_p2_customized_event(self, event_key, _handler):
calls.append(f"customized:{event_key}")
return self
def build(self): def build(self):
calls.append("build") calls.append("build")
return "handler" return "handler"
@ -628,6 +632,7 @@ class TestAdapterBehavior(unittest.TestCase):
"bot_deleted", "bot_deleted",
"p2p_chat_entered", "p2p_chat_entered",
"message_recalled", "message_recalled",
"customized:drive.notice.comment_add_v1",
"build", "build",
], ],
) )

View file

@ -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. Uses the same lazy-import + BaseRequest pattern as feishu_comment.py.
""" """
import asyncio
import json import json
import logging import logging
import threading import threading
@ -85,13 +84,9 @@ def _handle_feishu_doc_read(args: dict, **kwargs) -> str:
.build() .build()
) )
try: # Tool handlers run synchronously in a worker thread (no running event
response = asyncio.get_event_loop().run_until_complete( # loop), so call the blocking lark client directly.
asyncio.to_thread(client.request, request) response = client.request(request)
)
except RuntimeError:
# No running event loop -- call synchronously
response = client.request(request)
code = getattr(response, "code", None) code = getattr(response, "code", None)
if code != 0: if code != 0:

View file

@ -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. The lark client is injected per-thread by the comment event handler.
""" """
import asyncio
import json import json
import logging import logging
import threading import threading
@ -59,12 +58,9 @@ def _do_request(client, method, uri, paths=None, queries=None, body=None):
request = builder.build() request = builder.build()
try: # Tool handlers run synchronously in a worker thread (no running event
response = asyncio.get_event_loop().run_until_complete( # loop), so call the blocking lark client directly.
asyncio.to_thread(client.request, request) response = client.request(request)
)
except RuntimeError:
response = client.request(request)
code = getattr(response, "code", None) code = getattr(response, "code", None)
msg = getattr(response, "msg", "") msg = getattr(response, "msg", "")