refactor(chatter): 统一动作消息对象为DatabaseMessages模型

将动作规划与执行流程中的 `action_message` 从原始字典统一为 `DatabaseMessages` Pydantic模型实例。这增强了类型安全性和代码可读性,并简化了后续处理逻辑。

主要变更:
- `plan_filter`: 在解析LLM输出后,将目标消息字典转换为`DatabaseMessages`对象。
- `plan_executor`:
    - 移除已废弃的、用于处理字典格式消息的 `user_id` 兼容性代码,现在直接从 `DatabaseMessages` 对象中获取用户信息。
    - 删除了针对 `poke_user` 动作的特殊数据处理逻辑,因为相关信息已由 `DatabaseMessages` 模型统一承载。
    - 增加了对 `action_message` 中 `user_id` 缺失的健壮性检查。
This commit is contained in:
minecraft1024a
2025-10-31 21:12:43 +08:00
parent 6bacd7299f
commit 26ba4c3643
2 changed files with 26 additions and 43 deletions

View File

@@ -176,17 +176,19 @@ class ChatterPlanExecutor:
logger.info(f"执行回复动作: {action_info.action_type} (原因: {action_info.reasoning})")
# 获取用户ID - 兼容对象和字典
if hasattr(action_info.action_message, "user_info"):
if action_info.action_message:
# DatabaseMessages对象情况
user_id = action_info.action_message.user_info.user_id
else:
# 字典情况(向后兼容)- 适配扁平化消息字典结构
# 首先尝试从扁平化结构直接获取用户信息
user_id = action_info.action_message.get("user_id")
# 如果扁平化结构中没有用户信息再尝试从嵌套的user_info获取
if not user_id:
user_id = action_info.action_message.get("user_info", {}).get("user_id")
if not user_id:
logger.error("在action_message里面找不到userid,无法执行回复")
return {
"action_type": action_info.action_type,
"success": False,
"error_message": "在action_message里面找不到userid",
"execution_time": 0,
"reasoning": action_info.reasoning,
"reply_content": "",
}
if user_id == str(global_config.bot.qq_account):
logger.warning("尝试回复自己,跳过此动作以防止死循环。")
@@ -289,28 +291,6 @@ class ChatterPlanExecutor:
logger.info(f"执行其他动作: {action_info.action_type} (原因: {action_info.reasoning})")
action_data = action_info.action_data or {}
# 针对 poke_user 动作,特殊处理
if action_info.action_type == "poke_user":
target_message = action_info.action_message
if target_message:
# 优先直接获取 user_id这才是最可靠的信息
user_id = target_message.get("user_id")
if user_id:
action_data["user_id"] = user_id
logger.info(f"检测到戳一戳动作目标用户ID: {user_id}")
else:
# 如果没有 user_id再尝试用 user_nickname 作为备用方案
user_name = target_message.get("user_nickname")
if user_name:
action_data["user_name"] = user_name
logger.info(f"检测到戳一戳动作,目标用户: {user_name}")
else:
logger.warning("无法从戳一戳消息中获取用户ID或昵称。")
# 传递原始消息ID以支持引用
action_data["target_message_id"] = target_message.get("message_id")
# 构建动作参数
action_params = {
"chat_id": plan.chat_id,
@@ -387,9 +367,13 @@ class ChatterPlanExecutor:
user_cardname=bot_nickname,
user_platform="qq",
# 聊天上下文信息
chat_info_user_id=chat_stream.user_info.user_id if chat_stream.user_info else bot_user_id,
chat_info_user_nickname=chat_stream.user_info.user_nickname if chat_stream.user_info else bot_nickname,
chat_info_user_cardname=chat_stream.user_info.user_cardname if chat_stream.user_info else bot_nickname,
chat_info_user_id=(chat_stream.user_info.user_id or bot_user_id) if chat_stream.user_info else bot_user_id,
chat_info_user_nickname=(chat_stream.user_info.user_nickname or bot_nickname)
if chat_stream.user_info
else bot_nickname,
chat_info_user_cardname=(chat_stream.user_info.user_cardname or bot_nickname)
if chat_stream.user_info
else bot_nickname,
chat_info_user_platform=chat_stream.platform,
chat_info_stream_id=chat_stream.stream_id,
chat_info_platform=chat_stream.platform,

View File

@@ -581,22 +581,21 @@ class ChatterPlanFilter:
):
reasoning = f"LLM 返回了当前不可用的动作 '{action}'。原始理由: {reasoning}"
action = "no_action"
# TODO:把逻辑迁移到DatabaseMessages(如果没人做下个星期我自己来)
# from src.common.data_models.database_data_model import DatabaseMessages
from src.common.data_models.database_data_model import DatabaseMessages
# action_message_obj = None
# if target_message_obj:
# try:
# action_message_obj = DatabaseMessages(**target_message_obj)
# except Exception:
# logger.warning("无法将目标消息转换为DatabaseMessages对象")
action_message_obj = None
if target_message_obj:
try:
action_message_obj = DatabaseMessages(**target_message_obj)
except Exception:
logger.warning("无法将目标消息转换为DatabaseMessages对象")
parsed_actions.append(
ActionPlannerInfo(
action_type=action,
reasoning=reasoning,
action_data=action_data,
action_message=target_message_obj,
action_message=action_message_obj,
available_actions=plan.available_actions,
)
)