refactor(chat): 重构主动思考逻辑并将其集成到主聊天循环

将原有的 `ProactiveThinker` 类中的逻辑直接整合进 `HeartFChatting` 类中。此举简化了整体架构,减少了类之间的耦合,并使得主动思考的触发机制与主聊天循环的状态管理更加统一。

主要变更:
- 删除了独立的 `proactive_thinker.py` 文件。
- 将主动思考的监控循环、条件检查、动态间隔计算等功能实现为 `HeartFChatting` 的私有方法。
- 引入了 `ProactiveTriggerEvent` 事件,使触发源更加明确。
- 调整了相关模块的导入路径和配置项的调用方式,以适应新的结构。
This commit is contained in:
minecraft1024a
2025-09-05 20:30:35 +08:00
parent fc68958c8f
commit 488e959577
6 changed files with 255 additions and 367 deletions

View File

@@ -0,0 +1,11 @@
from dataclasses import dataclass, field
from typing import Optional, Dict, Any
@dataclass
class ProactiveTriggerEvent:
"""
主动思考触发事件的数据类
"""
source: str # 触发源的标识,例如 "silence_monitor", "insomnia_manager"
reason: str # 触发的具体原因,例如 "聊天已沉默10分钟", "深夜emo"
metadata: Optional[Dict[str, Any]] = field(default_factory=dict) # 可选的元数据,用于传递额外信息

View File

@@ -0,0 +1,125 @@
import time
import traceback
from typing import TYPE_CHECKING
from src.common.logger import get_logger
from src.plugin_system.base.component_types import ChatMode
from ..hfc_context import HfcContext
from .events import ProactiveTriggerEvent
if TYPE_CHECKING:
from ..cycle_processor import CycleProcessor
logger = get_logger("hfc")
class ProactiveThinker:
def __init__(self, context: HfcContext, cycle_processor: "CycleProcessor"):
"""
初始化主动思考器
Args:
context: HFC聊天上下文对象
cycle_processor: 循环处理器,用于执行主动思考的结果
功能说明:
- 接收主动思考事件并执行思考流程
- 根据事件类型执行不同的前置操作(如修改情绪)
- 调用planner进行决策并由cycle_processor执行
"""
self.context = context
self.cycle_processor = cycle_processor
async def think(self, trigger_event: ProactiveTriggerEvent):
"""
统一的API入口用于触发主动思考
Args:
trigger_event: 描述触发上下文的事件对象
"""
logger.info(f"{self.context.log_prefix} 接收到主动思考事件: "
f"来源='{trigger_event.source}', 原因='{trigger_event.reason}'")
try:
# 1. 根据事件类型执行前置操作
await self._prepare_for_thinking(trigger_event)
# 2. 执行核心思考逻辑
await self._execute_proactive_thinking(trigger_event)
except Exception as e:
logger.error(f"{self.context.log_prefix} 主动思考 think 方法执行异常: {e}")
logger.error(traceback.format_exc())
async def _prepare_for_thinking(self, trigger_event: ProactiveTriggerEvent):
"""
根据事件类型,执行思考前的准备工作,例如修改情绪
Args:
trigger_event: 触发事件
"""
if trigger_event.source != "insomnia_manager":
return
try:
from src.mood.mood_manager import mood_manager
mood_obj = mood_manager.get_mood_by_chat_id(self.context.stream_id)
new_mood = None
if trigger_event.reason == "low_pressure":
new_mood = "精力过剩,毫无睡意"
elif trigger_event.reason == "random":
new_mood = "深夜emo胡思乱想"
elif trigger_event.reason == "goodnight":
new_mood = "有点困了,准备睡觉了"
if new_mood:
mood_obj.mood_state = new_mood
mood_obj.last_change_time = time.time()
logger.info(f"{self.context.log_prefix}'{trigger_event.reason}'"
f"情绪状态被强制更新为: {mood_obj.mood_state}")
except Exception as e:
logger.error(f"{self.context.log_prefix} 设置失眠情绪时出错: {e}")
async def _execute_proactive_thinking(self, trigger_event: ProactiveTriggerEvent):
"""
执行主动思考的核心逻辑
Args:
trigger_event: 触发事件
"""
try:
# 直接调用 planner 的 PROACTIVE 模式
actions, target_message = await self.cycle_processor.action_planner.plan(
mode=ChatMode.PROACTIVE
)
# 获取第一个规划出的动作作为主要决策
action_result = actions[0] if actions else {}
# 如果决策不是 do_nothing则执行
if action_result and action_result.get("action_type") != "do_nothing":
# 在主动思考时,如果 target_message 为 None则默认选取最新 message 作为 target_message
if target_message is None and self.context.chat_stream and self.context.chat_stream.context:
from src.chat.message_receive.message import MessageRecv
latest_message = self.context.chat_stream.context.get_last_message()
if isinstance(latest_message, MessageRecv):
user_info = latest_message.message_info.user_info
target_message = {
"chat_info_platform": latest_message.message_info.platform,
"user_platform": user_info.platform if user_info else None,
"user_id": user_info.user_id if user_info else None,
"processed_plain_text": latest_message.processed_plain_text,
"is_mentioned": latest_message.is_mentioned,
}
# 将决策结果交给 cycle_processor 的后续流程处理
await self.cycle_processor.execute_plan(action_result, target_message)
else:
logger.info(f"{self.context.log_prefix} 主动思考决策: 保持沉默")
except Exception as e:
logger.error(f"{self.context.log_prefix} 主动思考执行异常: {e}")
logger.error(traceback.format_exc())