迁移:685c759 (feat:将no_reply功能移动到主循环中)
This commit is contained in:
@@ -85,6 +85,7 @@ class CycleProcessor:
|
|||||||
|
|
||||||
# 检查是否在normal模式下没有可用动作(除了reply相关动作)
|
# 检查是否在normal模式下没有可用动作(除了reply相关动作)
|
||||||
skip_planner = False
|
skip_planner = False
|
||||||
|
gen_task = None
|
||||||
if self.context.loop_mode == ChatMode.NORMAL:
|
if self.context.loop_mode == ChatMode.NORMAL:
|
||||||
non_reply_actions = {
|
non_reply_actions = {
|
||||||
k: v for k, v in available_actions.items() 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"]
|
||||||
@@ -95,7 +96,6 @@ class CycleProcessor:
|
|||||||
plan_result = self._get_direct_reply_plan(loop_start_time)
|
plan_result = self._get_direct_reply_plan(loop_start_time)
|
||||||
target_message = message_data
|
target_message = message_data
|
||||||
|
|
||||||
gen_task = None
|
|
||||||
# 如果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)
|
||||||
@@ -156,6 +156,28 @@ class CycleProcessor:
|
|||||||
loop_start_time,
|
loop_start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.context.last_action = action_type
|
||||||
|
|
||||||
|
# 处理no_reply相关的逻辑
|
||||||
|
if action_type != "no_reply" and action_type != "no_action":
|
||||||
|
# 导入NoReplyAction并重置计数器
|
||||||
|
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
||||||
|
NoReplyAction.reset_consecutive_count()
|
||||||
|
self.context.no_reply_consecutive = 0
|
||||||
|
logger.info(f"{self.context.log_prefix} 执行了{action_type}动作,重置no_reply计数器")
|
||||||
|
elif action_type == "no_action":
|
||||||
|
# 当执行回复动作时,也重置no_reply计数
|
||||||
|
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
||||||
|
NoReplyAction.reset_consecutive_count()
|
||||||
|
self.context.no_reply_consecutive = 0
|
||||||
|
logger.info(f"{self.context.log_prefix} 执行了回复动作,重置no_reply计数器")
|
||||||
|
|
||||||
|
if action_type == "no_reply":
|
||||||
|
self.context.no_reply_consecutive += 1
|
||||||
|
# 调用HeartFChatting中的_determine_form_type方法
|
||||||
|
if hasattr(self.context, 'chat_instance') and self.context.chat_instance:
|
||||||
|
self.context.chat_instance._determine_form_type()
|
||||||
|
|
||||||
if ENABLE_S4U:
|
if ENABLE_S4U:
|
||||||
await stop_typing()
|
await stop_typing()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Optional
|
import random
|
||||||
|
from typing import Optional, List, Dict, Any, Tuple
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
@@ -50,6 +51,8 @@ class HeartFChatting:
|
|||||||
# 将唤醒度管理器设置到上下文中
|
# 将唤醒度管理器设置到上下文中
|
||||||
self.context.wakeup_manager = self.wakeup_manager
|
self.context.wakeup_manager = self.wakeup_manager
|
||||||
self.context.energy_manager = self.energy_manager
|
self.context.energy_manager = self.energy_manager
|
||||||
|
# 将HeartFChatting实例设置到上下文中,以便其他组件可以调用其方法
|
||||||
|
self.context.chat_instance = self
|
||||||
|
|
||||||
self._loop_task: Optional[asyncio.Task] = None
|
self._loop_task: Optional[asyncio.Task] = None
|
||||||
|
|
||||||
@@ -217,6 +220,7 @@ class HeartFChatting:
|
|||||||
)
|
)
|
||||||
|
|
||||||
has_new_messages = bool(recent_messages)
|
has_new_messages = bool(recent_messages)
|
||||||
|
new_message_count = len(recent_messages)
|
||||||
|
|
||||||
# 只有在有新消息时才进行思考循环处理
|
# 只有在有新消息时才进行思考循环处理
|
||||||
if has_new_messages:
|
if has_new_messages:
|
||||||
@@ -239,13 +243,31 @@ class HeartFChatting:
|
|||||||
|
|
||||||
# 根据聊天模式处理新消息
|
# 根据聊天模式处理新消息
|
||||||
if self.context.loop_mode == ChatMode.FOCUS:
|
if self.context.loop_mode == ChatMode.FOCUS:
|
||||||
|
# 如果上一个动作是no_reply,则执行no_reply逻辑
|
||||||
|
if self.context.last_action == "no_reply":
|
||||||
|
if not await self._execute_no_reply(recent_messages):
|
||||||
|
self.context.energy_value -= 0.3 / global_config.chat.focus_value
|
||||||
|
logger.info(f"{self.context.log_prefix} 能量值减少,当前能量值:{self.context.energy_value:.1f}")
|
||||||
|
return has_new_messages
|
||||||
|
|
||||||
|
# 处理新消息
|
||||||
for message in recent_messages:
|
for message in recent_messages:
|
||||||
await self.cycle_processor.observe(message)
|
await self.cycle_processor.observe(message)
|
||||||
|
|
||||||
|
# 如果成功观察,增加能量值
|
||||||
|
if has_new_messages:
|
||||||
|
self.context.energy_value += 1 / global_config.chat.focus_value
|
||||||
|
logger.info(f"{self.context.log_prefix} 能量值增加,当前能量值:{self.context.energy_value:.1f}")
|
||||||
|
|
||||||
self._check_focus_exit()
|
self._check_focus_exit()
|
||||||
elif self.context.loop_mode == ChatMode.NORMAL:
|
elif self.context.loop_mode == ChatMode.NORMAL:
|
||||||
self._check_focus_entry(len(recent_messages))
|
self._check_focus_entry(len(recent_messages))
|
||||||
for message in recent_messages:
|
# 检查是否有足够的新消息触发处理
|
||||||
await self.normal_mode_handler.handle_message(message)
|
if new_message_count >= self.context.focus_energy:
|
||||||
|
earliest_messages_data = recent_messages[0]
|
||||||
|
self.context.last_read_time = earliest_messages_data.get("time")
|
||||||
|
for message in recent_messages:
|
||||||
|
await self.normal_mode_handler.handle_message(message)
|
||||||
else:
|
else:
|
||||||
# 无新消息时,只进行模式检查,不进行思考循环
|
# 无新消息时,只进行模式检查,不进行思考循环
|
||||||
if self.context.loop_mode == ChatMode.FOCUS:
|
if self.context.loop_mode == ChatMode.FOCUS:
|
||||||
@@ -369,3 +391,85 @@ class HeartFChatting:
|
|||||||
if woke_up:
|
if woke_up:
|
||||||
logger.info(f"{self.context.log_prefix} 被消息吵醒,进入愤怒状态!")
|
logger.info(f"{self.context.log_prefix} 被消息吵醒,进入愤怒状态!")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def _determine_form_type(self) -> str:
|
||||||
|
"""判断使用哪种形式的no_reply"""
|
||||||
|
# 如果连续no_reply次数少于3次,使用waiting形式
|
||||||
|
if self.context.no_reply_consecutive <= 3:
|
||||||
|
self.context.focus_energy = 1
|
||||||
|
else:
|
||||||
|
# 计算最近三次记录的兴趣度总和
|
||||||
|
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
||||||
|
total_recent_interest = sum(NoReplyAction._recent_interest_records)
|
||||||
|
|
||||||
|
# 获取当前聊天频率和意愿系数
|
||||||
|
talk_frequency = global_config.chat.get_current_talk_frequency(self.context.stream_id)
|
||||||
|
|
||||||
|
# 计算调整后的阈值
|
||||||
|
adjusted_threshold = 3 / talk_frequency
|
||||||
|
|
||||||
|
logger.info(f"{self.context.log_prefix} 最近三次兴趣度总和: {total_recent_interest:.2f}, 调整后阈值: {adjusted_threshold:.2f}")
|
||||||
|
|
||||||
|
# 如果兴趣度总和小于阈值,进入breaking形式
|
||||||
|
if total_recent_interest < adjusted_threshold:
|
||||||
|
logger.info(f"{self.context.log_prefix} 兴趣度不足,进入breaking形式")
|
||||||
|
self.context.focus_energy = random.randint(3, 6)
|
||||||
|
else:
|
||||||
|
logger.info(f"{self.context.log_prefix} 兴趣度充足")
|
||||||
|
self.context.focus_energy = 1
|
||||||
|
|
||||||
|
async def _execute_no_reply(self, new_message: List[Dict[str, Any]]) -> bool:
|
||||||
|
"""执行breaking形式的no_reply(原有逻辑)"""
|
||||||
|
new_message_count = len(new_message)
|
||||||
|
# 检查消息数量是否达到阈值
|
||||||
|
talk_frequency = global_config.chat.get_current_talk_frequency(self.context.stream_id)
|
||||||
|
modified_exit_count_threshold = self.context.focus_energy / talk_frequency
|
||||||
|
|
||||||
|
if new_message_count >= modified_exit_count_threshold:
|
||||||
|
# 记录兴趣度到列表
|
||||||
|
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
||||||
|
total_interest = 0.0
|
||||||
|
for msg_dict in new_message:
|
||||||
|
interest_value = msg_dict.get("interest_value", 0.0)
|
||||||
|
if msg_dict.get("processed_plain_text", ""):
|
||||||
|
total_interest += interest_value
|
||||||
|
|
||||||
|
NoReplyAction._recent_interest_records.append(total_interest)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"{self.context.log_prefix} 累计消息数量达到{new_message_count}条(>{modified_exit_count_threshold}),结束等待"
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 检查累计兴趣值
|
||||||
|
if new_message_count > 0:
|
||||||
|
accumulated_interest = 0.0
|
||||||
|
for msg_dict in new_message:
|
||||||
|
text = msg_dict.get("processed_plain_text", "")
|
||||||
|
interest_value = msg_dict.get("interest_value", 0.0)
|
||||||
|
if text:
|
||||||
|
accumulated_interest += interest_value
|
||||||
|
|
||||||
|
# 只在兴趣值变化时输出log
|
||||||
|
if not hasattr(self, "_last_accumulated_interest") or accumulated_interest != self._last_accumulated_interest:
|
||||||
|
logger.info(f"{self.context.log_prefix} breaking形式当前累计兴趣值: {accumulated_interest:.2f}, 当前聊天频率: {talk_frequency:.2f}")
|
||||||
|
self._last_accumulated_interest = accumulated_interest
|
||||||
|
|
||||||
|
if accumulated_interest >= 3 / talk_frequency:
|
||||||
|
# 记录兴趣度到列表
|
||||||
|
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
||||||
|
NoReplyAction._recent_interest_records.append(accumulated_interest)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"{self.context.log_prefix} 累计兴趣值达到{accumulated_interest:.2f}(>{5 / talk_frequency}),结束等待"
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 每10秒输出一次等待状态
|
||||||
|
if int(time.time() - self.context.last_read_time) > 0 and int(time.time() - self.context.last_read_time) % 10 == 0:
|
||||||
|
logger.info(
|
||||||
|
f"{self.context.log_prefix} 已等待{time.time() - self.context.last_read_time:.0f}秒,累计{new_message_count}条消息,继续等待..."
|
||||||
|
)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ class HfcContext:
|
|||||||
self.expression_learner: Optional[ExpressionLearner] = None
|
self.expression_learner: Optional[ExpressionLearner] = None
|
||||||
|
|
||||||
self.loop_mode = ChatMode.NORMAL
|
self.loop_mode = ChatMode.NORMAL
|
||||||
|
|
||||||
|
self.last_action = "no_action"
|
||||||
|
|
||||||
self.energy_value = self.chat_stream.energy_value
|
self.energy_value = self.chat_stream.energy_value
|
||||||
self.sleep_pressure = self.chat_stream.sleep_pressure
|
self.sleep_pressure = self.chat_stream.sleep_pressure
|
||||||
self.was_sleeping = False # 用于检测睡眠状态的切换
|
self.was_sleeping = False # 用于检测睡眠状态的切换
|
||||||
@@ -61,8 +64,16 @@ class HfcContext:
|
|||||||
self.wakeup_manager: Optional["WakeUpManager"] = None
|
self.wakeup_manager: Optional["WakeUpManager"] = None
|
||||||
self.energy_manager: Optional["EnergyManager"] = None
|
self.energy_manager: Optional["EnergyManager"] = None
|
||||||
|
|
||||||
|
self.focus_energy = 1
|
||||||
|
self.no_reply_consecutive = 0
|
||||||
|
|
||||||
|
# 引用HeartFChatting实例,以便其他组件可以调用其方法
|
||||||
|
self.chat_instance = None
|
||||||
|
|
||||||
def save_context_state(self):
|
def save_context_state(self):
|
||||||
"""将当前状态保存到聊天流"""
|
"""将当前状态保存到聊天流"""
|
||||||
if self.chat_stream:
|
if self.chat_stream:
|
||||||
self.chat_stream.energy_value = self.energy_value
|
self.chat_stream.energy_value = self.energy_value
|
||||||
self.chat_stream.sleep_pressure = self.sleep_pressure
|
self.chat_stream.sleep_pressure = self.sleep_pressure
|
||||||
|
self.chat_stream.focus_energy = self.focus_energy
|
||||||
|
self.chat_stream.no_reply_consecutive = self.no_reply_consecutive
|
||||||
@@ -83,6 +83,8 @@ class ChatStream:
|
|||||||
self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0
|
self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0
|
||||||
self.saved = False
|
self.saved = False
|
||||||
self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息
|
self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息
|
||||||
|
self.focus_energy = 1
|
||||||
|
self.no_reply_consecutive = 0
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"""转换为字典格式"""
|
"""转换为字典格式"""
|
||||||
|
|||||||
@@ -26,12 +26,6 @@ class NoReplyAction(BaseAction):
|
|||||||
# 最近三次no_reply的新消息兴趣度记录
|
# 最近三次no_reply的新消息兴趣度记录
|
||||||
_recent_interest_records: deque = deque(maxlen=3)
|
_recent_interest_records: deque = deque(maxlen=3)
|
||||||
|
|
||||||
# 兴趣值退出阈值
|
|
||||||
_interest_exit_threshold = 3.0
|
|
||||||
# 消息数量退出阈值
|
|
||||||
_min_exit_message_count = 3
|
|
||||||
_max_exit_message_count = 6
|
|
||||||
|
|
||||||
# 动作参数定义
|
# 动作参数定义
|
||||||
action_parameters = {}
|
action_parameters = {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user