typing and ruff fix
This commit is contained in:
@@ -2,7 +2,7 @@ import asyncio
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import random
|
import random
|
||||||
from typing import List, Optional, Dict, Any
|
from typing import List, Optional, Dict, Any, Tuple
|
||||||
from rich.traceback import install
|
from rich.traceback import install
|
||||||
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
@@ -219,7 +219,9 @@ class HeartFChatting:
|
|||||||
if global_config.chat.focus_value != 0:
|
if global_config.chat.focus_value != 0:
|
||||||
if len(new_messages_data) > 3 / pow(global_config.chat.focus_value, 0.5):
|
if len(new_messages_data) > 3 / pow(global_config.chat.focus_value, 0.5):
|
||||||
self.loop_mode = ChatMode.FOCUS
|
self.loop_mode = ChatMode.FOCUS
|
||||||
self.energy_value = 10 + (len(new_messages_data) / (3 / pow(global_config.chat.focus_value,0.5))) * 10
|
self.energy_value = (
|
||||||
|
10 + (len(new_messages_data) / (3 / pow(global_config.chat.focus_value, 0.5))) * 10
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self.energy_value >= 30:
|
if self.energy_value >= 30:
|
||||||
@@ -261,9 +263,10 @@ class HeartFChatting:
|
|||||||
reply_to_str,
|
reply_to_str,
|
||||||
loop_start_time,
|
loop_start_time,
|
||||||
action_message,
|
action_message,
|
||||||
cycle_timers,
|
cycle_timers: Dict[str, float],
|
||||||
thinking_id,
|
thinking_id,
|
||||||
plan_result):
|
plan_result,
|
||||||
|
) -> Tuple[Dict[str, Any], str, Dict[str, float]]:
|
||||||
with Timer("回复发送", cycle_timers):
|
with Timer("回复发送", cycle_timers):
|
||||||
reply_text = await self._send_response(response_set, reply_to_str, loop_start_time, action_message)
|
reply_text = await self._send_response(response_set, reply_to_str, loop_start_time, action_message)
|
||||||
|
|
||||||
@@ -286,9 +289,8 @@ class HeartFChatting:
|
|||||||
action_name="reply",
|
action_name="reply",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 构建循环信息
|
# 构建循环信息
|
||||||
loop_info = {
|
loop_info: Dict[str, Any] = {
|
||||||
"loop_plan_info": {
|
"loop_plan_info": {
|
||||||
"action_result": plan_result.get("action_result", {}),
|
"action_result": plan_result.get("action_result", {}),
|
||||||
},
|
},
|
||||||
@@ -337,8 +339,9 @@ class HeartFChatting:
|
|||||||
skip_planner = False
|
skip_planner = False
|
||||||
if self.loop_mode == ChatMode.NORMAL:
|
if self.loop_mode == ChatMode.NORMAL:
|
||||||
# 过滤掉reply相关的动作,检查是否还有其他动作
|
# 过滤掉reply相关的动作,检查是否还有其他动作
|
||||||
non_reply_actions = {k: v for k, v in available_actions.items()
|
non_reply_actions = {
|
||||||
if k not in ['reply', 'no_reply', 'no_action']}
|
k: v for k, v in available_actions.items() if k not in ["reply", "no_reply", "no_action"]
|
||||||
|
}
|
||||||
|
|
||||||
if not non_reply_actions:
|
if not non_reply_actions:
|
||||||
skip_planner = True
|
skip_planner = True
|
||||||
@@ -366,17 +369,20 @@ class HeartFChatting:
|
|||||||
# 如果normal模式且不跳过规划器,开始一个回复生成进程,先准备好回复(其实是和planer同时进行的)
|
# 如果normal模式且不跳过规划器,开始一个回复生成进程,先准备好回复(其实是和planer同时进行的)
|
||||||
if not skip_planner:
|
if not skip_planner:
|
||||||
reply_to_str = await self.build_reply_to_str(message_data)
|
reply_to_str = await self.build_reply_to_str(message_data)
|
||||||
gen_task = asyncio.create_task(self._generate_response(
|
gen_task = asyncio.create_task(
|
||||||
|
self._generate_response(
|
||||||
message_data=message_data,
|
message_data=message_data,
|
||||||
available_actions=available_actions,
|
available_actions=available_actions,
|
||||||
reply_to=reply_to_str,
|
reply_to=reply_to_str,
|
||||||
request_type="chat.replyer.normal"))
|
request_type="chat.replyer.normal",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if not skip_planner:
|
if not skip_planner:
|
||||||
with Timer("规划器", cycle_timers):
|
with Timer("规划器", cycle_timers):
|
||||||
plan_result, target_message = await self.action_planner.plan(mode=self.loop_mode)
|
plan_result, target_message = await self.action_planner.plan(mode=self.loop_mode)
|
||||||
|
|
||||||
action_result: dict = plan_result.get("action_result", {}) # type: ignore
|
action_result: Dict[str, Any] = plan_result.get("action_result", {}) # type: ignore
|
||||||
action_type, action_data, reasoning, is_parallel = (
|
action_type, action_data, reasoning, is_parallel = (
|
||||||
action_result.get("action_type", "error"),
|
action_result.get("action_type", "error"),
|
||||||
action_result.get("action_data", {}),
|
action_result.get("action_data", {}),
|
||||||
@@ -386,29 +392,27 @@ class HeartFChatting:
|
|||||||
|
|
||||||
action_data["loop_start_time"] = loop_start_time
|
action_data["loop_start_time"] = loop_start_time
|
||||||
|
|
||||||
|
|
||||||
if action_type == "reply":
|
if action_type == "reply":
|
||||||
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复")
|
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复")
|
||||||
elif is_parallel:
|
elif is_parallel:
|
||||||
logger.info(
|
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复, 同时执行{action_type}动作")
|
||||||
f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复, 同时执行{action_type}动作"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# 只有在gen_task存在时才进行相关操作
|
# 只有在gen_task存在时才进行相关操作
|
||||||
if gen_task is not None:
|
if gen_task:
|
||||||
if not gen_task.done():
|
if not gen_task.done():
|
||||||
gen_task.cancel()
|
gen_task.cancel()
|
||||||
logger.debug(f"{self.log_prefix} 已取消预生成的回复任务")
|
logger.debug(f"{self.log_prefix} 已取消预生成的回复任务")
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复,但选择执行{action_type},不发表回复"
|
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复,但选择执行{action_type},不发表回复"
|
||||||
)
|
)
|
||||||
else:
|
elif generation_result := gen_task.result():
|
||||||
content = " ".join([item[1] for item in gen_task.result() if item[0] == "text"])
|
content = " ".join([item[1] for item in generation_result if item[0] == "text"])
|
||||||
logger.debug(f"{self.log_prefix} 预生成的回复任务已完成")
|
logger.debug(f"{self.log_prefix} 预生成的回复任务已完成")
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复:{content},但选择执行{action_type},不发表回复"
|
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复:{content},但选择执行{action_type},不发表回复"
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
logger.warning(f"{self.log_prefix} 预生成的回复任务未生成有效内容")
|
||||||
|
|
||||||
action_message: Dict[str, Any] = message_data or target_message # type: ignore
|
action_message: Dict[str, Any] = message_data or target_message # type: ignore
|
||||||
if action_type == "reply":
|
if action_type == "reply":
|
||||||
@@ -417,11 +421,14 @@ class HeartFChatting:
|
|||||||
# 只有在gen_task存在时才等待
|
# 只有在gen_task存在时才等待
|
||||||
if not gen_task:
|
if not gen_task:
|
||||||
reply_to_str = await self.build_reply_to_str(message_data)
|
reply_to_str = await self.build_reply_to_str(message_data)
|
||||||
gen_task = asyncio.create_task(self._generate_response(
|
gen_task = asyncio.create_task(
|
||||||
|
self._generate_response(
|
||||||
message_data=message_data,
|
message_data=message_data,
|
||||||
available_actions=available_actions,
|
available_actions=available_actions,
|
||||||
reply_to=reply_to_str,
|
reply_to=reply_to_str,
|
||||||
request_type="chat.replyer.normal"))
|
request_type="chat.replyer.normal",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
gather_timeout = global_config.chat.thinking_timeout
|
gather_timeout = global_config.chat.thinking_timeout
|
||||||
try:
|
try:
|
||||||
@@ -446,30 +453,37 @@ class HeartFChatting:
|
|||||||
message_data=action_message,
|
message_data=action_message,
|
||||||
available_actions=available_actions,
|
available_actions=available_actions,
|
||||||
reply_to=reply_to_str,
|
reply_to=reply_to_str,
|
||||||
request_type="chat.replyer.focus")
|
request_type="chat.replyer.focus",
|
||||||
|
)
|
||||||
|
|
||||||
if not response_set:
|
if not response_set:
|
||||||
logger.warning(f"{self.log_prefix}模型未生成回复内容")
|
logger.warning(f"{self.log_prefix}模型未生成回复内容")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
loop_info, reply_text,cycle_timers = await self._send_and_store_reply(response_set, reply_to_str, loop_start_time, action_message, cycle_timers, thinking_id, plan_result)
|
loop_info, reply_text, cycle_timers = await self._send_and_store_reply(
|
||||||
|
response_set, reply_to_str, loop_start_time, action_message, cycle_timers, thinking_id, plan_result
|
||||||
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# 并行执行:同时进行回复发送和动作执行
|
# 并行执行:同时进行回复发送和动作执行
|
||||||
tasks = []
|
# 先置空防止未定义错误
|
||||||
|
background_reply_task = None
|
||||||
|
background_action_task = None
|
||||||
# 如果是并行执行且在normal模式下,需要等待预生成的回复任务完成并发送回复
|
# 如果是并行执行且在normal模式下,需要等待预生成的回复任务完成并发送回复
|
||||||
if self.loop_mode == ChatMode.NORMAL and is_parallel and gen_task:
|
if self.loop_mode == ChatMode.NORMAL and is_parallel and gen_task:
|
||||||
async def handle_reply_task():
|
|
||||||
|
async def handle_reply_task() -> Tuple[Optional[Dict[str, Any]], str, Dict[str, float]]:
|
||||||
# 等待预生成的回复任务完成
|
# 等待预生成的回复任务完成
|
||||||
gather_timeout = global_config.chat.thinking_timeout
|
gather_timeout = global_config.chat.thinking_timeout
|
||||||
try:
|
try:
|
||||||
response_set = await asyncio.wait_for(gen_task, timeout=gather_timeout)
|
response_set = await asyncio.wait_for(gen_task, timeout=gather_timeout)
|
||||||
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.warning(f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过")
|
logger.warning(
|
||||||
|
f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过"
|
||||||
|
)
|
||||||
return None, "", {}
|
return None, "", {}
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
||||||
@@ -480,11 +494,19 @@ class HeartFChatting:
|
|||||||
return None, "", {}
|
return None, "", {}
|
||||||
|
|
||||||
reply_to_str = await self.build_reply_to_str(action_message)
|
reply_to_str = await self.build_reply_to_str(action_message)
|
||||||
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(response_set, reply_to_str, loop_start_time, action_message, cycle_timers, thinking_id, plan_result)
|
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
|
||||||
|
response_set,
|
||||||
|
reply_to_str,
|
||||||
|
loop_start_time,
|
||||||
|
action_message,
|
||||||
|
cycle_timers,
|
||||||
|
thinking_id,
|
||||||
|
plan_result,
|
||||||
|
)
|
||||||
return loop_info, reply_text, cycle_timers_reply
|
return loop_info, reply_text, cycle_timers_reply
|
||||||
|
|
||||||
# 添加回复任务到并行任务列表
|
# 执行回复任务并赋值到变量
|
||||||
tasks.append(asyncio.create_task(handle_reply_task()))
|
background_reply_task = asyncio.create_task(handle_reply_task())
|
||||||
|
|
||||||
# 动作执行任务
|
# 动作执行任务
|
||||||
async def handle_action_task():
|
async def handle_action_task():
|
||||||
@@ -494,51 +516,54 @@ class HeartFChatting:
|
|||||||
)
|
)
|
||||||
return success, reply_text, command
|
return success, reply_text, command
|
||||||
|
|
||||||
# 添加动作执行任务到并行任务列表
|
# 执行动作任务并赋值到变量
|
||||||
tasks.append(asyncio.create_task(handle_action_task()))
|
background_action_task = asyncio.create_task(handle_action_task())
|
||||||
|
|
||||||
# 并行执行所有任务
|
|
||||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
||||||
|
|
||||||
# 处理结果
|
|
||||||
reply_loop_info = None
|
reply_loop_info = None
|
||||||
reply_text_from_reply = ""
|
reply_text_from_reply = ""
|
||||||
action_success = False
|
action_success = False
|
||||||
action_reply_text = ""
|
action_reply_text = ""
|
||||||
action_command = ""
|
action_command = ""
|
||||||
|
|
||||||
if len(tasks) == 2: # 有回复任务和动作任务
|
# 并行执行所有任务
|
||||||
|
if background_reply_task:
|
||||||
|
results = await asyncio.gather(
|
||||||
|
background_reply_task, background_action_task, return_exceptions=True
|
||||||
|
)
|
||||||
# 处理回复任务结果
|
# 处理回复任务结果
|
||||||
reply_result = results[0]
|
reply_result = results[0]
|
||||||
if isinstance(reply_result, Exception):
|
if isinstance(reply_result, BaseException):
|
||||||
logger.error(f"{self.log_prefix} 回复任务执行异常: {reply_result}")
|
logger.error(f"{self.log_prefix} 回复任务执行异常: {reply_result}")
|
||||||
elif reply_result and reply_result[0] is not None:
|
elif reply_result and reply_result[0] is not None:
|
||||||
reply_loop_info, reply_text_from_reply, _ = reply_result
|
reply_loop_info, reply_text_from_reply, _ = reply_result
|
||||||
|
|
||||||
# 处理动作任务结果
|
# 处理动作任务结果
|
||||||
action_result = results[1]
|
action_task_result = results[1]
|
||||||
if isinstance(action_result, Exception):
|
if isinstance(action_task_result, BaseException):
|
||||||
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_result}")
|
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_task_result}")
|
||||||
else:
|
else:
|
||||||
action_success, action_reply_text, action_command = action_result
|
action_success, action_reply_text, action_command = action_task_result
|
||||||
|
|
||||||
else: # 只有动作任务
|
|
||||||
action_result = results[0]
|
|
||||||
if isinstance(action_result, Exception):
|
|
||||||
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_result}")
|
|
||||||
else:
|
else:
|
||||||
action_success, action_reply_text, action_command = action_result
|
results = await asyncio.gather(background_action_task, return_exceptions=True)
|
||||||
|
# 只有动作任务
|
||||||
|
action_task_result = results[0]
|
||||||
|
if isinstance(action_task_result, BaseException):
|
||||||
|
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_task_result}")
|
||||||
|
else:
|
||||||
|
action_success, action_reply_text, action_command = action_task_result
|
||||||
|
|
||||||
# 构建最终的循环信息
|
# 构建最终的循环信息
|
||||||
if reply_loop_info:
|
if reply_loop_info:
|
||||||
# 如果有回复信息,使用回复的loop_info作为基础
|
# 如果有回复信息,使用回复的loop_info作为基础
|
||||||
loop_info = reply_loop_info
|
loop_info = reply_loop_info
|
||||||
# 更新动作执行信息
|
# 更新动作执行信息
|
||||||
loop_info["loop_action_info"].update({
|
loop_info["loop_action_info"].update(
|
||||||
|
{
|
||||||
"action_taken": action_success,
|
"action_taken": action_success,
|
||||||
"command": action_command,
|
"command": action_command,
|
||||||
"taken_time": time.time(),
|
"taken_time": time.time(),
|
||||||
})
|
}
|
||||||
|
)
|
||||||
reply_text = reply_text_from_reply
|
reply_text = reply_text_from_reply
|
||||||
else:
|
else:
|
||||||
# 没有回复信息,构建纯动作的loop_info
|
# 没有回复信息,构建纯动作的loop_info
|
||||||
@@ -555,7 +580,6 @@ class HeartFChatting:
|
|||||||
}
|
}
|
||||||
reply_text = action_reply_text
|
reply_text = action_reply_text
|
||||||
|
|
||||||
|
|
||||||
if ENABLE_S4U:
|
if ENABLE_S4U:
|
||||||
await stop_typing()
|
await stop_typing()
|
||||||
await mai_thinking_manager.get_mai_think(self.stream_id).do_think_after_response(reply_text)
|
await mai_thinking_manager.get_mai_think(self.stream_id).do_think_after_response(reply_text)
|
||||||
@@ -603,7 +627,7 @@ class HeartFChatting:
|
|||||||
action: str,
|
action: str,
|
||||||
reasoning: str,
|
reasoning: str,
|
||||||
action_data: dict,
|
action_data: dict,
|
||||||
cycle_timers: dict,
|
cycle_timers: Dict[str, float],
|
||||||
thinking_id: str,
|
thinking_id: str,
|
||||||
action_message: dict,
|
action_message: dict,
|
||||||
) -> tuple[bool, str, str]:
|
) -> tuple[bool, str, str]:
|
||||||
@@ -712,7 +736,11 @@ class HeartFChatting:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def _generate_response(
|
async def _generate_response(
|
||||||
self, message_data: dict, available_actions: Optional[Dict[str, ActionInfo]], reply_to: str, request_type: str = "chat.replyer.normal"
|
self,
|
||||||
|
message_data: dict,
|
||||||
|
available_actions: Optional[Dict[str, ActionInfo]],
|
||||||
|
reply_to: str,
|
||||||
|
request_type: str = "chat.replyer.normal",
|
||||||
) -> Optional[list]:
|
) -> Optional[list]:
|
||||||
"""生成普通回复"""
|
"""生成普通回复"""
|
||||||
try:
|
try:
|
||||||
@@ -734,7 +762,7 @@ class HeartFChatting:
|
|||||||
logger.error(f"{self.log_prefix}回复生成出现错误:{str(e)} {traceback.format_exc()}")
|
logger.error(f"{self.log_prefix}回复生成出现错误:{str(e)} {traceback.format_exc()}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def _send_response(self, reply_set, reply_to, thinking_start_time, message_data):
|
async def _send_response(self, reply_set, reply_to, thinking_start_time, message_data) -> str:
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
new_message_count = message_api.count_new_messages(
|
new_message_count = message_api.count_new_messages(
|
||||||
chat_id=self.chat_stream.stream_id, start_time=thinking_start_time, end_time=current_time
|
chat_id=self.chat_stream.stream_id, start_time=thinking_start_time, end_time=current_time
|
||||||
@@ -746,13 +774,9 @@ class HeartFChatting:
|
|||||||
need_reply = new_message_count >= random.randint(2, 4)
|
need_reply = new_message_count >= random.randint(2, 4)
|
||||||
|
|
||||||
if need_reply:
|
if need_reply:
|
||||||
logger.info(
|
logger.info(f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,使用引用回复")
|
||||||
f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,使用引用回复"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,不使用引用回复")
|
||||||
f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,不使用引用回复"
|
|
||||||
)
|
|
||||||
|
|
||||||
reply_text = ""
|
reply_text = ""
|
||||||
first_replied = False
|
first_replied = False
|
||||||
|
|||||||
@@ -211,8 +211,7 @@ class ActionPlanner:
|
|||||||
reasoning = f"Planner 内部处理错误: {outer_e}"
|
reasoning = f"Planner 内部处理错误: {outer_e}"
|
||||||
|
|
||||||
is_parallel = False
|
is_parallel = False
|
||||||
if mode == ChatMode.NORMAL:
|
if mode == ChatMode.NORMAL and action in current_available_actions:
|
||||||
if action in current_available_actions:
|
|
||||||
is_parallel = current_available_actions[action].parallel_action
|
is_parallel = current_available_actions[action].parallel_action
|
||||||
|
|
||||||
action_result = {
|
action_result = {
|
||||||
@@ -276,7 +275,6 @@ class ActionPlanner:
|
|||||||
if global_config.chat.at_bot_inevitable_reply:
|
if global_config.chat.at_bot_inevitable_reply:
|
||||||
mentioned_bonus = "\n- 有人提到你,或者at你"
|
mentioned_bonus = "\n- 有人提到你,或者at你"
|
||||||
|
|
||||||
|
|
||||||
by_what = "聊天内容"
|
by_what = "聊天内容"
|
||||||
target_prompt = '\n "target_message_id":"触发action的消息id"'
|
target_prompt = '\n "target_message_id":"触发action的消息id"'
|
||||||
no_action_block = f"""重要说明:
|
no_action_block = f"""重要说明:
|
||||||
|
|||||||
Reference in New Issue
Block a user