feat:添加取名工具
This commit is contained in:
112
src/do_tool/tool_can_use/rename_person_tool.py
Normal file
112
src/do_tool/tool_can_use/rename_person_tool.py
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
from src.do_tool.tool_can_use.base_tool import BaseTool, register_tool
|
||||||
|
from src.plugins.person_info.person_info import person_info_manager
|
||||||
|
from src.common.logger_manager import get_logger
|
||||||
|
import json
|
||||||
|
|
||||||
|
logger = get_logger("rename_person_tool")
|
||||||
|
|
||||||
|
class RenamePersonTool(BaseTool):
|
||||||
|
name = "rename_person"
|
||||||
|
description = "这个工具可以改变用户的昵称。你可以选择改变对他人的称呼。"
|
||||||
|
parameters = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"person_name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "需要重新取名的用户的当前昵称"
|
||||||
|
},
|
||||||
|
"message_content": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "可选的。当前的聊天内容或特定要求,用于提供取名建议的上下文。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["person_name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
async def execute(self, function_args: dict, message_txt=""):
|
||||||
|
"""
|
||||||
|
执行取名工具逻辑
|
||||||
|
|
||||||
|
Args:
|
||||||
|
function_args (dict): 包含 'person_name' 和可选 'message_content' 的字典
|
||||||
|
message_txt (str): 原始消息文本 (这里未使用,因为 message_content 更明确)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: 包含执行结果的字典
|
||||||
|
"""
|
||||||
|
person_name_to_find = function_args.get("person_name")
|
||||||
|
request_context = function_args.get("message_content", "") # 如果没有提供,则为空字符串
|
||||||
|
|
||||||
|
if not person_name_to_find:
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": "错误:必须提供需要重命名的用户昵称 (person_name)。"
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1. 根据昵称查找用户信息
|
||||||
|
logger.debug(f"尝试根据昵称 '{person_name_to_find}' 查找用户...")
|
||||||
|
person_info = await person_info_manager.get_person_info_by_name(person_name_to_find)
|
||||||
|
|
||||||
|
if not person_info:
|
||||||
|
logger.info(f"未找到昵称为 '{person_name_to_find}' 的用户。")
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"找不到昵称为 '{person_name_to_find}' 的用户。请确保输入的是我之前为该用户取的昵称。"
|
||||||
|
}
|
||||||
|
|
||||||
|
person_id = person_info.get("person_id")
|
||||||
|
user_nickname = person_info.get("nickname") # 这是用户原始昵称
|
||||||
|
user_cardname = person_info.get("user_cardname")
|
||||||
|
user_avatar = person_info.get("user_avatar")
|
||||||
|
|
||||||
|
if not person_id:
|
||||||
|
logger.error(f"找到了用户 '{person_name_to_find}' 但无法获取 person_id")
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"找到了用户 '{person_name_to_find}' 但获取内部ID时出错。"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. 调用 qv_person_name 进行取名
|
||||||
|
logger.debug(f"为用户 {person_id} (原昵称: {person_name_to_find}) 调用 qv_person_name,请求上下文: '{request_context}'")
|
||||||
|
result = await person_info_manager.qv_person_name(
|
||||||
|
person_id=person_id,
|
||||||
|
user_nickname=user_nickname,
|
||||||
|
user_cardname=user_cardname,
|
||||||
|
user_avatar=user_avatar,
|
||||||
|
request=request_context
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. 处理结果
|
||||||
|
if result and result.get("nickname"):
|
||||||
|
new_name = result["nickname"]
|
||||||
|
reason = result.get("reason", "未提供理由")
|
||||||
|
logger.info(f"成功为用户 {person_id} 取了新昵称: {new_name}")
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"好的,我已经给 '{person_name_to_find}' 取了新昵称:'{new_name}'。因为:{reason}"
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
logger.warning(f"为用户 {person_id} 调用 qv_person_name 后未能成功获取新昵称。")
|
||||||
|
# 尝试从内存中获取可能已经更新的名字
|
||||||
|
current_name = await person_info_manager.get_value(person_id, "person_name")
|
||||||
|
if current_name and current_name != person_name_to_find:
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"尝试取新昵称时遇到一点小问题,但我已经将 '{person_name_to_find}' 的昵称更新为 '{current_name}' 了。"
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"尝试为 '{person_name_to_find}' 取新昵称时遇到了问题,未能成功生成。可能需要稍后再试。"
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"执行 rename_person 工具时出错: {e}", exc_info=True)
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"content": f"执行重命名操作时遇到内部错误: {e}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 注册工具
|
||||||
|
register_tool(RenamePersonTool)
|
||||||
@@ -51,6 +51,8 @@ person_info_default = {
|
|||||||
"konw_time": 0,
|
"konw_time": 0,
|
||||||
"msg_interval": 2000,
|
"msg_interval": 2000,
|
||||||
"msg_interval_list": [],
|
"msg_interval_list": [],
|
||||||
|
"user_cardname": None, # 添加群名片
|
||||||
|
"user_avatar": None, # 添加头像信息(例如URL或标识符)
|
||||||
} # 个人信息的各项与默认值在此定义,以下处理会自动创建/补全每一项
|
} # 个人信息的各项与默认值在此定义,以下处理会自动创建/补全每一项
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +188,7 @@ class PersonInfoManager:
|
|||||||
logger.warning(f"无法从文本中提取有效的JSON字典: {text}")
|
logger.warning(f"无法从文本中提取有效的JSON字典: {text}")
|
||||||
return {"nickname": "", "reason": ""}
|
return {"nickname": "", "reason": ""}
|
||||||
|
|
||||||
async def qv_person_name(self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str):
|
async def qv_person_name(self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str, request: str = ""):
|
||||||
"""给某个用户取名"""
|
"""给某个用户取名"""
|
||||||
if not person_id:
|
if not person_id:
|
||||||
logger.debug("取名失败:person_id不能为空")
|
logger.debug("取名失败:person_id不能为空")
|
||||||
@@ -211,6 +213,8 @@ class PersonInfoManager:
|
|||||||
if old_name:
|
if old_name:
|
||||||
qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason},"
|
qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason},"
|
||||||
|
|
||||||
|
qv_name_prompt += f"\n其他取名的要求是:{request}"
|
||||||
|
|
||||||
qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,请最好使用用户的qq昵称,可以稍作修改"
|
qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,请最好使用用户的qq昵称,可以稍作修改"
|
||||||
if existing_names:
|
if existing_names:
|
||||||
qv_name_prompt += f"\n请注意,以下名称已被使用,不要使用以下昵称:{existing_names}。\n"
|
qv_name_prompt += f"\n请注意,以下名称已被使用,不要使用以下昵称:{existing_names}。\n"
|
||||||
@@ -511,5 +515,41 @@ class PersonInfoManager:
|
|||||||
|
|
||||||
return person_id
|
return person_id
|
||||||
|
|
||||||
|
async def get_person_info_by_name(self, person_name: str) -> dict | None:
|
||||||
|
"""根据 person_name 查找用户并返回基本信息 (如果找到)"""
|
||||||
|
if not person_name:
|
||||||
|
logger.debug("get_person_info_by_name 获取失败:person_name 不能为空")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 优先从内存缓存查找 person_id
|
||||||
|
found_person_id = None
|
||||||
|
for pid, name in self.person_name_list.items():
|
||||||
|
if name == person_name:
|
||||||
|
found_person_id = pid
|
||||||
|
break # 找到第一个匹配就停止
|
||||||
|
|
||||||
|
if not found_person_id:
|
||||||
|
# 如果内存没有,尝试数据库查询(可能内存未及时更新或启动时未加载)
|
||||||
|
document = db.person_info.find_one({"person_name": person_name})
|
||||||
|
if document:
|
||||||
|
found_person_id = document.get("person_id")
|
||||||
|
else:
|
||||||
|
logger.debug(f"数据库中也未找到名为 '{person_name}' 的用户")
|
||||||
|
return None # 数据库也找不到
|
||||||
|
|
||||||
|
# 根据找到的 person_id 获取所需信息
|
||||||
|
if found_person_id:
|
||||||
|
required_fields = ["person_id", "platform", "user_id", "nickname", "user_cardname", "user_avatar"]
|
||||||
|
person_data = await self.get_values(found_person_id, required_fields)
|
||||||
|
if person_data: # 确保 get_values 成功返回
|
||||||
|
return person_data
|
||||||
|
else:
|
||||||
|
logger.warning(f"找到了 person_id '{found_person_id}' 但获取详细信息失败")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# 这理论上不应该发生,因为上面已经处理了找不到的情况
|
||||||
|
logger.error(f"逻辑错误:未能为 '{person_name}' 确定 person_id")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
person_info_manager = PersonInfoManager()
|
person_info_manager = PersonInfoManager()
|
||||||
|
|||||||
Reference in New Issue
Block a user