fix:更名和小bug修复
This commit is contained in:
@@ -4,7 +4,7 @@ from src.plugins.moods.moods import MoodManager
|
||||
from src.plugins.models.utils_model import LLMRequest
|
||||
from src.config.config import global_config
|
||||
import time
|
||||
from typing import Optional, List, Dict
|
||||
from typing import Optional, List, Dict, Callable, TYPE_CHECKING
|
||||
import traceback
|
||||
from src.plugins.chat.utils import parse_text_timestamps
|
||||
import enum
|
||||
@@ -14,8 +14,14 @@ import random
|
||||
from src.plugins.person_info.relationship_manager import relationship_manager
|
||||
from ..plugins.utils.prompt_builder import Prompt, global_prompt_manager
|
||||
from src.plugins.chat.message import MessageRecv
|
||||
from src.plugins.chat.chat_stream import chat_manager
|
||||
import math
|
||||
|
||||
# Type hinting for circular dependency
|
||||
if TYPE_CHECKING:
|
||||
from .heartflow import Heartflow, MaiState # Import Heartflow for type hinting
|
||||
from .sub_heartflow import ChatState # Keep ChatState here too?
|
||||
|
||||
# 定义常量 (从 interest.py 移动过来)
|
||||
MAX_INTEREST = 15.0
|
||||
|
||||
@@ -68,9 +74,6 @@ class ChatStateInfo:
|
||||
self.mood_manager = MoodManager()
|
||||
self.mood = self.mood_manager.get_prompt()
|
||||
|
||||
def update_chat_state_info(self):
|
||||
self.chat_state_info = self.mood_manager.get_current_mood()
|
||||
|
||||
|
||||
base_reply_probability = 0.05
|
||||
probability_increase_rate_per_second = 0.08
|
||||
@@ -87,6 +90,7 @@ class InterestChatting:
|
||||
increase_rate=probability_increase_rate_per_second,
|
||||
decay_factor=global_config.probability_decay_factor_per_second,
|
||||
max_probability=max_reply_probability,
|
||||
state_change_callback: Optional[Callable[[ChatState], None]] = None
|
||||
):
|
||||
self.interest_level: float = 0.0
|
||||
self.last_update_time: float = time.time()
|
||||
@@ -101,6 +105,7 @@ class InterestChatting:
|
||||
self.max_reply_probability: float = max_probability
|
||||
self.current_reply_probability: float = 0.0
|
||||
self.is_above_threshold: bool = False
|
||||
self.state_change_callback = state_change_callback
|
||||
|
||||
self.interest_dict: Dict[str, tuple[MessageRecv, float, bool]] = {}
|
||||
|
||||
@@ -144,6 +149,7 @@ class InterestChatting:
|
||||
return
|
||||
|
||||
currently_above = self.interest_level >= self.trigger_threshold
|
||||
previous_is_above = self.is_above_threshold
|
||||
|
||||
if currently_above:
|
||||
if not self.is_above_threshold:
|
||||
@@ -158,6 +164,13 @@ class InterestChatting:
|
||||
self.current_reply_probability = min(self.current_reply_probability, self.max_reply_probability)
|
||||
|
||||
else:
|
||||
if previous_is_above:
|
||||
if self.state_change_callback:
|
||||
try:
|
||||
self.state_change_callback(ChatState.ABSENT)
|
||||
except Exception as e:
|
||||
interest_logger.error(f"Error calling state_change_callback for ABSENT: {e}")
|
||||
|
||||
if 0 < self.probability_decay_factor < 1:
|
||||
decay_multiplier = math.pow(self.probability_decay_factor, time_delta)
|
||||
self.current_reply_probability *= decay_multiplier
|
||||
@@ -216,14 +229,15 @@ class InterestChatting:
|
||||
|
||||
|
||||
class SubHeartflow:
|
||||
def __init__(self, subheartflow_id):
|
||||
def __init__(self, subheartflow_id, parent_heartflow: 'Heartflow'):
|
||||
self.subheartflow_id = subheartflow_id
|
||||
self.parent_heartflow = parent_heartflow
|
||||
|
||||
self.current_mind = "你什么也没想"
|
||||
self.past_mind = []
|
||||
self.chat_state: ChatStateInfo = ChatStateInfo()
|
||||
|
||||
self.interest_chatting = InterestChatting()
|
||||
self.interest_chatting = InterestChatting(state_change_callback=self.set_chat_state)
|
||||
|
||||
self.llm_model = LLMRequest(
|
||||
model=global_config.llm_sub_heartflow,
|
||||
@@ -234,33 +248,58 @@ class SubHeartflow:
|
||||
|
||||
self.main_heartflow_info = ""
|
||||
|
||||
self.last_active_time = time.time() # 添加最后激活时间
|
||||
self.should_stop = False # 添加停止标志
|
||||
self.task: Optional[asyncio.Task] = None # 添加 task 属性
|
||||
self.last_active_time = time.time()
|
||||
self.should_stop = False
|
||||
self.task: Optional[asyncio.Task] = None
|
||||
|
||||
self.is_active = False
|
||||
|
||||
self.observations: List[ChattingObservation] = [] # 使用 List 类型提示
|
||||
self.observations: List[ChattingObservation] = []
|
||||
|
||||
self.running_knowledges = []
|
||||
|
||||
self.bot_name = global_config.BOT_NICKNAME
|
||||
logger.info(f"SubHeartflow {self.subheartflow_id} created with initial state: {self.chat_state.chat_status.value}")
|
||||
|
||||
def set_chat_state(self, new_state: 'ChatState'):
|
||||
"""更新sub_heartflow的聊天状态"""
|
||||
|
||||
current_state = self.chat_state.chat_status
|
||||
if current_state == new_state:
|
||||
return # No change needed
|
||||
|
||||
log_prefix = f"[{chat_manager.get_stream_name(self.subheartflow_id) or self.subheartflow_id}]"
|
||||
|
||||
# --- Limit Check before entering CHAT state --- #
|
||||
if new_state == ChatState.CHAT:
|
||||
current_mai_state = self.parent_heartflow.current_state.mai_status
|
||||
normal_limit = current_mai_state.get_normal_chat_max_num()
|
||||
current_chat_count = self.parent_heartflow.count_subflows_by_state(ChatState.CHAT)
|
||||
|
||||
if current_chat_count >= normal_limit:
|
||||
logger.debug(f"{log_prefix} 拒绝从 {current_state.value} 转换到 CHAT。原因:CHAT 状态已达上限 ({normal_limit})。当前数量: {current_chat_count}")
|
||||
return # Block the state transition
|
||||
else:
|
||||
logger.debug(f"{log_prefix} 允许从 {current_state.value} 转换到 CHAT (上限: {normal_limit}, 当前: {current_chat_count})" )
|
||||
|
||||
# 如果检查通过或目标状态不是CHAT,则进行状态变更
|
||||
self.chat_state.chat_status = new_state
|
||||
# 状态变更时更新最后活跃时间
|
||||
self.last_active_time = time.time()
|
||||
logger.info(f"{log_prefix} 聊天状态从 {current_state.value} 变更为 {new_state.value}")
|
||||
|
||||
# TODO: 考虑从FOCUSED状态转出时是否需要停止PFChatting
|
||||
# 这部分逻辑可能更适合放在Heartflow的_stop_subheartflow或HeartFCController的循环中处理
|
||||
|
||||
async def subheartflow_start_working(self):
|
||||
while True:
|
||||
# --- 调整后台任务逻辑 --- #
|
||||
# 这个后台循环现在主要负责检查是否需要自我销毁
|
||||
# 不再主动进行思考或状态更新,这些由 HeartFC_Chat 驱动
|
||||
|
||||
# 检查是否被主心流标记为停止
|
||||
if self.should_stop:
|
||||
logger.info(f"子心流 {self.subheartflow_id} 被标记为停止,正在退出后台任务...")
|
||||
break # 退出循环以停止任务
|
||||
break
|
||||
|
||||
await asyncio.sleep(global_config.sub_heart_flow_update_interval) # 定期检查销毁条件
|
||||
await asyncio.sleep(global_config.sub_heart_flow_update_interval)
|
||||
|
||||
async def ensure_observed(self):
|
||||
"""确保在思考前执行了观察"""
|
||||
observation = self._get_primary_observation()
|
||||
if observation:
|
||||
try:
|
||||
@@ -273,18 +312,14 @@ class SubHeartflow:
|
||||
async def do_thinking_before_reply(
|
||||
self,
|
||||
extra_info: str,
|
||||
obs_id: list[str] = None, # 修改 obs_id 类型为 list[str]
|
||||
obs_id: list[str] = None,
|
||||
):
|
||||
# --- 在思考前确保观察已执行 --- #
|
||||
# await self.ensure_observed()
|
||||
|
||||
self.last_active_time = time.time() # 更新最后激活时间戳
|
||||
self.last_active_time = time.time()
|
||||
|
||||
current_thinking_info = self.current_mind
|
||||
mood_info = self.chat_state.mood
|
||||
observation = self._get_primary_observation()
|
||||
|
||||
# --- 获取观察信息 --- #
|
||||
chat_observe_info = ""
|
||||
if obs_id:
|
||||
try:
|
||||
@@ -294,12 +329,11 @@ class SubHeartflow:
|
||||
logger.error(
|
||||
f"[{self.subheartflow_id}] Error getting observe info with IDs {obs_id}: {e}. Falling back."
|
||||
)
|
||||
chat_observe_info = observation.get_observe_info() # 出错时回退到默认观察
|
||||
chat_observe_info = observation.get_observe_info()
|
||||
else:
|
||||
chat_observe_info = observation.get_observe_info()
|
||||
logger.debug(f"[{self.subheartflow_id}] Using default observation info.")
|
||||
# logger.debug(f"[{self.subheartflow_id}] Using default observation info.")
|
||||
|
||||
# --- 构建 Prompt (基本逻辑不变) --- #
|
||||
extra_info_prompt = ""
|
||||
if extra_info:
|
||||
for tool_name, tool_data in extra_info.items():
|
||||
@@ -307,28 +341,25 @@ class SubHeartflow:
|
||||
for item in tool_data:
|
||||
extra_info_prompt += f"- {item['name']}: {item['content']}\n"
|
||||
else:
|
||||
extra_info_prompt = "无工具信息。\n" # 提供默认值
|
||||
extra_info_prompt = "无工具信息。\n"
|
||||
|
||||
individuality = Individuality.get_instance()
|
||||
prompt_personality = f"你的名字是{self.bot_name},你"
|
||||
prompt_personality += individuality.personality.personality_core
|
||||
|
||||
# 添加随机性格侧面
|
||||
if individuality.personality.personality_sides:
|
||||
random_side = random.choice(individuality.personality.personality_sides)
|
||||
prompt_personality += f",{random_side}"
|
||||
|
||||
# 添加随机身份细节
|
||||
if individuality.identity.identity_detail:
|
||||
random_detail = random.choice(individuality.identity.identity_detail)
|
||||
prompt_personality += f",{random_detail}"
|
||||
|
||||
time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
|
||||
# 创建局部Random对象避免影响全局随机状态
|
||||
local_random = random.Random()
|
||||
current_minute = int(time.strftime("%M"))
|
||||
local_random.seed(current_minute) # 用分钟作为种子确保每分钟内选择一致
|
||||
local_random.seed(current_minute)
|
||||
|
||||
hf_options = [
|
||||
("继续生成你在这个聊天中的想法,在原来想法的基础上继续思考", 0.7),
|
||||
@@ -343,7 +374,6 @@ class SubHeartflow:
|
||||
|
||||
prompt = (await global_prompt_manager.get_prompt_async("sub_heartflow_prompt_before")).format(
|
||||
extra_info=extra_info_prompt,
|
||||
# relation_prompt_all=relation_prompt_all,
|
||||
prompt_personality=prompt_personality,
|
||||
bot_name=self.bot_name,
|
||||
current_thinking_info=current_thinking_info,
|
||||
@@ -351,8 +381,6 @@ class SubHeartflow:
|
||||
chat_observe_info=chat_observe_info,
|
||||
mood_info=mood_info,
|
||||
hf_do_next=hf_do_next,
|
||||
# sender_name=sender_name_sign,
|
||||
# message_txt=message_txt,
|
||||
)
|
||||
|
||||
prompt = await relationship_manager.convert_all_person_sign_to_person_name(prompt)
|
||||
@@ -365,18 +393,15 @@ class SubHeartflow:
|
||||
|
||||
logger.debug(f"[{self.subheartflow_id}] 心流思考结果:\n{response}\n")
|
||||
|
||||
if not response: # 如果 LLM 返回空,给一个默认想法
|
||||
if not response:
|
||||
response = "(不知道该想些什么...)"
|
||||
logger.warning(f"[{self.subheartflow_id}] LLM 返回空结果,思考失败。")
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.subheartflow_id}] 内心独白获取失败: {e}")
|
||||
response = "(思考时发生错误...)" # 错误时的默认想法
|
||||
response = "(思考时发生错误...)"
|
||||
|
||||
self.update_current_mind(response)
|
||||
|
||||
# self.current_mind 已经在 update_current_mind 中更新
|
||||
|
||||
# logger.info(f"[{self.subheartflow_id}] 思考前脑内状态:{self.current_mind}")
|
||||
return self.current_mind, self.past_mind
|
||||
|
||||
def update_current_mind(self, response):
|
||||
@@ -384,55 +409,41 @@ class SubHeartflow:
|
||||
self.current_mind = response
|
||||
|
||||
def add_observation(self, observation: Observation):
|
||||
"""添加一个新的observation对象到列表中,如果已存在相同id的observation则不添加"""
|
||||
# 查找是否存在相同id的observation
|
||||
for existing_obs in self.observations:
|
||||
if existing_obs.observe_id == observation.observe_id:
|
||||
# 如果找到相同id的observation,直接返回
|
||||
return
|
||||
# 如果没有找到相同id的observation,则添加新的
|
||||
self.observations.append(observation)
|
||||
|
||||
def remove_observation(self, observation: Observation):
|
||||
"""从列表中移除一个observation对象"""
|
||||
if observation in self.observations:
|
||||
self.observations.remove(observation)
|
||||
|
||||
def get_all_observations(self) -> list[Observation]:
|
||||
"""获取所有observation对象"""
|
||||
return self.observations
|
||||
|
||||
def clear_observations(self):
|
||||
"""清空所有observation对象"""
|
||||
self.observations.clear()
|
||||
|
||||
def _get_primary_observation(self) -> Optional[ChattingObservation]:
|
||||
"""获取主要的(通常是第一个)ChattingObservation实例"""
|
||||
if self.observations and isinstance(self.observations[0], ChattingObservation):
|
||||
return self.observations[0]
|
||||
logger.warning(f"SubHeartflow {self.subheartflow_id} 没有找到有效的 ChattingObservation")
|
||||
return None
|
||||
|
||||
def get_interest_state(self) -> dict:
|
||||
"""获取当前兴趣状态"""
|
||||
return self.interest_chatting.get_state()
|
||||
|
||||
def get_interest_level(self) -> float:
|
||||
"""获取当前兴趣等级"""
|
||||
return self.interest_chatting.get_interest()
|
||||
|
||||
def should_evaluate_reply(self) -> bool:
|
||||
"""判断是否应该评估回复"""
|
||||
return self.interest_chatting.should_evaluate_reply()
|
||||
|
||||
def add_interest_dict_entry(self, message: MessageRecv, interest_value: float, is_mentioned: bool):
|
||||
"""添加兴趣字典条目"""
|
||||
self.interest_chatting.add_interest_dict(message, interest_value, is_mentioned)
|
||||
|
||||
def get_interest_dict(self) -> Dict[str, tuple[MessageRecv, float, bool]]:
|
||||
"""获取兴趣字典"""
|
||||
return self.interest_chatting.interest_dict
|
||||
|
||||
|
||||
init_prompt()
|
||||
# subheartflow = SubHeartflow()
|
||||
|
||||
Reference in New Issue
Block a user