Refactor plugin runtime components and enhance message handling
- Removed unused core action mirror functionality from PluginRunnerSupervisor. - Simplified action and command execution logic in send_service.py. - Introduced ComponentQueryService for unified component querying in plugin runtime. - Enhanced message component handling with new binary component support. - Improved message sequence construction and detection of outbound message flags. - Updated methods for sending messages to streamline the process and improve readability.
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
from contextlib import suppress
|
||||
import traceback
|
||||
import os
|
||||
|
||||
from maim_message import MessageBase
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from maim_message import MessageBase
|
||||
|
||||
from src.chat.heart_flow.heartflow_message_processor import HeartFCMessageReceiver
|
||||
from src.common.logger import get_logger
|
||||
from src.common.utils.utils_message import MessageUtils
|
||||
from src.common.utils.utils_session import SessionUtils
|
||||
from src.chat.heart_flow.heartflow_message_processor import HeartFCMessageReceiver
|
||||
|
||||
# from src.chat.brain_chat.PFC.pfc_manager import PFCManager
|
||||
from src.core.announcement_manager import global_announcement_manager
|
||||
from src.core.component_registry import component_registry
|
||||
from src.plugin_runtime.component_query import component_query_service
|
||||
|
||||
from .message import SessionMessage
|
||||
from .chat_manager import chat_manager
|
||||
@@ -58,16 +58,22 @@ class ChatBot:
|
||||
logger.error(f"创建PFC聊天失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
async def _process_commands(self, message: SessionMessage):
|
||||
# sourcery skip: use-named-expression
|
||||
"""使用新插件系统处理命令"""
|
||||
async def _process_commands(self, message: SessionMessage) -> tuple[bool, Optional[str], bool]:
|
||||
"""使用统一组件注册表处理命令。
|
||||
|
||||
Args:
|
||||
message: 当前待处理的会话消息。
|
||||
|
||||
Returns:
|
||||
tuple[bool, Optional[str], bool]: ``(是否命中命令, 命令响应文本, 是否继续后续处理)``。
|
||||
"""
|
||||
if not message.processed_plain_text:
|
||||
return False, None, True # 没有文本内容,继续处理消息
|
||||
try:
|
||||
text = message.processed_plain_text
|
||||
|
||||
# 使用核心组件注册表查找命令
|
||||
command_result = component_registry.find_command_by_text(text)
|
||||
# 使用插件运行时统一查询服务查找命令
|
||||
command_result = component_query_service.find_command_by_text(text)
|
||||
if command_result:
|
||||
command_executor, matched_groups, command_info = command_result
|
||||
plugin_name = command_info.plugin_name
|
||||
@@ -81,7 +87,7 @@ class ChatBot:
|
||||
message.is_command = True
|
||||
|
||||
# 获取插件配置
|
||||
plugin_config = component_registry.get_plugin_config(plugin_name)
|
||||
plugin_config = component_query_service.get_plugin_config(plugin_name)
|
||||
|
||||
try:
|
||||
# 调用命令执行器
|
||||
@@ -112,88 +118,32 @@ class ChatBot:
|
||||
# 命令出错时,根据命令的拦截设置决定是否继续处理消息
|
||||
return True, str(e), False # 出错时继续处理消息
|
||||
|
||||
# 没有找到旧系统命令,尝试新版本插件运行时
|
||||
new_cmd_result = await self._process_new_runtime_command(message)
|
||||
return new_cmd_result if new_cmd_result is not None else (False, None, True)
|
||||
return False, None, True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理命令时出错: {e}")
|
||||
return False, None, True # 出错时继续处理消息
|
||||
|
||||
async def _process_new_runtime_command(self, message: SessionMessage):
|
||||
"""尝试在新版本插件运行时中查找并执行命令
|
||||
|
||||
Returns:
|
||||
(found, response, continue_processing) 三元组,
|
||||
或 None 表示新运行时中也未找到匹配命令。
|
||||
"""
|
||||
from src.plugin_runtime.integration import get_plugin_runtime_manager
|
||||
|
||||
prm = get_plugin_runtime_manager()
|
||||
if not prm.is_running:
|
||||
return None
|
||||
|
||||
matched = prm.find_command_by_text(message.processed_plain_text)
|
||||
if matched is None:
|
||||
return None
|
||||
|
||||
command_name = matched["name"]
|
||||
if message.session_id and command_name in global_announcement_manager.get_disabled_chat_commands(
|
||||
message.session_id
|
||||
):
|
||||
logger.info(f"[新运行时] 用户禁用的命令,跳过处理: {matched['full_name']}")
|
||||
return False, None, True
|
||||
|
||||
message.is_command = True
|
||||
logger.info(f"[新运行时] 匹配命令: {matched['full_name']}")
|
||||
|
||||
try:
|
||||
resp = await prm.invoke_plugin(
|
||||
method="plugin.invoke_command",
|
||||
plugin_id=matched["plugin_id"],
|
||||
component_name=matched["name"],
|
||||
args={
|
||||
"text": message.processed_plain_text,
|
||||
"stream_id": message.session_id or "",
|
||||
"matched_groups": matched.get("matched_groups") or {},
|
||||
},
|
||||
timeout_ms=30000,
|
||||
)
|
||||
|
||||
payload = resp.payload
|
||||
success = payload.get("success", False)
|
||||
cmd_result = payload.get("result")
|
||||
|
||||
# 拦截位优先从命令返回值中获取(支持运行时动态决定),
|
||||
# 回退到组件 metadata 中的静态声明
|
||||
if isinstance(cmd_result, (list, tuple)) and len(cmd_result) >= 3:
|
||||
# 命令返回 (found, response_text, intercept_bool) 三元组
|
||||
response_text = cmd_result[1] if cmd_result[1] is not None else ""
|
||||
intercept = bool(cmd_result[2])
|
||||
else:
|
||||
response_text = cmd_result if cmd_result is not None else ""
|
||||
intercept = bool(matched["metadata"].get("intercept_message_level", 0))
|
||||
|
||||
self._mark_command_message(message, int(intercept))
|
||||
|
||||
if success:
|
||||
logger.info(f"[新运行时] 命令执行成功: {matched['full_name']}")
|
||||
else:
|
||||
logger.warning(f"[新运行时] 命令执行失败: {matched['full_name']} - {response_text}")
|
||||
|
||||
return True, response_text, not intercept
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[新运行时] 执行命令 {matched['full_name']} 异常: {e}", exc_info=True)
|
||||
return True, str(e), True
|
||||
|
||||
@staticmethod
|
||||
def _mark_command_message(message: SessionMessage, intercept_message_level: int) -> None:
|
||||
"""标记消息已经被命令链消费。
|
||||
|
||||
Args:
|
||||
message: 待标记的会话消息。
|
||||
intercept_message_level: 命令设置的拦截级别。
|
||||
"""
|
||||
|
||||
message.is_command = True
|
||||
message.message_info.additional_config["intercept_message_level"] = intercept_message_level
|
||||
|
||||
@staticmethod
|
||||
def _store_intercepted_command_message(message: SessionMessage) -> None:
|
||||
"""将被命令链拦截的消息写入数据库。
|
||||
|
||||
Args:
|
||||
message: 已完成命令处理的会话消息。
|
||||
"""
|
||||
|
||||
MessageUtils.store_message_to_db(message)
|
||||
|
||||
async def _handle_command_processing_result(
|
||||
|
||||
Reference in New Issue
Block a user