From 1716272b25e920fbe2ae9000b4fa64810b76fce3 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Wed, 22 Apr 2026 11:26:39 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=94=AF=E6=8C=81msg=5Fid?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=B6=88=E6=81=AF=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/maisaka/builtin_tool/at.py | 2 +- src/plugin_runtime/capabilities/data.py | 23 ++++++++++++++++++++- src/plugin_runtime/capabilities/registry.py | 1 + src/services/message_service.py | 18 ++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/maisaka/builtin_tool/at.py b/src/maisaka/builtin_tool/at.py index 7f14ecba..69cae2c8 100644 --- a/src/maisaka/builtin_tool/at.py +++ b/src/maisaka/builtin_tool/at.py @@ -19,7 +19,7 @@ def get_tool_spec() -> ToolSpec: return ToolSpec( name="at", - brief_description="根据一条已知 msg_id 找到发言用户,并发送一条 @ 该用户的消息。", + brief_description="当明确提及某位用户时,发送一条 @ 该用户的消息。", detailed_description=( "参数说明:\n" "- msg_id:string,必填。要 @ 的目标用户发过的消息编号。\n" diff --git a/src/plugin_runtime/capabilities/data.py b/src/plugin_runtime/capabilities/data.py index 04eb50c0..3736230a 100644 --- a/src/plugin_runtime/capabilities/data.py +++ b/src/plugin_runtime/capabilities/data.py @@ -8,6 +8,7 @@ from src.chat.message_receive.chat_manager import BotChatSession, chat_manager from src.common.data_models.image_data_model import MaiEmoji from src.common.logger import get_logger from src.common.utils.utils_image import ImageUtils +from src.plugin_runtime.host.message_utils import PluginMessageUtils logger = get_logger("plugin_runtime.integration") @@ -298,7 +299,9 @@ class RuntimeDataCapabilityMixin: def _serialize_messages(messages: list) -> List[Any]: result: List[Any] = [] for msg in messages: - if hasattr(msg, "model_dump"): + if all(hasattr(msg, attr) for attr in ("message_id", "timestamp", "platform", "message_info", "raw_message")): + result.append(dict(PluginMessageUtils._session_message_to_dict(msg))) + elif hasattr(msg, "model_dump"): result.append(msg.model_dump()) elif hasattr(msg, "__dict__"): result.append(dict(msg.__dict__)) @@ -306,6 +309,24 @@ class RuntimeDataCapabilityMixin: result.append(str(msg)) return result + async def _cap_message_get_by_id(self, plugin_id: str, capability: str, args: Dict[str, Any]) -> Any: + from src.services import message_service + + message_id = str(args.get("message_id") or args.get("msg_id") or "").strip() + if not message_id: + return {"success": False, "error": "缺少必要参数 message_id"} + + try: + message = message_service.get_message_by_id( + message_id=message_id, + chat_id=str(args.get("chat_id") or args.get("stream_id") or "").strip() or None, + ) + serialized_message = self._serialize_messages([message])[0] if message is not None else None + return {"success": True, "message": serialized_message} + except Exception as e: + logger.error(f"[cap.message.get_by_id] 执行失败: {e}", exc_info=True) + return {"success": False, "error": str(e)} + async def _cap_message_get_by_time(self, plugin_id: str, capability: str, args: Dict[str, Any]) -> Any: from src.services import message_service diff --git a/src/plugin_runtime/capabilities/registry.py b/src/plugin_runtime/capabilities/registry.py index 2925a2b3..10dfd00b 100644 --- a/src/plugin_runtime/capabilities/registry.py +++ b/src/plugin_runtime/capabilities/registry.py @@ -51,6 +51,7 @@ def register_capability_impls(manager: "PluginRuntimeManager", supervisor: Plugi _register("message.get_by_time", manager._cap_message_get_by_time) _register("message.get_by_time_in_chat", manager._cap_message_get_by_time_in_chat) + _register("message.get_by_id", manager._cap_message_get_by_id) _register("message.get_recent", manager._cap_message_get_recent) _register("message.count_new", manager._cap_message_count_new) _register("message.build_readable", manager._cap_message_build_readable) diff --git a/src/services/message_service.py b/src/services/message_service.py index 5291bf04..4a0d2b6f 100644 --- a/src/services/message_service.py +++ b/src/services/message_service.py @@ -97,6 +97,24 @@ def get_messages_by_time_in_chat( return _normalize_messages(messages) +def get_message_by_id(message_id: str, chat_id: Optional[str] = None) -> Optional[SessionMessage]: + """按消息 ID 查询单条消息,可选限定会话。""" + + normalized_message_id = str(message_id or "").strip() + if not normalized_message_id: + raise ValueError("message_id 不能为空") + + normalized_chat_id = str(chat_id or "").strip() + messages = find_messages( + session_id=normalized_chat_id or None, + message_id=normalized_message_id, + limit=1, + limit_mode="latest", + ) + normalized_messages = _normalize_messages(messages) + return normalized_messages[0] if normalized_messages else None + + def get_messages_before_time(timestamp: float, limit: int = 0, filter_mai: bool = False) -> List[SessionMessage]: if not isinstance(timestamp, (int, float)): raise ValueError("timestamp 必须是数字类型")