From 3f765a791a0741610cd34bf69f3da5d81432052f Mon Sep 17 00:00:00 2001 From: Windpicker-owo <3431391539@qq.com> Date: Thu, 30 Oct 2025 17:35:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(relationship):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E4=BF=A1=E6=81=AF=E6=8F=90=E5=8F=96=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8C=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=9F=A5=E8=AF=A2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加对 points 和 forgotten_points 的类型检查,确保始终为列表类型 - 修复数据库查询中缺失的 await 调用 - 统一数据库查询结果的字典访问方式,替代之前的对象属性访问 - 改进错误日志记录,添加完整的异常堆栈信息 - 优化默认关系信息的返回逻辑,仅在完全无数据时返回初次交流提示 fix(plugins): 修复插件工具类初始化参数传递问题 - 在 ChatStreamImpressionTool 和 UserProfileTool 中添加 chat_stream 参数传递 - 确保插件工具类正确调用父类初始化方法 --- src/person_info/relationship_fetcher.py | 61 ++++++++++--------- .../chat_stream_impression_tool.py | 4 +- .../user_profile_tool.py | 4 +- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/person_info/relationship_fetcher.py b/src/person_info/relationship_fetcher.py index ca9eaeafc..243f64f80 100644 --- a/src/person_info/relationship_fetcher.py +++ b/src/person_info/relationship_fetcher.py @@ -120,13 +120,15 @@ class RelationshipFetcher: know_since = await person_info_manager.get_value(person_id, "know_since") last_know = await person_info_manager.get_value(person_id, "last_know") - # 如果用户没有基本信息,返回默认描述 - if person_name == nickname_str and not short_impression and not full_impression: - return f"你完全不认识{person_name},这是你们第一次交流。" - # 获取用户特征点 current_points = await person_info_manager.get_value(person_id, "points") or [] forgotten_points = await person_info_manager.get_value(person_id, "forgotten_points") or [] + + # 确保 points 是列表类型(可能从数据库返回字符串) + if not isinstance(current_points, list): + current_points = [] + if not isinstance(forgotten_points, list): + forgotten_points = [] # 按时间排序并选择最有代表性的特征点 all_points = current_points + forgotten_points @@ -182,8 +184,8 @@ class RelationshipFetcher: from src.common.database.sqlalchemy_database_api import db_query from src.common.database.sqlalchemy_models import UserRelationships - # 查询用户关系数据 - user_id = str(person_info_manager.get_value(person_id, "user_id")) + # 查询用户关系数据(修复:添加 await) + user_id = str(await person_info_manager.get_value(person_id, "user_id")) relationships = await db_query( UserRelationships, filters={"user_id": user_id}, @@ -191,33 +193,34 @@ class RelationshipFetcher: ) if relationships: + # db_query 返回字典列表,使用字典访问方式 rel_data = relationships[0] # 5.1 用户别名 - if rel_data.user_aliases: - aliases_list = [alias.strip() for alias in rel_data.user_aliases.split(",") if alias.strip()] + if rel_data.get("user_aliases"): + aliases_list = [alias.strip() for alias in rel_data["user_aliases"].split(",") if alias.strip()] if aliases_list: aliases_str = "、".join(aliases_list) relation_parts.append(f"{person_name}的别名有:{aliases_str}") # 5.2 关系印象文本(主观认知) - if rel_data.relationship_text: - relation_parts.append(f"你对{person_name}的整体认知:{rel_data.relationship_text}") + if rel_data.get("relationship_text"): + relation_parts.append(f"你对{person_name}的整体认知:{rel_data['relationship_text']}") # 5.3 用户偏好关键词 - if rel_data.preference_keywords: - keywords_list = [kw.strip() for kw in rel_data.preference_keywords.split(",") if kw.strip()] + if rel_data.get("preference_keywords"): + keywords_list = [kw.strip() for kw in rel_data["preference_keywords"].split(",") if kw.strip()] if keywords_list: keywords_str = "、".join(keywords_list) relation_parts.append(f"{person_name}的偏好和兴趣:{keywords_str}") # 5.4 关系亲密程度(好感分数) - if rel_data.relationship_score is not None: - score_desc = self._get_relationship_score_description(rel_data.relationship_score) - relation_parts.append(f"你们的关系程度:{score_desc}({rel_data.relationship_score:.2f})") + if rel_data.get("relationship_score") is not None: + score_desc = self._get_relationship_score_description(rel_data["relationship_score"]) + relation_parts.append(f"你们的关系程度:{score_desc}({rel_data['relationship_score']:.2f})") except Exception as e: - logger.debug(f"查询UserRelationships表失败: {e}") + logger.error(f"查询UserRelationships表失败: {e}", exc_info=True) # 构建最终的关系信息字符串 if relation_parts: @@ -225,7 +228,8 @@ class RelationshipFetcher: [f"• {part}" for part in relation_parts] ) else: - relation_info = f"你对{person_name}了解不多,这是比较初步的交流。" + # 只有当所有数据源都没有信息时才返回默认文本 + relation_info = f"你完全不认识{person_name},这是你们第一次交流。" return relation_info @@ -252,34 +256,35 @@ class RelationshipFetcher: if not streams: return "" + # db_query 返回字典列表,使用字典访问方式 stream_data = streams[0] impression_parts = [] # 1. 聊天环境基本信息 - if stream_data.group_name: - impression_parts.append(f"这是一个名为「{stream_data.group_name}」的群聊") + if stream_data.get("group_name"): + impression_parts.append(f"这是一个名为「{stream_data['group_name']}」的群聊") else: impression_parts.append("这是一个私聊对话") # 2. 聊天流的主观印象 - if stream_data.stream_impression_text: - impression_parts.append(f"你对这个聊天环境的印象:{stream_data.stream_impression_text}") + if stream_data.get("stream_impression_text"): + impression_parts.append(f"你对这个聊天环境的印象:{stream_data['stream_impression_text']}") # 3. 聊天风格 - if stream_data.stream_chat_style: - impression_parts.append(f"这里的聊天风格:{stream_data.stream_chat_style}") + if stream_data.get("stream_chat_style"): + impression_parts.append(f"这里的聊天风格:{stream_data['stream_chat_style']}") # 4. 常见话题 - if stream_data.stream_topic_keywords: - topics_list = [topic.strip() for topic in stream_data.stream_topic_keywords.split(",") if topic.strip()] + if stream_data.get("stream_topic_keywords"): + topics_list = [topic.strip() for topic in stream_data["stream_topic_keywords"].split(",") if topic.strip()] if topics_list: topics_str = "、".join(topics_list) impression_parts.append(f"这里常讨论的话题:{topics_str}") # 5. 兴趣程度 - if stream_data.stream_interest_score is not None: - interest_desc = self._get_interest_score_description(stream_data.stream_interest_score) - impression_parts.append(f"你对这个聊天环境的兴趣程度:{interest_desc}({stream_data.stream_interest_score:.2f})") + if stream_data.get("stream_interest_score") is not None: + interest_desc = self._get_interest_score_description(stream_data["stream_interest_score"]) + impression_parts.append(f"你对这个聊天环境的兴趣程度:{interest_desc}({stream_data['stream_interest_score']:.2f})") # 构建最终的印象信息字符串 if impression_parts: diff --git a/src/plugins/built_in/affinity_flow_chatter/chat_stream_impression_tool.py b/src/plugins/built_in/affinity_flow_chatter/chat_stream_impression_tool.py index b70a7d8d3..06be93119 100644 --- a/src/plugins/built_in/affinity_flow_chatter/chat_stream_impression_tool.py +++ b/src/plugins/built_in/affinity_flow_chatter/chat_stream_impression_tool.py @@ -39,8 +39,8 @@ class ChatStreamImpressionTool(BaseTool): available_for_llm = True history_ttl = 5 - def __init__(self, plugin_config: dict | None = None): - super().__init__(plugin_config) + def __init__(self, plugin_config: dict | None = None, chat_stream: Any = None): + super().__init__(plugin_config, chat_stream) # 初始化用于二步调用的LLM try: diff --git a/src/plugins/built_in/affinity_flow_chatter/user_profile_tool.py b/src/plugins/built_in/affinity_flow_chatter/user_profile_tool.py index 25811a8c7..b4fc68526 100644 --- a/src/plugins/built_in/affinity_flow_chatter/user_profile_tool.py +++ b/src/plugins/built_in/affinity_flow_chatter/user_profile_tool.py @@ -40,8 +40,8 @@ class UserProfileTool(BaseTool): available_for_llm = True history_ttl = 5 - def __init__(self, plugin_config: dict | None = None): - super().__init__(plugin_config) + def __init__(self, plugin_config: dict | None = None, chat_stream: Any = None): + super().__init__(plugin_config, chat_stream) # 初始化用于二步调用的LLM try: