mirror of https://github.com/Mai-with-u/MaiBot.git
再推!
parent
377d798c72
commit
67b958a140
|
|
@ -124,6 +124,48 @@ PROMPT_END_DECISION = """
|
|||
|
||||
注意:请严格按照 JSON 格式输出,不要包含任何其他内容。"""
|
||||
|
||||
# Prompt(4): 当 reply_generator 决定不发送消息后的反思决策 Prompt
|
||||
PROMPT_REFLECT_AND_ACT = """
|
||||
当前时间:{current_time_str}
|
||||
{persona_text}
|
||||
现在你正在和{sender_name}在QQ上私聊
|
||||
你与对方的关系是:{relationship_text}
|
||||
你现在的心情是:{current_emotion_text}
|
||||
刚刚你本来想发一条新消息,但是想了想,你决定不发了。
|
||||
请根据以下【所有信息】审慎且灵活的决策下一步行动,可以等待,可以倾听,可以结束对话,甚至可以屏蔽对方:
|
||||
|
||||
【当前对话目标】
|
||||
{goals_str}
|
||||
【最近行动历史概要】
|
||||
{action_history_summary}
|
||||
【你想起来的相关知识】
|
||||
{retrieved_knowledge_str}
|
||||
【上一次行动的详细情况和结果】
|
||||
{last_action_context}
|
||||
【时间和超时提示】
|
||||
{time_since_last_bot_message_info}{timeout_context}
|
||||
【最近的对话记录】(包括你已成功发送的消息 和 新收到的消息)
|
||||
{chat_history_text}
|
||||
【你的回忆】
|
||||
{retrieved_memory_str}
|
||||
|
||||
{spam_warning_info}
|
||||
|
||||
------
|
||||
可选行动类型以及解释:
|
||||
wait: 等待,暂时不说话。
|
||||
listening: 倾听对方发言(虽然你刚发过言,但如果对方立刻回复且明显话没说完,可以选择这个)
|
||||
rethink_goal: 思考一个对话目标,当你觉得目前对话需要目标,或当前目标不再适用,或话题卡住时选择。注意私聊的环境是灵活的,有可能需要经常选择
|
||||
end_conversation: 安全和平的结束对话,对方长时间没回复、繁忙、已经不再回复你消息、明显暗示或表达想结束聊天时,可以果断选择
|
||||
block_and_ignore: 更加极端的结束对话方式,直接结束对话并在一段时间内无视对方所有发言(屏蔽),当对话让你感到十分不适,或你遭到各类骚扰时选择
|
||||
|
||||
请以JSON格式输出你的决策:
|
||||
{{
|
||||
"action": "选择的行动类型 (必须是上面列表中的一个)",
|
||||
"reason": "选择该行动的详细原因 (必须有解释你是如何根据“上一次行动结果”、“对话记录”和自身设定人设做出合理判断的。)"
|
||||
}}
|
||||
|
||||
注意:请严格按照JSON格式输出,不要包含任何其他内容。"""
|
||||
|
||||
class ActionPlanner:
|
||||
"""行动规划器"""
|
||||
|
|
@ -162,6 +204,7 @@ class ActionPlanner:
|
|||
observation_info: ObservationInfo,
|
||||
conversation_info: ConversationInfo,
|
||||
last_successful_reply_action: Optional[str],
|
||||
use_reflect_prompt: bool = False # 新增参数,用于指示是否使用PROMPT_REFLECT_AND_ACT
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
规划下一步行动。
|
||||
|
|
@ -206,24 +249,38 @@ class ActionPlanner:
|
|||
|
||||
# --- 2. 选择并格式化 Prompt ---
|
||||
try:
|
||||
if last_successful_reply_action in ["direct_reply", "send_new_message"]:
|
||||
if use_reflect_prompt: # 新增的判断
|
||||
prompt_template = PROMPT_REFLECT_AND_ACT
|
||||
log_msg = "使用 PROMPT_REFLECT_AND_ACT (反思决策)"
|
||||
# 对于 PROMPT_REFLECT_AND_ACT,它不包含 send_new_message 选项,所以 spam_warning_message 中的相关提示可以调整或省略
|
||||
# 但为了保持占位符填充的一致性,我们仍然计算它
|
||||
spam_warning_message = ""
|
||||
if conversation_info.my_message_count > 5: # 这里的 my_message_count 仍有意义,表示之前连续发送了多少
|
||||
spam_warning_message = f"⚠️【警告】**你之前已连续发送{str(conversation_info.my_message_count)}条消息!请谨慎决策。**"
|
||||
elif conversation_info.my_message_count > 2:
|
||||
spam_warning_message = f"💬【提示】**你之前已连续发送{str(conversation_info.my_message_count)}条消息。请注意保持对话平衡。**"
|
||||
|
||||
elif last_successful_reply_action in ["direct_reply", "send_new_message"]:
|
||||
prompt_template = PROMPT_FOLLOW_UP
|
||||
log_msg = "使用 PROMPT_FOLLOW_UP (追问决策)"
|
||||
spam_warning_message = ""
|
||||
if conversation_info.my_message_count > 5:
|
||||
spam_warning_message = f"⚠️【警告】**你已连续发送{str(conversation_info.my_message_count)}条消息!请注意不要再选择send_new_message!以免刷屏对造成对方困扰!**"
|
||||
elif conversation_info.my_message_count > 2:
|
||||
spam_warning_message = f"💬【警告】**你已连续发送{str(conversation_info.my_message_count)}条消息。请保持理智,如果非必要,请避免选择send_new_message,以免给对方造成困扰。**"
|
||||
|
||||
else:
|
||||
prompt_template = PROMPT_INITIAL_REPLY
|
||||
log_msg = "使用 PROMPT_INITIAL_REPLY (首次/非连续回复决策)"
|
||||
spam_warning_message = "" # 初始回复时通常不需要刷屏警告
|
||||
|
||||
logger.debug(f"[私聊][{self.private_name}] {log_msg}")
|
||||
|
||||
current_time_value = "获取时间失败" # 默认值
|
||||
current_time_value = "获取时间失败"
|
||||
if observation_info and hasattr(observation_info, 'current_time_str') and observation_info.current_time_str:
|
||||
current_time_value = observation_info.current_time_str
|
||||
|
||||
spam_warning_message = "" # 初始化为空字符串
|
||||
if conversation_info.my_message_count > 5:
|
||||
spam_warning_message = f"⚠️【警告】**你已连续发送{str(conversation_info.my_message_count)}条消息!请注意不要再选择send_new_message!以免刷屏对造成对方困扰!**"
|
||||
elif conversation_info.my_message_count > 2:
|
||||
spam_warning_message = f"💬【警告】**你已连续发送{str(conversation_info.my_message_count)}条消息。请保持理智,如果非必要,请避免选择send_new_message,以免给对方造成困扰。**"
|
||||
if spam_warning_message: # 仅当有警告时才添加换行符
|
||||
if spam_warning_message:
|
||||
spam_warning_message = f"\n{spam_warning_message}\n"
|
||||
|
||||
prompt = prompt_template.format(
|
||||
|
|
@ -236,9 +293,8 @@ class ActionPlanner:
|
|||
chat_history_text=chat_history_text if chat_history_text.strip() else "还没有聊天记录。",
|
||||
retrieved_memory_str=retrieved_memory_str if retrieved_memory_str else "无相关记忆。",
|
||||
retrieved_knowledge_str=retrieved_knowledge_str if retrieved_knowledge_str else "无相关知识。",
|
||||
current_time_str=current_time_value, # 新增:传入当前时间字符串
|
||||
current_time_str=current_time_value,
|
||||
spam_warning_info=spam_warning_message,
|
||||
### 标记新增/修改区域 开始 ###
|
||||
sender_name=sender_name_str,
|
||||
relationship_text=relationship_text_str,
|
||||
current_emotion_text=current_emotion_text_str
|
||||
|
|
@ -299,7 +355,7 @@ class ActionPlanner:
|
|||
# final_reason = initial_reason
|
||||
|
||||
# --- 5. 验证最终行动类型 ---
|
||||
valid_actions = [
|
||||
valid_actions_default = [
|
||||
"direct_reply",
|
||||
"send_new_message",
|
||||
"wait",
|
||||
|
|
@ -309,7 +365,19 @@ class ActionPlanner:
|
|||
"block_and_ignore",
|
||||
"say_goodbye",
|
||||
]
|
||||
if final_action not in valid_actions:
|
||||
valid_actions_reflect = [ # PROMPT_REFLECT_AND_ACT 的动作
|
||||
"wait",
|
||||
"listening",
|
||||
"rethink_goal",
|
||||
"end_conversation",
|
||||
"block_and_ignore",
|
||||
# PROMPT_REFLECT_AND_ACT 也可以 end_conversation,然后也可能触发 say_goodbye
|
||||
"say_goodbye",
|
||||
]
|
||||
|
||||
current_valid_actions = valid_actions_reflect if use_reflect_prompt else valid_actions_default
|
||||
|
||||
if final_action not in current_valid_actions:
|
||||
logger.warning(f"[私聊][{self.private_name}] LLM 返回了未知的行动类型: '{final_action}',强制改为 wait")
|
||||
final_reason = f"(原始行动'{final_action}'无效,已强制改为wait) {final_reason}"
|
||||
final_action = "wait" # 遇到无效动作,默认等待
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import time
|
|||
import asyncio
|
||||
import datetime
|
||||
import traceback
|
||||
import json # 确保导入 json 模块
|
||||
from .pfc_utils import get_items_from_json # 导入JSON解析工具
|
||||
from typing import Dict, Any, Optional, Set, List
|
||||
from dateutil import tz
|
||||
|
||||
|
|
@ -506,7 +508,7 @@ class Conversation:
|
|||
if not self._initialized:
|
||||
logger.error(f"[私聊][{self.private_name}] 尝试在未初始化状态下运行规划循环,退出。")
|
||||
return # 明确退出
|
||||
|
||||
force_reflect_and_act = False
|
||||
# 主循环,只要 should_continue 为 True 就一直运行
|
||||
while self.should_continue:
|
||||
loop_iter_start_time = time.time() # 记录本次循环开始时间
|
||||
|
|
@ -654,10 +656,12 @@ class Conversation:
|
|||
logger.debug(f"[私聊][{self.private_name}] 调用 ActionPlanner.plan...")
|
||||
# 传入当前观察信息、对话信息和上次成功回复的动作类型
|
||||
action, reason = await self.action_planner.plan(
|
||||
self.observation_info,
|
||||
self.conversation_info,
|
||||
self.conversation_info.last_successful_reply_action
|
||||
self.observation_info,
|
||||
self.conversation_info, # type: ignore
|
||||
self.conversation_info.last_successful_reply_action, # type: ignore
|
||||
use_reflect_prompt=force_reflect_and_act # 使用标志
|
||||
)
|
||||
force_reflect_and_act = False
|
||||
planning_duration = time.time() - planning_start_time
|
||||
logger.debug(
|
||||
f"[私聊][{self.private_name}] ActionPlanner.plan 完成 (耗时: {planning_duration:.3f} 秒),初步规划动作: {action}"
|
||||
|
|
@ -765,6 +769,16 @@ class Conversation:
|
|||
await self._handle_action(action, reason, self.observation_info, self.conversation_info)
|
||||
logger.debug(f"[私聊][{self.private_name}] _handle_action 完成。")
|
||||
|
||||
# --- 新增逻辑:检查是否因为RG决定不发送而需要反思 ---
|
||||
last_action_record = (
|
||||
self.conversation_info.done_action[-1] if self.conversation_info.done_action else {} # type: ignore
|
||||
)
|
||||
if last_action_record.get("action") == "send_new_message" and \
|
||||
last_action_record.get("status") == "done_no_reply":
|
||||
logger.info(f"[私聊][{self.private_name}] 检测到 ReplyGenerator 决定不发送消息,将在下一轮强制使用反思Prompt。")
|
||||
force_reflect_and_act = True # 设置标志,下一轮使用反思prompt
|
||||
# 不需要立即 continue,让循环自然进入下一轮,下一轮的 plan 会用这个标志
|
||||
|
||||
# 8. 检查是否需要结束整个对话(例如目标达成或执行了结束动作)
|
||||
goal_ended: bool = False
|
||||
# 检查最新的目标是否是“结束对话”
|
||||
|
|
@ -913,68 +927,105 @@ class Conversation:
|
|||
check_reason: str = "未进行检查" # 存储检查结果原因
|
||||
|
||||
# --- [核心修复] 引入重试循环 ---
|
||||
is_send_decision_from_rg = False # 标记是否由 reply_generator 决定发送
|
||||
|
||||
while reply_attempt_count < max_reply_attempts and not is_suitable and not need_replan_from_checker:
|
||||
reply_attempt_count += 1
|
||||
log_prefix = f"[私聊][{self.private_name}] 尝试生成/检查 '{action}' 回复 (第 {reply_attempt_count}/{max_reply_attempts} 次)..."
|
||||
logger.info(log_prefix)
|
||||
|
||||
# --- a. 生成回复 ---
|
||||
self.state = ConversationState.GENERATING # 更新对话状态
|
||||
self.state = ConversationState.GENERATING
|
||||
if not self.reply_generator:
|
||||
# 检查依赖组件是否存在
|
||||
raise RuntimeError("ReplyGenerator 未初始化")
|
||||
# 调用 ReplyGenerator 生成回复内容
|
||||
generated_content = await self.reply_generator.generate(
|
||||
|
||||
raw_llm_output = await self.reply_generator.generate(
|
||||
observation_info, conversation_info, action_type=action
|
||||
)
|
||||
logger.info(f"{log_prefix} 生成内容: '{generated_content}'") # 日志中截断长内容
|
||||
logger.debug(f"{log_prefix} ReplyGenerator.generate 返回: '{raw_llm_output}'")
|
||||
|
||||
# 检查生成内容是否有效
|
||||
if not generated_content or generated_content.startswith("抱歉"):
|
||||
# 如果生成失败或返回错误提示
|
||||
logger.warning(f"{log_prefix} 生成内容为空或为错误提示,将进行下一次尝试。")
|
||||
check_reason = "生成内容无效" # 记录原因
|
||||
# 记录拒绝信息供下次生成参考
|
||||
should_send_reply = True # 默认对于 direct_reply 是要发送的
|
||||
text_to_process = raw_llm_output # 默认情况下,处理原始输出
|
||||
|
||||
if action == "send_new_message":
|
||||
is_send_decision_from_rg = True # 标记 send_new_message 的决策来自RG
|
||||
try:
|
||||
# 使用 pfc_utils.py 中的 get_items_from_json 来解析
|
||||
# 注意:get_items_from_json 目前主要用于提取固定字段的字典。
|
||||
# reply_generator 返回的是一个顶级JSON对象。
|
||||
# 我们需要稍微调整用法或增强 get_items_from_json。
|
||||
# 简单起见,这里我们先直接用 json.loads,后续可以优化。
|
||||
|
||||
parsed_json = None
|
||||
try:
|
||||
parsed_json = json.loads(raw_llm_output)
|
||||
except json.JSONDecodeError:
|
||||
logger.error(f"{log_prefix} ReplyGenerator 返回的不是有效的JSON: {raw_llm_output}")
|
||||
# 如果JSON解析失败,视为RG决定不发送,并给出原因
|
||||
conversation_info.last_reply_rejection_reason = "回复生成器未返回有效JSON"
|
||||
conversation_info.last_rejected_reply_content = raw_llm_output
|
||||
should_send_reply = False
|
||||
text_to_process = "no" # 或者一个特定的错误标记
|
||||
|
||||
if parsed_json:
|
||||
send_decision = parsed_json.get("send", "no").lower()
|
||||
generated_text_from_json = parsed_json.get("txt", "no")
|
||||
|
||||
if send_decision == "yes":
|
||||
should_send_reply = True
|
||||
text_to_process = generated_text_from_json
|
||||
logger.info(f"{log_prefix} ReplyGenerator 决定发送消息。内容: '{text_to_process[:100]}...'")
|
||||
else:
|
||||
should_send_reply = False
|
||||
text_to_process = "no" # 保持和 prompt 中一致,txt 为 "no"
|
||||
logger.info(f"{log_prefix} ReplyGenerator 决定不发送消息。")
|
||||
# 此时,我们应该跳出重试循环,并触发 action_planner 的反思 prompt
|
||||
# 将此信息传递到循环外部进行处理
|
||||
break # 跳出 while 循环
|
||||
|
||||
except Exception as e_json: # 更广泛地捕获解析相关的错误
|
||||
logger.error(f"{log_prefix} 解析 ReplyGenerator 的JSON输出时出错: {e_json}, 输出: {raw_llm_output}")
|
||||
conversation_info.last_reply_rejection_reason = f"解析回复生成器JSON输出错误: {e_json}"
|
||||
conversation_info.last_rejected_reply_content = raw_llm_output
|
||||
should_send_reply = False
|
||||
text_to_process = "no"
|
||||
|
||||
if not should_send_reply and action == "send_new_message": # 如果RG决定不发送 (send_new_message特定逻辑)
|
||||
break # 直接跳出重试循环,后续逻辑会处理这种情况
|
||||
|
||||
generated_content_for_check_or_send = text_to_process
|
||||
|
||||
if not generated_content_for_check_or_send or generated_content_for_check_or_send.startswith("抱歉") or (action == "send_new_message" and generated_content_for_check_or_send == "no"):
|
||||
logger.warning(f"{log_prefix} 生成内容无效或为错误提示 (或send:no),将进行下一次尝试 (如果适用)。")
|
||||
check_reason = "生成内容无效或选择不发送"
|
||||
conversation_info.last_reply_rejection_reason = check_reason
|
||||
conversation_info.last_rejected_reply_content = generated_content
|
||||
await asyncio.sleep(0.5) # 短暂等待后重试
|
||||
continue # 进入下一次循环尝试
|
||||
conversation_info.last_rejected_reply_content = generated_content_for_check_or_send
|
||||
if action == "direct_reply": # direct_reply 失败时才继续尝试
|
||||
await asyncio.sleep(0.5)
|
||||
continue
|
||||
else: # send_new_message 如果是 no,不应该继续尝试,上面已经break了
|
||||
pass # 理论上不会到这里如果上面break了
|
||||
|
||||
# --- b. 检查回复 ---
|
||||
self.state = ConversationState.CHECKING # 更新状态为检查中
|
||||
self.state = ConversationState.CHECKING
|
||||
if not self.reply_checker:
|
||||
raise RuntimeError("ReplyChecker 未初始化")
|
||||
|
||||
# 准备检查所需的上下文信息
|
||||
current_goal_str: str = "" # 当前对话目标字符串
|
||||
current_goal_str = ""
|
||||
if conversation_info.goal_list:
|
||||
# 通常检查最新的目标
|
||||
goal_item = conversation_info.goal_list[-1]
|
||||
if isinstance(goal_item, dict):
|
||||
current_goal_str = goal_item.get("goal", "")
|
||||
elif isinstance(goal_item, str):
|
||||
current_goal_str = goal_item
|
||||
# 获取用于检查的聊天记录 (列表和字符串形式)
|
||||
chat_history_for_check: List[Dict[str, Any]] = getattr(observation_info, "chat_history", [])
|
||||
chat_history_text_for_check: str = getattr(observation_info, "chat_history_str", "")
|
||||
# 当前重试次数 (传递给 checker,可能有用)
|
||||
# retry_count for checker starts from 0
|
||||
current_retry_for_checker = reply_attempt_count - 1
|
||||
|
||||
|
||||
chat_history_for_check = getattr(observation_info, "chat_history", [])
|
||||
chat_history_text_for_check = getattr(observation_info, "chat_history_str", "")
|
||||
current_retry_for_checker = reply_attempt_count - 1
|
||||
current_time_value_for_check = observation_info.current_time_str or "获取时间失败"
|
||||
|
||||
|
||||
current_time_value_for_check = "获取时间失败"
|
||||
if observation_info and hasattr(observation_info, 'current_time_str') and observation_info.current_time_str:
|
||||
current_time_value_for_check = observation_info.current_time_str
|
||||
|
||||
|
||||
logger.debug(f"{log_prefix} 调用 ReplyChecker 检查...")
|
||||
# --- 根据配置决定是否执行检查 ---
|
||||
if global_config.enable_pfc_reply_checker: # <--- 使用配置项
|
||||
if global_config.enable_pfc_reply_checker:
|
||||
logger.debug(f"{log_prefix} 调用 ReplyChecker 检查 (配置已启用)...")
|
||||
is_suitable, check_reason, need_replan_from_checker = await self.reply_checker.check(
|
||||
reply=generated_content,
|
||||
reply=generated_content_for_check_or_send,
|
||||
goal=current_goal_str,
|
||||
chat_history=chat_history_for_check,
|
||||
chat_history_text=chat_history_text_for_check,
|
||||
|
|
@ -985,67 +1036,96 @@ class Conversation:
|
|||
f"{log_prefix} ReplyChecker 结果: 合适={is_suitable}, 原因='{check_reason}', 需重规划={need_replan_from_checker}"
|
||||
)
|
||||
else:
|
||||
# 如果配置为关闭,则默认通过检查
|
||||
is_suitable = True
|
||||
check_reason = "ReplyChecker 已通过配置关闭"
|
||||
need_replan_from_checker = False
|
||||
logger.info(f"[配置关闭] ReplyChecker 已跳过,默认回复为合适。")
|
||||
# 如果不合适,记录原因并准备下一次尝试(如果还有次数)
|
||||
logger.info(f"{log_prefix} [配置关闭] ReplyChecker 已跳过,默认回复为合适。")
|
||||
|
||||
if not is_suitable:
|
||||
# 记录拒绝原因和内容,供下次生成时参考
|
||||
conversation_info.last_reply_rejection_reason = check_reason
|
||||
conversation_info.last_rejected_reply_content = generated_content
|
||||
# 如果不需要重规划且还有尝试次数
|
||||
conversation_info.last_rejected_reply_content = generated_content_for_check_or_send
|
||||
if not need_replan_from_checker and reply_attempt_count < max_reply_attempts:
|
||||
logger.warning(f"{log_prefix} 回复不合适,原因: {check_reason}。将进行下一次尝试。")
|
||||
await asyncio.sleep(0.5) # 等待后重试
|
||||
await asyncio.sleep(0.5)
|
||||
# 如果需要重规划或达到最大次数,循环会在下次判断时自动结束
|
||||
|
||||
# --- 循环结束后处理 ---
|
||||
if action == "send_new_message" and not should_send_reply and is_send_decision_from_rg:
|
||||
# 这是 reply_generator 决定不发送的情况
|
||||
logger.info(f"[私聊][{self.private_name}] 动作 '{action}': ReplyGenerator 决定不发送消息。将调用 ActionPlanner 进行反思。")
|
||||
final_status = "done_no_reply" # 一个新的状态,表示动作完成但无回复
|
||||
final_reason = "回复生成器决定不发送消息"
|
||||
action_successful = True # 动作本身(决策)是成功的
|
||||
|
||||
# --- 循环结束后,处理最终结果 ---
|
||||
if is_suitable:
|
||||
# 如果找到了合适的回复
|
||||
# 清除追问状态,因为没有实际发送
|
||||
conversation_info.last_successful_reply_action = None
|
||||
conversation_info.my_message_count = 0 # 重置连续发言计数
|
||||
|
||||
# !!! 触发 ActionPlanner 使用 PROMPT_REFLECT_AND_ACT !!!
|
||||
if not self.action_planner:
|
||||
raise RuntimeError("ActionPlanner 未初始化")
|
||||
|
||||
logger.info(f"[私聊][{self.private_name}] {self.name} 本来想发一条新消息,但是想想还是算了。现在重新规划...")
|
||||
# 调用 action_planner.plan 并传入 use_reflect_prompt=True
|
||||
new_action, new_reason = await self.action_planner.plan(
|
||||
observation_info,
|
||||
conversation_info,
|
||||
last_successful_reply_action=None, # 因为没发送,所以没有成功的回复动作
|
||||
use_reflect_prompt=True
|
||||
)
|
||||
# 记录这次特殊的“反思”动作
|
||||
reflect_action_record = {
|
||||
"action": f"reflect_after_no_send ({new_action})", # 记录原始意图和新规划
|
||||
"plan_reason": f"RG决定不发送后,AP规划: {new_reason}",
|
||||
"status": "delegated", # 标记为委托给新的规划
|
||||
"time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
}
|
||||
conversation_info.done_action.append(reflect_action_record)
|
||||
|
||||
logger.info(f"[私聊][{self.private_name}] 反思后的新规划动作: {new_action}, 原因: {new_reason}")
|
||||
# **暂定方案:**
|
||||
# _handle_action 在这种情况下返回一个特殊标记。
|
||||
# 为了不立即修改返回类型,我们暂时在这里记录日志,并在 _plan_and_action_loop 中添加逻辑。
|
||||
# _handle_action 会将 action_successful 设置为 True,final_status 为 "done_no_reply"。
|
||||
# _plan_and_action_loop 之后会检查这个状态。
|
||||
|
||||
# (这里的 final_status, final_reason, action_successful 已在上面设置)
|
||||
|
||||
elif is_suitable: # 适用于 direct_reply 或 send_new_message (RG决定发送且检查通过)
|
||||
logger.info(f"[私聊][{self.private_name}] 动作 '{action}': 找到合适的回复,准备发送。")
|
||||
# 清除上次的拒绝信息 (因为本次成功了)
|
||||
conversation_info.last_reply_rejection_reason = None
|
||||
conversation_info.last_rejected_reply_content = None
|
||||
|
||||
# --- c. 发送回复 ---
|
||||
self.generated_reply = generated_content # 使用最后一次检查通过的内容
|
||||
timestamp_before_sending = time.time() # 记录发送前时间戳
|
||||
self.generated_reply = generated_content_for_check_or_send
|
||||
timestamp_before_sending = time.time()
|
||||
logger.debug(
|
||||
f"[私聊][{self.private_name}] 动作 '{action}': 记录发送前时间戳: {timestamp_before_sending:.2f}"
|
||||
)
|
||||
self.state = ConversationState.SENDING # 更新状态为发送中
|
||||
# 调用内部发送方法
|
||||
send_success = await self._send_reply()
|
||||
send_end_time = time.time() # 记录发送结束时间
|
||||
self.state = ConversationState.SENDING
|
||||
send_success = await self._send_reply() # _send_reply 内部会更新 my_message_count
|
||||
send_end_time = time.time()
|
||||
|
||||
if send_success:
|
||||
# 如果发送成功
|
||||
action_successful = True # 标记动作成功
|
||||
# final_status 和 final_reason 会在 finally 中设置
|
||||
action_successful = True
|
||||
logger.info(f"[私聊][{self.private_name}] 动作 '{action}': 成功发送回复.")
|
||||
# 更新空闲计时器
|
||||
if self.idle_conversation_starter:
|
||||
await self.idle_conversation_starter.update_last_message_time(send_end_time)
|
||||
|
||||
# --- d. 清理已处理消息 ---
|
||||
current_unprocessed_messages = getattr(observation_info, "unprocessed_messages", [])
|
||||
message_ids_to_clear: Set[str] = set()
|
||||
# 遍历所有未处理消息
|
||||
for msg in current_unprocessed_messages:
|
||||
msg_time = msg.get("time")
|
||||
msg_id = msg.get("message_id")
|
||||
sender_id = msg.get("user_info", {}).get("user_id")
|
||||
# 规则:只清理【发送前】收到的、【来自他人】的消息
|
||||
sender_id_info = msg.get("user_info", {})
|
||||
sender_id = str(sender_id_info.get("user_id")) if sender_id_info else None
|
||||
|
||||
if (
|
||||
msg_id
|
||||
and msg_time
|
||||
and sender_id != self.bot_qq_str
|
||||
and msg_time < timestamp_before_sending
|
||||
and sender_id != self.bot_qq_str # 确保是对方的消息
|
||||
and msg_time < timestamp_before_sending # 只清理发送前的
|
||||
):
|
||||
message_ids_to_clear.add(msg_id)
|
||||
# 如果有需要清理的消息,调用清理方法
|
||||
|
||||
if message_ids_to_clear:
|
||||
logger.debug(
|
||||
f"[私聊][{self.private_name}] 准备清理 {len(message_ids_to_clear)} 条发送前(他人)消息: {message_ids_to_clear}"
|
||||
|
|
@ -1054,73 +1134,66 @@ class Conversation:
|
|||
else:
|
||||
logger.debug(f"[私聊][{self.private_name}] 没有需要清理的发送前(他人)消息。")
|
||||
|
||||
# --- e. 决定下一轮规划类型 ---
|
||||
# 从 conversation_info 获取【规划期间】收到的【他人】新消息数量
|
||||
other_new_msg_count_during_planning = getattr(
|
||||
conversation_info, "other_new_messages_during_planning_count", 0
|
||||
)
|
||||
|
||||
# 规则:如果规划期间收到他人新消息 (0 < count <= 2),则下一轮强制初始回复
|
||||
if other_new_msg_count_during_planning > 0:
|
||||
if other_new_msg_count_during_planning > 0 and action == "direct_reply":
|
||||
logger.info(
|
||||
f"[私聊][{self.private_name}] 因规划期间收到 {other_new_msg_count_during_planning} 条他人新消息,下一轮强制使用【初始回复】逻辑。"
|
||||
)
|
||||
conversation_info.last_successful_reply_action = None # 强制初始回复
|
||||
conversation_info.my_message_count = 0 # 自身发言数量清零
|
||||
else:
|
||||
# 规则:如果规划期间【没有】收到他人新消息,则允许追问
|
||||
conversation_info.last_successful_reply_action = None
|
||||
# conversation_info.my_message_count = 0 # 不在这里重置,因为刚发了一条
|
||||
elif action == "direct_reply" or action == "send_new_message": # 成功发送后
|
||||
logger.info(
|
||||
f"[私聊][{self.private_name}] 规划期间无他人新消息,下一轮【允许】使用追问逻辑 (基于 '{action}')。"
|
||||
)
|
||||
conversation_info.last_successful_reply_action = action # 允许追问
|
||||
|
||||
if conversation_info: # 确保 conversation_info 存在
|
||||
conversation_info.current_instance_message_count += 1
|
||||
logger.debug(f"[私聊][{self.private_name}] 实例消息计数(机器人发送后)增加到: {conversation_info.current_instance_message_count}")
|
||||
|
||||
if self.relationship_updater:
|
||||
await self.relationship_updater.update_relationship_incremental(
|
||||
conversation_info=conversation_info,
|
||||
observation_info=observation_info,
|
||||
chat_observer_for_history=self.chat_observer
|
||||
f"[私聊][{self.private_name}] 成功执行 '{action}', 下一轮【允许】使用追问逻辑。"
|
||||
)
|
||||
conversation_info.last_successful_reply_action = action
|
||||
|
||||
sent_reply_summary = self.generated_reply[:50] if self.generated_reply else "空回复"
|
||||
event_for_emotion_update = f"你刚刚发送了消息: '{sent_reply_summary}...'"
|
||||
if self.emotion_updater:
|
||||
await self.emotion_updater.update_emotion_based_on_context(
|
||||
conversation_info=conversation_info,
|
||||
observation_info=observation_info,
|
||||
chat_observer_for_history=self.chat_observer,
|
||||
event_description=event_for_emotion_update
|
||||
)
|
||||
else:
|
||||
# 如果发送失败
|
||||
if conversation_info:
|
||||
conversation_info.current_instance_message_count += 1
|
||||
logger.debug(f"[私聊][{self.private_name}] 实例消息计数(机器人发送后)增加到: {conversation_info.current_instance_message_count}")
|
||||
|
||||
if self.relationship_updater:
|
||||
await self.relationship_updater.update_relationship_incremental(
|
||||
conversation_info=conversation_info,
|
||||
observation_info=observation_info,
|
||||
chat_observer_for_history=self.chat_observer
|
||||
)
|
||||
|
||||
sent_reply_summary = self.generated_reply[:50] if self.generated_reply else "空回复"
|
||||
event_for_emotion_update = f"你刚刚发送了消息: '{sent_reply_summary}...'"
|
||||
if self.emotion_updater:
|
||||
await self.emotion_updater.update_emotion_based_on_context(
|
||||
conversation_info=conversation_info,
|
||||
observation_info=observation_info,
|
||||
chat_observer_for_history=self.chat_observer,
|
||||
event_description=event_for_emotion_update
|
||||
)
|
||||
else: # 发送失败
|
||||
logger.error(f"[私聊][{self.private_name}] 动作 '{action}': 发送回复失败。")
|
||||
final_status = "recall" # 发送失败,标记为 recall
|
||||
final_status = "recall"
|
||||
final_reason = "发送回复时失败"
|
||||
# 重置追问状态
|
||||
conversation_info.last_successful_reply_action = None
|
||||
conversation_info.my_message_count = 0 # 发送失败,重置计数
|
||||
|
||||
elif need_replan_from_checker:
|
||||
# 如果 Checker 要求重新规划
|
||||
logger.warning(
|
||||
f"[私聊][{self.private_name}] 动作 '{action}' 因 ReplyChecker 要求而被取消,将重新规划。原因: {check_reason}"
|
||||
)
|
||||
final_status = "recall" # 标记为 recall
|
||||
final_status = "recall"
|
||||
final_reason = f"回复检查要求重新规划: {check_reason}"
|
||||
# # 重置追问状态
|
||||
# conversation_info.last_successful_reply_action = None
|
||||
conversation_info.last_successful_reply_action = None
|
||||
# my_message_count 保持不变,因为没有成功发送
|
||||
|
||||
else:
|
||||
# 达到最大尝试次数仍未找到合适回复
|
||||
else: # 达到最大尝试次数仍未找到合适回复
|
||||
logger.warning(
|
||||
f"[私聊][{self.private_name}] 动作 '{action}': 达到最大尝试次数 ({max_reply_attempts}),未能生成/检查通过合适的回复。最终原因: {check_reason}"
|
||||
)
|
||||
final_status = "recall" # 标记为 recall
|
||||
final_status = "recall"
|
||||
final_reason = f"尝试{max_reply_attempts}次后失败: {check_reason}"
|
||||
# # 重置追问状态
|
||||
# conversation_info.last_successful_reply_action = None
|
||||
conversation_info.last_successful_reply_action = None
|
||||
# my_message_count 保持不变
|
||||
|
||||
# 2. 处理发送告别语动作 (保持简单,不加重试)
|
||||
elif action == "say_goodbye":
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ PROMPT_SEND_NEW_MESSAGE = """
|
|||
你正在和{sender_name}在QQ上私聊,**并且刚刚你已经发送了一条或多条消息**
|
||||
你与对方的关系是:{relationship_text}
|
||||
你现在的心情是:{current_emotion_text}
|
||||
现在请根据以下信息再发一条新消息:
|
||||
现在请根据以下信息判断你是否要继续发一条新消息,当然,如果你决定继续发消息不合适,也可以不发:
|
||||
|
||||
当前对话目标:{goals_str}
|
||||
|
||||
|
|
@ -79,7 +79,9 @@ PROMPT_SEND_NEW_MESSAGE = """
|
|||
|
||||
{last_rejection_info}
|
||||
|
||||
请根据上述信息,结合聊天记录,继续发一条新消息(例如对之前消息的补充,深入话题,或追问等等)。该消息应该:
|
||||
{spam_warning_info}
|
||||
|
||||
请根据上述信息,判断你是否要继续发一条新消息(例如对之前消息的补充,深入话题,或追问等等)。如果你觉得要发送,该消息应该:
|
||||
1. 符合对话目标,以"你"的角度发言(不要自己与自己对话!)
|
||||
2. 符合你的性格特征和身份细节
|
||||
3. 通俗易懂,自然流畅,像正常聊天一样,简短(通常20字以内,除非特殊情况)
|
||||
|
|
@ -88,10 +90,14 @@ PROMPT_SEND_NEW_MESSAGE = """
|
|||
|
||||
请注意把握聊天内容,不用太有条理,可以有个性。请分清"你"和对方说的话,不要把"你"说的话当做对方说的话,这是你自己说的话。
|
||||
这条消息可以自然随意自然一些,就像真人一样,注意把握聊天内容,整体风格可以平和、简短,不要刻意突出自身学科背景,不要说你说过的话,可以简短,多简短都可以,但是避免冗长。
|
||||
请你注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出消息内容。
|
||||
不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。
|
||||
如果你决定继续发消息不合适,也可以不发送。
|
||||
|
||||
请直接输出回复内容,不需要任何额外格式。"""
|
||||
请严格按照以下JSON格式输出你的选择和消息内容,不要包含任何其他说明或非JSON文本:
|
||||
{{
|
||||
"send": "yes/no",
|
||||
"txt": "如果选择发送,这里是具体的消息文本。如果选择不发送,这里也填写 'no'。"
|
||||
}}
|
||||
"""
|
||||
|
||||
# Prompt for say_goodbye (告别语生成)
|
||||
PROMPT_FAREWELL = """
|
||||
|
|
@ -125,7 +131,7 @@ class ReplyGenerator:
|
|||
self.llm = LLMRequest(
|
||||
model=global_config.llm_PFC_chat,
|
||||
temperature=global_config.llm_PFC_chat["temp"],
|
||||
max_tokens=300,
|
||||
max_tokens=300, # 对于JSON输出,这个可能需要适当调整,但一般回复短,JSON结构也简单
|
||||
request_type="reply_generation",
|
||||
)
|
||||
self.personality_info = Individuality.get_instance().get_prompt(x_person=2, level=3)
|
||||
|
|
@ -143,20 +149,18 @@ class ReplyGenerator:
|
|||
Args:
|
||||
observation_info: 观察信息
|
||||
conversation_info: 对话信息
|
||||
action_type: 当前执行的动作类型 ('direct_reply' 或 'send_new_message')
|
||||
action_type: 当前执行的动作类型 ('direct_reply', 'send_new_message', 'say_goodbye')
|
||||
|
||||
Returns:
|
||||
str: 生成的回复
|
||||
str: 生成的回复。
|
||||
对于 'direct_reply' 和 'say_goodbye',返回纯文本回复。
|
||||
对于 'send_new_message',返回包含决策和文本的JSON字符串。
|
||||
"""
|
||||
# 构建提示词
|
||||
logger.debug(
|
||||
f"[私聊][{self.private_name}]开始生成回复 (动作类型: {action_type}):当前目标: {conversation_info.goal_list}"
|
||||
)
|
||||
|
||||
# --- 构建通用 Prompt 参数 ---
|
||||
# (这部分逻辑基本不变)
|
||||
|
||||
# 构建对话目标 (goals_str)
|
||||
goals_str = ""
|
||||
if conversation_info.goal_list:
|
||||
for goal_reason in conversation_info.goal_list:
|
||||
|
|
@ -171,9 +175,8 @@ class ReplyGenerator:
|
|||
reasoning = str(reasoning) if reasoning is not None else "没有明确原因"
|
||||
goals_str += f"- 目标:{goal}\n 原因:{reasoning}\n"
|
||||
else:
|
||||
goals_str = "- 目前没有明确对话目标\n" # 简化无目标情况
|
||||
goals_str = "- 目前没有明确对话目标\n"
|
||||
|
||||
# 获取聊天历史记录 (chat_history_text)
|
||||
chat_history_text = observation_info.chat_history_str
|
||||
if observation_info.new_messages_count > 0 and observation_info.unprocessed_messages:
|
||||
new_messages_list = observation_info.unprocessed_messages
|
||||
|
|
@ -192,17 +195,14 @@ class ReplyGenerator:
|
|||
f"\n--- 以上均为已读消息,未读消息均已处理完毕 ---\n"
|
||||
)
|
||||
|
||||
# 获取 sender_name, relationship_text, current_emotion_text
|
||||
sender_name_str = getattr(observation_info, 'sender_name', '对方')
|
||||
if not sender_name_str: sender_name_str = '对方'
|
||||
|
||||
relationship_text_str = getattr(conversation_info, 'relationship_text', '你们还不熟悉。')
|
||||
current_emotion_text_str = getattr(conversation_info, 'current_emotion_text', '心情平静。')
|
||||
|
||||
# 构建 Persona 文本 (persona_text)
|
||||
persona_text = f"你的名字是{self.name},{self.personality_info}。"
|
||||
retrieval_context = chat_history_text # 使用前面构建好的 chat_history_text
|
||||
# 调用共享函数进行检索
|
||||
retrieval_context = chat_history_text
|
||||
retrieved_memory_str, retrieved_knowledge_str = await retrieve_contextual_info(
|
||||
retrieval_context, self.private_name
|
||||
)
|
||||
|
|
@ -210,9 +210,7 @@ class ReplyGenerator:
|
|||
f"[私聊][{self.private_name}] (ReplyGenerator) 统一检索完成。记忆: {'有' if '回忆起' in retrieved_memory_str else '无'} / 知识: {'有' if '出错' not in retrieved_knowledge_str and '无相关知识' not in retrieved_knowledge_str else '无'}"
|
||||
)
|
||||
|
||||
# --- 修改:构建上次回复失败原因和内容提示 ---
|
||||
last_rejection_info_str = ""
|
||||
# 检查 conversation_info 是否有上次拒绝的原因和内容,并且它们都不是 None
|
||||
last_reason = getattr(conversation_info, "last_reply_rejection_reason", None)
|
||||
last_content = getattr(conversation_info, "last_rejected_reply_content", None)
|
||||
|
||||
|
|
@ -220,7 +218,7 @@ class ReplyGenerator:
|
|||
last_rejection_info_str = (
|
||||
f"\n------\n"
|
||||
f"【重要提示:你上一次尝试回复时失败了,以下是详细信息】\n"
|
||||
f"上次试图发送的消息内容: “{last_content}”\n" # <-- 显示上次内容
|
||||
f"上次试图发送的消息内容: “{last_content}”\n"
|
||||
f"失败原因: “{last_reason}”\n"
|
||||
f"请根据【消息内容】和【失败原因】调整你的新回复,避免重复之前的错误。\n"
|
||||
f"------\n"
|
||||
|
|
@ -230,42 +228,67 @@ class ReplyGenerator:
|
|||
f" 内容: {last_content}\n"
|
||||
f" 原因: {last_reason}"
|
||||
)
|
||||
|
||||
# 新增:构建刷屏警告信息 for PROMPT_SEND_NEW_MESSAGE
|
||||
spam_warning_message = ""
|
||||
if action_type == "send_new_message": # 只在 send_new_message 时构建刷屏警告
|
||||
if conversation_info.my_message_count > 5:
|
||||
spam_warning_message = f"⚠️【警告】**你已连续发送{str(conversation_info.my_message_count)}条消息!请谨慎考虑是否继续发送!以免刷屏对造成对方困扰!**"
|
||||
elif conversation_info.my_message_count > 2:
|
||||
spam_warning_message = f"💬【提示】**你已连续发送{str(conversation_info.my_message_count)}条消息。如果非必要,请避免连续发送,以免给对方造成困扰。**"
|
||||
if spam_warning_message:
|
||||
spam_warning_message = f"\n{spam_warning_message}\n"
|
||||
|
||||
|
||||
# --- 选择 Prompt ---
|
||||
if action_type == "send_new_message":
|
||||
prompt_template = PROMPT_SEND_NEW_MESSAGE
|
||||
logger.info(f"[私聊][{self.private_name}]使用 PROMPT_SEND_NEW_MESSAGE (追问生成)")
|
||||
elif action_type == "say_goodbye": # 处理告别动作
|
||||
logger.info(f"[私聊][{self.private_name}]使用 PROMPT_SEND_NEW_MESSAGE (追问/补充生成, 期望JSON输出)")
|
||||
elif action_type == "say_goodbye":
|
||||
prompt_template = PROMPT_FAREWELL
|
||||
logger.info(f"[私聊][{self.private_name}]使用 PROMPT_FAREWELL (告别语生成)")
|
||||
else: # 默认使用 direct_reply 的 prompt (包括 'direct_reply' 或其他未明确处理的类型)
|
||||
else:
|
||||
prompt_template = PROMPT_DIRECT_REPLY
|
||||
logger.info(f"[私聊][{self.private_name}]使用 PROMPT_DIRECT_REPLY (首次/非连续回复生成)")
|
||||
|
||||
# --- 格式化最终的 Prompt ---
|
||||
try: # <--- 增加 try-except 块处理可能的 format 错误
|
||||
current_time_value = "获取时间失败" # 默认值
|
||||
try:
|
||||
current_time_value = "获取时间失败"
|
||||
if observation_info and hasattr(observation_info, 'current_time_str') and observation_info.current_time_str:
|
||||
current_time_value = observation_info.current_time_str
|
||||
|
||||
if action_type == "say_goodbye":
|
||||
prompt = prompt_template.format(
|
||||
persona_text=persona_text,
|
||||
chat_history_text=chat_history_text,
|
||||
current_time_str=current_time_value, # 添加时间
|
||||
current_time_str=current_time_value,
|
||||
sender_name=sender_name_str,
|
||||
relationship_text=relationship_text_str,
|
||||
current_emotion_text=current_emotion_text_str
|
||||
)
|
||||
|
||||
else:
|
||||
elif action_type == "send_new_message": # PROMPT_SEND_NEW_MESSAGE 增加了 spam_warning_info
|
||||
prompt = prompt_template.format(
|
||||
persona_text=persona_text,
|
||||
goals_str=goals_str,
|
||||
chat_history_text=chat_history_text,
|
||||
retrieved_memory_str=retrieved_memory_str if retrieved_memory_str else "无相关记忆。",
|
||||
retrieved_knowledge_str=retrieved_knowledge_str if retrieved_knowledge_str else "无相关知识。",
|
||||
last_rejection_info=last_rejection_info_str, # <--- 新增传递上次拒绝原因
|
||||
current_time_str=current_time_value, # 新增:传入当前时间字符串
|
||||
last_rejection_info=last_rejection_info_str,
|
||||
current_time_str=current_time_value,
|
||||
sender_name=sender_name_str,
|
||||
relationship_text=relationship_text_str,
|
||||
current_emotion_text=current_emotion_text_str,
|
||||
spam_warning_info=spam_warning_message # 添加 spam_warning_info
|
||||
)
|
||||
else: # PROMPT_DIRECT_REPLY (没有 spam_warning_info)
|
||||
prompt = prompt_template.format(
|
||||
persona_text=persona_text,
|
||||
goals_str=goals_str,
|
||||
chat_history_text=chat_history_text,
|
||||
retrieved_memory_str=retrieved_memory_str if retrieved_memory_str else "无相关记忆。",
|
||||
retrieved_knowledge_str=retrieved_knowledge_str if retrieved_knowledge_str else "无相关知识。",
|
||||
last_rejection_info=last_rejection_info_str,
|
||||
current_time_str=current_time_value,
|
||||
sender_name=sender_name_str,
|
||||
relationship_text=relationship_text_str,
|
||||
current_emotion_text=current_emotion_text_str
|
||||
|
|
@ -274,8 +297,7 @@ class ReplyGenerator:
|
|||
logger.error(
|
||||
f"[私聊][{self.private_name}]格式化 Prompt 时出错,缺少键: {e}。请检查 Prompt 模板和传递的参数。"
|
||||
)
|
||||
# 返回错误信息或默认回复
|
||||
return "抱歉,准备回复时出了点问题,请检查一下我的代码..."
|
||||
return "抱歉,准备回复时出了点问题,请检查一下我的代码..." # 对于JSON期望的场景,这里可能也需要返回一个固定的错误JSON
|
||||
except Exception as fmt_err:
|
||||
logger.error(f"[私聊][{self.private_name}]格式化 Prompt 时发生未知错误: {fmt_err}")
|
||||
return "抱歉,准备回复时出了点内部错误,请检查一下我的代码..."
|
||||
|
|
@ -284,19 +306,30 @@ class ReplyGenerator:
|
|||
logger.debug(f"[私聊][{self.private_name}]发送到LLM的生成提示词:\n------\n{prompt}\n------")
|
||||
try:
|
||||
content, _ = await self.llm.generate_response_async(prompt)
|
||||
logger.debug(f"[私聊][{self.private_name}]生成的回复: {content}")
|
||||
# 移除旧的检查新消息逻辑,这应该由 conversation 控制流处理
|
||||
# 对于 PROMPT_SEND_NEW_MESSAGE,我们期望 content 是一个 JSON 字符串
|
||||
# 对于其他 prompts,content 是纯文本回复
|
||||
# 该方法现在直接返回 LLM 的原始输出,由调用者 (conversation._handle_action) 负责解析
|
||||
logger.debug(f"[私聊][{self.private_name}]LLM原始生成内容: {content}")
|
||||
return content
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[私聊][{self.private_name}]生成回复时出错: {e}")
|
||||
return "抱歉,我现在有点混乱,让我重新思考一下..."
|
||||
# 根据 action_type 返回不同的错误指示
|
||||
if action_type == "send_new_message":
|
||||
# 返回一个表示错误的JSON,让调用方知道出错了但仍能解析
|
||||
return """{{
|
||||
"send": "no",
|
||||
"txt": "LLM生成回复时出错"
|
||||
}}""".strip()
|
||||
else:
|
||||
return "抱歉,我现在有点混乱,让我重新思考一下..."
|
||||
|
||||
# check_reply 方法保持不变
|
||||
async def check_reply(
|
||||
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_str: str, retry_count: int = 0
|
||||
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_str: str, current_time_str: str, retry_count: int = 0
|
||||
) -> Tuple[bool, str, bool]:
|
||||
"""检查回复是否合适
|
||||
(此方法逻辑保持不变)
|
||||
(此方法逻辑保持不变, 但注意 current_time_str 参数的传递)
|
||||
"""
|
||||
return await self.reply_checker.check(reply, goal, chat_history, chat_history_str, retry_count)
|
||||
# 确保 current_time_str 被正确传递给 reply_checker.check
|
||||
return await self.reply_checker.check(reply, goal, chat_history, chat_history_str, current_time_str, retry_count)
|
||||
Loading…
Reference in New Issue