refactor: 重构情绪管理器

This commit is contained in:
Oct-autumn
2025-05-08 23:56:28 +08:00
parent 46d15b1fe7
commit a1fbff1d6b
14 changed files with 379 additions and 391 deletions

View File

@@ -6,7 +6,6 @@ MaiMBot插件系统
from .chat.chat_stream import chat_manager
from .emoji_system.emoji_manager import emoji_manager
from .person_info.relationship_manager import relationship_manager
from .moods.moods import MoodManager
from .willing.willing_manager import willing_manager
from .schedule.schedule_generator import bot_schedule
@@ -15,7 +14,6 @@ __all__ = [
"chat_manager",
"emoji_manager",
"relationship_manager",
"MoodManager",
"willing_manager",
"bot_schedule",
]

View File

@@ -1,16 +1,15 @@
import traceback
from typing import Dict, Any
from ..moods.moods import MoodManager # 导入情绪管理器
from ...config.config import global_config
from .message import MessageRecv
from ..PFC.pfc_manager import PFCManager
from .chat_stream import chat_manager
from .only_message_process import MessageProcessor
from src.common.logger_manager import get_logger
from src.manager.mood_manager import mood_manager # 导入情绪管理器
from .chat_stream import chat_manager
from .message import MessageRecv
from .only_message_process import MessageProcessor
from ..PFC.pfc_manager import PFCManager
from ..heartFC_chat.heartflow_processor import HeartFCProcessor
from ..utils.prompt_builder import Prompt, global_prompt_manager
import traceback
from ...config.config import global_config
# 定义日志配置
@@ -23,7 +22,7 @@ class ChatBot:
def __init__(self):
self.bot = None # bot 实例引用
self._started = False
self.mood_manager = MoodManager.get_instance() # 获取情绪管理器单例
self.mood_manager = mood_manager # 获取情绪管理器单例
self.heartflow_processor = HeartFCProcessor() # 新增
# 创建初始化PFC管理器的任务会在_ensure_started时执行

View File

