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,30 +1,32 @@
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
|
||||
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
import random
|
||||
import re
|
||||
from typing import Dict, Optional, Tuple, List, TYPE_CHECKING
|
||||
from rich.traceback import install
|
||||
from datetime import datetime
|
||||
from json_repair import repair_json
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from json_repair import repair_json
|
||||
from rich.traceback import install
|
||||
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.config.config import global_config, model_config
|
||||
from src.common.logger import get_logger
|
||||
from src.chat.logger.plan_reply_logger import PlanReplyLogger
|
||||
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
|
||||
from src.chat.planner_actions.action_manager import ActionManager
|
||||
from src.chat.utils.utils import get_chat_type_and_target_info
|
||||
from src.common.data_models.info_data_model import ActionPlannerInfo
|
||||
from src.common.logger import get_logger
|
||||
from src.common.utils.utils_action import ActionUtils
|
||||
from src.config.config import global_config, model_config
|
||||
from src.core.types import ActionActivationType, ActionInfo, ComponentType
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.plugin_runtime.component_query import component_query_service
|
||||
from src.prompt.prompt_manager import prompt_manager
|
||||
from src.services.message_service import (
|
||||
build_readable_messages_with_id,
|
||||
get_actions_by_timestamp_with_chat,
|
||||
get_messages_before_time_in_chat,
|
||||
)
|
||||
from src.chat.utils.utils import get_chat_type_and_target_info
|
||||
from src.chat.planner_actions.action_manager import ActionManager
|
||||
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
|
||||
from src.core.types import ActionActivationType, ActionInfo, ComponentType
|
||||
from src.core.component_registry import component_registry
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.common.data_models.info_data_model import TargetPersonInfo
|
||||
@@ -320,7 +322,7 @@ class BrainPlanner:
|
||||
current_available_actions_dict = self.action_manager.get_using_actions()
|
||||
|
||||
# 获取完整的动作信息
|
||||
all_registered_actions: Dict[str, ActionInfo] = component_registry.get_components_by_type( # type: ignore
|
||||
all_registered_actions: Dict[str, ActionInfo] = component_query_service.get_components_by_type( # type: ignore
|
||||
ComponentType.ACTION
|
||||
)
|
||||
current_available_actions = {}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -3,8 +3,8 @@ from typing import Dict, Optional, Tuple
|
||||
from src.chat.message_receive.chat_manager import BotChatSession
|
||||
from src.chat.message_receive.message import SessionMessage
|
||||
from src.common.logger import get_logger
|
||||
from src.core.component_registry import component_registry, ActionExecutor
|
||||
from src.core.types import ActionInfo
|
||||
from src.plugin_runtime.component_query import ActionExecutor, component_query_service
|
||||
|
||||
logger = get_logger("action_manager")
|
||||
|
||||
@@ -28,7 +28,7 @@ class ActionManager:
|
||||
"""
|
||||
动作管理器,用于管理各种类型的动作
|
||||
|
||||
使用核心组件注册表的 executor-based 模式。
|
||||
使用插件运行时统一查询服务的 executor-based 模式。
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -38,7 +38,7 @@ class ActionManager:
|
||||
self._using_actions: Dict[str, ActionInfo] = {}
|
||||
|
||||
# 初始化时将默认动作加载到使用中的动作
|
||||
self._using_actions = component_registry.get_default_actions()
|
||||
self._using_actions = component_query_service.get_default_actions()
|
||||
|
||||
# === 执行Action方法 ===
|
||||
|
||||
@@ -72,17 +72,17 @@ class ActionManager:
|
||||
Optional[ActionHandle]: 执行句柄,如果动作未注册则返回 None
|
||||
"""
|
||||
try:
|
||||
executor = component_registry.get_action_executor(action_name)
|
||||
executor = component_query_service.get_action_executor(action_name)
|
||||
if not executor:
|
||||
logger.warning(f"{log_prefix} 未找到Action组件: {action_name}")
|
||||
return None
|
||||
|
||||
info = component_registry.get_action_info(action_name)
|
||||
info = component_query_service.get_action_info(action_name)
|
||||
if not info:
|
||||
logger.warning(f"{log_prefix} 未找到Action组件信息: {action_name}")
|
||||
return None
|
||||
|
||||
plugin_config = component_registry.get_plugin_config(info.plugin_name) or {}
|
||||
plugin_config = component_query_service.get_plugin_config(info.plugin_name) or {}
|
||||
|
||||
handle = ActionHandle(
|
||||
executor,
|
||||
@@ -133,5 +133,5 @@ class ActionManager:
|
||||
def restore_actions(self) -> None:
|
||||
"""恢复到默认动作集"""
|
||||
actions_to_restore = list(self._using_actions.keys())
|
||||
self._using_actions = component_registry.get_default_actions()
|
||||
self._using_actions = component_query_service.get_default_actions()
|
||||
logger.debug(f"恢复动作集: 从 {actions_to_restore} 恢复到默认动作集 {list(self._using_actions.keys())}")
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
import random
|
||||
import re
|
||||
import contextlib
|
||||
from typing import Dict, Optional, Tuple, List, TYPE_CHECKING, Union
|
||||
from collections import OrderedDict
|
||||
from rich.traceback import install
|
||||
from datetime import datetime
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from json_repair import repair_json
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.config.config import global_config, model_config
|
||||
from src.common.logger import get_logger
|
||||
from rich.traceback import install
|
||||
|
||||
from src.chat.logger.plan_reply_logger import PlanReplyLogger
|
||||
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
|
||||
from src.chat.message_receive.message import SessionMessage
|
||||
from src.chat.planner_actions.action_manager import ActionManager
|
||||
from src.chat.utils.utils import get_chat_type_and_target_info, is_bot_self
|
||||
from src.common.data_models.info_data_model import ActionPlannerInfo
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import global_config, model_config
|
||||
from src.core.types import ActionActivationType, ActionInfo, ComponentType
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.person_info.person_info import Person
|
||||
from src.plugin_runtime.component_query import component_query_service
|
||||
from src.prompt.prompt_manager import prompt_manager
|
||||
from src.services.message_service import (
|
||||
build_readable_messages_with_id,
|
||||
replace_user_references,
|
||||
get_messages_before_time_in_chat,
|
||||
replace_user_references,
|
||||
translate_pid_to_description,
|
||||
)
|
||||
from src.chat.utils.utils import get_chat_type_and_target_info, is_bot_self
|
||||
from src.chat.planner_actions.action_manager import ActionManager
|
||||
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
|
||||
from src.chat.message_receive.message import SessionMessage
|
||||
from src.core.types import ActionActivationType, ActionInfo, ComponentType
|
||||
from src.core.component_registry import component_registry
|
||||
from src.person_info.person_info import Person
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.common.data_models.info_data_model import TargetPersonInfo
|
||||
@@ -634,7 +637,7 @@ class ActionPlanner:
|
||||
current_available_actions_dict = self.action_manager.get_using_actions()
|
||||
|
||||
# 获取完整的动作信息
|
||||
all_registered_actions: Dict[str, ActionInfo] = component_registry.get_components_by_type( # type: ignore
|
||||
all_registered_actions: Dict[str, ActionInfo] = component_query_service.get_components_by_type( # type: ignore
|
||||
ComponentType.ACTION
|
||||
)
|
||||
current_available_actions = {}
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
"""
|
||||
工具执行器
|
||||
"""工具执行器。
|
||||
|
||||
独立的工具执行组件,可以直接输入聊天消息内容,
|
||||
自动判断并执行相应的工具,返回结构化的工具执行结果。
|
||||
|
||||
从 src.plugin_system.core.tool_use 迁移,使用新的核心组件注册表。
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import hashlib
|
||||
import time
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import global_config, model_config
|
||||
from src.core.announcement_manager import global_announcement_manager
|
||||
from src.core.component_registry import component_registry
|
||||
from src.llm_models.payload_content import ToolCall
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.plugin_runtime.component_query import component_query_service
|
||||
from src.prompt.prompt_manager import prompt_manager
|
||||
|
||||
logger = get_logger("tool_use")
|
||||
@@ -89,7 +87,7 @@ class ToolExecutor:
|
||||
|
||||
def _get_tool_definitions(self) -> List[Dict[str, Any]]:
|
||||
"""获取 LLM 可用的工具定义列表"""
|
||||
all_tools = component_registry.get_llm_available_tools()
|
||||
all_tools = component_query_service.get_llm_available_tools()
|
||||
user_disabled_tools = global_announcement_manager.get_disabled_chat_tools(self.chat_id)
|
||||
return [info.get_llm_definition() for name, info in all_tools.items() if name not in user_disabled_tools]
|
||||
|
||||
@@ -152,7 +150,7 @@ class ToolExecutor:
|
||||
function_args = tool_call.args or {}
|
||||
function_args["llm_called"] = True
|
||||
|
||||
executor = component_registry.get_tool_executor(function_name)
|
||||
executor = component_query_service.get_tool_executor(function_name)
|
||||
if not executor:
|
||||
logger.warning(f"未知工具名称: {function_name}")
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user