🤖 自动格式化代码 [skip ci]
This commit is contained in:
@@ -24,7 +24,9 @@ class ToolUser:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _build_tool_prompt(message_txt: str, chat_stream: ChatStream = None, observation: ChattingObservation = None):
|
async def _build_tool_prompt(
|
||||||
|
message_txt: str, chat_stream: ChatStream = None, observation: ChattingObservation = None
|
||||||
|
):
|
||||||
"""构建工具使用的提示词
|
"""构建工具使用的提示词
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ import enum
|
|||||||
import os # 新增
|
import os # 新增
|
||||||
import json # 新增
|
import json # 新增
|
||||||
from src.plugins.chat.chat_stream import chat_manager # 新增
|
from src.plugins.chat.chat_stream import chat_manager # 新增
|
||||||
|
|
||||||
# --- Add imports for merged dependencies ---
|
# --- Add imports for merged dependencies ---
|
||||||
from src.plugins.heartFC_chat.heartFC_generator import ResponseGenerator
|
from src.plugins.heartFC_chat.heartFC_generator import ResponseGenerator
|
||||||
from src.do_tool.tool_use import ToolUser
|
from src.do_tool.tool_use import ToolUser
|
||||||
from src.plugins.chat.emoji_manager import emoji_manager # Module instance
|
from src.plugins.chat.emoji_manager import emoji_manager # Module instance
|
||||||
from src.plugins.person_info.relationship_manager import relationship_manager # Module instance
|
from src.plugins.person_info.relationship_manager import relationship_manager # Module instance
|
||||||
# --- End imports ---
|
# --- End imports ---
|
||||||
|
|
||||||
heartflow_config = LogConfig(
|
heartflow_config = LogConfig(
|
||||||
@@ -31,9 +32,10 @@ logger = get_module_logger("heartflow", config=heartflow_config)
|
|||||||
|
|
||||||
# Type hinting for circular dependency
|
# Type hinting for circular dependency
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from src.heart_flow.sub_heartflow import SubHeartflow, ChatState # Keep SubHeartflow here too
|
from src.heart_flow.sub_heartflow import SubHeartflow, ChatState # Keep SubHeartflow here too
|
||||||
# from src.plugins.heartFC_chat.heartFC_controler import HeartFCController # No longer needed
|
# from src.plugins.heartFC_chat.heartFC_controler import HeartFCController # No longer needed
|
||||||
|
|
||||||
|
|
||||||
def init_prompt():
|
def init_prompt():
|
||||||
prompt = ""
|
prompt = ""
|
||||||
prompt += "你刚刚在做的事情是:{schedule_info}\n"
|
prompt += "你刚刚在做的事情是:{schedule_info}\n"
|
||||||
@@ -64,7 +66,7 @@ LOG_INTERVAL_SECONDS = 3 # 日志记录间隔 (例如:3秒) - 保持与 inter
|
|||||||
# --- 结束新增常量 ---
|
# --- 结束新增常量 ---
|
||||||
|
|
||||||
# --- 新增:状态更新常量 ---
|
# --- 新增:状态更新常量 ---
|
||||||
STATE_UPDATE_INTERVAL_SECONDS = 30 # 状态更新检查间隔(秒)
|
STATE_UPDATE_INTERVAL_SECONDS = 30 # 状态更新检查间隔(秒)
|
||||||
FIVE_MINUTES = 1 * 60
|
FIVE_MINUTES = 1 * 60
|
||||||
FIFTEEN_MINUTES = 5 * 60
|
FIFTEEN_MINUTES = 5 * 60
|
||||||
TWENTY_MINUTES = 10 * 60
|
TWENTY_MINUTES = 10 * 60
|
||||||
@@ -109,12 +111,11 @@ class MaiState(enum.Enum):
|
|||||||
|
|
||||||
class MaiStateInfo:
|
class MaiStateInfo:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
# 使用枚举类型初始化状态,默认为正常聊天
|
# 使用枚举类型初始化状态,默认为正常聊天
|
||||||
self.mai_status: MaiState = MaiState.OFFLINE
|
self.mai_status: MaiState = MaiState.OFFLINE
|
||||||
self.mai_status_history = [] # 历史状态,包含 状态,最后时间
|
self.mai_status_history = [] # 历史状态,包含 状态,最后时间
|
||||||
self.last_status_change_time: float = time.time() # 新增:状态最后改变时间
|
self.last_status_change_time: float = time.time() # 新增:状态最后改变时间
|
||||||
self.last_5min_check_time: float = time.time() # 新增:上次5分钟规则检查时间
|
self.last_5min_check_time: float = time.time() # 新增:上次5分钟规则检查时间
|
||||||
|
|
||||||
self.normal_chatting = []
|
self.normal_chatting = []
|
||||||
self.focused_chatting = []
|
self.focused_chatting = []
|
||||||
@@ -125,11 +126,11 @@ class MaiStateInfo:
|
|||||||
# 新增更新聊天状态的方法
|
# 新增更新聊天状态的方法
|
||||||
def update_mai_status(self, new_status: MaiState):
|
def update_mai_status(self, new_status: MaiState):
|
||||||
"""更新聊天状态"""
|
"""更新聊天状态"""
|
||||||
if isinstance(new_status, MaiState) and new_status != self.mai_status: # 只有状态实际改变时才更新
|
if isinstance(new_status, MaiState) and new_status != self.mai_status: # 只有状态实际改变时才更新
|
||||||
self.mai_status = new_status
|
self.mai_status = new_status
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
self.last_status_change_time = current_time # 更新状态改变时间
|
self.last_status_change_time = current_time # 更新状态改变时间
|
||||||
self.last_5min_check_time = current_time # 重置5分钟检查计时器
|
self.last_5min_check_time = current_time # 重置5分钟检查计时器
|
||||||
# 将新状态和时间戳添加到历史记录
|
# 将新状态和时间戳添加到历史记录
|
||||||
self.mai_status_history.append((new_status, current_time))
|
self.mai_status_history.append((new_status, current_time))
|
||||||
logger.info(f"麦麦状态更新为: {self.mai_status.value}")
|
logger.info(f"麦麦状态更新为: {self.mai_status.value}")
|
||||||
@@ -148,14 +149,16 @@ class Heartflow:
|
|||||||
model=global_config.llm_heartflow, temperature=0.6, max_tokens=1000, request_type="heart_flow"
|
model=global_config.llm_heartflow, temperature=0.6, max_tokens=1000, request_type="heart_flow"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._subheartflows: Dict[Any, 'SubHeartflow'] = {} # Update type hint
|
self._subheartflows: Dict[Any, "SubHeartflow"] = {} # Update type hint
|
||||||
|
|
||||||
# --- Dependencies moved from HeartFCController ---
|
# --- Dependencies moved from HeartFCController ---
|
||||||
self.gpt_instance = ResponseGenerator()
|
self.gpt_instance = ResponseGenerator()
|
||||||
self.mood_manager = MoodManager.get_instance() # Note: MaiStateInfo also has one, consider consolidating later if needed
|
self.mood_manager = (
|
||||||
|
MoodManager.get_instance()
|
||||||
|
) # Note: MaiStateInfo also has one, consider consolidating later if needed
|
||||||
self.tool_user_instance = ToolUser()
|
self.tool_user_instance = ToolUser()
|
||||||
self.emoji_manager_instance = emoji_manager # Module instance
|
self.emoji_manager_instance = emoji_manager # Module instance
|
||||||
self.relationship_manager_instance = relationship_manager # Module instance
|
self.relationship_manager_instance = relationship_manager # Module instance
|
||||||
# --- End moved dependencies ---
|
# --- End moved dependencies ---
|
||||||
|
|
||||||
# --- Background Task Management ---
|
# --- Background Task Management ---
|
||||||
@@ -163,7 +166,7 @@ class Heartflow:
|
|||||||
self._ensure_log_directory() # 初始化时确保目录存在
|
self._ensure_log_directory() # 初始化时确保目录存在
|
||||||
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._state_update_task: Optional[asyncio.Task] = None # 新增:状态更新任务
|
self._state_update_task: Optional[asyncio.Task] = None # 新增:状态更新任务
|
||||||
# 注意:衰减任务 (_decay_task) 不再需要,衰减在 SubHeartflow 的 InterestChatting 内部处理
|
# 注意:衰减任务 (_decay_task) 不再需要,衰减在 SubHeartflow 的 InterestChatting 内部处理
|
||||||
# --- End moved dependencies ---
|
# --- End moved dependencies ---
|
||||||
|
|
||||||
@@ -243,24 +246,24 @@ class Heartflow:
|
|||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
# 获取更新前的状态
|
# 获取更新前的状态
|
||||||
previous_status = self.current_state.mai_status
|
previous_status = self.current_state.mai_status
|
||||||
current_status = self.current_state.mai_status # 保持此行以进行后续逻辑
|
current_status = self.current_state.mai_status # 保持此行以进行后续逻辑
|
||||||
time_in_current_status = current_time - self.current_state.last_status_change_time
|
time_in_current_status = current_time - self.current_state.last_status_change_time
|
||||||
time_since_last_5min_check = current_time - self.current_state.last_5min_check_time
|
time_since_last_5min_check = current_time - self.current_state.last_5min_check_time
|
||||||
next_state = None # 预设下一状态为 None
|
next_state = None # 预设下一状态为 None
|
||||||
|
|
||||||
# --- 状态转换逻辑 (保持不变) ---
|
# --- 状态转换逻辑 (保持不变) ---
|
||||||
# 1. 通用规则:每5分钟检查 (对于非 OFFLINE 状态)
|
# 1. 通用规则:每5分钟检查 (对于非 OFFLINE 状态)
|
||||||
if time_since_last_5min_check >= FIVE_MINUTES:
|
if time_since_last_5min_check >= FIVE_MINUTES:
|
||||||
self.current_state.last_5min_check_time = current_time # 重置5分钟检查计时器(无论是否切换)
|
self.current_state.last_5min_check_time = current_time # 重置5分钟检查计时器(无论是否切换)
|
||||||
if current_status != MaiState.OFFLINE:
|
if current_status != MaiState.OFFLINE:
|
||||||
if random.random() < 0.10: # 10% 概率切换到 OFFLINE
|
if random.random() < 0.10: # 10% 概率切换到 OFFLINE
|
||||||
logger.debug(f"[Heartflow State] 触发5分钟规则,从 {current_status.value} 切换到 OFFLINE")
|
logger.debug(f"[Heartflow State] 触发5分钟规则,从 {current_status.value} 切换到 OFFLINE")
|
||||||
next_state = MaiState.OFFLINE # 设置 next_state 而不是直接更新
|
next_state = MaiState.OFFLINE # 设置 next_state 而不是直接更新
|
||||||
# self.current_state.update_mai_status(MaiState.OFFLINE)
|
# self.current_state.update_mai_status(MaiState.OFFLINE)
|
||||||
# continue # 状态已改变,进入下一轮循环
|
# continue # 状态已改变,进入下一轮循环
|
||||||
|
|
||||||
# 2. 状态持续时间规则 (仅在未被5分钟规则覆盖时执行)
|
# 2. 状态持续时间规则 (仅在未被5分钟规则覆盖时执行)
|
||||||
if next_state is None: # 仅当5分钟规则未触发切换时检查持续时间
|
if next_state is None: # 仅当5分钟规则未触发切换时检查持续时间
|
||||||
if current_status == MaiState.OFFLINE:
|
if current_status == MaiState.OFFLINE:
|
||||||
# OFFLINE 状态下,检查是否已持续5分钟
|
# OFFLINE 状态下,检查是否已持续5分钟
|
||||||
if time_in_current_status >= FIVE_MINUTES:
|
if time_in_current_status >= FIVE_MINUTES:
|
||||||
@@ -274,26 +277,26 @@ class Heartflow:
|
|||||||
# 保持 OFFLINE,重置计时器以开始新的5分钟计时
|
# 保持 OFFLINE,重置计时器以开始新的5分钟计时
|
||||||
logger.debug("[Heartflow State] OFFLINE 持续时间达到,保持 OFFLINE,重置计时器")
|
logger.debug("[Heartflow State] OFFLINE 持续时间达到,保持 OFFLINE,重置计时器")
|
||||||
self.current_state.last_status_change_time = current_time
|
self.current_state.last_status_change_time = current_time
|
||||||
self.current_state.last_5min_check_time = current_time # 保持一致
|
self.current_state.last_5min_check_time = current_time # 保持一致
|
||||||
# 显式将 next_state 设为 OFFLINE 以便后续处理
|
# 显式将 next_state 设为 OFFLINE 以便后续处理
|
||||||
next_state = MaiState.OFFLINE
|
next_state = MaiState.OFFLINE
|
||||||
|
|
||||||
elif current_status == MaiState.PEEKING:
|
elif current_status == MaiState.PEEKING:
|
||||||
if time_in_current_status >= FIVE_MINUTES: # PEEKING 最多持续 5 分钟
|
if time_in_current_status >= FIVE_MINUTES: # PEEKING 最多持续 5 分钟
|
||||||
weights = [50, 30, 20]
|
weights = [50, 30, 20]
|
||||||
choices_list = [MaiState.OFFLINE, MaiState.NORMAL_CHAT, MaiState.FOCUSED_CHAT]
|
choices_list = [MaiState.OFFLINE, MaiState.NORMAL_CHAT, MaiState.FOCUSED_CHAT]
|
||||||
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
||||||
logger.debug(f"[Heartflow State] PEEKING 持续时间达到,切换到 {next_state.value}")
|
logger.debug(f"[Heartflow State] PEEKING 持续时间达到,切换到 {next_state.value}")
|
||||||
|
|
||||||
elif current_status == MaiState.NORMAL_CHAT:
|
elif current_status == MaiState.NORMAL_CHAT:
|
||||||
if time_in_current_status >= FIFTEEN_MINUTES: # NORMAL_CHAT 最多持续 15 分钟
|
if time_in_current_status >= FIFTEEN_MINUTES: # NORMAL_CHAT 最多持续 15 分钟
|
||||||
weights = [50, 50]
|
weights = [50, 50]
|
||||||
choices_list = [MaiState.OFFLINE, MaiState.FOCUSED_CHAT]
|
choices_list = [MaiState.OFFLINE, MaiState.FOCUSED_CHAT]
|
||||||
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
||||||
logger.debug(f"[Heartflow State] NORMAL_CHAT 持续时间达到,切换到 {next_state.value}")
|
logger.debug(f"[Heartflow State] NORMAL_CHAT 持续时间达到,切换到 {next_state.value}")
|
||||||
|
|
||||||
elif current_status == MaiState.FOCUSED_CHAT:
|
elif current_status == MaiState.FOCUSED_CHAT:
|
||||||
if time_in_current_status >= TWENTY_MINUTES: # FOCUSED_CHAT 最多持续 20 分钟
|
if time_in_current_status >= TWENTY_MINUTES: # FOCUSED_CHAT 最多持续 20 分钟
|
||||||
weights = [80, 20]
|
weights = [80, 20]
|
||||||
choices_list = [MaiState.OFFLINE, MaiState.NORMAL_CHAT]
|
choices_list = [MaiState.OFFLINE, MaiState.NORMAL_CHAT]
|
||||||
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
next_state = random.choices(choices_list, weights=weights, k=1)[0]
|
||||||
@@ -325,7 +328,7 @@ class Heartflow:
|
|||||||
if time_in_current_status >= FIVE_MINUTES:
|
if time_in_current_status >= FIVE_MINUTES:
|
||||||
# 确保计时器已在上面重置,这里无需操作,只记录日志
|
# 确保计时器已在上面重置,这里无需操作,只记录日志
|
||||||
logger.debug("[Heartflow State] 保持 OFFLINE 状态,计时器已重置。")
|
logger.debug("[Heartflow State] 保持 OFFLINE 状态,计时器已重置。")
|
||||||
pass # 无需状态转换,也无需调用激活/停用逻辑
|
pass # 无需状态转换,也无需调用激活/停用逻辑
|
||||||
|
|
||||||
# --- 如果没有确定 next_state (即没有触发任何切换规则) --- #
|
# --- 如果没有确定 next_state (即没有触发任何切换规则) --- #
|
||||||
# logger.debug(f"[Heartflow State] 状态未改变,保持 {current_status.value}") # 减少日志噪音
|
# logger.debug(f"[Heartflow State] 状态未改变,保持 {current_status.value}") # 减少日志噪音
|
||||||
@@ -340,10 +343,15 @@ class Heartflow:
|
|||||||
|
|
||||||
for sub_hf in subflows_snapshot:
|
for sub_hf in subflows_snapshot:
|
||||||
# Double-check if subflow still exists and is in CHAT state
|
# Double-check if subflow still exists and is in CHAT state
|
||||||
if sub_hf.subheartflow_id in self._subheartflows and sub_hf.chat_state.chat_status == ChatState.CHAT:
|
if (
|
||||||
|
sub_hf.subheartflow_id in self._subheartflows
|
||||||
|
and sub_hf.chat_state.chat_status == ChatState.CHAT
|
||||||
|
):
|
||||||
evaluated_count += 1
|
evaluated_count += 1
|
||||||
if sub_hf.should_evaluate_reply():
|
if sub_hf.should_evaluate_reply():
|
||||||
stream_name = chat_manager.get_stream_name(sub_hf.subheartflow_id) or sub_hf.subheartflow_id
|
stream_name = (
|
||||||
|
chat_manager.get_stream_name(sub_hf.subheartflow_id) or sub_hf.subheartflow_id
|
||||||
|
)
|
||||||
log_prefix = f"[{stream_name}]"
|
log_prefix = f"[{stream_name}]"
|
||||||
logger.info(f"{log_prefix} 兴趣概率触发,尝试将状态从 CHAT 提升到 FOCUSED")
|
logger.info(f"{log_prefix} 兴趣概率触发,尝试将状态从 CHAT 提升到 FOCUSED")
|
||||||
# set_chat_state handles limit checks and HeartFChatting creation internally
|
# set_chat_state handles limit checks and HeartFChatting creation internally
|
||||||
@@ -352,10 +360,12 @@ class Heartflow:
|
|||||||
if sub_hf.chat_state.chat_status == ChatState.FOCUSED:
|
if sub_hf.chat_state.chat_status == ChatState.FOCUSED:
|
||||||
promoted_count += 1
|
promoted_count += 1
|
||||||
# else: # No need to log every non-trigger event
|
# else: # No need to log every non-trigger event
|
||||||
# logger.trace(f"[{sub_hf.subheartflow_id}] In CHAT state, but should_evaluate_reply returned False.")
|
# logger.trace(f"[{sub_hf.subheartflow_id}] In CHAT state, but should_evaluate_reply returned False.")
|
||||||
|
|
||||||
if evaluated_count > 0:
|
if evaluated_count > 0:
|
||||||
logger.debug(f"[Heartflow Interest Eval] Evaluated {evaluated_count} CHAT flows. Promoted {promoted_count} to FOCUSED.")
|
logger.debug(
|
||||||
|
f"[Heartflow Interest Eval] Evaluated {evaluated_count} CHAT flows. Promoted {promoted_count} to FOCUSED."
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[Heartflow] 兴趣评估任务出错: {e}")
|
logger.error(f"[Heartflow] 兴趣评估任务出错: {e}")
|
||||||
@@ -431,7 +441,6 @@ class Heartflow:
|
|||||||
# logger.info(f"[Heartflow] 清理完成。没有流符合移除条件。当前数量: {initial_count}") # 减少日志噪音
|
# logger.info(f"[Heartflow] 清理完成。没有流符合移除条件。当前数量: {initial_count}") # 减少日志噪音
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
async def heartflow_start_working(self):
|
async def heartflow_start_working(self):
|
||||||
# 启动清理任务 (使用新的 periodic_cleanup_task)
|
# 启动清理任务 (使用新的 periodic_cleanup_task)
|
||||||
if self._cleanup_task is None or self._cleanup_task.done():
|
if self._cleanup_task is None or self._cleanup_task.done():
|
||||||
@@ -593,7 +602,7 @@ class Heartflow:
|
|||||||
return "(想法汇总时发生错误...)"
|
return "(想法汇总时发生错误...)"
|
||||||
|
|
||||||
# --- Add helper method to count subflows by state --- #
|
# --- Add helper method to count subflows by state --- #
|
||||||
def count_subflows_by_state(self, target_state: 'ChatState') -> int:
|
def count_subflows_by_state(self, target_state: "ChatState") -> int:
|
||||||
"""Counts the number of subheartflows currently in the specified state."""
|
"""Counts the number of subheartflows currently in the specified state."""
|
||||||
count = 0
|
count = 0
|
||||||
# Use items() directly for read-only iteration if thread safety isn't a major concern here
|
# Use items() directly for read-only iteration if thread safety isn't a major concern here
|
||||||
@@ -604,9 +613,10 @@ class Heartflow:
|
|||||||
if flow.subheartflow_id in self._subheartflows and flow.chat_state.chat_status == target_state:
|
if flow.subheartflow_id in self._subheartflows and flow.chat_state.chat_status == target_state:
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
# --- End helper method --- #
|
# --- End helper method --- #
|
||||||
|
|
||||||
async def create_subheartflow(self, subheartflow_id: Any) -> Optional['SubHeartflow']:
|
async def create_subheartflow(self, subheartflow_id: Any) -> Optional["SubHeartflow"]:
|
||||||
"""
|
"""
|
||||||
获取或创建一个新的SubHeartflow实例。
|
获取或创建一个新的SubHeartflow实例。
|
||||||
创建本身不受限,因为初始状态是ABSENT。
|
创建本身不受限,因为初始状态是ABSENT。
|
||||||
@@ -627,7 +637,6 @@ class Heartflow:
|
|||||||
await observation.initialize()
|
await observation.initialize()
|
||||||
subheartflow.add_observation(observation)
|
subheartflow.add_observation(observation)
|
||||||
|
|
||||||
|
|
||||||
# 创建并存储后台任务 (SubHeartflow 自己的后台任务)
|
# 创建并存储后台任务 (SubHeartflow 自己的后台任务)
|
||||||
subheartflow.task = asyncio.create_task(subheartflow.subheartflow_start_working())
|
subheartflow.task = asyncio.create_task(subheartflow.subheartflow_start_working())
|
||||||
logger.debug(f"[Heartflow] 为 {subheartflow_id} 创建后台任务成功,添加 observation 成功")
|
logger.debug(f"[Heartflow] 为 {subheartflow_id} 创建后台任务成功,添加 observation 成功")
|
||||||
@@ -641,7 +650,7 @@ class Heartflow:
|
|||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_subheartflow(self, observe_chat_id: Any) -> Optional['SubHeartflow']:
|
def get_subheartflow(self, observe_chat_id: Any) -> Optional["SubHeartflow"]:
|
||||||
"""获取指定ID的SubHeartflow实例"""
|
"""获取指定ID的SubHeartflow实例"""
|
||||||
return self._subheartflows.get(observe_chat_id)
|
return self._subheartflows.get(observe_chat_id)
|
||||||
|
|
||||||
@@ -659,13 +668,13 @@ class Heartflow:
|
|||||||
# --- 新增:在取消任务和删除前,先设置状态为 ABSENT 以关闭 HeartFChatting ---
|
# --- 新增:在取消任务和删除前,先设置状态为 ABSENT 以关闭 HeartFChatting ---
|
||||||
try:
|
try:
|
||||||
if subheartflow.chat_state.chat_status != ChatState.ABSENT:
|
if subheartflow.chat_state.chat_status != ChatState.ABSENT:
|
||||||
logger.debug(f"[Heartflow Limits] 将子心流 {stream_name} 状态设置为 ABSENT 以确保资源释放...")
|
logger.debug(f"[Heartflow Limits] 将子心流 {stream_name} 状态设置为 ABSENT 以确保资源释放...")
|
||||||
await subheartflow.set_chat_state(ChatState.ABSENT) # 调用异步方法
|
await subheartflow.set_chat_state(ChatState.ABSENT) # 调用异步方法
|
||||||
else:
|
else:
|
||||||
logger.debug(f"[Heartflow Limits] 子心流 {stream_name} 已经是 ABSENT 状态。")
|
logger.debug(f"[Heartflow Limits] 子心流 {stream_name} 已经是 ABSENT 状态。")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[Heartflow Limits] 在停止子心流 {stream_name} 时设置状态为 ABSENT 出错: {e}")
|
logger.error(f"[Heartflow Limits] 在停止子心流 {stream_name} 时设置状态为 ABSENT 出错: {e}")
|
||||||
# 即使出错,仍继续尝试停止任务和移除
|
# 即使出错,仍继续尝试停止任务和移除
|
||||||
# --- 结束新增逻辑 ---
|
# --- 结束新增逻辑 ---
|
||||||
|
|
||||||
# 标记停止并取消任务
|
# 标记停止并取消任务
|
||||||
@@ -692,12 +701,14 @@ class Heartflow:
|
|||||||
"""根据当前的 MaiState 强制执行 SubHeartflow 数量限制"""
|
"""根据当前的 MaiState 强制执行 SubHeartflow 数量限制"""
|
||||||
normal_limit = current_mai_state.get_normal_chat_max_num()
|
normal_limit = current_mai_state.get_normal_chat_max_num()
|
||||||
focused_limit = current_mai_state.get_focused_chat_max_num()
|
focused_limit = current_mai_state.get_focused_chat_max_num()
|
||||||
logger.debug(f"[Heartflow Limits] 执行限制检查。当前状态: {current_mai_state.value}, Normal上限: {normal_limit}, Focused上限: {focused_limit}")
|
logger.debug(
|
||||||
|
f"[Heartflow Limits] 执行限制检查。当前状态: {current_mai_state.value}, Normal上限: {normal_limit}, Focused上限: {focused_limit}"
|
||||||
|
)
|
||||||
|
|
||||||
# 分类并统计当前 subheartflows
|
# 分类并统计当前 subheartflows
|
||||||
normal_flows = []
|
normal_flows = []
|
||||||
focused_flows = []
|
focused_flows = []
|
||||||
other_flows = [] # e.g., ABSENT
|
other_flows = [] # e.g., ABSENT
|
||||||
|
|
||||||
# 创建快照以安全迭代
|
# 创建快照以安全迭代
|
||||||
items_snapshot = list(self._subheartflows.items())
|
items_snapshot = list(self._subheartflows.items())
|
||||||
@@ -713,7 +724,9 @@ class Heartflow:
|
|||||||
else:
|
else:
|
||||||
other_flows.append((flow_id, flow.last_active_time))
|
other_flows.append((flow_id, flow.last_active_time))
|
||||||
|
|
||||||
logger.debug(f"[Heartflow Limits] 当前计数 - Normal: {len(normal_flows)}, Focused: {len(focused_flows)}, Other: {len(other_flows)}")
|
logger.debug(
|
||||||
|
f"[Heartflow Limits] 当前计数 - Normal: {len(normal_flows)}, Focused: {len(focused_flows)}, Other: {len(other_flows)}"
|
||||||
|
)
|
||||||
|
|
||||||
stopped_count = 0
|
stopped_count = 0
|
||||||
|
|
||||||
@@ -726,32 +739,40 @@ class Heartflow:
|
|||||||
# 停止最不活跃的超额部分
|
# 停止最不活跃的超额部分
|
||||||
for i in range(excess_count):
|
for i in range(excess_count):
|
||||||
flow_id_to_stop = normal_flows[i][0]
|
flow_id_to_stop = normal_flows[i][0]
|
||||||
if await self._stop_subheartflow(flow_id_to_stop, f"Normal (CHAT) 状态超出上限 ({normal_limit}),停止最不活跃的实例"):
|
if await self._stop_subheartflow(
|
||||||
|
flow_id_to_stop, f"Normal (CHAT) 状态超出上限 ({normal_limit}),停止最不活跃的实例"
|
||||||
|
):
|
||||||
stopped_count += 1
|
stopped_count += 1
|
||||||
|
|
||||||
# 重新获取 focused_flows 列表,因为上面的停止操作可能已经改变了状态或移除了实例
|
# 重新获取 focused_flows 列表,因为上面的停止操作可能已经改变了状态或移除了实例
|
||||||
focused_flows = []
|
focused_flows = []
|
||||||
items_snapshot_after_normal = list(self._subheartflows.items())
|
items_snapshot_after_normal = list(self._subheartflows.items())
|
||||||
for flow_id, flow in items_snapshot_after_normal:
|
for flow_id, flow in items_snapshot_after_normal:
|
||||||
if flow_id not in self._subheartflows:
|
if flow_id not in self._subheartflows:
|
||||||
continue # Double check
|
continue # Double check
|
||||||
if flow.chat_state.chat_status == ChatState.FOCUSED:
|
if flow.chat_state.chat_status == ChatState.FOCUSED:
|
||||||
focused_flows.append((flow_id, flow.last_active_time))
|
focused_flows.append((flow_id, flow.last_active_time))
|
||||||
|
|
||||||
# 检查 Focused (FOCUSED) 限制
|
# 检查 Focused (FOCUSED) 限制
|
||||||
if len(focused_flows) > focused_limit:
|
if len(focused_flows) > focused_limit:
|
||||||
excess_count = len(focused_flows) - focused_limit
|
excess_count = len(focused_flows) - focused_limit
|
||||||
logger.info(f"[Heartflow Limits] 检测到 Focused (FOCUSED) 状态超额 {excess_count} 个。上限: {focused_limit}")
|
logger.info(
|
||||||
|
f"[Heartflow Limits] 检测到 Focused (FOCUSED) 状态超额 {excess_count} 个。上限: {focused_limit}"
|
||||||
|
)
|
||||||
# 按 last_active_time 升序排序
|
# 按 last_active_time 升序排序
|
||||||
focused_flows.sort(key=lambda item: item[1])
|
focused_flows.sort(key=lambda item: item[1])
|
||||||
# 停止最不活跃的超额部分
|
# 停止最不活跃的超额部分
|
||||||
for i in range(excess_count):
|
for i in range(excess_count):
|
||||||
flow_id_to_stop = focused_flows[i][0]
|
flow_id_to_stop = focused_flows[i][0]
|
||||||
if await self._stop_subheartflow(flow_id_to_stop, f"Focused (FOCUSED) 状态超出上限 ({focused_limit}),停止最不活跃的实例"):
|
if await self._stop_subheartflow(
|
||||||
|
flow_id_to_stop, f"Focused (FOCUSED) 状态超出上限 ({focused_limit}),停止最不活跃的实例"
|
||||||
|
):
|
||||||
stopped_count += 1
|
stopped_count += 1
|
||||||
|
|
||||||
if stopped_count > 0:
|
if stopped_count > 0:
|
||||||
logger.info(f"[Heartflow Limits] 限制执行完成,共停止了 {stopped_count} 个子心流。当前总数: {len(self._subheartflows)}")
|
logger.info(
|
||||||
|
f"[Heartflow Limits] 限制执行完成,共停止了 {stopped_count} 个子心流。当前总数: {len(self._subheartflows)}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
logger.debug(f"[Heartflow Limits] 限制检查完成,无需停止子心流。当前总数: {len(self._subheartflows)}")
|
logger.debug(f"[Heartflow Limits] 限制检查完成,无需停止子心流。当前总数: {len(self._subheartflows)}")
|
||||||
|
|
||||||
@@ -765,7 +786,11 @@ class Heartflow:
|
|||||||
|
|
||||||
# 使用快照进行迭代
|
# 使用快照进行迭代
|
||||||
all_flows_snapshot = list(self._subheartflows.values())
|
all_flows_snapshot = list(self._subheartflows.values())
|
||||||
absent_flows = [flow for flow in all_flows_snapshot if flow.subheartflow_id in self._subheartflows and flow.chat_state.chat_status == ChatState.ABSENT]
|
absent_flows = [
|
||||||
|
flow
|
||||||
|
for flow in all_flows_snapshot
|
||||||
|
if flow.subheartflow_id in self._subheartflows and flow.chat_state.chat_status == ChatState.ABSENT
|
||||||
|
]
|
||||||
|
|
||||||
num_to_activate = min(limit, len(absent_flows))
|
num_to_activate = min(limit, len(absent_flows))
|
||||||
|
|
||||||
@@ -773,13 +798,18 @@ class Heartflow:
|
|||||||
logger.info(f"[Heartflow Activate] 没有处于 ABSENT 状态的子心流可供激活至 CHAT (上限: {limit})。")
|
logger.info(f"[Heartflow Activate] 没有处于 ABSENT 状态的子心流可供激活至 CHAT (上限: {limit})。")
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info(f"[Heartflow Activate] 将随机选择 {num_to_activate} 个 (上限 {limit}) ABSENT 子心流激活至 CHAT 状态。")
|
logger.info(
|
||||||
|
f"[Heartflow Activate] 将随机选择 {num_to_activate} 个 (上限 {limit}) ABSENT 子心流激活至 CHAT 状态。"
|
||||||
|
)
|
||||||
selected_flows = random.sample(absent_flows, num_to_activate)
|
selected_flows = random.sample(absent_flows, num_to_activate)
|
||||||
|
|
||||||
activated_count = 0
|
activated_count = 0
|
||||||
for flow in selected_flows:
|
for flow in selected_flows:
|
||||||
# 再次检查 flow 是否仍然存在且状态为 ABSENT (以防并发修改)
|
# 再次检查 flow 是否仍然存在且状态为 ABSENT (以防并发修改)
|
||||||
if flow.subheartflow_id in self._subheartflows and self._subheartflows[flow.subheartflow_id].chat_state.chat_status == ChatState.ABSENT:
|
if (
|
||||||
|
flow.subheartflow_id in self._subheartflows
|
||||||
|
and self._subheartflows[flow.subheartflow_id].chat_state.chat_status == ChatState.ABSENT
|
||||||
|
):
|
||||||
stream_name = chat_manager.get_stream_name(flow.subheartflow_id) or flow.subheartflow_id
|
stream_name = chat_manager.get_stream_name(flow.subheartflow_id) or flow.subheartflow_id
|
||||||
logger.debug(f"[Heartflow Activate] 正在将子心流 {stream_name} 状态设置为 CHAT。")
|
logger.debug(f"[Heartflow Activate] 正在将子心流 {stream_name} 状态设置为 CHAT。")
|
||||||
# 调用 set_chat_state,它内部会处理日志记录
|
# 调用 set_chat_state,它内部会处理日志记录
|
||||||
@@ -809,7 +839,7 @@ class Heartflow:
|
|||||||
for flow_id in flow_ids_snapshot:
|
for flow_id in flow_ids_snapshot:
|
||||||
subflow = self._subheartflows.get(flow_id)
|
subflow = self._subheartflows.get(flow_id)
|
||||||
if not subflow:
|
if not subflow:
|
||||||
continue # Subflow 可能在迭代过程中被清理
|
continue # Subflow 可能在迭代过程中被清理
|
||||||
|
|
||||||
stream_name = chat_manager.get_stream_name(flow_id) or flow_id
|
stream_name = chat_manager.get_stream_name(flow_id) or flow_id
|
||||||
|
|
||||||
@@ -835,11 +865,14 @@ class Heartflow:
|
|||||||
logger.error(f"[Heartflow Deactivate] 停用子心流 {stream_name} 时出错: {e}")
|
logger.error(f"[Heartflow Deactivate] 停用子心流 {stream_name} 时出错: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
logger.info(f"[Heartflow Deactivate] 完成停用,共将 {deactivated_count} 个子心流设置为 ABSENT 状态 (不包括已是 ABSENT 的)。")
|
logger.info(
|
||||||
|
f"[Heartflow Deactivate] 完成停用,共将 {deactivated_count} 个子心流设置为 ABSENT 状态 (不包括已是 ABSENT 的)。"
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[Heartflow Deactivate] 停用所有子心流时出错: {e}")
|
logger.error(f"[Heartflow Deactivate] 停用所有子心流时出错: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
init_prompt()
|
init_prompt()
|
||||||
# 创建一个全局的管理器实例
|
# 创建一个全局的管理器实例
|
||||||
heartflow = Heartflow()
|
heartflow = Heartflow()
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ class ChattingObservation(Observation):
|
|||||||
)
|
)
|
||||||
self.mid_memory_info = mid_memory_str
|
self.mid_memory_info = mid_memory_str
|
||||||
|
|
||||||
|
|
||||||
self.talking_message_str = await build_readable_messages(messages=self.talking_message, timestamp_mode="normal")
|
self.talking_message_str = await build_readable_messages(messages=self.talking_message, timestamp_mode="normal")
|
||||||
|
|
||||||
logger.trace(
|
logger.trace(
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ from src.plugins.heartFC_chat.heartFC_chat import HeartFChatting
|
|||||||
|
|
||||||
# Type hinting for circular dependency
|
# Type hinting for circular dependency
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .heartflow import Heartflow # Import Heartflow for type hinting
|
from .heartflow import Heartflow # Import Heartflow for type hinting
|
||||||
from .sub_heartflow import ChatState # Keep ChatState here too?
|
from .sub_heartflow import ChatState # Keep ChatState here too?
|
||||||
from src.plugins.heartFC_chat.heartFC_chat import HeartFChatting # <-- Add for type hint
|
from src.plugins.heartFC_chat.heartFC_chat import HeartFChatting # <-- Add for type hint
|
||||||
|
|
||||||
# 定义常量 (从 interest.py 移动过来)
|
# 定义常量 (从 interest.py 移动过来)
|
||||||
MAX_INTEREST = 15.0
|
MAX_INTEREST = 15.0
|
||||||
@@ -92,7 +92,7 @@ class InterestChatting:
|
|||||||
increase_rate=probability_increase_rate_per_second,
|
increase_rate=probability_increase_rate_per_second,
|
||||||
decay_factor=global_config.probability_decay_factor_per_second,
|
decay_factor=global_config.probability_decay_factor_per_second,
|
||||||
max_probability=max_reply_probability,
|
max_probability=max_reply_probability,
|
||||||
state_change_callback: Optional[Callable[[ChatState], None]] = None
|
state_change_callback: Optional[Callable[[ChatState], None]] = None,
|
||||||
):
|
):
|
||||||
self.interest_level: float = 0.0
|
self.interest_level: float = 0.0
|
||||||
self.last_update_time: float = time.time()
|
self.last_update_time: float = time.time()
|
||||||
@@ -231,9 +231,9 @@ class InterestChatting:
|
|||||||
|
|
||||||
|
|
||||||
class SubHeartflow:
|
class SubHeartflow:
|
||||||
def __init__(self, subheartflow_id, parent_heartflow: 'Heartflow'):
|
def __init__(self, subheartflow_id, parent_heartflow: "Heartflow"):
|
||||||
"""子心流初始化函数
|
"""子心流初始化函数
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
subheartflow_id: 子心流唯一标识符
|
subheartflow_id: 子心流唯一标识符
|
||||||
parent_heartflow: 父级心流实例
|
parent_heartflow: 父级心流实例
|
||||||
@@ -242,27 +242,27 @@ class SubHeartflow:
|
|||||||
self.subheartflow_id = subheartflow_id
|
self.subheartflow_id = subheartflow_id
|
||||||
self.parent_heartflow = parent_heartflow
|
self.parent_heartflow = parent_heartflow
|
||||||
self.bot_name = global_config.BOT_NICKNAME # 机器人昵称
|
self.bot_name = global_config.BOT_NICKNAME # 机器人昵称
|
||||||
|
|
||||||
# 思维状态相关
|
# 思维状态相关
|
||||||
self.current_mind = "你什么也没想" # 当前想法
|
self.current_mind = "你什么也没想" # 当前想法
|
||||||
self.past_mind = [] # 历史想法记录
|
self.past_mind = [] # 历史想法记录
|
||||||
self.main_heartflow_info = "" # 主心流信息
|
self.main_heartflow_info = "" # 主心流信息
|
||||||
|
|
||||||
# 聊天状态管理
|
# 聊天状态管理
|
||||||
self.chat_state: ChatStateInfo = ChatStateInfo() # 聊天状态信息
|
self.chat_state: ChatStateInfo = ChatStateInfo() # 聊天状态信息
|
||||||
self.interest_chatting = InterestChatting(state_change_callback=self.set_chat_state) # 兴趣聊天系统
|
self.interest_chatting = InterestChatting(state_change_callback=self.set_chat_state) # 兴趣聊天系统
|
||||||
|
|
||||||
# 活动状态管理
|
# 活动状态管理
|
||||||
self.last_active_time = time.time() # 最后活跃时间
|
self.last_active_time = time.time() # 最后活跃时间
|
||||||
self.is_active = False # 是否活跃标志
|
self.is_active = False # 是否活跃标志
|
||||||
self.should_stop = False # 停止标志
|
self.should_stop = False # 停止标志
|
||||||
self.task: Optional[asyncio.Task] = None # 后台任务
|
self.task: Optional[asyncio.Task] = None # 后台任务
|
||||||
self.heart_fc_instance: Optional['HeartFChatting'] = None # <-- Add instance variable
|
self.heart_fc_instance: Optional["HeartFChatting"] = None # <-- Add instance variable
|
||||||
|
|
||||||
# 观察和知识系统
|
# 观察和知识系统
|
||||||
self.observations: List[ChattingObservation] = [] # 观察列表
|
self.observations: List[ChattingObservation] = [] # 观察列表
|
||||||
self.running_knowledges = [] # 运行中的知识
|
self.running_knowledges = [] # 运行中的知识
|
||||||
|
|
||||||
# LLM模型配置
|
# LLM模型配置
|
||||||
self.llm_model = LLMRequest(
|
self.llm_model = LLMRequest(
|
||||||
model=global_config.llm_sub_heartflow,
|
model=global_config.llm_sub_heartflow,
|
||||||
@@ -271,13 +271,13 @@ class SubHeartflow:
|
|||||||
request_type="sub_heart_flow",
|
request_type="sub_heart_flow",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def set_chat_state(self, new_state: 'ChatState'):
|
async def set_chat_state(self, new_state: "ChatState"):
|
||||||
"""更新sub_heartflow的聊天状态,并管理 HeartFChatting 实例"""
|
"""更新sub_heartflow的聊天状态,并管理 HeartFChatting 实例"""
|
||||||
|
|
||||||
current_state = self.chat_state.chat_status
|
current_state = self.chat_state.chat_status
|
||||||
if current_state == new_state:
|
if current_state == new_state:
|
||||||
logger.trace(f"[{self.subheartflow_id}] State already {current_state.value}, no change.")
|
logger.trace(f"[{self.subheartflow_id}] State already {current_state.value}, no change.")
|
||||||
return # No change needed
|
return # No change needed
|
||||||
|
|
||||||
log_prefix = f"[{chat_manager.get_stream_name(self.subheartflow_id) or self.subheartflow_id}]"
|
log_prefix = f"[{chat_manager.get_stream_name(self.subheartflow_id) or self.subheartflow_id}]"
|
||||||
current_mai_state = self.parent_heartflow.current_state.mai_status
|
current_mai_state = self.parent_heartflow.current_state.mai_status
|
||||||
@@ -288,10 +288,14 @@ class SubHeartflow:
|
|||||||
current_chat_count = self.parent_heartflow.count_subflows_by_state(ChatState.CHAT)
|
current_chat_count = self.parent_heartflow.count_subflows_by_state(ChatState.CHAT)
|
||||||
|
|
||||||
if current_chat_count >= normal_limit:
|
if current_chat_count >= normal_limit:
|
||||||
logger.debug(f"{log_prefix} 拒绝从 {current_state.value} 转换到 CHAT。原因:CHAT 状态已达上限 ({normal_limit})。当前数量: {current_chat_count}")
|
logger.debug(
|
||||||
return # Block the state transition
|
f"{log_prefix} 拒绝从 {current_state.value} 转换到 CHAT。原因:CHAT 状态已达上限 ({normal_limit})。当前数量: {current_chat_count}"
|
||||||
|
)
|
||||||
|
return # Block the state transition
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{log_prefix} 允许从 {current_state.value} 转换到 CHAT (上限: {normal_limit}, 当前: {current_chat_count})" )
|
logger.debug(
|
||||||
|
f"{log_prefix} 允许从 {current_state.value} 转换到 CHAT (上限: {normal_limit}, 当前: {current_chat_count})"
|
||||||
|
)
|
||||||
# If transitioning out of FOCUSED, shut down HeartFChatting first
|
# If transitioning out of FOCUSED, shut down HeartFChatting first
|
||||||
if current_state == ChatState.FOCUSED and self.heart_fc_instance:
|
if current_state == ChatState.FOCUSED and self.heart_fc_instance:
|
||||||
logger.info(f"{log_prefix} 从 FOCUSED 转换到 CHAT,正在关闭 HeartFChatting...")
|
logger.info(f"{log_prefix} 从 FOCUSED 转换到 CHAT,正在关闭 HeartFChatting...")
|
||||||
@@ -304,10 +308,14 @@ class SubHeartflow:
|
|||||||
current_focused_count = self.parent_heartflow.count_subflows_by_state(ChatState.FOCUSED)
|
current_focused_count = self.parent_heartflow.count_subflows_by_state(ChatState.FOCUSED)
|
||||||
|
|
||||||
if current_focused_count >= focused_limit:
|
if current_focused_count >= focused_limit:
|
||||||
logger.debug(f"{log_prefix} 拒绝从 {current_state.value} 转换到 FOCUSED。原因:FOCUSED 状态已达上限 ({focused_limit})。当前数量: {current_focused_count}")
|
logger.debug(
|
||||||
return # Block the state transition
|
f"{log_prefix} 拒绝从 {current_state.value} 转换到 FOCUSED。原因:FOCUSED 状态已达上限 ({focused_limit})。当前数量: {current_focused_count}"
|
||||||
|
)
|
||||||
|
return # Block the state transition
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{log_prefix} 允许从 {current_state.value} 转换到 FOCUSED (上限: {focused_limit}, 当前: {current_focused_count})" )
|
logger.debug(
|
||||||
|
f"{log_prefix} 允许从 {current_state.value} 转换到 FOCUSED (上限: {focused_limit}, 当前: {current_focused_count})"
|
||||||
|
)
|
||||||
if not self.heart_fc_instance:
|
if not self.heart_fc_instance:
|
||||||
logger.info(f"{log_prefix} 状态转为 FOCUSED,创建并初始化 HeartFChatting 实例...")
|
logger.info(f"{log_prefix} 状态转为 FOCUSED,创建并初始化 HeartFChatting 实例...")
|
||||||
try:
|
try:
|
||||||
@@ -323,14 +331,16 @@ class SubHeartflow:
|
|||||||
await self.heart_fc_instance.add_time()
|
await self.heart_fc_instance.add_time()
|
||||||
logger.info(f"{log_prefix} HeartFChatting 实例已创建并启动。")
|
logger.info(f"{log_prefix} HeartFChatting 实例已创建并启动。")
|
||||||
else:
|
else:
|
||||||
logger.error(f"{log_prefix} HeartFChatting 实例初始化失败,状态回滚到 {current_state.value}")
|
logger.error(
|
||||||
|
f"{log_prefix} HeartFChatting 实例初始化失败,状态回滚到 {current_state.value}"
|
||||||
|
)
|
||||||
self.heart_fc_instance = None
|
self.heart_fc_instance = None
|
||||||
return # Prevent state change if HeartFChatting fails to init
|
return # Prevent state change if HeartFChatting fails to init
|
||||||
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 # Prevent state change on error
|
return # Prevent state change on error
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.warning(f"{log_prefix} 尝试进入 FOCUSED 状态,但 HeartFChatting 实例已存在。")
|
logger.warning(f"{log_prefix} 尝试进入 FOCUSED 状态,但 HeartFChatting 实例已存在。")
|
||||||
@@ -341,13 +351,11 @@ class SubHeartflow:
|
|||||||
await self.heart_fc_instance.shutdown()
|
await self.heart_fc_instance.shutdown()
|
||||||
self.heart_fc_instance = None
|
self.heart_fc_instance = None
|
||||||
|
|
||||||
|
|
||||||
# --- Update state and timestamp if transition is allowed --- # 更新状态必须放在所有检查和操作之后
|
# --- Update state and timestamp if transition is allowed --- # 更新状态必须放在所有检查和操作之后
|
||||||
self.chat_state.chat_status = new_state
|
self.chat_state.chat_status = new_state
|
||||||
self.last_active_time = time.time()
|
self.last_active_time = time.time()
|
||||||
logger.info(f"{log_prefix} 聊天状态从 {current_state.value} 变更为 {new_state.value}")
|
logger.info(f"{log_prefix} 聊天状态从 {current_state.value} 变更为 {new_state.value}")
|
||||||
|
|
||||||
|
|
||||||
async def subheartflow_start_working(self):
|
async def subheartflow_start_working(self):
|
||||||
while True:
|
while True:
|
||||||
if self.should_stop:
|
if self.should_stop:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import time
|
|||||||
from typing import Dict, List, Optional, Union
|
from typing import Dict, List, Optional, Union
|
||||||
|
|
||||||
from src.common.logger import get_module_logger
|
from src.common.logger import get_module_logger
|
||||||
|
|
||||||
# from ...common.database import db # 数据库依赖似乎不需要了,注释掉
|
# from ...common.database import db # 数据库依赖似乎不需要了,注释掉
|
||||||
from ..message.api import global_api
|
from ..message.api import global_api
|
||||||
from .message import MessageSending, MessageThinking, MessageSet
|
from .message import MessageSending, MessageThinking, MessageSet
|
||||||
@@ -75,7 +76,7 @@ class MessageSender:
|
|||||||
await self.send_via_ws(message)
|
await self.send_via_ws(message)
|
||||||
else:
|
else:
|
||||||
await self.send_via_ws(message)
|
await self.send_via_ws(message)
|
||||||
logger.success(f"发送消息 '{message_preview}' 成功") # 调整日志格式
|
logger.success(f"发送消息 '{message_preview}' 成功") # 调整日志格式
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"发送消息 '{message_preview}' 失败: {str(e)}")
|
logger.error(f"发送消息 '{message_preview}' 失败: {str(e)}")
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ class MessageContainer:
|
|||||||
def __init__(self, chat_id: str, max_size: int = 100):
|
def __init__(self, chat_id: str, max_size: int = 100):
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.max_size = max_size
|
self.max_size = max_size
|
||||||
self.messages: List[Union[MessageThinking, MessageSending]] = [] # 明确类型
|
self.messages: List[Union[MessageThinking, MessageSending]] = [] # 明确类型
|
||||||
self.last_send_time = 0
|
self.last_send_time = 0
|
||||||
self.thinking_wait_timeout = 20 # 思考等待超时时间(秒) - 从旧 sender 合并
|
self.thinking_wait_timeout = 20 # 思考等待超时时间(秒) - 从旧 sender 合并
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ class MessageContainer:
|
|||||||
earliest_message = None
|
earliest_message = None
|
||||||
for msg in self.messages:
|
for msg in self.messages:
|
||||||
# 确保消息有 thinking_start_time 属性
|
# 确保消息有 thinking_start_time 属性
|
||||||
msg_time = getattr(msg, 'thinking_start_time', float('inf'))
|
msg_time = getattr(msg, "thinking_start_time", float("inf"))
|
||||||
if msg_time < earliest_time:
|
if msg_time < earliest_time:
|
||||||
earliest_time = msg_time
|
earliest_time = msg_time
|
||||||
earliest_message = msg
|
earliest_message = msg
|
||||||
@@ -156,7 +157,7 @@ class MessageContainer:
|
|||||||
|
|
||||||
def get_all_messages(self) -> List[Union[MessageSending, MessageThinking]]:
|
def get_all_messages(self) -> List[Union[MessageSending, MessageThinking]]:
|
||||||
"""获取所有消息"""
|
"""获取所有消息"""
|
||||||
return list(self.messages) # 返回副本
|
return list(self.messages) # 返回副本
|
||||||
|
|
||||||
|
|
||||||
class MessageManager:
|
class MessageManager:
|
||||||
@@ -164,29 +165,28 @@ class MessageManager:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.containers: Dict[str, MessageContainer] = {}
|
self.containers: Dict[str, MessageContainer] = {}
|
||||||
self.storage = MessageStorage() # 添加 storage 实例
|
self.storage = MessageStorage() # 添加 storage 实例
|
||||||
self._running = True # 处理器运行状态
|
self._running = True # 处理器运行状态
|
||||||
self._container_lock = asyncio.Lock() # 保护 containers 字典的锁
|
self._container_lock = asyncio.Lock() # 保护 containers 字典的锁
|
||||||
# self.message_sender = MessageSender() # 创建发送器实例 (改为全局实例)
|
# self.message_sender = MessageSender() # 创建发送器实例 (改为全局实例)
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""启动后台处理器任务。"""
|
"""启动后台处理器任务。"""
|
||||||
# 检查是否已有任务在运行,避免重复启动
|
# 检查是否已有任务在运行,避免重复启动
|
||||||
if hasattr(self, '_processor_task') and not self._processor_task.done():
|
if hasattr(self, "_processor_task") and not self._processor_task.done():
|
||||||
logger.warning("Processor task already running.")
|
logger.warning("Processor task already running.")
|
||||||
return
|
return
|
||||||
self._processor_task = asyncio.create_task(self._start_processor_loop())
|
self._processor_task = asyncio.create_task(self._start_processor_loop())
|
||||||
logger.info("MessageManager processor task started.")
|
logger.info("MessageManager processor task started.")
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""停止后台处理器任务。"""
|
"""停止后台处理器任务。"""
|
||||||
self._running = False
|
self._running = False
|
||||||
if hasattr(self, '_processor_task') and not self._processor_task.done():
|
if hasattr(self, "_processor_task") and not self._processor_task.done():
|
||||||
self._processor_task.cancel()
|
self._processor_task.cancel()
|
||||||
logger.info("MessageManager processor task stopping.")
|
logger.info("MessageManager processor task stopping.")
|
||||||
else:
|
else:
|
||||||
logger.info("MessageManager processor task not running or already stopped.")
|
logger.info("MessageManager processor task not running or already stopped.")
|
||||||
|
|
||||||
|
|
||||||
async def get_container(self, chat_id: str) -> MessageContainer:
|
async def get_container(self, chat_id: str) -> MessageContainer:
|
||||||
"""获取或创建聊天流的消息容器 (异步,使用锁)"""
|
"""获取或创建聊天流的消息容器 (异步,使用锁)"""
|
||||||
@@ -200,18 +200,18 @@ class MessageManager:
|
|||||||
chat_stream = message.chat_stream
|
chat_stream = message.chat_stream
|
||||||
if not chat_stream:
|
if not chat_stream:
|
||||||
logger.error("消息缺少 chat_stream,无法添加到容器")
|
logger.error("消息缺少 chat_stream,无法添加到容器")
|
||||||
return # 或者抛出异常
|
return # 或者抛出异常
|
||||||
container = await self.get_container(chat_stream.stream_id)
|
container = await self.get_container(chat_stream.stream_id)
|
||||||
container.add_message(message)
|
container.add_message(message)
|
||||||
|
|
||||||
def check_if_sending_message_exist(self, chat_id, thinking_id):
|
def check_if_sending_message_exist(self, chat_id, thinking_id):
|
||||||
"""检查指定聊天流的容器中是否存在具有特定 thinking_id 的 MessageSending 消息 或 emoji 消息"""
|
"""检查指定聊天流的容器中是否存在具有特定 thinking_id 的 MessageSending 消息 或 emoji 消息"""
|
||||||
# 这个方法现在是非异步的,因为它只读取数据
|
# 这个方法现在是非异步的,因为它只读取数据
|
||||||
container = self.containers.get(chat_id) # 直接 get,因为读取不需要锁
|
container = self.containers.get(chat_id) # 直接 get,因为读取不需要锁
|
||||||
if container and container.has_messages():
|
if container and container.has_messages():
|
||||||
for message in container.get_all_messages():
|
for message in container.get_all_messages():
|
||||||
if isinstance(message, MessageSending):
|
if isinstance(message, MessageSending):
|
||||||
msg_id = getattr(message.message_info, 'message_id', None)
|
msg_id = getattr(message.message_info, "message_id", None)
|
||||||
# 检查 message_id 是否匹配 thinking_id 或以 "me" 开头 (emoji)
|
# 检查 message_id 是否匹配 thinking_id 或以 "me" 开头 (emoji)
|
||||||
if msg_id == thinking_id or (msg_id and msg_id.startswith("me")):
|
if msg_id == thinking_id or (msg_id and msg_id.startswith("me")):
|
||||||
# logger.debug(f"检查到存在相同thinking_id或emoji的消息: {msg_id} for {thinking_id}")
|
# logger.debug(f"检查到存在相同thinking_id或emoji的消息: {msg_id} for {thinking_id}")
|
||||||
@@ -221,7 +221,7 @@ class MessageManager:
|
|||||||
async def _handle_sending_message(self, container: MessageContainer, message: MessageSending):
|
async def _handle_sending_message(self, container: MessageContainer, message: MessageSending):
|
||||||
"""处理单个 MessageSending 消息 (包含 set_reply 逻辑)"""
|
"""处理单个 MessageSending 消息 (包含 set_reply 逻辑)"""
|
||||||
try:
|
try:
|
||||||
_ = message.update_thinking_time() # 更新思考时间
|
_ = message.update_thinking_time() # 更新思考时间
|
||||||
thinking_start_time = message.thinking_start_time
|
thinking_start_time = message.thinking_start_time
|
||||||
now_time = time.time()
|
now_time = time.time()
|
||||||
thinking_messages_count, thinking_messages_length = count_messages_between(
|
thinking_messages_count, thinking_messages_length = count_messages_between(
|
||||||
@@ -230,16 +230,18 @@ class MessageManager:
|
|||||||
|
|
||||||
# --- 条件应用 set_reply 逻辑 ---
|
# --- 条件应用 set_reply 逻辑 ---
|
||||||
if (
|
if (
|
||||||
message.apply_set_reply_logic # 检查标记
|
message.apply_set_reply_logic # 检查标记
|
||||||
and message.is_head
|
and message.is_head
|
||||||
and (thinking_messages_count > 4 or thinking_messages_length > 250)
|
and (thinking_messages_count > 4 or thinking_messages_length > 250)
|
||||||
and not message.is_private_message()
|
and not message.is_private_message()
|
||||||
):
|
):
|
||||||
logger.debug(f"[{message.chat_stream.stream_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}...")
|
logger.debug(
|
||||||
|
f"[{message.chat_stream.stream_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}..."
|
||||||
|
)
|
||||||
message.set_reply()
|
message.set_reply()
|
||||||
# --- 结束条件 set_reply ---
|
# --- 结束条件 set_reply ---
|
||||||
|
|
||||||
await message.process() # 预处理消息内容
|
await message.process() # 预处理消息内容
|
||||||
|
|
||||||
# 使用全局 message_sender 实例
|
# 使用全局 message_sender 实例
|
||||||
await message_sender.send_message(message)
|
await message_sender.send_message(message)
|
||||||
@@ -250,22 +252,23 @@ class MessageManager:
|
|||||||
# logger.debug(f"[{message.chat_stream.stream_id}] Sent and removed message: {message.message_info.message_id}")
|
# logger.debug(f"[{message.chat_stream.stream_id}] Sent and removed message: {message.message_info.message_id}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[{message.chat_stream.stream_id}] 处理发送消息 {getattr(message.message_info, 'message_id', 'N/A')} 时出错: {e}")
|
logger.error(
|
||||||
|
f"[{message.chat_stream.stream_id}] 处理发送消息 {getattr(message.message_info, 'message_id', 'N/A')} 时出错: {e}"
|
||||||
|
)
|
||||||
logger.exception("详细错误信息:")
|
logger.exception("详细错误信息:")
|
||||||
# 考虑是否移除出错的消息,防止无限循环
|
# 考虑是否移除出错的消息,防止无限循环
|
||||||
removed = container.remove_message(message)
|
removed = container.remove_message(message)
|
||||||
if removed:
|
if removed:
|
||||||
logger.warning(f"[{message.chat_stream.stream_id}] 已移除处理出错的消息。")
|
logger.warning(f"[{message.chat_stream.stream_id}] 已移除处理出错的消息。")
|
||||||
|
|
||||||
|
|
||||||
async def _process_chat_messages(self, chat_id: str):
|
async def _process_chat_messages(self, chat_id: str):
|
||||||
"""处理单个聊天流消息 (合并后的逻辑)"""
|
"""处理单个聊天流消息 (合并后的逻辑)"""
|
||||||
container = await self.get_container(chat_id) # 获取容器是异步的了
|
container = await self.get_container(chat_id) # 获取容器是异步的了
|
||||||
|
|
||||||
if container.has_messages():
|
if container.has_messages():
|
||||||
message_earliest = container.get_earliest_message()
|
message_earliest = container.get_earliest_message()
|
||||||
|
|
||||||
if not message_earliest: # 如果最早消息为空,则退出
|
if not message_earliest: # 如果最早消息为空,则退出
|
||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(message_earliest, MessageThinking):
|
if isinstance(message_earliest, MessageThinking):
|
||||||
@@ -273,7 +276,7 @@ class MessageManager:
|
|||||||
message_earliest.update_thinking_time()
|
message_earliest.update_thinking_time()
|
||||||
thinking_time = message_earliest.thinking_time
|
thinking_time = message_earliest.thinking_time
|
||||||
# 减少控制台刷新频率或只在时间显著变化时打印
|
# 减少控制台刷新频率或只在时间显著变化时打印
|
||||||
if int(thinking_time) % 5 == 0: # 每5秒打印一次
|
if int(thinking_time) % 5 == 0: # 每5秒打印一次
|
||||||
print(
|
print(
|
||||||
f"消息 {message_earliest.message_info.message_id} 正在思考中,已思考 {int(thinking_time)} 秒\r",
|
f"消息 {message_earliest.message_info.message_id} 正在思考中,已思考 {int(thinking_time)} 秒\r",
|
||||||
end="",
|
end="",
|
||||||
@@ -282,9 +285,11 @@ class MessageManager:
|
|||||||
|
|
||||||
# 检查是否超时
|
# 检查是否超时
|
||||||
if thinking_time > global_config.thinking_timeout:
|
if thinking_time > global_config.thinking_timeout:
|
||||||
logger.warning(f"[{chat_id}] 消息思考超时 ({thinking_time:.1f}秒),移除消息 {message_earliest.message_info.message_id}")
|
logger.warning(
|
||||||
|
f"[{chat_id}] 消息思考超时 ({thinking_time:.1f}秒),移除消息 {message_earliest.message_info.message_id}"
|
||||||
|
)
|
||||||
container.remove_message(message_earliest)
|
container.remove_message(message_earliest)
|
||||||
print() # 超时后换行,避免覆盖下一条日志
|
print() # 超时后换行,避免覆盖下一条日志
|
||||||
|
|
||||||
elif isinstance(message_earliest, MessageSending):
|
elif isinstance(message_earliest, MessageSending):
|
||||||
# --- 处理发送消息 ---
|
# --- 处理发送消息 ---
|
||||||
@@ -300,7 +305,7 @@ class MessageManager:
|
|||||||
if msg is message_earliest:
|
if msg is message_earliest:
|
||||||
continue
|
continue
|
||||||
logger.info(f"[{chat_id}] 处理超时发送消息: {msg.message_info.message_id}")
|
logger.info(f"[{chat_id}] 处理超时发送消息: {msg.message_info.message_id}")
|
||||||
await self._handle_sending_message(container, msg) # 复用处理逻辑
|
await self._handle_sending_message(container, msg) # 复用处理逻辑
|
||||||
|
|
||||||
# 清理空容器 (可选)
|
# 清理空容器 (可选)
|
||||||
# async with self._container_lock:
|
# async with self._container_lock:
|
||||||
@@ -308,7 +313,6 @@ class MessageManager:
|
|||||||
# logger.debug(f"[{chat_id}] 容器已空,准备移除。")
|
# logger.debug(f"[{chat_id}] 容器已空,准备移除。")
|
||||||
# del self.containers[chat_id]
|
# del self.containers[chat_id]
|
||||||
|
|
||||||
|
|
||||||
async def _start_processor_loop(self):
|
async def _start_processor_loop(self):
|
||||||
"""消息处理器主循环"""
|
"""消息处理器主循环"""
|
||||||
while self._running:
|
while self._running:
|
||||||
@@ -319,8 +323,8 @@ class MessageManager:
|
|||||||
chat_ids = list(self.containers.keys())
|
chat_ids = list(self.containers.keys())
|
||||||
|
|
||||||
for chat_id in chat_ids:
|
for chat_id in chat_ids:
|
||||||
# 为每个 chat_id 创建一个处理任务
|
# 为每个 chat_id 创建一个处理任务
|
||||||
tasks.append(asyncio.create_task(self._process_chat_messages(chat_id)))
|
tasks.append(asyncio.create_task(self._process_chat_messages(chat_id)))
|
||||||
|
|
||||||
if tasks:
|
if tasks:
|
||||||
try:
|
try:
|
||||||
@@ -331,13 +335,14 @@ class MessageManager:
|
|||||||
|
|
||||||
# 等待一小段时间,避免CPU空转
|
# 等待一小段时间,避免CPU空转
|
||||||
try:
|
try:
|
||||||
await asyncio.sleep(0.1) # 稍微降低轮询频率
|
await asyncio.sleep(0.1) # 稍微降低轮询频率
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info("Processor loop sleep cancelled.")
|
logger.info("Processor loop sleep cancelled.")
|
||||||
break # 退出循环
|
break # 退出循环
|
||||||
logger.info("MessageManager processor loop finished.")
|
logger.info("MessageManager processor loop finished.")
|
||||||
|
|
||||||
|
|
||||||
# --- 创建全局实例 ---
|
# --- 创建全局实例 ---
|
||||||
message_manager = MessageManager()
|
message_manager = MessageManager()
|
||||||
message_sender = MessageSender()
|
message_sender = MessageSender()
|
||||||
# --- 结束全局实例 ---
|
# --- 结束全局实例 ---
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ from src.plugins.models.utils_model import LLMRequest
|
|||||||
from src.config.config import global_config
|
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.chat.utils_image import image_path_to_base64 # Local import needed after move
|
||||||
from src.plugins.utils.timer_calculater import Timer # <--- Import Timer
|
from src.plugins.utils.timer_calculater import Timer # <--- Import Timer
|
||||||
|
|
||||||
# --- Import necessary dependencies directly ---
|
# --- Import necessary dependencies directly ---
|
||||||
from .heartFC_generator import ResponseGenerator # Assuming this is the type for gpt
|
from .heartFC_generator import ResponseGenerator # Assuming this is the type for gpt
|
||||||
from src.do_tool.tool_use import ToolUser
|
from src.do_tool.tool_use import ToolUser
|
||||||
from src.plugins.chat.emoji_manager import EmojiManager # Assuming this is the type
|
from src.plugins.chat.emoji_manager import EmojiManager # Assuming this is the type
|
||||||
from ..chat.message_sender import message_manager # <-- Import the global manager
|
from ..chat.message_sender import message_manager # <-- Import the global manager
|
||||||
# --- End import ---
|
# --- End import ---
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ if TYPE_CHECKING:
|
|||||||
# Keep this if HeartFCController methods are still needed elsewhere,
|
# Keep this if HeartFCController methods are still needed elsewhere,
|
||||||
# but the instance variable will be removed from HeartFChatting
|
# but the instance variable will be removed from HeartFChatting
|
||||||
# from .heartFC_controler import HeartFCController
|
# from .heartFC_controler import HeartFCController
|
||||||
from src.heart_flow.heartflow import SubHeartflow, heartflow # <-- 同时导入 heartflow 实例用于类型检查
|
from src.heart_flow.heartflow import SubHeartflow, heartflow # <-- 同时导入 heartflow 实例用于类型检查
|
||||||
|
|
||||||
PLANNER_TOOL_DEFINITION = [
|
PLANNER_TOOL_DEFINITION = [
|
||||||
{
|
{
|
||||||
@@ -74,16 +75,17 @@ class HeartFChatting:
|
|||||||
现在由其关联的 SubHeartflow 管理生命周期。
|
现在由其关联的 SubHeartflow 管理生命周期。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(
|
||||||
chat_id: str,
|
self,
|
||||||
# 显式依赖注入
|
chat_id: str,
|
||||||
gpt_instance: ResponseGenerator, # 文本回复生成器
|
# 显式依赖注入
|
||||||
tool_user_instance: ToolUser, # 工具使用实例
|
gpt_instance: ResponseGenerator, # 文本回复生成器
|
||||||
emoji_manager_instance: EmojiManager, # 表情管理实例
|
tool_user_instance: ToolUser, # 工具使用实例
|
||||||
):
|
emoji_manager_instance: EmojiManager, # 表情管理实例
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
HeartFChatting 初始化函数
|
HeartFChatting 初始化函数
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
chat_id: 聊天流唯一标识符(如stream_id)
|
chat_id: 聊天流唯一标识符(如stream_id)
|
||||||
gpt_instance: 文本回复生成器实例
|
gpt_instance: 文本回复生成器实例
|
||||||
@@ -94,7 +96,7 @@ class HeartFChatting:
|
|||||||
self.stream_id: str = chat_id # 聊天流ID
|
self.stream_id: str = chat_id # 聊天流ID
|
||||||
self.chat_stream: Optional[ChatStream] = None # 关联的聊天流
|
self.chat_stream: Optional[ChatStream] = None # 关联的聊天流
|
||||||
self.sub_hf: Optional[SubHeartflow] = None # 关联的子心流
|
self.sub_hf: Optional[SubHeartflow] = None # 关联的子心流
|
||||||
|
|
||||||
# 初始化状态控制
|
# 初始化状态控制
|
||||||
self._initialized = False # 是否已初始化标志
|
self._initialized = False # 是否已初始化标志
|
||||||
self._init_lock = asyncio.Lock() # 初始化锁(确保只初始化一次)
|
self._init_lock = asyncio.Lock() # 初始化锁(确保只初始化一次)
|
||||||
@@ -145,6 +147,7 @@ class HeartFChatting:
|
|||||||
|
|
||||||
# <-- 在这里导入 heartflow 实例
|
# <-- 在这里导入 heartflow 实例
|
||||||
from src.heart_flow.heartflow import heartflow
|
from src.heart_flow.heartflow import heartflow
|
||||||
|
|
||||||
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
||||||
if not self.sub_hf:
|
if not self.sub_hf:
|
||||||
logger.warning(f"{log_prefix} 获取SubHeartflow失败。一些功能可能受限。")
|
logger.warning(f"{log_prefix} 获取SubHeartflow失败。一些功能可能受限。")
|
||||||
@@ -391,7 +394,9 @@ class HeartFChatting:
|
|||||||
logger.info(f"{log_prefix} 等待新消息的 sleep 被中断。")
|
logger.info(f"{log_prefix} 等待新消息的 sleep 被中断。")
|
||||||
raise # 重新抛出取消错误,以便外层循环处理
|
raise # 重新抛出取消错误,以便外层循环处理
|
||||||
else:
|
else:
|
||||||
logger.warning(f"{log_prefix} HeartFChatting: 无法获取 Observation 实例,无法等待新消息。")
|
logger.warning(
|
||||||
|
f"{log_prefix} HeartFChatting: 无法获取 Observation 实例,无法等待新消息。"
|
||||||
|
)
|
||||||
# --- 等待结束 ---
|
# --- 等待结束 ---
|
||||||
|
|
||||||
elif action == "error": # Action specifically set to error by planner
|
elif action == "error": # Action specifically set to error by planner
|
||||||
@@ -413,9 +418,7 @@ class HeartFChatting:
|
|||||||
timer_strings.append(f"{name}: {formatted_time}")
|
timer_strings.append(f"{name}: {formatted_time}")
|
||||||
|
|
||||||
if timer_strings: # 如果有有效计时器数据才打印
|
if timer_strings: # 如果有有效计时器数据才打印
|
||||||
logger.debug(
|
logger.debug(f"{log_prefix} 该次决策耗时: {'; '.join(timer_strings)}")
|
||||||
f"{log_prefix} 该次决策耗时: {'; '.join(timer_strings)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# --- Timer Decrement --- #
|
# --- Timer Decrement --- #
|
||||||
cycle_duration = time.monotonic() - loop_cycle_start_time
|
cycle_duration = time.monotonic() - loop_cycle_start_time
|
||||||
@@ -484,8 +487,12 @@ class HeartFChatting:
|
|||||||
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
self.sub_hf = heartflow.get_subheartflow(self.stream_id)
|
||||||
if not self.sub_hf:
|
if not self.sub_hf:
|
||||||
logger.error(f"{log_prefix}[Planner] SubHeartflow is not available. Cannot proceed.")
|
logger.error(f"{log_prefix}[Planner] SubHeartflow is not available. Cannot proceed.")
|
||||||
return {"action": "error", "reasoning": "SubHeartflow unavailable", "llm_error": True, "observed_messages": []}
|
return {
|
||||||
|
"action": "error",
|
||||||
|
"reasoning": "SubHeartflow unavailable",
|
||||||
|
"llm_error": True,
|
||||||
|
"observed_messages": [],
|
||||||
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Access observation via self.sub_hf
|
# Access observation via self.sub_hf
|
||||||
@@ -503,9 +510,7 @@ class HeartFChatting:
|
|||||||
# --- (Moved from _replier_work) 1. 思考前使用工具 --- #
|
# --- (Moved from _replier_work) 1. 思考前使用工具 --- #
|
||||||
try:
|
try:
|
||||||
# Access tool_user directly
|
# Access tool_user directly
|
||||||
tool_result = await self.tool_user.use_tool(
|
tool_result = await self.tool_user.use_tool(message_txt=observed_messages_str, sub_heartflow=self.sub_hf)
|
||||||
message_txt=observed_messages_str, sub_heartflow=self.sub_hf
|
|
||||||
)
|
|
||||||
if tool_result.get("used_tools", False):
|
if tool_result.get("used_tools", False):
|
||||||
tool_result_info = tool_result.get("structured_info", {})
|
tool_result_info = tool_result.get("structured_info", {})
|
||||||
logger.debug(f"{log_prefix}[Planner] 规划前工具结果: {tool_result_info}")
|
logger.debug(f"{log_prefix}[Planner] 规划前工具结果: {tool_result_info}")
|
||||||
@@ -620,7 +625,6 @@ class HeartFChatting:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
# --- Create Placeholder --- #
|
# --- Create Placeholder --- #
|
||||||
placeholder_id = f"mid_pf_{int(time.time() * 1000)}"
|
placeholder_id = f"mid_pf_{int(time.time() * 1000)}"
|
||||||
placeholder_user = UserInfo(
|
placeholder_user = UserInfo(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
|||||||
from ..utils.timer_calculater import Timer
|
from ..utils.timer_calculater import Timer
|
||||||
|
|
||||||
from src.plugins.moods.moods import MoodManager
|
from src.plugins.moods.moods import MoodManager
|
||||||
|
|
||||||
# 定义日志配置
|
# 定义日志配置
|
||||||
llm_config = LogConfig(
|
llm_config = LogConfig(
|
||||||
# 使用消息发送专用样式
|
# 使用消息发送专用样式
|
||||||
@@ -78,7 +79,6 @@ class ResponseGenerator:
|
|||||||
|
|
||||||
sender_name = f"<{message.chat_stream.user_info.platform}:{message.chat_stream.user_info.user_id}:{message.chat_stream.user_info.user_nickname}:{message.chat_stream.user_info.user_cardname}>"
|
sender_name = f"<{message.chat_stream.user_info.platform}:{message.chat_stream.user_info.user_id}:{message.chat_stream.user_info.user_nickname}:{message.chat_stream.user_info.user_cardname}>"
|
||||||
|
|
||||||
|
|
||||||
with Timer() as t_build_prompt:
|
with Timer() as t_build_prompt:
|
||||||
prompt = await prompt_builder.build_prompt(
|
prompt = await prompt_builder.build_prompt(
|
||||||
build_mode="focus",
|
build_mode="focus",
|
||||||
@@ -86,7 +86,7 @@ class ResponseGenerator:
|
|||||||
current_mind_info=current_mind_info,
|
current_mind_info=current_mind_info,
|
||||||
message_txt=message.processed_plain_text,
|
message_txt=message.processed_plain_text,
|
||||||
sender_name=sender_name,
|
sender_name=sender_name,
|
||||||
chat_stream=message.chat_stream
|
chat_stream=message.chat_stream,
|
||||||
)
|
)
|
||||||
logger.info(f"构建prompt时间: {t_build_prompt.human_readable}")
|
logger.info(f"构建prompt时间: {t_build_prompt.human_readable}")
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ def init_prompt():
|
|||||||
涉及政治敏感以及违法违规的内容请规避。""",
|
涉及政治敏感以及违法违规的内容请规避。""",
|
||||||
"moderation_prompt",
|
"moderation_prompt",
|
||||||
)
|
)
|
||||||
|
|
||||||
Prompt(
|
Prompt(
|
||||||
"""
|
"""
|
||||||
{relation_prompt_all}
|
{relation_prompt_all}
|
||||||
@@ -77,23 +77,18 @@ class PromptBuilder:
|
|||||||
self.prompt_built = ""
|
self.prompt_built = ""
|
||||||
self.activate_messages = ""
|
self.activate_messages = ""
|
||||||
|
|
||||||
|
|
||||||
async def build_prompt(
|
async def build_prompt(
|
||||||
self, build_mode,reason,current_mind_info, message_txt: str, sender_name: str = "某人",chat_stream=None
|
self, build_mode, reason, current_mind_info, message_txt: str, sender_name: str = "某人", chat_stream=None
|
||||||
) -> tuple[str, str]:
|
) -> tuple[str, str]:
|
||||||
|
|
||||||
if build_mode == "normal":
|
if build_mode == "normal":
|
||||||
return await self._build_prompt_normal(chat_stream, message_txt, sender_name)
|
return await self._build_prompt_normal(chat_stream, message_txt, sender_name)
|
||||||
|
|
||||||
elif build_mode == "focus":
|
elif build_mode == "focus":
|
||||||
return await self._build_prompt_focus(reason, current_mind_info, chat_stream, message_txt, sender_name)
|
return await self._build_prompt_focus(reason, current_mind_info, chat_stream, message_txt, sender_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def _build_prompt_focus(
|
async def _build_prompt_focus(
|
||||||
self, reason, current_mind_info, chat_stream, message_txt: str, sender_name: str = "某人"
|
self, reason, current_mind_info, chat_stream, message_txt: str, sender_name: str = "某人"
|
||||||
) -> tuple[str, str]:
|
) -> tuple[str, str]:
|
||||||
|
|
||||||
individuality = Individuality.get_instance()
|
individuality = Individuality.get_instance()
|
||||||
prompt_personality = individuality.get_prompt(type="personality", x_person=2, level=1)
|
prompt_personality = individuality.get_prompt(type="personality", x_person=2, level=1)
|
||||||
prompt_identity = individuality.get_prompt(type="identity", x_person=2, level=1)
|
prompt_identity = individuality.get_prompt(type="identity", x_person=2, level=1)
|
||||||
@@ -104,14 +99,14 @@ class PromptBuilder:
|
|||||||
if chat_stream.group_info:
|
if chat_stream.group_info:
|
||||||
chat_in_group = True
|
chat_in_group = True
|
||||||
else:
|
else:
|
||||||
chat_in_group = False
|
chat_in_group = False
|
||||||
|
|
||||||
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
|
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
|
||||||
chat_id =chat_stream.stream_id,
|
chat_id=chat_stream.stream_id,
|
||||||
timestamp = time.time(),
|
timestamp=time.time(),
|
||||||
limit=global_config.MAX_CONTEXT_SIZE,
|
limit=global_config.MAX_CONTEXT_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
chat_talking_prompt = await build_readable_messages(
|
chat_talking_prompt = await build_readable_messages(
|
||||||
message_list_before_now,
|
message_list_before_now,
|
||||||
replace_bot_name=True,
|
replace_bot_name=True,
|
||||||
@@ -147,7 +142,6 @@ class PromptBuilder:
|
|||||||
if random.random() < 0.02:
|
if random.random() < 0.02:
|
||||||
prompt_ger += "你喜欢用反问句"
|
prompt_ger += "你喜欢用反问句"
|
||||||
|
|
||||||
|
|
||||||
logger.debug("开始构建prompt")
|
logger.debug("开始构建prompt")
|
||||||
|
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
prompt = await global_prompt_manager.format_prompt(
|
||||||
@@ -176,11 +170,7 @@ class PromptBuilder:
|
|||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
async def _build_prompt_normal(self, chat_stream, message_txt: str, sender_name: str = "某人") -> tuple[str, str]:
|
||||||
|
|
||||||
async def _build_prompt_normal(
|
|
||||||
self, chat_stream, message_txt: str, sender_name: str = "某人"
|
|
||||||
) -> tuple[str, str]:
|
|
||||||
# 开始构建prompt
|
# 开始构建prompt
|
||||||
prompt_personality = "你"
|
prompt_personality = "你"
|
||||||
# person
|
# person
|
||||||
@@ -245,14 +235,14 @@ class PromptBuilder:
|
|||||||
if chat_stream.group_info:
|
if chat_stream.group_info:
|
||||||
chat_in_group = True
|
chat_in_group = True
|
||||||
else:
|
else:
|
||||||
chat_in_group = False
|
chat_in_group = False
|
||||||
|
|
||||||
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
|
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
|
||||||
chat_id =chat_stream.stream_id,
|
chat_id=chat_stream.stream_id,
|
||||||
timestamp = time.time(),
|
timestamp=time.time(),
|
||||||
limit=global_config.MAX_CONTEXT_SIZE,
|
limit=global_config.MAX_CONTEXT_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
chat_talking_prompt = await build_readable_messages(
|
chat_talking_prompt = await build_readable_messages(
|
||||||
message_list_before_now,
|
message_list_before_now,
|
||||||
replace_bot_name=True,
|
replace_bot_name=True,
|
||||||
@@ -260,9 +250,7 @@ class PromptBuilder:
|
|||||||
timestamp_mode="relative",
|
timestamp_mode="relative",
|
||||||
read_mark=0.0,
|
read_mark=0.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 关键词检测与反应
|
# 关键词检测与反应
|
||||||
keywords_reaction_prompt = ""
|
keywords_reaction_prompt = ""
|
||||||
for rule in global_config.keywords_reaction_rules:
|
for rule in global_config.keywords_reaction_rules:
|
||||||
@@ -303,11 +291,11 @@ class PromptBuilder:
|
|||||||
logger.debug(f"知识检索耗时: {(end_time - start_time):.3f}秒")
|
logger.debug(f"知识检索耗时: {(end_time - start_time):.3f}秒")
|
||||||
|
|
||||||
logger.debug("开始构建prompt")
|
logger.debug("开始构建prompt")
|
||||||
|
|
||||||
schedule_prompt=await global_prompt_manager.format_prompt(
|
schedule_prompt = await global_prompt_manager.format_prompt(
|
||||||
"schedule_prompt", schedule_info=bot_schedule.get_current_num_task(num=1, time_info=False)
|
"schedule_prompt", schedule_info=bot_schedule.get_current_num_task(num=1, time_info=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
prompt = await global_prompt_manager.format_prompt(
|
||||||
"reasoning_prompt_main",
|
"reasoning_prompt_main",
|
||||||
relation_prompt_all=await global_prompt_manager.get_prompt_async("relationship_prompt"),
|
relation_prompt_all=await global_prompt_manager.get_prompt_async("relationship_prompt"),
|
||||||
@@ -558,6 +546,5 @@ class PromptBuilder:
|
|||||||
return "\n".join(str(result["content"]) for result in results)
|
return "\n".join(str(result["content"]) for result in results)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init_prompt()
|
init_prompt()
|
||||||
prompt_builder = PromptBuilder()
|
prompt_builder = PromptBuilder()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
|||||||
from src.plugins.utils.timer_calculater import Timer
|
from src.plugins.utils.timer_calculater import Timer
|
||||||
from src.heart_flow.heartflow import heartflow
|
from src.heart_flow.heartflow import heartflow
|
||||||
from src.heart_flow.sub_heartflow import ChatState
|
from src.heart_flow.sub_heartflow import ChatState
|
||||||
|
|
||||||
# 定义日志配置
|
# 定义日志配置
|
||||||
chat_config = LogConfig(
|
chat_config = LogConfig(
|
||||||
console_format=CHAT_STYLE_CONFIG["console_format"],
|
console_format=CHAT_STYLE_CONFIG["console_format"],
|
||||||
@@ -129,7 +130,7 @@ class NormalChat:
|
|||||||
is_head=not mark_head,
|
is_head=not mark_head,
|
||||||
is_emoji=False,
|
is_emoji=False,
|
||||||
thinking_start_time=thinking_start_time,
|
thinking_start_time=thinking_start_time,
|
||||||
apply_set_reply_logic=True
|
apply_set_reply_logic=True,
|
||||||
)
|
)
|
||||||
if not mark_head:
|
if not mark_head:
|
||||||
mark_head = True
|
mark_head = True
|
||||||
@@ -165,7 +166,7 @@ class NormalChat:
|
|||||||
reply=message,
|
reply=message,
|
||||||
is_head=False,
|
is_head=False,
|
||||||
is_emoji=True,
|
is_emoji=True,
|
||||||
apply_set_reply_logic=True
|
apply_set_reply_logic=True,
|
||||||
)
|
)
|
||||||
await message_manager.add_message(bot_message)
|
await message_manager.add_message(bot_message)
|
||||||
|
|
||||||
@@ -212,13 +213,13 @@ class NormalChat:
|
|||||||
if removed_item:
|
if removed_item:
|
||||||
# logger.debug(f"[{stream_name}] 已从兴趣字典中移除消息 {msg_id} (因状态跳过)") # 减少日志
|
# logger.debug(f"[{stream_name}] 已从兴趣字典中移除消息 {msg_id} (因状态跳过)") # 减少日志
|
||||||
pass
|
pass
|
||||||
continue # 处理下一条消息
|
continue # 处理下一条消息
|
||||||
# --- 结束状态检查 --- #
|
# --- 结束状态检查 --- #
|
||||||
|
|
||||||
# --- 检查 HeartFChatting 是否活跃 (改为检查 SubHeartflow 状态) --- #
|
# --- 检查 HeartFChatting 是否活跃 (改为检查 SubHeartflow 状态) --- #
|
||||||
is_focused = subheartflow.chat_state.chat_status == ChatState.FOCUSED
|
is_focused = subheartflow.chat_state.chat_status == ChatState.FOCUSED
|
||||||
|
|
||||||
if is_focused: # New check: If the subflow is focused, NormalChat shouldn't process
|
if is_focused: # New check: If the subflow is focused, NormalChat shouldn't process
|
||||||
removed_item = interest_dict.pop(msg_id, None)
|
removed_item = interest_dict.pop(msg_id, None)
|
||||||
if removed_item:
|
if removed_item:
|
||||||
# logger.debug(f"[{stream_name}] SubHeartflow 处于 FOCUSED 状态,已跳过并移除 NormalChat 兴趣消息 {msg_id}") # Reduce noise
|
# logger.debug(f"[{stream_name}] SubHeartflow 处于 FOCUSED 状态,已跳过并移除 NormalChat 兴趣消息 {msg_id}") # Reduce noise
|
||||||
@@ -264,7 +265,7 @@ class NormalChat:
|
|||||||
)
|
)
|
||||||
# 可以在这里添加 not_reply_handle 逻辑吗? 如果不回复,也需要清理意愿。
|
# 可以在这里添加 not_reply_handle 逻辑吗? 如果不回复,也需要清理意愿。
|
||||||
# 注意:willing_manager.setup 尚未调用
|
# 注意:willing_manager.setup 尚未调用
|
||||||
willing_manager.setup(message, chat, is_mentioned, interested_rate) # 先 setup
|
willing_manager.setup(message, chat, is_mentioned, interested_rate) # 先 setup
|
||||||
await willing_manager.not_reply_handle(message.message_info.message_id)
|
await willing_manager.not_reply_handle(message.message_info.message_id)
|
||||||
willing_manager.delete(message.message_info.message_id)
|
willing_manager.delete(message.message_info.message_id)
|
||||||
return
|
return
|
||||||
@@ -313,7 +314,7 @@ class NormalChat:
|
|||||||
|
|
||||||
# 生成回复
|
# 生成回复
|
||||||
sub_hf = heartflow.get_subheartflow(stream_id)
|
sub_hf = heartflow.get_subheartflow(stream_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with Timer("生成回复", timing_results):
|
with Timer("生成回复", timing_results):
|
||||||
response_set = await self.gpt.generate_response(
|
response_set = await self.gpt.generate_response(
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from ..utils.timer_calculater import Timer
|
|||||||
from src.common.logger import get_module_logger, LogConfig, LLM_STYLE_CONFIG
|
from src.common.logger import get_module_logger, LogConfig, LLM_STYLE_CONFIG
|
||||||
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
||||||
from src.heart_flow.sub_heartflow import SubHeartflow
|
from src.heart_flow.sub_heartflow import SubHeartflow
|
||||||
|
|
||||||
# 定义日志配置
|
# 定义日志配置
|
||||||
llm_config = LogConfig(
|
llm_config = LogConfig(
|
||||||
# 使用消息发送专用样式
|
# 使用消息发送专用样式
|
||||||
@@ -40,7 +41,9 @@ class ResponseGenerator:
|
|||||||
self.current_model_type = "r1" # 默认使用 R1
|
self.current_model_type = "r1" # 默认使用 R1
|
||||||
self.current_model_name = "unknown model"
|
self.current_model_name = "unknown model"
|
||||||
|
|
||||||
async def generate_response(self, sub_hf: SubHeartflow, message: MessageThinking, thinking_id: str) -> Optional[Union[str, List[str]]]:
|
async def generate_response(
|
||||||
|
self, sub_hf: SubHeartflow, message: MessageThinking, thinking_id: str
|
||||||
|
) -> Optional[Union[str, List[str]]]:
|
||||||
"""根据当前模型类型选择对应的生成函数"""
|
"""根据当前模型类型选择对应的生成函数"""
|
||||||
# 从global_config中获取模型概率值并选择模型
|
# 从global_config中获取模型概率值并选择模型
|
||||||
if random.random() < global_config.model_reasoning_probability:
|
if random.random() < global_config.model_reasoning_probability:
|
||||||
@@ -67,7 +70,9 @@ class ResponseGenerator:
|
|||||||
logger.info(f"{self.current_model_type}思考,失败")
|
logger.info(f"{self.current_model_type}思考,失败")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def _generate_response_with_model(self, sub_hf: SubHeartflow, message: MessageThinking, model: LLMRequest, thinking_id: str):
|
async def _generate_response_with_model(
|
||||||
|
self, sub_hf: SubHeartflow, message: MessageThinking, model: LLMRequest, thinking_id: str
|
||||||
|
):
|
||||||
info_catcher = info_catcher_manager.get_info_catcher(thinking_id)
|
info_catcher = info_catcher_manager.get_info_catcher(thinking_id)
|
||||||
|
|
||||||
if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname:
|
if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname:
|
||||||
@@ -85,7 +90,7 @@ class ResponseGenerator:
|
|||||||
with Timer() as t_build_prompt:
|
with Timer() as t_build_prompt:
|
||||||
prompt = await prompt_builder.build_prompt(
|
prompt = await prompt_builder.build_prompt(
|
||||||
build_mode="normal",
|
build_mode="normal",
|
||||||
reason= "",
|
reason="",
|
||||||
current_mind_info="",
|
current_mind_info="",
|
||||||
message_txt=message.processed_plain_text,
|
message_txt=message.processed_plain_text,
|
||||||
sender_name=sender_name,
|
sender_name=sender_name,
|
||||||
@@ -95,7 +100,7 @@ class ResponseGenerator:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
content, reasoning_content, self.current_model_name = await model.generate_response(prompt)
|
content, reasoning_content, self.current_model_name = await model.generate_response(prompt)
|
||||||
|
|
||||||
logger.info(f"prompt:{prompt}\n生成回复:{content}")
|
logger.info(f"prompt:{prompt}\n生成回复:{content}")
|
||||||
|
|
||||||
info_catcher.catch_after_llm_generated(
|
info_catcher.catch_after_llm_generated(
|
||||||
@@ -108,7 +113,6 @@ class ResponseGenerator:
|
|||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
async def _get_emotion_tags(self, content: str, processed_plain_text: str):
|
async def _get_emotion_tags(self, content: str, processed_plain_text: str):
|
||||||
"""提取情感标签,结合立场和情绪"""
|
"""提取情感标签,结合立场和情绪"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ async def _build_readable_messages_internal(
|
|||||||
if stripped_line.endswith("。"):
|
if stripped_line.endswith("。"):
|
||||||
stripped_line = stripped_line[:-1]
|
stripped_line = stripped_line[:-1]
|
||||||
output_lines.append(f"{stripped_line};")
|
output_lines.append(f"{stripped_line};")
|
||||||
output_lines.append("\n") # 在每个消息块后添加换行,保持可读性
|
output_lines.append("\n") # 在每个消息块后添加换行,保持可读性
|
||||||
|
|
||||||
# 移除可能的多余换行,然后合并
|
# 移除可能的多余换行,然后合并
|
||||||
formatted_string = "".join(output_lines).strip()
|
formatted_string = "".join(output_lines).strip()
|
||||||
@@ -314,5 +314,4 @@ async def build_readable_messages(
|
|||||||
return f"{read_mark_line}{formatted_after}"
|
return f"{read_mark_line}{formatted_after}"
|
||||||
else:
|
else:
|
||||||
# 理论上不应该发生,但作为保险
|
# 理论上不应该发生,但作为保险
|
||||||
return read_mark_line.strip() # 如果前后都无消息,只返回标记行
|
return read_mark_line.strip() # 如果前后都无消息,只返回标记行
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user