fix:修改config

This commit is contained in:
SengokuCola
2025-04-21 12:34:00 +08:00
parent 58c66c5c9b
commit 7e0f41c039
6 changed files with 179 additions and 155 deletions

View File

@@ -186,12 +186,18 @@ class BotConfig:
ban_words = set()
ban_msgs_regex = set()
# heartflow
# enable_heartflow: bool = False # 是否启用心流
sub_heart_flow_update_interval: int = 60 # 子心流更新频率,间隔 单位秒
sub_heart_flow_freeze_time: int = 120 # 心流冻结时间,超过这个时间没有回复,子心流会冻结,间隔 单位秒
# [heartflow] # 启用启用heart_flowC(心流聊天)模式时生效, 需要填写token消耗量巨大的相关模型
# 启用后麦麦会自主选择进入heart_flowC模式(持续一段时间), 进行长时间高质量的聊天
enable_heart_flowC: bool = True # 是否启用heart_flowC(心流聊天, HFC)模式
reply_trigger_threshold: float = 3.0 # 心流聊天触发阈值,越低越容易触发
probability_decay_factor_per_second: float = 0.2 # 概率衰减因子,越大衰减越快
default_decay_rate_per_second: float = 0.98 # 默认衰减率,越大衰减越慢
initial_duration: int = 60 # 初始持续时间,越大心流聊天持续的时间越长
# sub_heart_flow_update_interval: int = 60 # 子心流更新频率,间隔 单位秒
# sub_heart_flow_freeze_time: int = 120 # 子心流冻结时间,超过这个时间没有回复,子心流会冻结,间隔 单位秒
sub_heart_flow_stop_time: int = 600 # 子心流停止时间,超过这个时间没有回复,子心流会停止,间隔 单位秒
heart_flow_update_interval: int = 300 # 心流更新频率,间隔 单位秒
# heart_flow_update_interval: int = 300 # 心流更新频率,间隔 单位秒
observation_context_size: int = 20 # 心流观察到的最长上下文大小,超过这个值的上下文会被压缩
compressed_length: int = 5 # 不能大于observation_context_size,心流上下文压缩的最短压缩长度超过心流观察到的上下文长度会压缩最短压缩长度为5
compress_length_limit: int = 5 # 最多压缩份数,超过该数值的压缩上下文会被删除
@@ -207,8 +213,8 @@ class BotConfig:
# response
response_mode: str = "heart_flow" # 回复策略
MODEL_R1_PROBABILITY: float = 0.8 # R1模型概率
MODEL_V3_PROBABILITY: float = 0.1 # V3模型概率
model_reasoning_probability: float = 0.7 # 麦麦回答时选择推理模型(主要)模型概率
model_normal_probability: float = 0.3 # 麦麦回答时选择一般模型(次要)模型概率
# MODEL_R1_DISTILL_PROBABILITY: float = 0.1 # R1蒸馏模型概率
# emoji
@@ -401,29 +407,32 @@ class BotConfig:
def response(parent: dict):
response_config = parent["response"]
config.MODEL_R1_PROBABILITY = response_config.get("model_r1_probability", config.MODEL_R1_PROBABILITY)
config.MODEL_V3_PROBABILITY = response_config.get("model_v3_probability", config.MODEL_V3_PROBABILITY)
# config.MODEL_R1_DISTILL_PROBABILITY = response_config.get(
# "model_r1_distill_probability", config.MODEL_R1_DISTILL_PROBABILITY
# )
config.max_response_length = response_config.get("max_response_length", config.max_response_length)
if config.INNER_VERSION in SpecifierSet(">=1.0.4"):
config.response_mode = response_config.get("response_mode", config.response_mode)
config.model_reasoning_probability = response_config.get("model_reasoning_probability", config.model_reasoning_probability)
config.model_normal_probability = response_config.get("model_normal_probability", config.model_normal_probability)
# 添加 enable_heart_flowC 的加载逻辑 (假设它在 [response] 部分)
if config.INNER_VERSION in SpecifierSet(">=1.4.0"):
config.enable_heart_flowC = response_config.get("enable_heart_flowC", config.enable_heart_flowC)
def heartflow(parent: dict):
heartflow_config = parent["heartflow"]
config.sub_heart_flow_update_interval = heartflow_config.get(
"sub_heart_flow_update_interval", config.sub_heart_flow_update_interval
)
config.sub_heart_flow_freeze_time = heartflow_config.get(
"sub_heart_flow_freeze_time", config.sub_heart_flow_freeze_time
)
# 加载新增的 heartflowC 参数
# 加载原有的 heartflow 参数
# config.sub_heart_flow_update_interval = heartflow_config.get(
# "sub_heart_flow_update_interval", config.sub_heart_flow_update_interval
# )
# config.sub_heart_flow_freeze_time = heartflow_config.get(
# "sub_heart_flow_freeze_time", config.sub_heart_flow_freeze_time
# )
config.sub_heart_flow_stop_time = heartflow_config.get(
"sub_heart_flow_stop_time", config.sub_heart_flow_stop_time
)
config.heart_flow_update_interval = heartflow_config.get(
"heart_flow_update_interval", config.heart_flow_update_interval
)
# config.heart_flow_update_interval = heartflow_config.get(
# "heart_flow_update_interval", config.heart_flow_update_interval
# )
if config.INNER_VERSION in SpecifierSet(">=1.3.0"):
config.observation_context_size = heartflow_config.get(
"observation_context_size", config.observation_context_size
@@ -432,6 +441,11 @@ class BotConfig:
config.compress_length_limit = heartflow_config.get(
"compress_length_limit", config.compress_length_limit
)
if config.INNER_VERSION in SpecifierSet(">=1.4.0"):
config.reply_trigger_threshold = heartflow_config.get("reply_trigger_threshold", config.reply_trigger_threshold)
config.probability_decay_factor_per_second = heartflow_config.get("probability_decay_factor_per_second", config.probability_decay_factor_per_second)
config.default_decay_rate_per_second = heartflow_config.get("default_decay_rate_per_second", config.default_decay_rate_per_second)
config.initial_duration = heartflow_config.get("initial_duration", config.initial_duration)
def willing(parent: dict):
willing_config = parent["willing"]

View File

@@ -1,5 +1,4 @@
from .sub_heartflow import SubHeartflow
from .observation import ChattingObservation
from .sub_heartflow import SubHeartflow, ChattingObservation
from src.plugins.moods.moods import MoodManager
from src.plugins.models.utils_model import LLMRequest
from src.config.config import global_config
@@ -10,7 +9,8 @@ from src.common.logger import get_module_logger, LogConfig, HEARTFLOW_STYLE_CONF
from src.individuality.individuality import Individuality
import time
import random
from typing import Dict, Any
from typing import Dict, Any, Optional
import traceback
heartflow_config = LogConfig(
# 使用海马体专用样式
@@ -70,20 +70,27 @@ class Heartflow:
"""定期清理不活跃的子心流"""
while True:
current_time = time.time()
inactive_subheartflows = []
inactive_subheartflows_ids = [] # 修改变量名以清晰表示存储的是ID
# 检查所有子心流
for subheartflow_id, subheartflow in self._subheartflows.items():
# 使用 list(self._subheartflows.items()) 避免在迭代时修改字典
for subheartflow_id, subheartflow in list(self._subheartflows.items()):
if (
current_time - subheartflow.last_active_time > global_config.sub_heart_flow_stop_time
): # 10分钟 = 600秒
inactive_subheartflows.append(subheartflow_id)
logger.info(f"发现不活跃的子心流: {subheartflow_id}")
logger.info(f"发现不活跃的子心流: {subheartflow_id}, 准备清理。")
# 1. 标记子心流让其后台任务停止
subheartflow.should_stop = True
# 2. 将ID添加到待清理列表
inactive_subheartflows_ids.append(subheartflow_id)
# 清理不活跃的子心流
for subheartflow_id in inactive_subheartflows:
del self._subheartflows[subheartflow_id]
logger.info(f"已清理不活跃的子心流: {subheartflow_id}")
# 清理不活跃的子心流 (从字典中移除)
for subheartflow_id in inactive_subheartflows_ids:
if subheartflow_id in self._subheartflows:
del self._subheartflows[subheartflow_id]
logger.info(f"已从主心流移除子心流: {subheartflow_id}")
else:
logger.warning(f"尝试移除子心流 {subheartflow_id} 时发现其已被移除。")
await asyncio.sleep(30) # 每分钟检查一次
@@ -95,8 +102,10 @@ class Heartflow:
await asyncio.sleep(30) # 每分钟检查一次是否有新的子心流
continue
await self.do_a_thinking()
await asyncio.sleep(global_config.heart_flow_update_interval * 3) # 5分钟思考一次
# await self.do_a_thinking()
# await asyncio.sleep(global_config.heart_flow_update_interval * 3) # 5分钟思考一次
await asyncio.sleep(300)
async def heartflow_start_working(self):
# 启动清理任务
@@ -216,33 +225,55 @@ class Heartflow:
return response
async def create_subheartflow(self, subheartflow_id):
"""
创建一个新的SubHeartflow实例
添加一个SubHeartflow实例到self._subheartflows字典中
并根据subheartflow_id为子心流创建一个观察对象
async def create_subheartflow(self, subheartflow_id: Any) -> Optional[SubHeartflow]:
"""
获取或创建一个新的SubHeartflow实例。
如果实例已存在,则直接返回。
如果不存在,则创建实例、观察对象、启动后台任务,并返回新实例。
创建过程中发生任何错误将返回 None。
Args:
subheartflow_id: 用于标识子心流的ID (例如群聊ID)。
Returns:
对应的 SubHeartflow 实例,如果创建失败则返回 None。
"""
# 检查是否已存在
existing_subheartflow = self._subheartflows.get(subheartflow_id)
if existing_subheartflow:
logger.debug(f"返回已存在的 subheartflow: {subheartflow_id}")
return existing_subheartflow
# 如果不存在,则创建新的
logger.info(f"尝试创建新的 subheartflow: {subheartflow_id}")
try:
if subheartflow_id not in self._subheartflows:
subheartflow = SubHeartflow(subheartflow_id)
# 创建一个观察对象目前只可以用chat_id创建观察对象
logger.debug(f"创建 observation: {subheartflow_id}")
observation = ChattingObservation(subheartflow_id)
await observation.initialize()
subheartflow.add_observation(observation)
logger.debug("添加 observation 成功")
# 创建异步任务
asyncio.create_task(subheartflow.subheartflow_start_working())
logger.debug("创建异步任务 成功")
self._subheartflows[subheartflow_id] = subheartflow
logger.info("添加 subheartflow 成功")
return self._subheartflows[subheartflow_id]
subheartflow = SubHeartflow(subheartflow_id)
# 创建并初始化观察对象
logger.debug(f" {subheartflow_id} 创建 observation")
observation = ChattingObservation(subheartflow_id)
await observation.initialize() # 等待初始化完成
subheartflow.add_observation(observation)
logger.debug(f"{subheartflow_id} 添加 observation 成功")
# 创建并存储后台任务
subheartflow.task = asyncio.create_task(subheartflow.subheartflow_start_working())
logger.debug(f"{subheartflow_id} 创建后台任务成功")
# 添加到管理字典
self._subheartflows[subheartflow_id] = subheartflow
logger.info(f"添加 subheartflow {subheartflow_id} 成功")
return subheartflow
except Exception as e:
logger.error(f"创建 subheartflow 失败: {e}")
# 记录详细错误信息
logger.error(f"创建 subheartflow {subheartflow_id} 失败: {e}")
logger.error(traceback.format_exc()) # 记录完整的 traceback
# 考虑是否需要更具体的错误处理或资源清理逻辑
return None
def get_subheartflow(self, observe_chat_id) -> SubHeartflow:
def get_subheartflow(self, observe_chat_id: Any) -> Optional[SubHeartflow]:
"""获取指定ID的SubHeartflow实例"""
return self._subheartflows.get(observe_chat_id)

View File

@@ -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
from typing import Optional, List
from datetime import datetime
import traceback
from src.plugins.chat.utils import parse_text_timestamps
@@ -65,7 +65,7 @@ class SubHeartflow:
def __init__(self, subheartflow_id):
self.subheartflow_id = subheartflow_id
self.current_mind = ""
self.current_mind = "你什么也没想"
self.past_mind = []
self.current_state: CurrentState = CurrentState()
self.llm_model = LLMRequest(
@@ -76,16 +76,14 @@ class SubHeartflow:
)
self.main_heartflow_info = ""
self.last_reply_time = time.time()
self.last_active_time = time.time() # 添加最后激活时间
if not self.current_mind:
self.current_mind = "你什么也没想"
self.should_stop = False # 添加停止标志
self.task: Optional[asyncio.Task] = None # 添加 task 属性
self.is_active = False
self.observations: list[ChattingObservation] = []
self.observations: List[ChattingObservation] = [] # 使用 List 类型提示
self.running_knowledges = []
@@ -93,20 +91,14 @@ class SubHeartflow:
async def subheartflow_start_working(self):
while True:
current_time = time.time()
# --- 调整后台任务逻辑 --- #
# 这个后台循环现在主要负责检查是否需要自我销毁
# 不再主动进行思考或状态更新,这些由 HeartFC_Chat 驱动
# 检查是否超过指定时间没有激活 (例如,没有被调用进行思考)
if current_time - self.last_active_time > global_config.sub_heart_flow_stop_time: # 例如 5 分钟
logger.info(
f"子心流 {self.subheartflow_id} 超过 {global_config.sub_heart_flow_stop_time} 秒没有激活,正在销毁..."
f" (Last active: {datetime.fromtimestamp(self.last_active_time).strftime('%Y-%m-%d %H:%M:%S')})"
)
# 在这里添加实际的销毁逻辑,例如从主 Heartflow 管理器中移除自身
# heartflow.remove_subheartflow(self.subheartflow_id) # 假设有这样的方法
break # 退出循环以停止任务
# 检查是否被主心流标记为停止
if self.should_stop:
logger.info(f"子心流 {self.subheartflow_id} 被标记为停止,正在退出后台任务...")
break # 退出循环以停止任务
await asyncio.sleep(global_config.sub_heart_flow_update_interval) # 定期检查销毁条件

View File

@@ -105,53 +105,26 @@ class ChatBot:
template_group_name = None
async def preprocess():
if global_config.enable_pfc_chatting:
try:
if groupinfo is None:
if global_config.enable_friend_chat:
userinfo = message.message_info.user_info
messageinfo = message.message_info
# 创建聊天流
chat = await chat_manager.get_or_create_stream(
platform=messageinfo.platform,
user_info=userinfo,
group_info=groupinfo,
)
message.update_chat_stream(chat)
await self.only_process_chat.process_message(message)
await self._create_pfc_chat(message)
if groupinfo is None:
if global_config.enable_friend_chat:
if global_config.enable_pfc_chatting:
userinfo = message.message_info.user_info
messageinfo = message.message_info
# 创建聊天流
chat = await chat_manager.get_or_create_stream(
platform=messageinfo.platform,
user_info=userinfo,
group_info=groupinfo,
)
message.update_chat_stream(chat)
await self.only_process_chat.process_message(message)
await self._create_pfc_chat(message)
else:
if groupinfo.group_id in global_config.talk_allowed_groups:
# logger.debug(f"开始群聊模式{str(message_data)[:50]}...")
if global_config.response_mode == "heart_flow":
# logger.info(f"启动最新最好的思维流FC模式{str(message_data)[:50]}...")
await self.heartFC_processor.process_message(message_data)
elif global_config.response_mode == "reasoning":
# logger.debug(f"开始推理模式{str(message_data)[:50]}...")
await self.reasoning_chat.process_message(message_data)
else:
logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}")
except Exception as e:
logger.error(f"处理PFC消息失败: {e}")
await self.heartFC_processor.process_message(message_data)
else:
if groupinfo is None:
if global_config.enable_friend_chat:
# 私聊处理流程
# await self._handle_private_chat(message)
if global_config.response_mode == "heart_flow":
await self.heartFC_processor.process_message(message_data)
elif global_config.response_mode == "reasoning":
await self.reasoning_chat.process_message(message_data)
else:
logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}")
else: # 群聊处理
if groupinfo.group_id in global_config.talk_allowed_groups:
if global_config.response_mode == "heart_flow":
await self.heartFC_processor.process_message(message_data)
elif global_config.response_mode == "reasoning":
await self.reasoning_chat.process_message(message_data)
else:
logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}")
await self.heartFC_processor.process_message(message_data)
if template_group_name:
async with global_prompt_manager.async_message_scope(template_group_name):

View File

@@ -15,6 +15,9 @@ 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
INITIAL_DURATION = 60.0
# 定义日志配置 (使用 loguru 格式)
interest_log_config = LogConfig(
console_format=PFC_STYLE_CONFIG["console_format"], # 使用默认控制台格式
@@ -91,7 +94,7 @@ class PFChatting:
self._loop_active: bool = False # Is the loop currently running?
self._loop_task: Optional[asyncio.Task] = None # Stores the main loop task
self._trigger_count_this_activation: int = 0 # Counts triggers within an active period
self._initial_duration: float = 60.0 # 首次触发增加的时间
self._initial_duration: float = INITIAL_DURATION # 首次触发增加的时间
self._last_added_duration: float = self._initial_duration # <--- 新增:存储上次增加的时间
def _get_log_prefix(self) -> str: