🤖 自动格式化代码 [skip ci]
This commit is contained in:
@@ -513,7 +513,9 @@ CONFIRM_STYLE_CONFIG = {
|
||||
# 根据SIMPLE_OUTPUT选择配置
|
||||
MAIN_STYLE_CONFIG = MAIN_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MAIN_STYLE_CONFIG["advanced"]
|
||||
EMOJI_STYLE_CONFIG = EMOJI_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else EMOJI_STYLE_CONFIG["advanced"]
|
||||
PFC_ACTION_PLANNER_STYLE_CONFIG = PFC_ACTION_PLANNER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_ACTION_PLANNER_STYLE_CONFIG["advanced"]
|
||||
PFC_ACTION_PLANNER_STYLE_CONFIG = (
|
||||
PFC_ACTION_PLANNER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_ACTION_PLANNER_STYLE_CONFIG["advanced"]
|
||||
)
|
||||
REMOTE_STYLE_CONFIG = REMOTE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else REMOTE_STYLE_CONFIG["advanced"]
|
||||
BASE_TOOL_STYLE_CONFIG = BASE_TOOL_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else BASE_TOOL_STYLE_CONFIG["advanced"]
|
||||
PERSON_INFO_STYLE_CONFIG = PERSON_INFO_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PERSON_INFO_STYLE_CONFIG["advanced"]
|
||||
|
||||
@@ -16,6 +16,7 @@ pfc_action_log_config = LogConfig(
|
||||
|
||||
logger = get_module_logger("action_planner", config=pfc_action_log_config)
|
||||
|
||||
|
||||
# 注意:这个 ActionPlannerInfo 类似乎没有在 ActionPlanner 中使用,
|
||||
# 如果确实没用,可以考虑移除,但暂时保留以防万一。
|
||||
class ActionPlannerInfo:
|
||||
@@ -25,9 +26,11 @@ class ActionPlannerInfo:
|
||||
self.knowledge_list = []
|
||||
self.memory_list = []
|
||||
|
||||
|
||||
# ActionPlanner 类定义,顶格
|
||||
class ActionPlanner:
|
||||
"""行动规划器"""
|
||||
|
||||
def __init__(self, stream_id: str):
|
||||
self.llm = LLMRequest(
|
||||
model=global_config.llm_PFC_action_planner,
|
||||
@@ -54,18 +57,20 @@ class ActionPlanner:
|
||||
time_since_last_bot_message_info = ""
|
||||
try:
|
||||
bot_id = str(global_config.BOT_QQ)
|
||||
if hasattr(observation_info, 'chat_history') and observation_info.chat_history:
|
||||
if hasattr(observation_info, "chat_history") and observation_info.chat_history:
|
||||
for i in range(len(observation_info.chat_history) - 1, -1, -1):
|
||||
msg = observation_info.chat_history[i]
|
||||
if not isinstance(msg, dict):
|
||||
continue
|
||||
sender_info = msg.get('user_info', {})
|
||||
sender_id = str(sender_info.get('user_id')) if isinstance(sender_info, dict) else None
|
||||
msg_time = msg.get('time')
|
||||
sender_info = msg.get("user_info", {})
|
||||
sender_id = str(sender_info.get("user_id")) if isinstance(sender_info, dict) else None
|
||||
msg_time = msg.get("time")
|
||||
if sender_id == bot_id and msg_time:
|
||||
time_diff = time.time() - msg_time
|
||||
if time_diff < 60.0:
|
||||
time_since_last_bot_message_info = f"提示:你上一条成功发送的消息是在 {time_diff:.1f} 秒前。\n"
|
||||
time_since_last_bot_message_info = (
|
||||
f"提示:你上一条成功发送的消息是在 {time_diff:.1f} 秒前。\n"
|
||||
)
|
||||
break
|
||||
else:
|
||||
logger.debug("Observation info chat history is empty or not available for bot time check.")
|
||||
@@ -77,13 +82,13 @@ class ActionPlanner:
|
||||
|
||||
timeout_context = ""
|
||||
try: # 添加 try-except 以增加健壮性
|
||||
if hasattr(conversation_info, 'goal_list') and conversation_info.goal_list:
|
||||
if hasattr(conversation_info, "goal_list") and conversation_info.goal_list:
|
||||
last_goal_tuple = conversation_info.goal_list[-1]
|
||||
if isinstance(last_goal_tuple, tuple) and len(last_goal_tuple) > 0:
|
||||
last_goal_text = last_goal_tuple[0]
|
||||
if isinstance(last_goal_text, str) and "分钟,思考接下来要做什么" in last_goal_text:
|
||||
try:
|
||||
timeout_minutes_text = last_goal_text.split(',')[0].replace('你等待了','')
|
||||
timeout_minutes_text = last_goal_text.split(",")[0].replace("你等待了", "")
|
||||
timeout_context = f"重要提示:你刚刚因为对方长时间({timeout_minutes_text})没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n"
|
||||
except Exception:
|
||||
timeout_context = "重要提示:你刚刚因为对方长时间没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n"
|
||||
@@ -100,7 +105,7 @@ class ActionPlanner:
|
||||
# 构建对话目标 (goals_str)
|
||||
goals_str = ""
|
||||
try: # 添加 try-except
|
||||
if hasattr(conversation_info, 'goal_list') and conversation_info.goal_list:
|
||||
if hasattr(conversation_info, "goal_list") and conversation_info.goal_list:
|
||||
for goal_reason in conversation_info.goal_list:
|
||||
if isinstance(goal_reason, tuple) and len(goal_reason) > 0:
|
||||
goal = goal_reason[0]
|
||||
@@ -126,10 +131,10 @@ class ActionPlanner:
|
||||
# 获取聊天历史记录 (chat_history_text)
|
||||
chat_history_text = ""
|
||||
try:
|
||||
if hasattr(observation_info, 'chat_history') and observation_info.chat_history:
|
||||
if hasattr(observation_info, "chat_history") and observation_info.chat_history:
|
||||
chat_history_list = observation_info.chat_history[-20:]
|
||||
for msg in chat_history_list:
|
||||
if isinstance(msg, dict) and 'detailed_plain_text' in msg:
|
||||
if isinstance(msg, dict) and "detailed_plain_text" in msg:
|
||||
chat_history_text += f"{msg.get('detailed_plain_text', '')}\n"
|
||||
elif isinstance(msg, str):
|
||||
chat_history_text += f"{msg}\n"
|
||||
@@ -138,12 +143,12 @@ class ActionPlanner:
|
||||
else:
|
||||
chat_history_text = "还没有聊天记录。\n"
|
||||
|
||||
if hasattr(observation_info, 'new_messages_count') and observation_info.new_messages_count > 0:
|
||||
if hasattr(observation_info, 'unprocessed_messages') and observation_info.unprocessed_messages:
|
||||
if hasattr(observation_info, "new_messages_count") and observation_info.new_messages_count > 0:
|
||||
if hasattr(observation_info, "unprocessed_messages") and observation_info.unprocessed_messages:
|
||||
new_messages_list = observation_info.unprocessed_messages
|
||||
chat_history_text += f"--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n"
|
||||
for msg in new_messages_list:
|
||||
if isinstance(msg, dict) and 'detailed_plain_text' in msg:
|
||||
if isinstance(msg, dict) and "detailed_plain_text" in msg:
|
||||
chat_history_text += f"{msg.get('detailed_plain_text', '')}\n"
|
||||
elif isinstance(msg, str):
|
||||
chat_history_text += f"{msg}\n"
|
||||
@@ -151,7 +156,9 @@ class ActionPlanner:
|
||||
# if hasattr(observation_info, 'clear_unprocessed_messages'):
|
||||
# observation_info.clear_unprocessed_messages()
|
||||
else:
|
||||
logger.warning("ObservationInfo has new_messages_count > 0 but unprocessed_messages is empty or missing.")
|
||||
logger.warning(
|
||||
"ObservationInfo has new_messages_count > 0 but unprocessed_messages is empty or missing."
|
||||
)
|
||||
except AttributeError:
|
||||
logger.warning("ObservationInfo object might be missing expected attributes for chat history.")
|
||||
chat_history_text = "获取聊天记录时出错。\n"
|
||||
@@ -159,7 +166,6 @@ class ActionPlanner:
|
||||
logger.error(f"处理聊天记录时发生未知错误: {e}")
|
||||
chat_history_text = "处理聊天记录时出错。\n"
|
||||
|
||||
|
||||
# 构建 Persona 文本 (persona_text)
|
||||
identity_details_only = self.identity_detail_info
|
||||
identity_addon = ""
|
||||
@@ -168,11 +174,11 @@ class ActionPlanner:
|
||||
# original_details = identity_details_only
|
||||
for p in pronouns:
|
||||
if identity_details_only.startswith(p):
|
||||
identity_details_only = identity_details_only[len(p):]
|
||||
identity_details_only = identity_details_only[len(p) :]
|
||||
break
|
||||
if identity_details_only.endswith("。"):
|
||||
identity_details_only = identity_details_only[:-1]
|
||||
cleaned_details = identity_details_only.strip(',, ')
|
||||
cleaned_details = identity_details_only.strip(",, ")
|
||||
if cleaned_details:
|
||||
identity_addon = f"并且{cleaned_details}"
|
||||
persona_text = f"你的名字是{self.name},{self.personality_info}{identity_addon}。"
|
||||
@@ -183,7 +189,7 @@ class ActionPlanner:
|
||||
|
||||
action_history_list = []
|
||||
try: # 添加 try-except
|
||||
if hasattr(conversation_info, 'done_action') and conversation_info.done_action:
|
||||
if hasattr(conversation_info, "done_action") and conversation_info.done_action:
|
||||
action_history_list = conversation_info.done_action[-5:]
|
||||
else:
|
||||
logger.debug("Conversation info done_action is empty or not available.")
|
||||
@@ -279,14 +285,15 @@ end_conversation: 决定结束对话,对方长时间没回复或者当你觉
|
||||
logger.debug(f"LLM原始返回内容: {content}")
|
||||
|
||||
success, result = get_items_from_json(
|
||||
content, "action", "reason",
|
||||
default_values={"action": "wait", "reason": "LLM返回格式错误或未提供原因,默认等待"}
|
||||
content,
|
||||
"action",
|
||||
"reason",
|
||||
default_values={"action": "wait", "reason": "LLM返回格式错误或未提供原因,默认等待"},
|
||||
)
|
||||
|
||||
action = result.get("action", "wait")
|
||||
reason = result.get("reason", "LLM未提供原因,默认等待")
|
||||
|
||||
|
||||
# 验证action类型
|
||||
valid_actions = ["direct_reply", "fetch_knowledge", "wait", "listening", "rethink_goal", "end_conversation"]
|
||||
if action not in valid_actions:
|
||||
|
||||
@@ -81,7 +81,7 @@ class Conversation:
|
||||
initial_messages = await storage.get_messages_before(
|
||||
chat_id=self.stream_id,
|
||||
time_point=time.time(),
|
||||
limit=30 # 加载最近20条作为初始上下文,可以调整
|
||||
limit=30, # 加载最近20条作为初始上下文,可以调整
|
||||
)
|
||||
if initial_messages:
|
||||
# 将加载的消息填充到 ObservationInfo 的 chat_history
|
||||
@@ -90,7 +90,7 @@ class Conversation:
|
||||
|
||||
# 更新 ObservationInfo 中的时间戳等信息
|
||||
last_msg = initial_messages[-1]
|
||||
self.observation_info.last_message_time = last_msg.get('time')
|
||||
self.observation_info.last_message_time = last_msg.get("time")
|
||||
last_user_info = UserInfo.from_dict(last_msg.get("user_info", {}))
|
||||
self.observation_info.last_message_sender = last_user_info.user_id
|
||||
self.observation_info.last_message_content = last_msg.get("processed_plain_text", "")
|
||||
@@ -98,7 +98,9 @@ class Conversation:
|
||||
# (可选)可以遍历 initial_messages 来设置 last_bot_speak_time 和 last_user_speak_time
|
||||
# 这里为了简化,只用了最后一条消息的时间,如果需要精确的发言者时间需要遍历
|
||||
|
||||
logger.info(f"成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}")
|
||||
logger.info(
|
||||
f"成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}"
|
||||
)
|
||||
|
||||
# 让 ChatObserver 从加载的最后一条消息之后开始同步
|
||||
self.chat_observer.last_message_time = self.observation_info.last_message_time
|
||||
@@ -128,24 +130,28 @@ class Conversation:
|
||||
try:
|
||||
# --- 在规划前记录当前新消息数量 ---
|
||||
initial_new_message_count = 0
|
||||
if hasattr(self.observation_info, 'new_messages_count'):
|
||||
if hasattr(self.observation_info, "new_messages_count"):
|
||||
initial_new_message_count = self.observation_info.new_messages_count
|
||||
else:
|
||||
logger.warning("ObservationInfo missing 'new_messages_count' before planning.")
|
||||
|
||||
# 使用决策信息来辅助行动规划
|
||||
action, reason = await self.action_planner.plan(self.observation_info, self.conversation_info) # 注意:plan 函数内部现在不应再调用 clear_unprocessed_messages
|
||||
action, reason = await self.action_planner.plan(
|
||||
self.observation_info, self.conversation_info
|
||||
) # 注意:plan 函数内部现在不应再调用 clear_unprocessed_messages
|
||||
|
||||
# --- 规划后检查是否有 *更多* 新消息到达 ---
|
||||
current_new_message_count = 0
|
||||
if hasattr(self.observation_info, 'new_messages_count'):
|
||||
if hasattr(self.observation_info, "new_messages_count"):
|
||||
current_new_message_count = self.observation_info.new_messages_count
|
||||
else:
|
||||
logger.warning("ObservationInfo missing 'new_messages_count' after planning.")
|
||||
|
||||
if current_new_message_count > initial_new_message_count:
|
||||
# 只有当规划期间消息数量 *增加* 了,才认为需要重新规划
|
||||
logger.info(f"规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count}),跳过本次行动,重新规划")
|
||||
logger.info(
|
||||
f"规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count}),跳过本次行动,重新规划"
|
||||
)
|
||||
await asyncio.sleep(0.1) # 短暂延时
|
||||
continue # 跳过本次行动,重新规划
|
||||
|
||||
@@ -154,23 +160,22 @@ class Conversation:
|
||||
# --- 清理未处理消息:移到这里,在执行动作前 ---
|
||||
# 只有当确实有新消息被 planner 看到,并且 action 是要处理它们的时候才清理
|
||||
if initial_new_message_count > 0 and action == "direct_reply":
|
||||
if hasattr(self.observation_info, 'clear_unprocessed_messages'):
|
||||
if hasattr(self.observation_info, "clear_unprocessed_messages"):
|
||||
# 确保 clear_unprocessed_messages 方法存在
|
||||
logger.debug(f"准备执行 direct_reply,清理 {initial_new_message_count} 条规划时已知的新消息。")
|
||||
self.observation_info.clear_unprocessed_messages()
|
||||
# 手动重置计数器,确保状态一致性(理想情况下 clear 方法会做这个)
|
||||
if hasattr(self.observation_info, 'new_messages_count'):
|
||||
if hasattr(self.observation_info, "new_messages_count"):
|
||||
self.observation_info.new_messages_count = 0
|
||||
else:
|
||||
logger.error("无法清理未处理消息: ObservationInfo 缺少 clear_unprocessed_messages 方法!")
|
||||
# 这里可能需要考虑是否继续执行 action,或者抛出错误
|
||||
|
||||
|
||||
# --- 执行行动 ---
|
||||
await self._handle_action(action, reason, self.observation_info, self.conversation_info)
|
||||
|
||||
goal_ended = False
|
||||
if hasattr(self.conversation_info, 'goal_list') and self.conversation_info.goal_list:
|
||||
if hasattr(self.conversation_info, "goal_list") and self.conversation_info.goal_list:
|
||||
for goal in self.conversation_info.goal_list:
|
||||
if isinstance(goal, tuple) and len(goal) > 0 and goal[0] == "结束对话":
|
||||
goal_ended = True
|
||||
@@ -189,7 +194,7 @@ class Conversation:
|
||||
logger.error(traceback.format_exc())
|
||||
# 发生严重错误时可以考虑停止,或者至少等待一下再继续
|
||||
await asyncio.sleep(1) # 发生错误时等待1秒
|
||||
#添加短暂的异步睡眠
|
||||
# 添加短暂的异步睡眠
|
||||
if self.should_continue: # 只有在还需要继续循环时才 sleep
|
||||
await asyncio.sleep(0.1) # 等待 0.1 秒,给其他任务执行时间
|
||||
|
||||
@@ -232,10 +237,10 @@ class Conversation:
|
||||
# 记录action历史,先设置为start,完成后再设置为done (这个 update 移到后面执行成功后再做)
|
||||
current_action_record = {
|
||||
"action": action,
|
||||
"plan_reason": reason, #使用 plan_reason 存储规划原因
|
||||
"plan_reason": reason, # 使用 plan_reason 存储规划原因
|
||||
"status": "start", # 初始状态为 start
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
"final_reason": None
|
||||
"final_reason": None,
|
||||
}
|
||||
conversation_info.done_action.append(current_action_record)
|
||||
# 获取刚刚添加记录的索引,方便后面更新状态
|
||||
@@ -264,7 +269,7 @@ class Conversation:
|
||||
reply=self.generated_reply,
|
||||
goal=current_goal_str,
|
||||
chat_history=observation_info.chat_history, # 传入最新的历史记录!
|
||||
retry_count=0
|
||||
retry_count=0,
|
||||
)
|
||||
logger.info(f"回复检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}")
|
||||
|
||||
@@ -280,31 +285,37 @@ class Conversation:
|
||||
if self._check_new_messages_after_planning():
|
||||
logger.info("检查到新消息,取消发送已生成的回复,重新规划行动")
|
||||
# 更新 action 状态为 recall
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "recall",
|
||||
"reason": f"有新消息,取消发送: {self.generated_reply}", # 更新原因
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
return None # 退出 _handle_action
|
||||
|
||||
# 发送回复
|
||||
await self._send_reply() # 这个函数内部会处理自己的错误
|
||||
|
||||
# 更新 action 历史状态为 done
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done",
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
else:
|
||||
# 回复不合适
|
||||
logger.warning(f"生成的回复被 ReplyChecker 拒绝: '{self.generated_reply}'. 原因: {check_reason}")
|
||||
# 更新 action 状态为 recall (因为没执行发送)
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "recall",
|
||||
"final_reason": check_reason,
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
# 如果检查器建议重新规划
|
||||
if need_replan:
|
||||
@@ -325,20 +336,24 @@ class Conversation:
|
||||
if knowledge:
|
||||
pass # 简单处理
|
||||
# 标记 action 为 done
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done",
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
elif action == "rethink_goal":
|
||||
self.waiter.wait_accumulated_time = 0
|
||||
self.state = ConversationState.RETHINKING
|
||||
await self.goal_analyzer.analyze_goal(conversation_info, observation_info)
|
||||
# 标记 action 为 done
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done",
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
elif action == "listening":
|
||||
self.state = ConversationState.LISTENING
|
||||
@@ -347,20 +362,23 @@ class Conversation:
|
||||
# listening 和 wait 通常在完成后不需要标记为 done,因为它们是持续状态,
|
||||
# 但如果需要记录,可以在 waiter 返回后标记。目前逻辑是 waiter 返回后主循环继续。
|
||||
# 为了统一,可以暂时在这里也标记一下(或者都不标记)
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done", # 或 "completed"
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
elif action == "end_conversation":
|
||||
self.should_continue = False # 设置循环停止标志
|
||||
logger.info("决定结束对话...")
|
||||
# 标记 action 为 done
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done",
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
# 这里不需要 return,主循环会在下一轮检查 should_continue
|
||||
|
||||
else: # 对应 'wait' 动作
|
||||
@@ -368,10 +386,12 @@ class Conversation:
|
||||
logger.info("等待更多信息...")
|
||||
await self.waiter.wait(self.conversation_info)
|
||||
# 同 listening,可以考虑是否标记状态
|
||||
conversation_info.done_action[action_index].update({
|
||||
conversation_info.done_action[action_index].update(
|
||||
{
|
||||
"status": "done", # 或 "completed"
|
||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
async def _send_timeout_message(self):
|
||||
"""发送超时结束消息"""
|
||||
@@ -412,7 +432,7 @@ class Conversation:
|
||||
"user_info": UserInfo( # 使用 UserInfo 类构建用户信息
|
||||
user_id=str(global_config.BOT_QQ),
|
||||
user_nickname=global_config.BOT_NICKNAME,
|
||||
platform=self.chat_stream.platform # 从 chat_stream 获取平台信息
|
||||
platform=self.chat_stream.platform, # 从 chat_stream 获取平台信息
|
||||
).to_dict(), # 转换为字典格式存储
|
||||
"processed_plain_text": reply_content, # 使用发送的内容
|
||||
"detailed_plain_text": f"{int(current_time)},{global_config.BOT_NICKNAME}:{reply_content}", # 构造一个简单的详细文本, 时间戳取整
|
||||
@@ -432,7 +452,6 @@ class Conversation:
|
||||
logger.error(f"手动更新 ObservationInfo 时出错: {update_err}")
|
||||
# --- 添加的立即更新状态逻辑结束 ---
|
||||
|
||||
|
||||
# 原有的触发更新和等待代码
|
||||
self.chat_observer.trigger_update()
|
||||
if not await self.chat_observer.wait_for_update():
|
||||
|
||||
@@ -100,11 +100,11 @@ class GoalAnalyzer:
|
||||
pronouns = ["你", "我", "他"]
|
||||
for p in pronouns:
|
||||
if identity_details_only.startswith(p):
|
||||
identity_details_only = identity_details_only[len(p):]
|
||||
identity_details_only = identity_details_only[len(p) :]
|
||||
break
|
||||
if identity_details_only.endswith("。"):
|
||||
identity_details_only = identity_details_only[:-1]
|
||||
cleaned_details = identity_details_only.strip(',, ')
|
||||
cleaned_details = identity_details_only.strip(",, ")
|
||||
if cleaned_details:
|
||||
identity_addon = f"并且{cleaned_details}"
|
||||
|
||||
@@ -263,11 +263,11 @@ class GoalAnalyzer:
|
||||
pronouns = ["你", "我", "他"]
|
||||
for p in pronouns:
|
||||
if identity_details_only.startswith(p):
|
||||
identity_details_only = identity_details_only[len(p):]
|
||||
identity_details_only = identity_details_only[len(p) :]
|
||||
break
|
||||
if identity_details_only.endswith("。"):
|
||||
identity_details_only = identity_details_only[:-1]
|
||||
cleaned_details = identity_details_only.strip(',, ')
|
||||
cleaned_details = identity_details_only.strip(",, ")
|
||||
if cleaned_details:
|
||||
identity_addon = f"并且{cleaned_details}"
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ class ReplyChecker:
|
||||
self.chat_observer = ChatObserver.get_instance(stream_id)
|
||||
self.max_retries = 2 # 最大重试次数
|
||||
|
||||
async def check(self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0) -> Tuple[bool, str, bool]:
|
||||
async def check(
|
||||
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0
|
||||
) -> Tuple[bool, str, bool]:
|
||||
"""检查生成的回复是否合适
|
||||
|
||||
Args:
|
||||
@@ -41,7 +43,7 @@ class ReplyChecker:
|
||||
for msg in reversed(chat_history):
|
||||
user_info = UserInfo.from_dict(msg.get("user_info", {}))
|
||||
if str(user_info.user_id) == str(global_config.BOT_QQ): # 确保比较的是字符串
|
||||
bot_messages.append(msg.get('processed_plain_text', ''))
|
||||
bot_messages.append(msg.get("processed_plain_text", ""))
|
||||
if len(bot_messages) >= 2: # 只和最近的两条比较
|
||||
break
|
||||
# 进行比较
|
||||
@@ -50,9 +52,14 @@ class ReplyChecker:
|
||||
# 简单比较:是否完全相同
|
||||
if reply == bot_messages[0]: # 和最近一条完全一样
|
||||
logger.warning(f"ReplyChecker 检测到回复与上一条 Bot 消息完全相同: '{reply}'")
|
||||
return False, "回复内容与你上一条发言完全相同,请修改,可以选择深入话题或寻找其它话题或等待", False # 不合适,无需重新规划
|
||||
return (
|
||||
False,
|
||||
"回复内容与你上一条发言完全相同,请修改,可以选择深入话题或寻找其它话题或等待",
|
||||
False,
|
||||
) # 不合适,无需重新规划
|
||||
# 2. 相似度检查 (如果精确匹配未通过)
|
||||
import difflib # 导入 difflib 库
|
||||
|
||||
# 计算编辑距离相似度,ratio() 返回 0 到 1 之间的浮点数
|
||||
similarity_ratio = difflib.SequenceMatcher(None, reply, bot_messages[0]).ratio()
|
||||
logger.debug(f"ReplyChecker - 相似度: {similarity_ratio:.2f}")
|
||||
@@ -60,8 +67,14 @@ class ReplyChecker:
|
||||
# 设置一个相似度阈值
|
||||
similarity_threshold = 0.9
|
||||
if similarity_ratio > similarity_threshold:
|
||||
logger.warning(f"ReplyChecker 检测到回复与上一条 Bot 消息高度相似 (相似度 {similarity_ratio:.2f}): '{reply}'")
|
||||
return False, f"拒绝发送:回复内容与你上一条发言高度相似 (相似度 {similarity_ratio:.2f}),请修改,可以选择深入话题或寻找其它话题或等待。", False
|
||||
logger.warning(
|
||||
f"ReplyChecker 检测到回复与上一条 Bot 消息高度相似 (相似度 {similarity_ratio:.2f}): '{reply}'"
|
||||
)
|
||||
return (
|
||||
False,
|
||||
f"拒绝发送:回复内容与你上一条发言高度相似 (相似度 {similarity_ratio:.2f}),请修改,可以选择深入话题或寻找其它话题或等待。",
|
||||
False,
|
||||
)
|
||||
|
||||
except Exception as self_check_err:
|
||||
logger.error(f"检查自身重复发言时出错: {self_check_err}")
|
||||
|
||||
@@ -92,11 +92,11 @@ class ReplyGenerator:
|
||||
pronouns = ["你", "我", "他"]
|
||||
for p in pronouns:
|
||||
if identity_details_only.startswith(p):
|
||||
identity_details_only = identity_details_only[len(p):]
|
||||
identity_details_only = identity_details_only[len(p) :]
|
||||
break
|
||||
if identity_details_only.endswith("。"):
|
||||
identity_details_only = identity_details_only[:-1]
|
||||
cleaned_details = identity_details_only.strip(',, ')
|
||||
cleaned_details = identity_details_only.strip(",, ")
|
||||
if cleaned_details:
|
||||
identity_addon = f"并且{cleaned_details}"
|
||||
persona_text = f"你的名字是{self.name},{self.personality_info}{identity_addon}。"
|
||||
@@ -172,7 +172,9 @@ class ReplyGenerator:
|
||||
logger.error(f"生成回复时出错: {e}")
|
||||
return "抱歉,我现在有点混乱,让我重新思考一下..."
|
||||
|
||||
async def check_reply(self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0) -> Tuple[bool, str, bool]:
|
||||
async def check_reply(
|
||||
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0
|
||||
) -> Tuple[bool, str, bool]:
|
||||
"""检查回复是否合适
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from src.common.logger import get_module_logger
|
||||
from .chat_observer import ChatObserver
|
||||
from .conversation_info import ConversationInfo
|
||||
|
||||
# from src.individuality.individuality import Individuality # 不再需要
|
||||
from ...config.config import global_config
|
||||
import time
|
||||
@@ -12,6 +13,7 @@ logger = get_module_logger("waiter")
|
||||
# 例如: 120 秒 = 2 分钟
|
||||
DESIRED_TIMEOUT_SECONDS = 300
|
||||
|
||||
|
||||
class Waiter:
|
||||
"""等待处理类"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user