mirror of https://github.com/Mai-with-u/MaiBot.git
feat:为动作添加更明确的反馈
parent
dbdf650b1d
commit
57c9811a78
|
|
@ -381,21 +381,26 @@ class HeartFChatting:
|
||||||
action_success = False
|
action_success = False
|
||||||
action_reply_text = ""
|
action_reply_text = ""
|
||||||
|
|
||||||
|
excute_result_str = ""
|
||||||
for result in results:
|
for result in results:
|
||||||
|
excute_result_str += f"{result['action_type']} 执行结果:{result['result']}\n"
|
||||||
|
|
||||||
if isinstance(result, BaseException):
|
if isinstance(result, BaseException):
|
||||||
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
|
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if result["action_type"] != "reply":
|
if result["action_type"] != "reply":
|
||||||
action_success = result["success"]
|
action_success = result["success"]
|
||||||
action_reply_text = result["reply_text"]
|
action_reply_text = result["result"]
|
||||||
elif result["action_type"] == "reply":
|
elif result["action_type"] == "reply":
|
||||||
if result["success"]:
|
if result["success"]:
|
||||||
reply_loop_info = result["loop_info"]
|
reply_loop_info = result["loop_info"]
|
||||||
reply_text_from_reply = result["reply_text"]
|
reply_text_from_reply = result["result"]
|
||||||
else:
|
else:
|
||||||
logger.warning(f"{self.log_prefix} 回复动作执行失败")
|
logger.warning(f"{self.log_prefix} 回复动作执行失败")
|
||||||
|
|
||||||
|
self.action_planner.add_plan_excute_log(result=excute_result_str)
|
||||||
|
|
||||||
# 构建最终的循环信息
|
# 构建最终的循环信息
|
||||||
if reply_loop_info:
|
if reply_loop_info:
|
||||||
# 如果有回复信息,使用回复的loop_info作为基础
|
# 如果有回复信息,使用回复的loop_info作为基础
|
||||||
|
|
@ -490,23 +495,19 @@ class HeartFChatting:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 创建动作处理器时出错: {e}")
|
logger.error(f"{self.log_prefix} 创建动作处理器时出错: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, "", ""
|
return False, ""
|
||||||
|
|
||||||
if not action_handler:
|
|
||||||
logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}")
|
|
||||||
return False, "", ""
|
|
||||||
|
|
||||||
# 处理动作并获取结果(固定记录一次动作信息)
|
# 处理动作并获取结果(固定记录一次动作信息)
|
||||||
result = await action_handler.execute()
|
result = await action_handler.execute()
|
||||||
success, action_text = result
|
success, action_text = result
|
||||||
command = ""
|
|
||||||
|
|
||||||
return success, action_text, command
|
|
||||||
|
return success, action_text
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 处理{action}时出错: {e}")
|
logger.error(f"{self.log_prefix} 处理{action}时出错: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, "", ""
|
return False, ""
|
||||||
|
|
||||||
async def _send_response(
|
async def _send_response(
|
||||||
self,
|
self,
|
||||||
|
|
@ -581,7 +582,7 @@ class HeartFChatting:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
|
return {"action_type": "no_reply", "success": True, "result": "选择不回复", "command": ""}
|
||||||
|
|
||||||
elif action_planner_info.action_type == "no_reply_until_call":
|
elif action_planner_info.action_type == "no_reply_until_call":
|
||||||
# 直接当场执行no_reply_until_call逻辑
|
# 直接当场执行no_reply_until_call逻辑
|
||||||
|
|
@ -601,46 +602,44 @@ class HeartFChatting:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
return {"action_type": "no_reply_until_call", "success": True, "reply_text": "", "command": ""}
|
return {"action_type": "no_reply_until_call", "success": True, "result": "保持沉默,直到有人直接叫的名字", "command": ""}
|
||||||
|
|
||||||
elif action_planner_info.action_type == "reply":
|
elif action_planner_info.action_type == "reply":
|
||||||
# 直接当场执行reply逻辑
|
# 直接当场执行reply逻辑
|
||||||
try:
|
|
||||||
reason = action_planner_info.reasoning or "选择回复"
|
|
||||||
await database_api.store_action_info(
|
|
||||||
chat_stream=self.chat_stream,
|
|
||||||
action_build_into_prompt=False,
|
|
||||||
action_prompt_display=reason,
|
|
||||||
action_done=True,
|
|
||||||
thinking_id=thinking_id,
|
|
||||||
action_data={},
|
|
||||||
action_name="reply",
|
|
||||||
action_reasoning=reason,
|
|
||||||
)
|
|
||||||
|
|
||||||
success, llm_response = await generator_api.generate_reply(
|
reason = action_planner_info.reasoning or "选择回复"
|
||||||
chat_stream=self.chat_stream,
|
await database_api.store_action_info(
|
||||||
reply_message=action_planner_info.action_message,
|
chat_stream=self.chat_stream,
|
||||||
available_actions=available_actions,
|
action_build_into_prompt=False,
|
||||||
chosen_actions=chosen_action_plan_infos,
|
action_prompt_display=reason,
|
||||||
reply_reason=reason,
|
action_done=True,
|
||||||
enable_tool=global_config.tool.enable_tool,
|
thinking_id=thinking_id,
|
||||||
request_type="replyer",
|
action_data={},
|
||||||
from_plugin=False,
|
action_name="reply",
|
||||||
)
|
action_reasoning=reason,
|
||||||
|
)
|
||||||
|
|
||||||
|
success, llm_response = await generator_api.generate_reply(
|
||||||
|
chat_stream=self.chat_stream,
|
||||||
|
reply_message=action_planner_info.action_message,
|
||||||
|
available_actions=available_actions,
|
||||||
|
chosen_actions=chosen_action_plan_infos,
|
||||||
|
reply_reason=reason,
|
||||||
|
enable_tool=global_config.tool.enable_tool,
|
||||||
|
request_type="replyer",
|
||||||
|
from_plugin=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success or not llm_response or not llm_response.reply_set:
|
||||||
|
if action_planner_info.action_message:
|
||||||
|
logger.info(
|
||||||
|
f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.info("回复生成失败")
|
||||||
|
return {"action_type": "reply", "success": False, "result": "回复生成失败", "loop_info": None}
|
||||||
|
|
||||||
if not success or not llm_response or not llm_response.reply_set:
|
|
||||||
if action_planner_info.action_message:
|
|
||||||
logger.info(
|
|
||||||
f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
logger.info("回复生成失败")
|
|
||||||
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
|
||||||
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
|
||||||
response_set = llm_response.reply_set
|
response_set = llm_response.reply_set
|
||||||
selected_expressions = llm_response.selected_expressions
|
selected_expressions = llm_response.selected_expressions
|
||||||
loop_info, reply_text, _ = await self._send_and_store_reply(
|
loop_info, reply_text, _ = await self._send_and_store_reply(
|
||||||
|
|
@ -654,13 +653,13 @@ class HeartFChatting:
|
||||||
return {
|
return {
|
||||||
"action_type": "reply",
|
"action_type": "reply",
|
||||||
"success": True,
|
"success": True,
|
||||||
"reply_text": reply_text,
|
"result": f"你回复内容{reply_text}",
|
||||||
"loop_info": loop_info,
|
"loop_info": loop_info,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
# 执行普通动作
|
# 执行普通动作
|
||||||
with Timer("动作执行", cycle_timers):
|
with Timer("动作执行", cycle_timers):
|
||||||
success, reply_text, command = await self._handle_action(
|
success, result = await self._handle_action(
|
||||||
action = action_planner_info.action_type,
|
action = action_planner_info.action_type,
|
||||||
action_reasoning = action_planner_info.action_reasoning or "",
|
action_reasoning = action_planner_info.action_reasoning or "",
|
||||||
action_data = action_planner_info.action_data or {},
|
action_data = action_planner_info.action_data or {},
|
||||||
|
|
@ -671,8 +670,7 @@ class HeartFChatting:
|
||||||
return {
|
return {
|
||||||
"action_type": action_planner_info.action_type,
|
"action_type": action_planner_info.action_type,
|
||||||
"success": success,
|
"success": success,
|
||||||
"reply_text": reply_text,
|
"result": result,
|
||||||
"command": command,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -681,7 +679,7 @@ class HeartFChatting:
|
||||||
return {
|
return {
|
||||||
"action_type": action_planner_info.action_type,
|
"action_type": action_planner_info.action_type,
|
||||||
"success": False,
|
"success": False,
|
||||||
"reply_text": "",
|
"result": "",
|
||||||
"loop_info": None,
|
"loop_info": None,
|
||||||
"error": str(e),
|
"error": str(e),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import time
|
||||||
import traceback
|
import traceback
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
from typing import Dict, Optional, Tuple, List, TYPE_CHECKING
|
from typing import Dict, Optional, Tuple, List, TYPE_CHECKING, Union
|
||||||
from rich.traceback import install
|
from rich.traceback import install
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from json_repair import repair_json
|
from json_repair import repair_json
|
||||||
|
|
@ -132,7 +132,7 @@ class ActionPlanner:
|
||||||
self.last_obs_time_mark = 0.0
|
self.last_obs_time_mark = 0.0
|
||||||
|
|
||||||
|
|
||||||
self.plan_log:List[Tuple[str,str,ActionPlannerInfo]] = []
|
self.plan_log: List[Tuple[str, float, Union[List[ActionPlannerInfo], str]]] = []
|
||||||
|
|
||||||
def find_message_by_id(
|
def find_message_by_id(
|
||||||
self, message_id: str, message_id_list: List[Tuple[str, "DatabaseMessages"]]
|
self, message_id: str, message_id_list: List[Tuple[str, "DatabaseMessages"]]
|
||||||
|
|
@ -293,14 +293,24 @@ class ActionPlanner:
|
||||||
|
|
||||||
def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]):
|
def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]):
|
||||||
self.plan_log.append((reasoning, time.time(), actions))
|
self.plan_log.append((reasoning, time.time(), actions))
|
||||||
if len(self.plan_log) > 100:
|
if len(self.plan_log) > 20:
|
||||||
|
self.plan_log.pop(0)
|
||||||
|
|
||||||
|
def add_plan_excute_log(self, result: str):
|
||||||
|
self.plan_log.append(("", time.time(), result))
|
||||||
|
if len(self.plan_log) > 20:
|
||||||
self.plan_log.pop(0)
|
self.plan_log.pop(0)
|
||||||
|
|
||||||
def get_plan_log_str(self) -> str:
|
def get_plan_log_str(self) -> str:
|
||||||
plan_log_str = ""
|
plan_log_str = ""
|
||||||
for reasoning, time, actions in self.plan_log:
|
for reasoning, time, content in self.plan_log:
|
||||||
time = datetime.fromtimestamp(time).strftime("%H:%M:%S")
|
if isinstance(content, list) and all(isinstance(action, ActionPlannerInfo) for action in content):
|
||||||
plan_log_str += f"{time}:{reasoning}|使用了{','.join([action.action_type for action in actions])}\n"
|
time = datetime.fromtimestamp(time).strftime("%H:%M:%S")
|
||||||
|
plan_log_str += f"{time}:{reasoning}|你使用了{','.join([action.action_type for action in content])}\n"
|
||||||
|
else:
|
||||||
|
time = datetime.fromtimestamp(time).strftime("%H:%M:%S")
|
||||||
|
plan_log_str += f"{time}:{content}\n"
|
||||||
|
|
||||||
return plan_log_str
|
return plan_log_str
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue