typing和防炸
This commit is contained in:
@@ -11,7 +11,6 @@ from src.common.logger import get_logger
|
|||||||
from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager
|
from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager
|
||||||
from src.chat.utils.prompt_builder import global_prompt_manager
|
from src.chat.utils.prompt_builder import global_prompt_manager
|
||||||
from src.chat.utils.timer_calculator import Timer
|
from src.chat.utils.timer_calculator import Timer
|
||||||
from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_with_chat
|
|
||||||
from src.chat.planner_actions.planner import ActionPlanner
|
from src.chat.planner_actions.planner import ActionPlanner
|
||||||
from src.chat.planner_actions.action_modifier import ActionModifier
|
from src.chat.planner_actions.action_modifier import ActionModifier
|
||||||
from src.chat.planner_actions.action_manager import ActionManager
|
from src.chat.planner_actions.action_manager import ActionManager
|
||||||
@@ -25,6 +24,7 @@ from src.plugin_system.apis import generator_api, send_api, message_api, databas
|
|||||||
from src.chat.willing.willing_manager import get_willing_manager
|
from src.chat.willing.willing_manager import get_willing_manager
|
||||||
from src.mais4u.mai_think import mai_thinking_manager
|
from src.mais4u.mai_think import mai_thinking_manager
|
||||||
from src.mais4u.constant_s4u import ENABLE_S4U
|
from src.mais4u.constant_s4u import ENABLE_S4U
|
||||||
|
|
||||||
# no_reply逻辑已集成到heartFC_chat.py中,不再需要导入
|
# no_reply逻辑已集成到heartFC_chat.py中,不再需要导入
|
||||||
from src.chat.chat_loop.hfc_utils import send_typing, stop_typing
|
from src.chat.chat_loop.hfc_utils import send_typing, stop_typing
|
||||||
|
|
||||||
@@ -91,7 +91,6 @@ class HeartFChatting:
|
|||||||
self.relationship_builder = relationship_builder_manager.get_or_create_builder(self.stream_id)
|
self.relationship_builder = relationship_builder_manager.get_or_create_builder(self.stream_id)
|
||||||
self.expression_learner = expression_learner_manager.get_expression_learner(self.stream_id)
|
self.expression_learner = expression_learner_manager.get_expression_learner(self.stream_id)
|
||||||
|
|
||||||
|
|
||||||
self.action_manager = ActionManager()
|
self.action_manager = ActionManager()
|
||||||
self.action_planner = ActionPlanner(chat_id=self.stream_id, action_manager=self.action_manager)
|
self.action_planner = ActionPlanner(chat_id=self.stream_id, action_manager=self.action_manager)
|
||||||
self.action_modifier = ActionModifier(action_manager=self.action_manager, chat_id=self.stream_id)
|
self.action_modifier = ActionModifier(action_manager=self.action_manager, chat_id=self.stream_id)
|
||||||
@@ -194,28 +193,27 @@ class HeartFChatting:
|
|||||||
|
|
||||||
# 获取动作类型,兼容新旧格式
|
# 获取动作类型,兼容新旧格式
|
||||||
action_type = "未知动作"
|
action_type = "未知动作"
|
||||||
if hasattr(self, '_current_cycle_detail') and self._current_cycle_detail:
|
if hasattr(self, "_current_cycle_detail") and self._current_cycle_detail:
|
||||||
loop_plan_info = self._current_cycle_detail.loop_plan_info
|
loop_plan_info = self._current_cycle_detail.loop_plan_info
|
||||||
if isinstance(loop_plan_info, dict):
|
if isinstance(loop_plan_info, dict):
|
||||||
action_result = loop_plan_info.get('action_result', {})
|
action_result = loop_plan_info.get("action_result", {})
|
||||||
if isinstance(action_result, dict):
|
if isinstance(action_result, dict):
|
||||||
# 旧格式:action_result是字典
|
# 旧格式:action_result是字典
|
||||||
action_type = action_result.get('action_type', '未知动作')
|
action_type = action_result.get("action_type", "未知动作")
|
||||||
elif isinstance(action_result, list) and action_result:
|
elif isinstance(action_result, list) and action_result:
|
||||||
# 新格式:action_result是actions列表
|
# 新格式:action_result是actions列表
|
||||||
action_type = action_result[0].get('action_type', '未知动作')
|
action_type = action_result[0].get("action_type", "未知动作")
|
||||||
elif isinstance(loop_plan_info, list) and loop_plan_info:
|
elif isinstance(loop_plan_info, list) and loop_plan_info:
|
||||||
# 直接是actions列表的情况
|
# 直接是actions列表的情况
|
||||||
action_type = loop_plan_info[0].get('action_type', '未知动作')
|
action_type = loop_plan_info[0].get("action_type", "未知动作")
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix} 第{self._current_cycle_detail.cycle_id}次思考,"
|
f"{self.log_prefix} 第{self._current_cycle_detail.cycle_id}次思考,"
|
||||||
f"耗时: {self._current_cycle_detail.end_time - self._current_cycle_detail.start_time:.1f}秒, " # type: ignore
|
f"耗时: {self._current_cycle_detail.end_time - self._current_cycle_detail.start_time:.1f}秒, " # type: ignore
|
||||||
f"选择动作: {action_type}"
|
f"选择动作: {action_type}" + (f"\n详情: {'; '.join(timer_strings)}" if timer_strings else "")
|
||||||
+ (f"\n详情: {'; '.join(timer_strings)}" if timer_strings else "")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _determine_form_type(self) -> str:
|
def _determine_form_type(self):
|
||||||
"""判断使用哪种形式的no_reply"""
|
"""判断使用哪种形式的no_reply"""
|
||||||
# 如果连续no_reply次数少于3次,使用waiting形式
|
# 如果连续no_reply次数少于3次,使用waiting形式
|
||||||
if self.no_reply_consecutive <= 3:
|
if self.no_reply_consecutive <= 3:
|
||||||
@@ -227,7 +225,9 @@ class HeartFChatting:
|
|||||||
# 计算调整后的阈值
|
# 计算调整后的阈值
|
||||||
adjusted_threshold = 3 / global_config.chat.get_current_talk_frequency(self.stream_id)
|
adjusted_threshold = 3 / global_config.chat.get_current_talk_frequency(self.stream_id)
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 最近三次兴趣度总和: {total_recent_interest:.2f}, 调整后阈值: {adjusted_threshold:.2f}")
|
logger.info(
|
||||||
|
f"{self.log_prefix} 最近三次兴趣度总和: {total_recent_interest:.2f}, 调整后阈值: {adjusted_threshold:.2f}"
|
||||||
|
)
|
||||||
|
|
||||||
# 如果兴趣度总和小于阈值,进入breaking形式
|
# 如果兴趣度总和小于阈值,进入breaking形式
|
||||||
if total_recent_interest < adjusted_threshold:
|
if total_recent_interest < adjusted_threshold:
|
||||||
@@ -250,7 +250,6 @@ class HeartFChatting:
|
|||||||
"""
|
"""
|
||||||
new_message_count = len(new_message)
|
new_message_count = len(new_message)
|
||||||
|
|
||||||
|
|
||||||
# talk_frequency = global_config.chat.get_current_talk_frequency(self.stream_id)
|
# talk_frequency = global_config.chat.get_current_talk_frequency(self.stream_id)
|
||||||
modified_exit_count_threshold = self.focus_energy / global_config.chat.focus_value
|
modified_exit_count_threshold = self.focus_energy / global_config.chat.focus_value
|
||||||
|
|
||||||
@@ -263,21 +262,22 @@ class HeartFChatting:
|
|||||||
if new_message_count >= modified_exit_count_threshold:
|
if new_message_count >= modified_exit_count_threshold:
|
||||||
# 记录兴趣度到列表
|
# 记录兴趣度到列表
|
||||||
|
|
||||||
|
|
||||||
self.recent_interest_records.append(total_interest)
|
self.recent_interest_records.append(total_interest)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix} 累计消息数量达到{new_message_count}条(>{modified_exit_count_threshold:.1f}),结束等待"
|
f"{self.log_prefix} 累计消息数量达到{new_message_count}条(>{modified_exit_count_threshold:.1f}),结束等待"
|
||||||
)
|
)
|
||||||
logger.info(self.last_read_time)
|
logger.info(str(self.last_read_time))
|
||||||
logger.info(new_message)
|
logger.info(str(new_message))
|
||||||
return True, total_interest / new_message_count
|
return True, total_interest / new_message_count
|
||||||
|
|
||||||
# 检查累计兴趣值
|
# 检查累计兴趣值
|
||||||
if new_message_count > 0:
|
if new_message_count > 0:
|
||||||
# 只在兴趣值变化时输出log
|
# 只在兴趣值变化时输出log
|
||||||
if not hasattr(self, "_last_accumulated_interest") or total_interest != self._last_accumulated_interest:
|
if not hasattr(self, "_last_accumulated_interest") or total_interest != self._last_accumulated_interest:
|
||||||
logger.info(f"{self.log_prefix} breaking形式当前累计兴趣值: {total_interest:.2f}, 专注度: {global_config.chat.focus_value:.1f}")
|
logger.info(
|
||||||
|
f"{self.log_prefix} breaking形式当前累计兴趣值: {total_interest:.2f}, 专注度: {global_config.chat.focus_value:.1f}"
|
||||||
|
)
|
||||||
self._last_accumulated_interest = total_interest
|
self._last_accumulated_interest = total_interest
|
||||||
|
|
||||||
if total_interest >= 3 / global_config.chat.focus_value:
|
if total_interest >= 3 / global_config.chat.focus_value:
|
||||||
@@ -298,7 +298,6 @@ class HeartFChatting:
|
|||||||
|
|
||||||
return False, 0.0
|
return False, 0.0
|
||||||
|
|
||||||
|
|
||||||
async def _loopbody(self):
|
async def _loopbody(self):
|
||||||
recent_messages_dict = message_api.get_messages_by_time_in_chat(
|
recent_messages_dict = message_api.get_messages_by_time_in_chat(
|
||||||
chat_id=self.stream_id,
|
chat_id=self.stream_id,
|
||||||
@@ -395,10 +394,8 @@ class HeartFChatting:
|
|||||||
return loop_info, reply_text, cycle_timers
|
return loop_info, reply_text, cycle_timers
|
||||||
|
|
||||||
async def _observe(self, interest_value: float = 0.0) -> bool:
|
async def _observe(self, interest_value: float = 0.0) -> bool:
|
||||||
|
|
||||||
action_type = "no_action"
|
action_type = "no_action"
|
||||||
reply_text = "" # 初始化reply_text变量,避免UnboundLocalError
|
reply_text = "" # 初始化reply_text变量,避免UnboundLocalError
|
||||||
reply_to_str = "" # 初始化reply_to_str变量
|
|
||||||
|
|
||||||
# 根据interest_value计算概率,决定使用哪种planner模式
|
# 根据interest_value计算概率,决定使用哪种planner模式
|
||||||
# interest_value越高,越倾向于使用Normal模式
|
# interest_value越高,越倾向于使用Normal模式
|
||||||
@@ -418,15 +415,21 @@ class HeartFChatting:
|
|||||||
x0 = 1.0 # 控制曲线中心点
|
x0 = 1.0 # 控制曲线中心点
|
||||||
return 1.0 / (1.0 + math.exp(-k * (interest_val - x0)))
|
return 1.0 / (1.0 + math.exp(-k * (interest_val - x0)))
|
||||||
|
|
||||||
normal_mode_probability = calculate_normal_mode_probability(interest_value) / global_config.chat.get_current_talk_frequency(self.stream_id)
|
normal_mode_probability = calculate_normal_mode_probability(
|
||||||
|
interest_value
|
||||||
|
) / global_config.chat.get_current_talk_frequency(self.stream_id)
|
||||||
|
|
||||||
# 根据概率决定使用哪种模式
|
# 根据概率决定使用哪种模式
|
||||||
if random.random() < normal_mode_probability:
|
if random.random() < normal_mode_probability:
|
||||||
mode = ChatMode.NORMAL
|
mode = ChatMode.NORMAL
|
||||||
logger.info(f"{self.log_prefix} 基于兴趣值 {interest_value:.2f},概率 {normal_mode_probability:.2f},选择Normal planner模式")
|
logger.info(
|
||||||
|
f"{self.log_prefix} 基于兴趣值 {interest_value:.2f},概率 {normal_mode_probability:.2f},选择Normal planner模式"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
mode = ChatMode.FOCUS
|
mode = ChatMode.FOCUS
|
||||||
logger.info(f"{self.log_prefix} 基于兴趣值 {interest_value:.2f},概率 {normal_mode_probability:.2f},选择Focus planner模式")
|
logger.info(
|
||||||
|
f"{self.log_prefix} 基于兴趣值 {interest_value:.2f},概率 {normal_mode_probability:.2f},选择Focus planner模式"
|
||||||
|
)
|
||||||
|
|
||||||
# 创建新的循环信息
|
# 创建新的循环信息
|
||||||
cycle_timers, thinking_id = self.start_cycle()
|
cycle_timers, thinking_id = self.start_cycle()
|
||||||
@@ -477,7 +480,6 @@ class HeartFChatting:
|
|||||||
# action_result.get("is_parallel", True),
|
# action_result.get("is_parallel", True),
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
# 3. 并行执行所有动作
|
# 3. 并行执行所有动作
|
||||||
async def execute_action(action_info):
|
async def execute_action(action_info):
|
||||||
"""执行单个动作的通用函数"""
|
"""执行单个动作的通用函数"""
|
||||||
@@ -498,12 +500,7 @@ class HeartFChatting:
|
|||||||
action_name="no_reply",
|
action_name="no_reply",
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
|
||||||
"action_type": "no_reply",
|
|
||||||
"success": True,
|
|
||||||
"reply_text": "",
|
|
||||||
"command": ""
|
|
||||||
}
|
|
||||||
elif action_info["action_type"] != "reply":
|
elif action_info["action_type"] != "reply":
|
||||||
# 执行普通动作
|
# 执行普通动作
|
||||||
with Timer("动作执行", cycle_timers):
|
with Timer("动作执行", cycle_timers):
|
||||||
@@ -513,19 +510,18 @@ class HeartFChatting:
|
|||||||
action_info["action_data"],
|
action_info["action_data"],
|
||||||
cycle_timers,
|
cycle_timers,
|
||||||
thinking_id,
|
thinking_id,
|
||||||
action_info["action_message"]
|
action_info["action_message"],
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"action_type": action_info["action_type"],
|
"action_type": action_info["action_type"],
|
||||||
"success": success,
|
"success": success,
|
||||||
"reply_text": reply_text,
|
"reply_text": reply_text,
|
||||||
"command": command
|
"command": command,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
# 执行回复动作
|
# 执行回复动作
|
||||||
reply_to_str = await self.build_reply_to_str(action_info["action_message"])
|
reply_to_str = await self.build_reply_to_str(action_info["action_message"])
|
||||||
|
|
||||||
|
|
||||||
# 生成回复
|
# 生成回复
|
||||||
gather_timeout = global_config.chat.thinking_timeout
|
gather_timeout = global_config.chat.thinking_timeout
|
||||||
try:
|
try:
|
||||||
@@ -536,35 +532,20 @@ class HeartFChatting:
|
|||||||
reply_to=reply_to_str,
|
reply_to=reply_to_str,
|
||||||
request_type="chat.replyer",
|
request_type="chat.replyer",
|
||||||
),
|
),
|
||||||
timeout=gather_timeout
|
timeout=gather_timeout,
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过"
|
f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过"
|
||||||
)
|
)
|
||||||
return {
|
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||||
"action_type": "reply",
|
|
||||||
"success": False,
|
|
||||||
"reply_text": "",
|
|
||||||
"loop_info": None
|
|
||||||
}
|
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
||||||
return {
|
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||||
"action_type": "reply",
|
|
||||||
"success": False,
|
|
||||||
"reply_text": "",
|
|
||||||
"loop_info": None
|
|
||||||
}
|
|
||||||
|
|
||||||
if not response_set:
|
if not response_set:
|
||||||
logger.warning(f"{self.log_prefix} 模型超时或生成回复内容为空")
|
logger.warning(f"{self.log_prefix} 模型超时或生成回复内容为空")
|
||||||
return {
|
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||||
"action_type": "reply",
|
|
||||||
"success": False,
|
|
||||||
"reply_text": "",
|
|
||||||
"loop_info": None
|
|
||||||
}
|
|
||||||
|
|
||||||
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
|
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
|
||||||
response_set,
|
response_set,
|
||||||
@@ -579,7 +560,7 @@ class HeartFChatting:
|
|||||||
"action_type": "reply",
|
"action_type": "reply",
|
||||||
"success": True,
|
"success": True,
|
||||||
"reply_text": reply_text,
|
"reply_text": reply_text,
|
||||||
"loop_info": loop_info
|
"loop_info": loop_info,
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 执行动作时出错: {e}")
|
logger.error(f"{self.log_prefix} 执行动作时出错: {e}")
|
||||||
@@ -589,7 +570,7 @@ class HeartFChatting:
|
|||||||
"success": False,
|
"success": False,
|
||||||
"reply_text": "",
|
"reply_text": "",
|
||||||
"loop_info": None,
|
"loop_info": None,
|
||||||
"error": str(e)
|
"error": str(e),
|
||||||
}
|
}
|
||||||
|
|
||||||
# 创建所有动作的后台任务
|
# 创建所有动作的后台任务
|
||||||
@@ -607,12 +588,11 @@ class HeartFChatting:
|
|||||||
action_reply_text = ""
|
action_reply_text = ""
|
||||||
action_command = ""
|
action_command = ""
|
||||||
|
|
||||||
for i, result in enumerate(results):
|
for result in results:
|
||||||
if isinstance(result, BaseException):
|
if isinstance(result, BaseException):
|
||||||
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
|
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
action_info = actions[i]
|
|
||||||
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["reply_text"]
|
||||||
@@ -652,7 +632,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)
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ class QAManager:
|
|||||||
self.kg_manager = kg_manager
|
self.kg_manager = kg_manager
|
||||||
self.qa_model = LLMRequest(model_set=model_config.model_task_config.lpmm_qa, request_type="lpmm.qa")
|
self.qa_model = LLMRequest(model_set=model_config.model_task_config.lpmm_qa, request_type="lpmm.qa")
|
||||||
|
|
||||||
async def process_query(self, question: str) -> Optional[Tuple[List[Tuple[str, float, float]], Optional[Dict[str, float]]]]:
|
async def process_query(
|
||||||
|
self, question: str
|
||||||
|
) -> Optional[Tuple[List[Tuple[str, float, float]], Optional[Dict[str, float]]]]:
|
||||||
"""处理查询"""
|
"""处理查询"""
|
||||||
|
|
||||||
# 生成问题的Embedding
|
# 生成问题的Embedding
|
||||||
@@ -56,7 +58,8 @@ class QAManager:
|
|||||||
logger.debug(f"关系检索用时:{part_end_time - part_start_time:.5f}s")
|
logger.debug(f"关系检索用时:{part_end_time - part_start_time:.5f}s")
|
||||||
|
|
||||||
for res in relation_search_res:
|
for res in relation_search_res:
|
||||||
rel_str = self.embed_manager.relation_embedding_store.store.get(res[0]).str
|
if store_item := self.embed_manager.relation_embedding_store.store.get(res[0]):
|
||||||
|
rel_str = store_item.str
|
||||||
print(f"找到相关关系,相似度:{(res[1] * 100):.2f}% - {rel_str}")
|
print(f"找到相关关系,相似度:{(res[1] * 100):.2f}% - {rel_str}")
|
||||||
|
|
||||||
# TODO: 使用LLM过滤三元组结果
|
# TODO: 使用LLM过滤三元组结果
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ def get_key_comment(toml_table, key):
|
|||||||
return item.trivia.comment
|
return item.trivia.comment
|
||||||
if hasattr(toml_table, "keys"):
|
if hasattr(toml_table, "keys"):
|
||||||
for k in toml_table.keys():
|
for k in toml_table.keys():
|
||||||
if isinstance(k, KeyType) and k.key == key:
|
if isinstance(k, KeyType) and k.key == key: # type: ignore
|
||||||
return k.trivia.comment
|
return k.trivia.comment # type: ignore
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user