fix:修复hfc根本不会被触发的bug
This commit is contained in:
@@ -3,7 +3,7 @@ from ...config.config import global_config
|
||||
from .message import MessageRecv
|
||||
from ..PFC.pfc_manager import PFCManager
|
||||
from .chat_stream import chat_manager
|
||||
from ..chat_module.only_process.only_message_process import MessageProcessor
|
||||
from .only_message_process import MessageProcessor
|
||||
|
||||
from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig
|
||||
from ..heartFC_chat.heartflow_processor import HeartFCProcessor
|
||||
|
||||
@@ -13,9 +13,7 @@ from src.plugins.models.utils_model import LLMRequest
|
||||
from src.config.config import global_config
|
||||
from src.plugins.chat.utils_image import image_path_to_base64 # Local import needed after move
|
||||
from src.plugins.utils.timer_calculater import Timer # <--- Import Timer
|
||||
|
||||
# --- Import necessary dependencies directly ---
|
||||
from .heartFC_generator import ResponseGenerator # Assuming this is the type for gpt
|
||||
from src.plugins.heartFC_chat.heartFC_generator import HeartFCGenerator
|
||||
from src.do_tool.tool_use import ToolUser
|
||||
from ..chat.message_sender import message_manager # <-- Import the global manager
|
||||
from src.plugins.chat.emoji_manager import emoji_manager
|
||||
@@ -77,9 +75,7 @@ class HeartFChatting:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
chat_id: str,
|
||||
gpt_instance: ResponseGenerator, # 文本回复生成器
|
||||
tool_user_instance: ToolUser, # 工具使用实例
|
||||
chat_id: str
|
||||
):
|
||||
"""
|
||||
HeartFChatting 初始化函数
|
||||
@@ -97,13 +93,12 @@ class HeartFChatting:
|
||||
|
||||
# 初始化状态控制
|
||||
self._initialized = False # 是否已初始化标志
|
||||
self._init_lock = asyncio.Lock() # 初始化锁(确保只初始化一次)
|
||||
self._processing_lock = asyncio.Lock() # 处理锁(确保单次Plan-Replier-Sender周期)
|
||||
self._timer_lock = asyncio.Lock() # 计时器锁(安全更新计时器)
|
||||
|
||||
# 依赖注入存储
|
||||
self.gpt_instance = gpt_instance # 文本回复生成器
|
||||
self.tool_user = tool_user_instance # 工具使用实例
|
||||
self.gpt_instance = HeartFCGenerator() # 文本回复生成器
|
||||
self.tool_user = ToolUser() # 工具使用实例
|
||||
|
||||
# LLM规划器配置
|
||||
self.planner_llm = LLMRequest(
|
||||
@@ -117,7 +112,6 @@ class HeartFChatting:
|
||||
self._loop_timer: float = 0.0 # 循环剩余时间(秒)
|
||||
self._loop_active: bool = False # 循环是否正在运行
|
||||
self._loop_task: Optional[asyncio.Task] = None # 主循环任务
|
||||
self._trigger_count_this_activation: int = 0 # 当前激活周期内的触发计数
|
||||
self._initial_duration: float = INITIAL_DURATION # 首次触发增加的时间
|
||||
self._last_added_duration: float = self._initial_duration # 上次增加的时间
|
||||
|
||||
@@ -131,35 +125,34 @@ class HeartFChatting:
|
||||
懒初始化以使用提供的标识符解析chat_stream和sub_hf。
|
||||
确保实例已准备好处理触发器。
|
||||
"""
|
||||
async with self._init_lock:
|
||||
if self._initialized:
|
||||
return True
|
||||
log_prefix = self._get_log_prefix() # 获取前缀
|
||||
try:
|
||||
self.chat_stream = chat_manager.get_stream(self.stream_id)
|
||||
if self._initialized:
|
||||
return True
|
||||
log_prefix = self._get_log_prefix() # 获取前缀
|
||||
try:
|
||||
self.chat_stream = chat_manager.get_stream(self.stream_id)
|
||||
|
||||
if not self.chat_stream:
|
||||
logger.error(f"{log_prefix} 获取ChatStream失败。")
|
||||
return False
|
||||
|
||||
# <-- 在这里导入 heartflow 实例
|
||||
from src.heart_flow.heartflow import heartflow
|
||||
|
||||
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
||||
if not self.sub_hf:
|
||||
logger.warning(f"{log_prefix} 获取SubHeartflow失败。一些功能可能受限。")
|
||||
|
||||
self._initialized = True
|
||||
logger.info(f"麦麦感觉到了,激发了HeartFChatting{log_prefix} 初始化成功。")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"{log_prefix} 初始化失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
if not self.chat_stream:
|
||||
logger.error(f"{log_prefix} 获取ChatStream失败。")
|
||||
return False
|
||||
|
||||
# <-- 在这里导入 heartflow 实例
|
||||
from src.heart_flow.heartflow import heartflow
|
||||
|
||||
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
||||
if not self.sub_hf:
|
||||
logger.warning(f"{log_prefix} 获取SubHeartflow失败。一些功能可能受限。")
|
||||
|
||||
self._initialized = True
|
||||
logger.info(f"麦麦感觉到了,激发了HeartFChatting{log_prefix} 初始化成功。")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"{log_prefix} 初始化失败: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
async def add_time(self):
|
||||
"""
|
||||
为麦麦添加时间,麦麦有兴趣时,时间增加。
|
||||
为麦麦添加时间,麦麦有兴趣时,固定增加15秒
|
||||
"""
|
||||
log_prefix = self._get_log_prefix()
|
||||
if not self._initialized:
|
||||
@@ -168,45 +161,61 @@ class HeartFChatting:
|
||||
return
|
||||
|
||||
async with self._timer_lock:
|
||||
duration_to_add: float = 0.0
|
||||
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.")
|
||||
|
||||
if not self._loop_active: # First trigger for this activation cycle
|
||||
duration_to_add = self._initial_duration # 使用初始值
|
||||
self._last_added_duration = duration_to_add # 更新上次增加的值
|
||||
self._trigger_count_this_activation = 1 # Start counting
|
||||
logger.info(
|
||||
f"{log_prefix} 麦麦有兴趣! #{self._trigger_count_this_activation}. 麦麦打算聊: {duration_to_add:.2f}s."
|
||||
)
|
||||
else: # Loop is already active, apply 50% reduction
|
||||
self._trigger_count_this_activation += 1
|
||||
duration_to_add = self._last_added_duration * 0.5
|
||||
if duration_to_add < 1.5:
|
||||
duration_to_add = 1.5
|
||||
# Update _last_added_duration only if it's >= 0.5 to prevent it from becoming too small
|
||||
self._last_added_duration = duration_to_add
|
||||
logger.info(
|
||||
f"{log_prefix} 麦麦兴趣增加! #{self._trigger_count_this_activation}. 想继续聊: {duration_to_add:.2f}s, 麦麦还能聊: {self._loop_timer:.1f}s."
|
||||
)
|
||||
|
||||
# 添加计算出的时间
|
||||
# 添加固定时间
|
||||
new_timer_value = self._loop_timer + duration_to_add
|
||||
# Add max timer duration limit? e.g., max(0, min(new_timer_value, 300))
|
||||
self._loop_timer = max(0, new_timer_value)
|
||||
# Log less frequently, e.g., every 10 seconds or significant change?
|
||||
# if self._trigger_count_this_activation % 5 == 0:
|
||||
# logger.info(f"{log_prefix} 麦麦现在想聊{self._loop_timer:.1f}秒")
|
||||
|
||||
# Start the loop if it wasn't active and timer is positive
|
||||
# 添加时间后,检查是否需要启动循环
|
||||
await self._start_loop_if_needed()
|
||||
|
||||
async def start(self):
|
||||
"""
|
||||
显式尝试启动 HeartFChatting 的主循环。
|
||||
如果循环未激活且计时器 > 0,则启动循环。
|
||||
"""
|
||||
log_prefix = self._get_log_prefix()
|
||||
if not self._initialized:
|
||||
if not await self._initialize():
|
||||
logger.error(f"{log_prefix} 无法启动循环: 初始化失败。")
|
||||
return
|
||||
logger.info(f"{log_prefix} 尝试显式启动循环...")
|
||||
await self._start_loop_if_needed()
|
||||
|
||||
async def _start_loop_if_needed(self):
|
||||
"""检查是否需要启动主循环,如果未激活且计时器大于0,则启动。"""
|
||||
log_prefix = self._get_log_prefix()
|
||||
should_start_loop = False
|
||||
async with self._timer_lock:
|
||||
# 检查是否满足启动条件:未激活且计时器有时间
|
||||
if not self._loop_active and self._loop_timer > 0:
|
||||
self._loop_active = True
|
||||
if self._loop_task and not self._loop_task.done():
|
||||
logger.warning(f"{log_prefix} 发现意外的循环任务正在进行。取消它。")
|
||||
self._loop_task.cancel()
|
||||
should_start_loop = True
|
||||
self._loop_active = True # 在锁内标记为活动,防止重复启动
|
||||
|
||||
self._loop_task = asyncio.create_task(self._run_pf_loop())
|
||||
self._loop_task.add_done_callback(self._handle_loop_completion)
|
||||
elif self._loop_active:
|
||||
logger.trace(f"{log_prefix} 循环已经激活。计时器延长。")
|
||||
if should_start_loop:
|
||||
# 检查是否已有任务在运行(理论上不应该,因为 _loop_active=False)
|
||||
if self._loop_task and not self._loop_task.done():
|
||||
logger.warning(f"{log_prefix} 发现之前的循环任务仍在运行(不符合预期)。取消旧任务。")
|
||||
self._loop_task.cancel()
|
||||
try:
|
||||
# 等待旧任务确实被取消
|
||||
await asyncio.wait_for(self._loop_task, timeout=0.5)
|
||||
except (asyncio.CancelledError, asyncio.TimeoutError):
|
||||
pass # 忽略取消或超时错误
|
||||
self._loop_task = None # 清理旧任务引用
|
||||
|
||||
logger.info(f"{log_prefix} 计时器 > 0 且循环未激活,启动主循环...")
|
||||
# 创建新的循环任务
|
||||
self._loop_task = asyncio.create_task(self._run_pf_loop())
|
||||
# 添加完成回调
|
||||
self._loop_task.add_done_callback(self._handle_loop_completion)
|
||||
# else:
|
||||
# logger.trace(f"{log_prefix} 不需要启动循环(已激活或计时器为0)") # 可以取消注释以进行调试
|
||||
|
||||
def _handle_loop_completion(self, task: asyncio.Task):
|
||||
"""当 _run_pf_loop 任务完成时执行的回调。"""
|
||||
@@ -228,8 +237,6 @@ class HeartFChatting:
|
||||
if self._processing_lock.locked():
|
||||
logger.warning(f"{log_prefix} HeartFChatting: 处理锁在循环结束时仍被锁定,强制释放。")
|
||||
self._processing_lock.release()
|
||||
# Instance removal is now handled by SubHeartflow
|
||||
# asyncio.create_task(self.heartfc_controller._remove_heartFC_chat_instance(self.stream_id)) # Removed
|
||||
|
||||
async def _run_pf_loop(self):
|
||||
"""
|
||||
|
||||
@@ -22,7 +22,7 @@ llm_config = LogConfig(
|
||||
logger = get_module_logger("llm_generator", config=llm_config)
|
||||
|
||||
|
||||
class ResponseGenerator:
|
||||
class HeartFCGenerator:
|
||||
def __init__(self):
|
||||
self.model_normal = LLMRequest(
|
||||
model=global_config.llm_normal,
|
||||
|
||||
@@ -67,11 +67,8 @@ class HeartFCProcessor:
|
||||
group_info=groupinfo,
|
||||
)
|
||||
|
||||
# --- 确保 SubHeartflow 存在 ---
|
||||
subheartflow = await heartflow.create_subheartflow(chat.stream_id)
|
||||
if not subheartflow:
|
||||
logger.error(f"无法为 stream_id {chat.stream_id} 创建或获取 SubHeartflow,中止处理")
|
||||
return
|
||||
|
||||
|
||||
message.update_chat_stream(chat)
|
||||
|
||||
@@ -137,33 +134,16 @@ class HeartFCProcessor:
|
||||
|
||||
# --- 修改:兴趣度更新逻辑 --- #
|
||||
if is_mentioned:
|
||||
interest_increase_on_mention = 2
|
||||
interest_increase_on_mention = 1
|
||||
mentioned_boost = interest_increase_on_mention # 从配置获取提及增加值
|
||||
interested_rate += mentioned_boost
|
||||
logger.trace(f"消息提及机器人,额外增加兴趣 {mentioned_boost:.2f}")
|
||||
|
||||
# 更新兴趣度 (调用 SubHeartflow 的方法)
|
||||
current_interest = 0.0 # 初始化
|
||||
try:
|
||||
# 获取当前时间,传递给 increase_interest
|
||||
current_time = time.time()
|
||||
await subheartflow.interest_chatting.increase_interest(current_time, value=interested_rate)
|
||||
current_interest = await subheartflow.get_interest_level() # 获取更新后的值
|
||||
current_time = time.time()
|
||||
await subheartflow.interest_chatting.increase_interest(current_time, value=interested_rate)
|
||||
|
||||
logger.trace(
|
||||
f"使用激活率 {interested_rate:.2f} 更新后 (通过缓冲后),当前兴趣度: {current_interest:.2f} (Stream: {chat.stream_id})"
|
||||
)
|
||||
|
||||
# 添加到 SubHeartflow 的 interest_dict
|
||||
await subheartflow.add_interest_dict_entry(message, interested_rate, is_mentioned)
|
||||
logger.trace(
|
||||
f"Message {message.message_info.message_id} added to interest dict for stream {chat.stream_id}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新兴趣度失败 (Stream: {chat.stream_id}): {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
# --- 结束修改 --- #
|
||||
# 添加到 SubHeartflow 的 interest_dict,给normal_chat处理
|
||||
await subheartflow.add_interest_dict_entry(message, interested_rate, is_mentioned)
|
||||
|
||||
# 打印消息接收和处理信息
|
||||
mes_name = chat.group_info.group_name if chat.group_info else "私聊"
|
||||
@@ -172,7 +152,7 @@ class HeartFCProcessor:
|
||||
f"[{current_time}][{mes_name}]"
|
||||
f"{chat.user_info.user_nickname}:"
|
||||
f"{message.processed_plain_text}"
|
||||
f"兴趣度: {current_interest:.2f}"
|
||||
f"[兴趣度: {interested_rate:.2f}]"
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -7,7 +7,7 @@ from typing import List, Optional # 导入 Optional
|
||||
from ..moods.moods import MoodManager
|
||||
from ...config.config import global_config
|
||||
from ..chat.emoji_manager import emoji_manager
|
||||
from .normal_chat_generator import ResponseGenerator
|
||||
from .normal_chat_generator import NormalChatGenerator
|
||||
from ..chat.message import MessageSending, MessageRecv, MessageThinking, MessageSet
|
||||
from ..chat.message_sender import message_manager
|
||||
from ..chat.utils_image import image_path_to_base64
|
||||
@@ -43,12 +43,10 @@ class NormalChat:
|
||||
|
||||
self.interest_dict = interest_dict
|
||||
|
||||
logger.info(f"[{self.stream_name}] 正在初始化 NormalChat 实例...")
|
||||
|
||||
self.gpt = ResponseGenerator()
|
||||
self.gpt = NormalChatGenerator()
|
||||
self.mood_manager = MoodManager.get_instance() # MoodManager 保持单例
|
||||
# 存储此实例的兴趣监控任务
|
||||
self._interest_monitoring_task: Optional[asyncio.Task] = None
|
||||
self._chat_task: Optional[asyncio.Task] = None
|
||||
logger.info(f"[{self.stream_name}] NormalChat 实例初始化完成。")
|
||||
|
||||
# 改为实例方法
|
||||
@@ -73,7 +71,6 @@ class NormalChat:
|
||||
)
|
||||
|
||||
await message_manager.add_message(thinking_message)
|
||||
|
||||
return thinking_id
|
||||
|
||||
# 改为实例方法
|
||||
@@ -176,7 +173,7 @@ class NormalChat:
|
||||
await asyncio.sleep(1) # 每秒检查一次
|
||||
|
||||
# 检查任务是否已被取消
|
||||
if self._interest_monitoring_task is None or self._interest_monitoring_task.cancelled():
|
||||
if self._chat_task is None or self._chat_task.cancelled():
|
||||
logger.info(f"[{self.stream_name}] 兴趣监控任务被取消或置空,退出")
|
||||
break
|
||||
|
||||
@@ -352,19 +349,21 @@ class NormalChat:
|
||||
return False
|
||||
|
||||
# 改为实例方法, 移除 chat 参数
|
||||
async def start_monitoring_interest(self):
|
||||
"""为此 NormalChat 实例关联的 ChatStream 启动兴趣消息监控任务(如果尚未运行)。"""
|
||||
if self._interest_monitoring_task is None or self._interest_monitoring_task.done():
|
||||
logger.info(f"[{self.stream_name}] 启动兴趣消息监控任务...")
|
||||
|
||||
async def start_chat(self):
|
||||
"""为此 NormalChat 实例关联的 ChatStream 启动聊天任务(如果尚未运行)。"""
|
||||
if self._chat_task is None or self._chat_task.done():
|
||||
logger.info(f"[{self.stream_name}] 启动聊天任务...")
|
||||
task = asyncio.create_task(self._find_interested_message())
|
||||
task.add_done_callback(lambda t: self._handle_task_completion(t)) # 回调现在是实例方法
|
||||
self._interest_monitoring_task = task
|
||||
self._chat_task = task
|
||||
|
||||
|
||||
# 改为实例方法, 移除 stream_id 参数
|
||||
def _handle_task_completion(self, task: asyncio.Task):
|
||||
"""兴趣监控任务完成时的回调函数。"""
|
||||
# 检查完成的任务是否是当前实例的任务
|
||||
if task is not self._interest_monitoring_task:
|
||||
if task is not self._chat_task:
|
||||
logger.warning(f"[{self.stream_name}] 收到一个未知或过时任务的完成回调。")
|
||||
return
|
||||
|
||||
@@ -382,27 +381,26 @@ class NormalChat:
|
||||
logger.error(f"[{self.stream_name}] 处理任务完成回调时出错: {e}")
|
||||
finally:
|
||||
# 标记任务已完成/移除
|
||||
if self._interest_monitoring_task is task: # 再次确认是当前任务
|
||||
self._interest_monitoring_task = None
|
||||
logger.debug(f"[{self.stream_name}] 兴趣监控任务已被标记为完成/移除。")
|
||||
if self._chat_task is task: # 再次确认是当前任务
|
||||
self._chat_task = None
|
||||
logger.debug(f"[{self.stream_name}] 聊天任务已被标记为完成/移除。")
|
||||
|
||||
# 改为实例方法, 移除 stream_id 参数
|
||||
async def stop_monitoring_interest(self):
|
||||
async def stop_chat(self):
|
||||
"""停止当前实例的兴趣监控任务。"""
|
||||
if self._interest_monitoring_task and not self._interest_monitoring_task.done():
|
||||
task = self._interest_monitoring_task
|
||||
logger.info(f"[{self.stream_name}] 尝试取消兴趣监控任务。")
|
||||
if self._chat_task and not self._chat_task.done():
|
||||
task = self._chat_task
|
||||
logger.info(f"[{self.stream_name}] 尝试取消聊天任务。")
|
||||
task.cancel()
|
||||
try:
|
||||
await task # 等待任务响应取消
|
||||
except asyncio.CancelledError:
|
||||
logger.info(f"[{self.stream_name}] 兴趣监控任务已成功取消。")
|
||||
logger.info(f"[{self.stream_name}] 聊天任务已成功取消。")
|
||||
except Exception as e:
|
||||
# 回调函数 _handle_task_completion 会处理异常日志
|
||||
logger.warning(f"[{self.stream_name}] 等待监控任务取消时捕获到异常 (可能已在回调中记录): {e}")
|
||||
finally:
|
||||
# 确保任务状态更新,即使等待出错 (回调函数也会尝试更新)
|
||||
if self._interest_monitoring_task is task:
|
||||
self._interest_monitoring_task = None
|
||||
# else:
|
||||
# logger.debug(f"[{self.stream_name}] 没有正在运行的兴趣监控任务可停止。")
|
||||
if self._chat_task is task:
|
||||
self._chat_task = None
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ llm_config = LogConfig(
|
||||
logger = get_module_logger("llm_generator", config=llm_config)
|
||||
|
||||
|
||||
class ResponseGenerator:
|
||||
class NormalChatGenerator:
|
||||
def __init__(self):
|
||||
self.model_reasoning = LLMRequest(
|
||||
model=global_config.llm_reasoning,
|
||||
@@ -77,8 +77,6 @@ class ResponseGenerator:
|
||||
sender_name = f"({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}"
|
||||
else:
|
||||
sender_name = f"用户({message.chat_stream.user_info.user_id})"
|
||||
|
||||
logger.debug("开始使用生成回复-2")
|
||||
# 构建prompt
|
||||
with Timer() as t_build_prompt:
|
||||
prompt = await prompt_builder.build_prompt(
|
||||
|
||||
Reference in New Issue
Block a user