@@ -1,21 +1,20 @@
import random
import time
import re
import time
from collections import Counter
import jieba
import numpy as np
from src.common.logger import get_module_logger
from maim_message import UserInfo
from pymongo.errors import PyMongoError
from src.common.logger import get_module_logger
from src.manager.mood_manager import mood_manager
from .message import MessageRecv
from ..models.utils_model import LLMRequest
from ..utils.typo_generator import ChineseTypoGenerator
from ...config.config import global_config
from .message import MessageRecv
from maim_message import UserInfo
from ..moods.moods import MoodManager
from ...common.database import db
from ...config.config import global_config
logger = get_module_logger("chat_utils")
@@ -405,7 +404,6 @@ def calculate_typing_time(
- 在所有输入结束后额外加上回车时间0.3秒
- 如果is_emoji为True将使用固定1秒的输入时间
"""
mood_manager = MoodManager.get_instance()
# 将0-1的唤醒度映射到-1到1
mood_arousal = mood_manager.current_mood.arousal
# 映射到0.5到2倍的速度系数

View File

@@ -1,33 +1,35 @@
import asyncio
import contextlib
import json # <--- 确保导入 json
import random # <--- 添加导入
import time
import traceback
import random # <--- 添加导入
import json # <--- 确保导入 json
from typing import List, Optional, Dict, Any, Deque, Callable, Coroutine
from collections import deque
from typing import List, Optional, Dict, Any, Deque, Callable, Coroutine
from rich.traceback import install
from src.common.logger_manager import get_logger
from src.config.config import global_config
from src.heart_flow.observation import Observation
from src.heart_flow.sub_mind import SubMind
from src.heart_flow.utils_chat import get_chat_type_and_target_info
from src.manager.mood_manager import mood_manager
from src.plugins.chat.chat_stream import ChatStream
from src.plugins.chat.chat_stream import chat_manager
from src.plugins.chat.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending
from src.plugins.chat.message import Seg # Local import needed after move
from src.plugins.chat.chat_stream import ChatStream
from src.plugins.chat.message import UserInfo
from src.plugins.chat.chat_stream import chat_manager
from src.common.logger_manager import get_logger
from src.plugins.models.utils_model import LLMRequest
from src.config.config import global_config
from src.plugins.chat.utils_image import image_path_to_base64 # Local import needed after move
from src.plugins.utils.timer_calculator import Timer # <--- Import Timer
from src.plugins.emoji_system.emoji_manager import emoji_manager
from src.heart_flow.sub_mind import SubMind
from src.heart_flow.observation import Observation
from src.plugins.heartFC_chat.heartflow_prompt_builder import global_prompt_manager, prompt_builder
import contextlib
from src.plugins.utils.chat_message_builder import num_new_messages_since
from src.plugins.heartFC_chat.heartFC_Cycleinfo import CycleInfo
from .heartFC_sender import HeartFCSender
from src.plugins.chat.utils import process_llm_response
from src.plugins.chat.utils_image import image_path_to_base64 # Local import needed after move
from src.plugins.emoji_system.emoji_manager import emoji_manager
from src.plugins.heartFC_chat.heartFC_Cycleinfo import CycleInfo
from src.plugins.heartFC_chat.heartflow_prompt_builder import global_prompt_manager, prompt_builder
from src.plugins.models.utils_model import LLMRequest
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
from src.plugins.moods.moods import MoodManager
from src.heart_flow.utils_chat import get_chat_type_and_target_info
from rich.traceback import install
from src.plugins.utils.chat_message_builder import num_new_messages_since
from src.plugins.utils.timer_calculator import Timer # <--- Import Timer
from .heartFC_sender import HeartFCSender
install(extra_lines=3)
@@ -1275,7 +1277,7 @@ class HeartFChatting:
"""
try:
# 1. 获取情绪影响因子并调整模型温度
arousal_multiplier = MoodManager.get_instance().get_arousal_multiplier()
arousal_multiplier = mood_manager.get_arousal_multiplier()
current_temp = global_config.llm_normal["temp"] * arousal_multiplier
self.model_normal.temperature = current_temp # 动态调整温度

View File

@@ -10,7 +10,7 @@ import time
from typing import Union, Optional, Deque, Dict, Any
from ...common.database import db
from ..chat.utils import get_recent_group_speaker
from ..moods.moods import MoodManager
from src.manager.mood_manager import mood_manager
from ..memory_system.Hippocampus import HippocampusManager
from ..schedule.schedule_generator import bot_schedule
from ..knowledge.knowledge_lib import qa_manager
@@ -341,8 +341,7 @@ class PromptBuilder:
else:
logger.warning(f"Invalid person tuple encountered for relationship prompt: {person}")
mood_manager = MoodManager.get_instance()
mood_prompt = mood_manager.get_prompt()
mood_prompt = mood_manager.get_mood_prompt()
reply_styles1 = [
("然后给出日常且口语化的回复,平淡一些", 0.4),
("给出非常简短的回复", 0.4),

View File

@@ -1,26 +1,26 @@
import time
import asyncio
import traceback
import statistics # 导入 statistics 模块
import time
import traceback
from random import random
from typing import List, Optional # 导入 Optional
from ..moods.moods import MoodManager
from ...config.config import global_config
from ..emoji_system.emoji_manager import emoji_manager
from .normal_chat_generator import NormalChatGenerator
from ..chat.message import MessageSending, MessageRecv, MessageThinking, MessageSet
from ..chat.message_sender import message_manager
from ..chat.utils_image import image_path_to_base64
from ..willing.willing_manager import willing_manager
from maim_message import UserInfo, Seg
from src.common.logger_manager import get_logger
from src.heart_flow.utils_chat import get_chat_type_and_target_info
from src.manager.mood_manager import mood_manager
from src.plugins.chat.chat_stream import ChatStream, chat_manager
from src.plugins.person_info.relationship_manager import relationship_manager
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
from src.plugins.utils.timer_calculator import Timer
from src.heart_flow.utils_chat import get_chat_type_and_target_info
from .normal_chat_generator import NormalChatGenerator
from ..chat.message import MessageSending, MessageRecv, MessageThinking, MessageSet
from ..chat.message_sender import message_manager
from ..chat.utils_image import image_path_to_base64
from ..emoji_system.emoji_manager import emoji_manager
from ..willing.willing_manager import willing_manager
from ...config.config import global_config
logger = get_logger("chat")
@@ -45,7 +45,7 @@ class NormalChat:
# Other sync initializations
self.gpt = NormalChatGenerator()
self.mood_manager = MoodManager.get_instance()
self.mood_manager = mood_manager
self.start_time = time.time()
self.last_speak_time = 0
self._chat_task: Optional[asyncio.Task] = None

View File

@@ -1,293 +0,0 @@
import math
import threading
import time
from dataclasses import dataclass
from ...config.config import global_config
from src.common.logger_manager import get_logger
from ..person_info.relationship_manager import relationship_manager
from src.individuality.individuality import Individuality
logger = get_logger("mood")
@dataclass
class MoodState:
valence: float # 愉悦度 (-1.0 到 1.0)-1表示极度负面1表示极度正面
arousal: float # 唤醒度 (-1.0 到 1.0)-1表示抑制1表示兴奋
text: str # 心情文本描述
class MoodManager:
_instance = None
_lock = threading.Lock()
def __new__(cls):
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._initialized = False
return cls._instance
def __init__(self):
# 确保初始化代码只运行一次
if self._initialized:
return
self._initialized = True
# 初始化心情状态
self.current_mood = MoodState(valence=0.0, arousal=0.0, text="平静")
# 从配置文件获取衰减率
self.decay_rate_valence = 1 - global_config.mood_decay_rate # 愉悦度衰减率
self.decay_rate_arousal = 1 - global_config.mood_decay_rate # 唤醒度衰减率
# 上次更新时间
self.last_update = time.time()
# 线程控制
self._running = False
self._update_thread = None
# 情绪词映射表 (valence, arousal)
self.emotion_map = {
"开心": (0.21, 0.6),
"害羞": (0.15, 0.2),
"愤怒": (-0.24, 0.8),
"恐惧": (-0.21, 0.7),
"悲伤": (-0.21, 0.3),
"厌恶": (-0.12, 0.4),
"惊讶": (0.06, 0.7),
"困惑": (0.0, 0.6),
"平静": (0.03, 0.5),
}
# 情绪文本映射表
self.mood_text_map = {
# 第一象限:高唤醒,正愉悦
(0.5, 0.4): "兴奋",
(0.3, 0.6): "快乐",
(0.2, 0.3): "满足",
# 第二象限:高唤醒,负愉悦
(-0.5, 0.4): "愤怒",
(-0.3, 0.6): "焦虑",
(-0.2, 0.3): "烦躁",
# 第三象限:低唤醒,负愉悦
(-0.5, -0.4): "悲伤",
(-0.3, -0.3): "疲倦",
(-0.4, -0.7): "疲倦",
# 第四象限:低唤醒,正愉悦
(0.2, -0.1): "平静",
(0.3, -0.2): "安宁",
(0.5, -0.4): "放松",
}
@classmethod
def get_instance(cls) -> "MoodManager":
"""获取MoodManager的单例实例"""
if cls._instance is None:
cls._instance = MoodManager()
return cls._instance
def start_mood_update(self, update_interval: float = 5.0) -> None:
"""
启动情绪更新线程
:param update_interval: 更新间隔(秒)
"""
if self._running:
return
self._running = True
self._update_thread = threading.Thread(
target=self._continuous_mood_update, args=(update_interval,), daemon=True
)
self._update_thread.start()
def stop_mood_update(self) -> None:
"""停止情绪更新线程"""
self._running = False
if self._update_thread and self._update_thread.is_alive():
self._update_thread.join()
def _continuous_mood_update(self, update_interval: float) -> None:
"""
持续更新情绪状态的线程函数
:param update_interval: 更新间隔(秒)
"""
while self._running:
self._apply_decay()
self._update_mood_text()
time.sleep(update_interval)
def _apply_decay(self) -> None:
"""应用情绪衰减,正向和负向情绪分开计算"""
current_time = time.time()
time_diff = current_time - self.last_update
agreeableness_factor = 1
agreeableness_bias = 0
neuroticism_factor = 0.5
# 获取人格特质
personality = Individuality.get_instance().personality
if personality:
# 神经质:影响情绪变化速度
neuroticism_factor = 1 + (personality.neuroticism - 0.5) * 0.4
agreeableness_factor = 1 + (personality.agreeableness - 0.5) * 0.4
# 宜人性:影响情绪基准线
if personality.agreeableness < 0.2:
agreeableness_bias = (personality.agreeableness - 0.2) * 0.5
elif personality.agreeableness > 0.8:
agreeableness_bias = (personality.agreeableness - 0.8) * 0.5
else:
agreeableness_bias = 0
# 分别计算正向和负向的衰减率
if self.current_mood.valence >= 0:
# 正向情绪衰减
decay_rate_positive = self.decay_rate_valence * (1 / agreeableness_factor)
valence_target = 0 + agreeableness_bias
self.current_mood.valence = valence_target + (self.current_mood.valence - valence_target) * math.exp(
-decay_rate_positive * time_diff * neuroticism_factor
)
else:
# 负向情绪衰减
decay_rate_negative = self.decay_rate_valence * agreeableness_factor
valence_target = 0 + agreeableness_bias
self.current_mood.valence = valence_target + (self.current_mood.valence - valence_target) * math.exp(
-decay_rate_negative * time_diff * neuroticism_factor
)
# Arousal 向中性0回归
arousal_target = 0
self.current_mood.arousal = arousal_target + (self.current_mood.arousal - arousal_target) * math.exp(
-self.decay_rate_arousal * time_diff * neuroticism_factor
)
# 确保值在合理范围内
self.current_mood.valence = max(-1.0, min(1.0, self.current_mood.valence))
self.current_mood.arousal = max(-1.0, min(1.0, self.current_mood.arousal))
self.last_update = current_time
def update_mood_from_text(self, text: str, valence_change: float, arousal_change: float) -> None:
"""根据输入文本更新情绪状态"""
self.current_mood.valence += valence_change
self.current_mood.arousal += arousal_change
# 限制范围
self.current_mood.valence = max(-1.0, min(1.0, self.current_mood.valence))
self.current_mood.arousal = max(-1.0, min(1.0, self.current_mood.arousal))
self._update_mood_text()
def set_mood_text(self, text: str) -> None:
"""直接设置心情文本"""
self.current_mood.text = text
def _update_mood_text(self) -> None:
"""根据当前情绪状态更新文本描述"""
closest_mood = None
min_distance = float("inf")
for (v, a), text in self.mood_text_map.items():
distance = math.sqrt((self.current_mood.valence - v) ** 2 + (self.current_mood.arousal - a) ** 2)
if distance < min_distance:
min_distance = distance
closest_mood = text
if closest_mood:
self.current_mood.text = closest_mood
def update_mood_by_user(self, user_id: str, valence_change: float, arousal_change: float) -> None:
"""根据用户ID更新情绪状态"""
# 这里可以根据用户ID添加特定的权重或规则
weight = 1.0 # 默认权重
self.current_mood.valence += valence_change * weight
self.current_mood.arousal += arousal_change * weight
# 限制范围
self.current_mood.valence = max(-1.0, min(1.0, self.current_mood.valence))
self.current_mood.arousal = max(-1.0, min(1.0, self.current_mood.arousal))
self._update_mood_text()
def get_prompt(self) -> str:
"""根据当前情绪状态生成提示词"""
base_prompt = f"当前心情:{self.current_mood.text}"
# 根据情绪状态添加额外的提示信息
if self.current_mood.valence > 0.5:
base_prompt += "你现在心情很好,"
elif self.current_mood.valence < -0.5:
base_prompt += "你现在心情不太好,"
if self.current_mood.arousal > 0.4:
base_prompt += "情绪比较激动。"
elif self.current_mood.arousal < -0.4:
base_prompt += "情绪比较平静。"
return base_prompt
def get_arousal_multiplier(self) -> float:
"""根据当前情绪状态返回唤醒度乘数"""
if self.current_mood.arousal > 0.4:
multiplier = 1 + min(0.15, (self.current_mood.arousal - 0.4) / 3)
return multiplier
elif self.current_mood.arousal < -0.4:
multiplier = 1 - min(0.15, ((0 - self.current_mood.arousal) - 0.4) / 3)
return multiplier
return 1.0
def get_current_mood(self) -> MoodState:
"""获取当前情绪状态"""
return self.current_mood
def print_mood_status(self) -> None:
"""打印当前情绪状态"""
logger.info(
f"愉悦度: {self.current_mood.valence:.2f}, "
f"唤醒度: {self.current_mood.arousal:.2f}, "
f"心情: {self.current_mood.text}"
)
def update_mood_from_emotion(self, emotion: str, intensity: float = 1.0) -> None:
"""
根据情绪词更新心情状态
:param emotion: 情绪词(如'happy', 'sad'等)
:param intensity: 情绪强度0.0-1.0
"""
if emotion not in self.emotion_map:
logger.debug(f"[情绪更新] 未知情绪词: {emotion}")
return
valence_change, arousal_change = self.emotion_map[emotion]
old_valence = self.current_mood.valence
old_arousal = self.current_mood.arousal
old_mood = self.current_mood.text
valence_change = relationship_manager.feedback_to_mood(valence_change)
# 应用情绪强度
valence_change *= intensity
arousal_change *= intensity
# 更新当前情绪状态
self.current_mood.valence += valence_change
self.current_mood.arousal += arousal_change
# 限制范围
self.current_mood.valence = max(-1.0, min(1.0, self.current_mood.valence))
self.current_mood.arousal = max(-1.0, min(1.0, self.current_mood.arousal))
self._update_mood_text()
logger.info(
f"[情绪变化] {emotion}(强度:{intensity:.2f}) | 愉悦度:{old_valence:.2f}->{self.current_mood.valence:.2f}, 唤醒度:{old_arousal:.2f}->{self.current_mood.arousal:.2f} | 心情:{old_mood}->{self.current_mood.text}"
)

View File

@@ -6,6 +6,9 @@ from .person_info import person_info_manager
import time
import random
from maim_message import UserInfo
from ...manager.mood_manager import mood_manager
# import re
# import traceback
@@ -22,9 +25,7 @@ class RelationshipManager:
@property
def mood_manager(self):
if self._mood_manager is None:
from ..moods.moods import MoodManager # 延迟导入
self._mood_manager = MoodManager.get_instance()
self._mood_manager = mood_manager
return self._mood_manager
def positive_feedback_sys(self, label: str, stance: str):
@@ -60,9 +61,7 @@ class RelationshipManager:
def mood_feedback(self, value):
"""情绪反馈"""
mood_manager = self.mood_manager
mood_gain = mood_manager.get_current_mood().valence ** 2 * math.copysign(
1, value * mood_manager.get_current_mood().valence
)
mood_gain = mood_manager.current_mood.valence**2 * math.copysign(1, value * mood_manager.current_mood.valence)
value += value * mood_gain
logger.info(f"当前relationship增益系数{mood_gain:.3f}")
return value