fix:hfc现在会在FOCUS下持续运行,有小概率掉出FOCUS模式
This commit is contained in:
@@ -28,7 +28,7 @@ logger = get_module_logger("config", config=config_config)
|
|||||||
# 考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
|
# 考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
|
||||||
is_test = True
|
is_test = True
|
||||||
mai_version_main = "0.6.3"
|
mai_version_main = "0.6.3"
|
||||||
mai_version_fix = "snapshot-3"
|
mai_version_fix = "snapshot-4"
|
||||||
|
|
||||||
if mai_version_fix:
|
if mai_version_fix:
|
||||||
if is_test:
|
if is_test:
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ background_tasks_log_config = LogConfig(
|
|||||||
|
|
||||||
logger = get_module_logger("background_tasks", config=background_tasks_log_config)
|
logger = get_module_logger("background_tasks", config=background_tasks_log_config)
|
||||||
|
|
||||||
|
# 新增随机停用间隔 (5 分钟)
|
||||||
|
RANDOM_DEACTIVATION_INTERVAL_SECONDS = 300
|
||||||
# 新增兴趣评估间隔
|
# 新增兴趣评估间隔
|
||||||
INTEREST_EVAL_INTERVAL_SECONDS = 5
|
INTEREST_EVAL_INTERVAL_SECONDS = 5
|
||||||
|
|
||||||
@@ -35,6 +37,8 @@ class BackgroundTaskManager:
|
|||||||
inactive_threshold: int,
|
inactive_threshold: int,
|
||||||
# 新增兴趣评估间隔参数
|
# 新增兴趣评估间隔参数
|
||||||
interest_eval_interval: int = INTEREST_EVAL_INTERVAL_SECONDS,
|
interest_eval_interval: int = INTEREST_EVAL_INTERVAL_SECONDS,
|
||||||
|
# 新增随机停用间隔参数
|
||||||
|
random_deactivation_interval: int = RANDOM_DEACTIVATION_INTERVAL_SECONDS,
|
||||||
):
|
):
|
||||||
self.mai_state_info = mai_state_info
|
self.mai_state_info = mai_state_info
|
||||||
self.mai_state_manager = mai_state_manager
|
self.mai_state_manager = mai_state_manager
|
||||||
@@ -47,19 +51,21 @@ class BackgroundTaskManager:
|
|||||||
self.log_interval = log_interval
|
self.log_interval = log_interval
|
||||||
self.inactive_threshold = inactive_threshold # For cleanup task
|
self.inactive_threshold = inactive_threshold # For cleanup task
|
||||||
self.interest_eval_interval = interest_eval_interval # 存储兴趣评估间隔
|
self.interest_eval_interval = interest_eval_interval # 存储兴趣评估间隔
|
||||||
|
self.random_deactivation_interval = random_deactivation_interval # 存储随机停用间隔
|
||||||
|
|
||||||
# Task references
|
# Task references
|
||||||
self._state_update_task: Optional[asyncio.Task] = None
|
self._state_update_task: Optional[asyncio.Task] = None
|
||||||
self._cleanup_task: Optional[asyncio.Task] = None
|
self._cleanup_task: Optional[asyncio.Task] = None
|
||||||
self._logging_task: Optional[asyncio.Task] = None
|
self._logging_task: Optional[asyncio.Task] = None
|
||||||
self._interest_eval_task: Optional[asyncio.Task] = None # 新增兴趣评估任务引用
|
self._interest_eval_task: Optional[asyncio.Task] = None # 新增兴趣评估任务引用
|
||||||
|
self._random_deactivation_task: Optional[asyncio.Task] = None # 新增随机停用任务引用
|
||||||
self._tasks: List[Optional[asyncio.Task]] = [] # Keep track of all tasks
|
self._tasks: List[Optional[asyncio.Task]] = [] # Keep track of all tasks
|
||||||
|
|
||||||
async def start_tasks(self):
|
async def start_tasks(self):
|
||||||
"""启动所有后台任务
|
"""启动所有后台任务
|
||||||
|
|
||||||
功能说明:
|
功能说明:
|
||||||
- 启动核心后台任务: 状态更新、清理、日志记录和兴趣评估
|
- 启动核心后台任务: 状态更新、清理、日志记录、兴趣评估和随机停用
|
||||||
- 每个任务启动前检查是否已在运行
|
- 每个任务启动前检查是否已在运行
|
||||||
- 将任务引用保存到任务列表
|
- 将任务引用保存到任务列表
|
||||||
"""
|
"""
|
||||||
@@ -99,6 +105,15 @@ class BackgroundTaskManager:
|
|||||||
f"兴趣评估任务已启动 间隔:{self.interest_eval_interval}s",
|
f"兴趣评估任务已启动 间隔:{self.interest_eval_interval}s",
|
||||||
"_interest_eval_task",
|
"_interest_eval_task",
|
||||||
),
|
),
|
||||||
|
# 新增随机停用任务配置
|
||||||
|
(
|
||||||
|
self._random_deactivation_task,
|
||||||
|
self._run_random_deactivation_cycle,
|
||||||
|
"hf_random_deactivation",
|
||||||
|
"debug", # 设为debug,避免过多日志
|
||||||
|
f"随机停用任务已启动 间隔:{self.random_deactivation_interval}s",
|
||||||
|
"_random_deactivation_task",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# 统一启动所有任务
|
# 统一启动所有任务
|
||||||
@@ -230,6 +245,12 @@ class BackgroundTaskManager:
|
|||||||
|
|
||||||
# --- 结束新增 ---
|
# --- 结束新增 ---
|
||||||
|
|
||||||
|
# --- 新增随机停用工作函数 ---
|
||||||
|
async def _perform_random_deactivation_work(self):
|
||||||
|
"""执行一轮子心流随机停用检查。"""
|
||||||
|
await self.subheartflow_manager.randomly_deactivate_subflows()
|
||||||
|
# --- 结束新增 ---
|
||||||
|
|
||||||
# --- Specific Task Runners --- #
|
# --- Specific Task Runners --- #
|
||||||
async def _run_state_update_cycle(self, interval: int):
|
async def _run_state_update_cycle(self, interval: int):
|
||||||
await self._run_periodic_loop(
|
await self._run_periodic_loop(
|
||||||
@@ -255,3 +276,14 @@ class BackgroundTaskManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# --- 结束新增 ---
|
# --- 结束新增 ---
|
||||||
|
|
||||||
|
# --- 新增随机停用任务运行器 ---
|
||||||
|
async def _run_random_deactivation_cycle(self):
|
||||||
|
"""运行随机停用循环。"""
|
||||||
|
await self._run_periodic_loop(
|
||||||
|
task_name="Random Deactivation",
|
||||||
|
interval=self.random_deactivation_interval,
|
||||||
|
task_func=self._perform_random_deactivation_work,
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- 结束新增 ---
|
||||||
|
|||||||
@@ -358,30 +358,40 @@ class SubHeartflow:
|
|||||||
self.clear_interest_dict() # 清理兴趣字典,准备专注聊天
|
self.clear_interest_dict() # 清理兴趣字典,准备专注聊天
|
||||||
|
|
||||||
log_prefix = self.log_prefix
|
log_prefix = self.log_prefix
|
||||||
|
# 如果实例已存在,检查其循环任务状态
|
||||||
if self.heart_fc_instance:
|
if self.heart_fc_instance:
|
||||||
if not self.heart_fc_instance._loop_active:
|
# 如果任务已完成或不存在,则尝试重新启动
|
||||||
logger.warning(f"{log_prefix} HeartFChatting 实例存在但未激活,尝试重新激活...")
|
if self.heart_fc_instance._loop_task is None or self.heart_fc_instance._loop_task.done():
|
||||||
await self.heart_fc_instance.add_time() # 尝试添加时间以激活循环
|
logger.info(f"{log_prefix} HeartFChatting 实例存在但循环未运行,尝试启动...")
|
||||||
return True # 假设 add_time 会处理激活逻辑
|
try:
|
||||||
|
await self.heart_fc_instance.start() # 启动循环
|
||||||
|
logger.info(f"{log_prefix} HeartFChatting 循环已启动。")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{log_prefix} 尝试启动现有 HeartFChatting 循环时出错: {e}")
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
return False # 启动失败
|
||||||
else:
|
else:
|
||||||
|
# 任务正在运行
|
||||||
logger.debug(f"{log_prefix} HeartFChatting 已在运行中。")
|
logger.debug(f"{log_prefix} HeartFChatting 已在运行中。")
|
||||||
return True # 已经在运行
|
return True # 已经在运行
|
||||||
|
|
||||||
logger.info(f"{log_prefix} 麦麦准备开始专注聊天...")
|
# 如果实例不存在,则创建并启动
|
||||||
|
logger.info(f"{log_prefix} 麦麦准备开始专注聊天 (创建新实例)...")
|
||||||
try:
|
try:
|
||||||
self.heart_fc_instance = HeartFChatting(
|
self.heart_fc_instance = HeartFChatting(
|
||||||
chat_id=self.chat_id,
|
chat_id=self.chat_id,
|
||||||
)
|
)
|
||||||
if await self.heart_fc_instance._initialize():
|
if await self.heart_fc_instance._initialize():
|
||||||
await self.heart_fc_instance.add_time() # 初始化成功后添加初始时间
|
await self.heart_fc_instance.start() # 初始化成功后启动循环
|
||||||
logger.info(f"{log_prefix} 麦麦已成功进入专注聊天模式。")
|
logger.info(f"{log_prefix} 麦麦已成功进入专注聊天模式 (新实例已启动)。")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.error(f"{log_prefix} HeartFChatting 初始化失败,无法进入专注模式。")
|
logger.error(f"{log_prefix} HeartFChatting 初始化失败,无法进入专注模式。")
|
||||||
self.heart_fc_instance = None # 初始化失败,清理实例
|
self.heart_fc_instance = None # 初始化失败,清理实例
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{log_prefix} 创建或初始化 HeartFChatting 实例时出错: {e}")
|
logger.error(f"{log_prefix} 创建或启动 HeartFChatting 实例时出错: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
self.heart_fc_instance = None # 创建或初始化异常,清理实例
|
self.heart_fc_instance = None # 创建或初始化异常,清理实例
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -358,6 +358,74 @@ class SubHeartflowManager:
|
|||||||
else:
|
else:
|
||||||
logger.debug(f"{log_prefix_manager} 评估周期结束, 未提升任何子心流。")
|
logger.debug(f"{log_prefix_manager} 评估周期结束, 未提升任何子心流。")
|
||||||
|
|
||||||
|
async def randomly_deactivate_subflows(self, deactivation_probability: float = 0.3):
|
||||||
|
"""以一定概率将 FOCUSED 或 CHAT 状态的子心流回退到 ABSENT 状态。"""
|
||||||
|
log_prefix_manager = "[子心流管理器-随机停用]"
|
||||||
|
logger.debug(f"{log_prefix_manager} 开始随机停用检查... (概率: {deactivation_probability:.0%})")
|
||||||
|
|
||||||
|
# 使用快照安全遍历
|
||||||
|
subflows_snapshot = list(self.subheartflows.values())
|
||||||
|
deactivated_count = 0
|
||||||
|
|
||||||
|
# 预先计算状态数量,因为 set_chat_state 需要
|
||||||
|
states_num_before = (
|
||||||
|
self.count_subflows_by_state(ChatState.ABSENT),
|
||||||
|
self.count_subflows_by_state(ChatState.CHAT),
|
||||||
|
self.count_subflows_by_state(ChatState.FOCUSED),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
for sub_hf in subflows_snapshot:
|
||||||
|
flow_id = sub_hf.subheartflow_id
|
||||||
|
stream_name = chat_manager.get_stream_name(flow_id) or flow_id
|
||||||
|
log_prefix_flow = f"[{stream_name}]"
|
||||||
|
current_state = sub_hf.chat_state.chat_status
|
||||||
|
|
||||||
|
# 只处理 FOCUSED 或 CHAT 状态
|
||||||
|
if current_state not in [ChatState.FOCUSED, ChatState.CHAT]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 检查随机概率
|
||||||
|
if random.random() < deactivation_probability:
|
||||||
|
logger.info(
|
||||||
|
f"{log_prefix_manager} {log_prefix_flow} 随机触发停用 (从 {current_state.value}) -> ABSENT"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 获取当前实例以检查最新状态
|
||||||
|
current_subflow = self.subheartflows.get(flow_id)
|
||||||
|
if not current_subflow or current_subflow.chat_state.chat_status != current_state:
|
||||||
|
logger.warning(f"{log_prefix_manager} {log_prefix_flow} 尝试停用时状态已改变或实例消失,跳过。")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# --- 状态设置 --- #
|
||||||
|
# 注意:这里传递的状态数量是 *停用前* 的状态数量
|
||||||
|
await current_subflow.set_chat_state(ChatState.ABSENT, states_num_before)
|
||||||
|
|
||||||
|
# --- 状态验证 (可选) ---
|
||||||
|
final_subflow = self.subheartflows.get(flow_id)
|
||||||
|
if final_subflow:
|
||||||
|
final_state = final_subflow.chat_state.chat_status
|
||||||
|
if final_state == ChatState.ABSENT:
|
||||||
|
logger.debug(
|
||||||
|
f"{log_prefix_manager} {log_prefix_flow} 成功从 {current_state.value} 停用到 ABSENT 状态"
|
||||||
|
)
|
||||||
|
deactivated_count += 1
|
||||||
|
# 注意:停用后不需要更新 states_num_before,因为它只用于 set_chat_state 的限制检查
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
f"{log_prefix_manager} {log_prefix_flow} 尝试停用到 ABSENT 后状态仍为 {final_state.value}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.warning(f"{log_prefix_manager} {log_prefix_flow} 停用后验证时子心流 {flow_id} 消失")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{log_prefix_manager} 随机停用周期出错: {e}", exc_info=True)
|
||||||
|
|
||||||
|
if deactivated_count > 0:
|
||||||
|
logger.info(f"{log_prefix_manager} 随机停用周期结束, 成功停用 {deactivated_count} 个子心流。")
|
||||||
|
else:
|
||||||
|
logger.debug(f"{log_prefix_manager} 随机停用周期结束, 未停用任何子心流。")
|
||||||
|
|
||||||
def count_subflows_by_state(self, state: ChatState) -> int:
|
def count_subflows_by_state(self, state: ChatState) -> int:
|
||||||
"""统计指定状态的子心流数量
|
"""统计指定状态的子心流数量
|
||||||
|
|
||||||
|
|||||||
@@ -68,9 +68,8 @@ PLANNER_TOOL_DEFINITION = [
|
|||||||
class HeartFChatting:
|
class HeartFChatting:
|
||||||
"""
|
"""
|
||||||
管理一个连续的Plan-Replier-Sender循环
|
管理一个连续的Plan-Replier-Sender循环
|
||||||
用于在特定聊天流中生成回复,由计时器控制。
|
用于在特定聊天流中生成回复。
|
||||||
只要计时器>0,循环就会继续。
|
其生命周期现在由其关联的 SubHeartflow 的 FOCUSED 状态控制。
|
||||||
现在由其关联的 SubHeartflow 管理生命周期。
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, chat_id: str):
|
def __init__(self, chat_id: str):
|
||||||
@@ -79,9 +78,6 @@ class HeartFChatting:
|
|||||||
|
|
||||||
参数:
|
参数:
|
||||||
chat_id: 聊天流唯一标识符(如stream_id)
|
chat_id: 聊天流唯一标识符(如stream_id)
|
||||||
gpt_instance: 文本回复生成器实例
|
|
||||||
tool_user_instance: 工具使用实例
|
|
||||||
emoji_manager_instance: 表情管理实例
|
|
||||||
"""
|
"""
|
||||||
# 基础属性
|
# 基础属性
|
||||||
self.stream_id: str = chat_id # 聊天流ID
|
self.stream_id: str = chat_id # 聊天流ID
|
||||||
@@ -91,7 +87,6 @@ class HeartFChatting:
|
|||||||
# 初始化状态控制
|
# 初始化状态控制
|
||||||
self._initialized = False # 是否已初始化标志
|
self._initialized = False # 是否已初始化标志
|
||||||
self._processing_lock = asyncio.Lock() # 处理锁(确保单次Plan-Replier-Sender周期)
|
self._processing_lock = asyncio.Lock() # 处理锁(确保单次Plan-Replier-Sender周期)
|
||||||
self._timer_lock = asyncio.Lock() # 计时器锁(安全更新计时器)
|
|
||||||
|
|
||||||
# 依赖注入存储
|
# 依赖注入存储
|
||||||
self.gpt_instance = HeartFCGenerator() # 文本回复生成器
|
self.gpt_instance = HeartFCGenerator() # 文本回复生成器
|
||||||
@@ -106,11 +101,8 @@ class HeartFChatting:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 循环控制内部状态
|
# 循环控制内部状态
|
||||||
self._loop_timer: float = 0.0 # 循环剩余时间(秒)
|
|
||||||
self._loop_active: bool = False # 循环是否正在运行
|
self._loop_active: bool = False # 循环是否正在运行
|
||||||
self._loop_task: Optional[asyncio.Task] = None # 主循环任务
|
self._loop_task: Optional[asyncio.Task] = None # 主循环任务
|
||||||
self._initial_duration: float = INITIAL_DURATION # 首次触发增加的时间
|
|
||||||
self._last_added_duration: float = self._initial_duration # 上次增加的时间
|
|
||||||
|
|
||||||
def _get_log_prefix(self) -> str:
|
def _get_log_prefix(self) -> str:
|
||||||
"""获取日志前缀,包含可读的流名称"""
|
"""获取日志前缀,包含可读的流名称"""
|
||||||
@@ -147,34 +139,10 @@ class HeartFChatting:
|
|||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def add_time(self):
|
|
||||||
"""
|
|
||||||
为麦麦添加时间,麦麦有兴趣时,固定增加15秒
|
|
||||||
"""
|
|
||||||
log_prefix = self._get_log_prefix()
|
|
||||||
if not self._initialized:
|
|
||||||
if not await self._initialize():
|
|
||||||
logger.error(f"{log_prefix} 无法添加时间: 未初始化。")
|
|
||||||
return
|
|
||||||
|
|
||||||
async with self._timer_lock:
|
|
||||||
duration_to_add: float = 15.0 # 固定增加15秒
|
|
||||||
if not self._loop_active: # 首次触发
|
|
||||||
logger.info(f"{log_prefix} 麦麦有兴趣! 打算聊:15s.")
|
|
||||||
else: # 循环已激活
|
|
||||||
logger.info(f"{log_prefix} 麦麦想继续聊:15s, 还能聊: {self._loop_timer:.1f}s.")
|
|
||||||
|
|
||||||
# 添加固定时间
|
|
||||||
new_timer_value = self._loop_timer + duration_to_add
|
|
||||||
self._loop_timer = max(0, new_timer_value)
|
|
||||||
|
|
||||||
# 添加时间后,检查是否需要启动循环
|
|
||||||
await self._start_loop_if_needed()
|
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""
|
"""
|
||||||
显式尝试启动 HeartFChatting 的主循环。
|
显式尝试启动 HeartFChatting 的主循环。
|
||||||
如果循环未激活且计时器 > 0,则启动循环。
|
如果循环未激活,则启动循环。
|
||||||
"""
|
"""
|
||||||
log_prefix = self._get_log_prefix()
|
log_prefix = self._get_log_prefix()
|
||||||
if not self._initialized:
|
if not self._initialized:
|
||||||
@@ -185,14 +153,13 @@ class HeartFChatting:
|
|||||||
await self._start_loop_if_needed()
|
await self._start_loop_if_needed()
|
||||||
|
|
||||||
async def _start_loop_if_needed(self):
|
async def _start_loop_if_needed(self):
|
||||||
"""检查是否需要启动主循环,如果未激活且计时器大于0,则启动。"""
|
"""检查是否需要启动主循环,如果未激活则启动。"""
|
||||||
log_prefix = self._get_log_prefix()
|
log_prefix = self._get_log_prefix()
|
||||||
should_start_loop = False
|
should_start_loop = False
|
||||||
async with self._timer_lock:
|
# 直接检查是否激活,无需检查计时器
|
||||||
# 检查是否满足启动条件:未激活且计时器有时间
|
if not self._loop_active:
|
||||||
if not self._loop_active and self._loop_timer > 0:
|
should_start_loop = True
|
||||||
should_start_loop = True
|
self._loop_active = True # 标记为活动,防止重复启动
|
||||||
self._loop_active = True # 在锁内标记为活动,防止重复启动
|
|
||||||
|
|
||||||
if should_start_loop:
|
if should_start_loop:
|
||||||
# 检查是否已有任务在运行(理论上不应该,因为 _loop_active=False)
|
# 检查是否已有任务在运行(理论上不应该,因为 _loop_active=False)
|
||||||
@@ -206,13 +173,13 @@ class HeartFChatting:
|
|||||||
pass # 忽略取消或超时错误
|
pass # 忽略取消或超时错误
|
||||||
self._loop_task = None # 清理旧任务引用
|
self._loop_task = None # 清理旧任务引用
|
||||||
|
|
||||||
logger.info(f"{log_prefix} 计时器 > 0 且循环未激活,启动主循环...")
|
logger.info(f"{log_prefix} 循环未激活,启动主循环...")
|
||||||
# 创建新的循环任务
|
# 创建新的循环任务
|
||||||
self._loop_task = asyncio.create_task(self._run_pf_loop())
|
self._loop_task = asyncio.create_task(self._run_pf_loop())
|
||||||
# 添加完成回调
|
# 添加完成回调
|
||||||
self._loop_task.add_done_callback(self._handle_loop_completion)
|
self._loop_task.add_done_callback(self._handle_loop_completion)
|
||||||
# else:
|
# else:
|
||||||
# logger.trace(f"{log_prefix} 不需要启动循环(已激活或计时器为0)") # 可以取消注释以进行调试
|
# logger.trace(f"{log_prefix} 不需要启动循环(已激活)") # 可以取消注释以进行调试
|
||||||
|
|
||||||
def _handle_loop_completion(self, task: asyncio.Task):
|
def _handle_loop_completion(self, task: asyncio.Task):
|
||||||
"""当 _run_pf_loop 任务完成时执行的回调。"""
|
"""当 _run_pf_loop 任务完成时执行的回调。"""
|
||||||
@@ -223,47 +190,38 @@ class HeartFChatting:
|
|||||||
logger.error(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天(异常): {exception}")
|
logger.error(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天(异常): {exception}")
|
||||||
logger.error(traceback.format_exc()) # Log full traceback for exceptions
|
logger.error(traceback.format_exc()) # Log full traceback for exceptions
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天 (正常完成)")
|
# Loop completing normally now means it was cancelled/shutdown externally
|
||||||
|
logger.info(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天 (外部停止)")
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天(任务取消)")
|
logger.info(f"{log_prefix} HeartFChatting: 麦麦脱离了聊天(任务取消)")
|
||||||
finally:
|
finally:
|
||||||
self._loop_active = False
|
self._loop_active = False
|
||||||
self._loop_task = None
|
self._loop_task = None
|
||||||
self._last_added_duration = self._initial_duration
|
|
||||||
self._trigger_count_this_activation = 0
|
|
||||||
if self._processing_lock.locked():
|
if self._processing_lock.locked():
|
||||||
logger.warning(f"{log_prefix} HeartFChatting: 处理锁在循环结束时仍被锁定,强制释放。")
|
logger.warning(f"{log_prefix} HeartFChatting: 处理锁在循环结束时仍被锁定,强制释放。")
|
||||||
self._processing_lock.release()
|
self._processing_lock.release()
|
||||||
|
|
||||||
async def _run_pf_loop(self):
|
async def _run_pf_loop(self):
|
||||||
"""
|
"""
|
||||||
主循环,当计时器>0时持续进行计划并可能回复消息
|
主循环,持续进行计划并可能回复消息,直到被外部取消。
|
||||||
管理每个循环周期的处理锁
|
管理每个循环周期的处理锁。
|
||||||
"""
|
"""
|
||||||
log_prefix = self._get_log_prefix()
|
log_prefix = self._get_log_prefix()
|
||||||
logger.info(f"{log_prefix} HeartFChatting: 麦麦打算好好聊聊 (定时器: {self._loop_timer:.1f}s)")
|
logger.info(f"{log_prefix} HeartFChatting: 麦麦打算好好聊聊 (进入专注模式)")
|
||||||
try:
|
try:
|
||||||
thinking_id = ""
|
thinking_id = ""
|
||||||
while True:
|
while True: # Loop indefinitely until cancelled
|
||||||
cycle_timers = {} # <--- Initialize timers dict for this cycle
|
cycle_timers = {} # <--- Initialize timers dict for this cycle
|
||||||
|
|
||||||
# Access MessageManager directly
|
# Access MessageManager directly
|
||||||
if message_manager.check_if_sending_message_exist(self.stream_id, thinking_id):
|
if message_manager.check_if_sending_message_exist(self.stream_id, thinking_id):
|
||||||
# logger.info(f"{log_prefix} HeartFChatting: 11111111111111111111111111111111麦麦还在发消息,等会再规划")
|
# logger.info(f"{log_prefix} HeartFChatting: 麦麦还在发消息,等会再规划")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# logger.info(f"{log_prefix} HeartFChatting: 11111111111111111111111111111111麦麦不发消息了,开始规划")
|
# logger.info(f"{log_prefix} HeartFChatting: 麦麦不发消息了,开始规划")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async with self._timer_lock:
|
|
||||||
current_timer = self._loop_timer
|
|
||||||
if current_timer <= 0:
|
|
||||||
logger.info(
|
|
||||||
f"{log_prefix} HeartFChatting: 聊太久了,麦麦打算休息一下 (计时器为 {current_timer:.1f}s)。退出HeartFChatting。"
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
# 记录循环周期开始时间,用于计时和休眠计算
|
# 记录循环周期开始时间,用于计时和休眠计算
|
||||||
loop_cycle_start_time = time.monotonic()
|
loop_cycle_start_time = time.monotonic()
|
||||||
action_taken_this_cycle = False
|
action_taken_this_cycle = False
|
||||||
@@ -296,7 +254,7 @@ class HeartFChatting:
|
|||||||
logger.error(f"{log_prefix} Planner LLM 失败,跳过本周期回复尝试。理由: {reasoning}")
|
logger.error(f"{log_prefix} Planner LLM 失败,跳过本周期回复尝试。理由: {reasoning}")
|
||||||
# Optionally add a longer sleep?
|
# Optionally add a longer sleep?
|
||||||
action_taken_this_cycle = False # Ensure no action is counted
|
action_taken_this_cycle = False # Ensure no action is counted
|
||||||
# Continue to timer decrement and sleep
|
# Continue to sleep logic
|
||||||
|
|
||||||
elif action == "text_reply":
|
elif action == "text_reply":
|
||||||
logger.debug(f"{log_prefix} HeartFChatting: 麦麦决定回复文本. 理由: {reasoning}")
|
logger.debug(f"{log_prefix} HeartFChatting: 麦麦决定回复文本. 理由: {reasoning}")
|
||||||
@@ -371,11 +329,11 @@ class HeartFChatting:
|
|||||||
with Timer("Wait New Msg", cycle_timers): # <--- Start Wait timer
|
with Timer("Wait New Msg", cycle_timers): # <--- Start Wait timer
|
||||||
wait_start_time = time.monotonic()
|
wait_start_time = time.monotonic()
|
||||||
while True:
|
while True:
|
||||||
# 检查计时器是否耗尽
|
# Removed timer check within wait loop
|
||||||
async with self._timer_lock:
|
# async with self._timer_lock:
|
||||||
if self._loop_timer <= 0:
|
# if self._loop_timer <= 0:
|
||||||
logger.info(f"{log_prefix} HeartFChatting: 等待新消息时计时器耗尽。")
|
# logger.info(f"{log_prefix} HeartFChatting: 等待新消息时计时器耗尽。")
|
||||||
break # 计时器耗尽,退出等待
|
# break # 计时器耗尽,退出等待
|
||||||
|
|
||||||
# 检查是否有新消息
|
# 检查是否有新消息
|
||||||
has_new = await observation.has_new_messages_since(planner_start_db_time)
|
has_new = await observation.has_new_messages_since(planner_start_db_time)
|
||||||
@@ -421,7 +379,7 @@ class HeartFChatting:
|
|||||||
if timer_strings: # 如果有有效计时器数据才打印
|
if timer_strings: # 如果有有效计时器数据才打印
|
||||||
logger.debug(f"{log_prefix} 该次决策耗时: {'; '.join(timer_strings)}")
|
logger.debug(f"{log_prefix} 该次决策耗时: {'; '.join(timer_strings)}")
|
||||||
|
|
||||||
# --- Timer Decrement --- #
|
# --- Timer Decrement Removed --- #
|
||||||
cycle_duration = time.monotonic() - loop_cycle_start_time
|
cycle_duration = time.monotonic() - loop_cycle_start_time
|
||||||
|
|
||||||
except Exception as e_cycle:
|
except Exception as e_cycle:
|
||||||
@@ -437,20 +395,24 @@ class HeartFChatting:
|
|||||||
self._processing_lock.release()
|
self._processing_lock.release()
|
||||||
# logger.trace(f"{log_prefix} 循环释放了处理锁.") # Reduce noise
|
# logger.trace(f"{log_prefix} 循环释放了处理锁.") # Reduce noise
|
||||||
|
|
||||||
async with self._timer_lock:
|
# --- Timer Decrement Logging Removed ---
|
||||||
self._loop_timer -= cycle_duration
|
# async with self._timer_lock:
|
||||||
# Log timer decrement less aggressively
|
# self._loop_timer -= cycle_duration
|
||||||
if cycle_duration > 0.1 or not action_taken_this_cycle:
|
# # Log timer decrement less aggressively
|
||||||
logger.debug(
|
# if cycle_duration > 0.1 or not action_taken_this_cycle:
|
||||||
f"{log_prefix} HeartFChatting: 周期耗时 {cycle_duration:.2f}s. 剩余时间: {self._loop_timer:.1f}s."
|
# logger.debug(
|
||||||
)
|
# f"{log_prefix} HeartFChatting: 周期耗时 {cycle_duration:.2f}s. 剩余时间: {self._loop_timer:.1f}s."
|
||||||
|
# )
|
||||||
|
if cycle_duration > 0.1:
|
||||||
|
logger.debug(f"{log_prefix} HeartFChatting: 周期耗时 {cycle_duration:.2f}s.")
|
||||||
|
|
||||||
|
|
||||||
# --- Delay --- #
|
# --- Delay --- #
|
||||||
try:
|
try:
|
||||||
sleep_duration = 0.0
|
sleep_duration = 0.0
|
||||||
if not action_taken_this_cycle and cycle_duration < 1.5:
|
if not action_taken_this_cycle and cycle_duration < 1.5:
|
||||||
sleep_duration = 1.5 - cycle_duration
|
sleep_duration = 1.5 - cycle_duration
|
||||||
elif cycle_duration < 0.2:
|
elif cycle_duration < 0.2: # Keep minimal sleep even after action
|
||||||
sleep_duration = 0.2
|
sleep_duration = 0.2
|
||||||
|
|
||||||
if sleep_duration > 0:
|
if sleep_duration > 0:
|
||||||
@@ -459,7 +421,7 @@ class HeartFChatting:
|
|||||||
|
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info(f"{log_prefix} Sleep interrupted, loop likely cancelling.")
|
logger.info(f"{log_prefix} Sleep interrupted, loop likely cancelling.")
|
||||||
break
|
break # Exit loop immediately on cancellation
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info(f"{log_prefix} HeartFChatting: 麦麦的聊天主循环被取消了")
|
logger.info(f"{log_prefix} HeartFChatting: 麦麦的聊天主循环被取消了")
|
||||||
|
|||||||
Reference in New Issue
Block a user