diff --git a/bot.py b/bot.py index a966ca628..586d76a32 100644 --- a/bot.py +++ b/bot.py @@ -16,6 +16,15 @@ from rich.traceback import install from src.manager.async_task_manager import async_task_manager +logger = get_logger("main") + +# 直接加载生产环境变量配置 +if os.path.exists(".env"): + load_dotenv(".env", override=True) + logger.info("成功加载环境变量配置") +else: + logger.warning("未找到.env文件,请确保程序所需的环境变量被正确设置") + install(extra_lines=3) # 设置工作目录为脚本所在目录 @@ -24,7 +33,6 @@ os.chdir(script_dir) print(f"已设置工作目录为: {script_dir}") -logger = get_logger("main") confirm_logger = get_logger("confirm") # 获取没有加载env时的环境变量 env_mask = {key: os.getenv(key) for key in os.environ} @@ -65,15 +73,6 @@ def easter_egg(): print(rainbow_text) -def load_env(): - # 直接加载生产环境变量配置 - if os.path.exists(".env"): - load_dotenv(".env", override=True) - logger.info("成功加载环境变量配置") - else: - logger.warning("未找到.env文件,请确保程序所需的环境变量被正确设置") - - def scan_provider(env_config: dict): provider = {} @@ -198,7 +197,6 @@ def check_eula(): def raw_main(): - load_env() # 利用 TZ 环境变量设定程序工作的时区 if platform.system().lower() != "windows": time.tzset() diff --git a/scripts/message_retrieval_script.py b/scripts/message_retrieval_script.py index 3def2da00..78c37f238 100644 --- a/scripts/message_retrieval_script.py +++ b/scripts/message_retrieval_script.py @@ -36,7 +36,8 @@ from src.common.logger import get_logger from src.common.database.database import db from src.config.config import global_config from src.llm_models.utils_model import LLMRequest -from src.person_info.person_info import PersonInfoManager, person_info_manager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager + logger = get_logger("message_retrieval") @@ -77,7 +78,7 @@ async def build_name_mapping(messages: List[Dict[str, Any]], target_person_name: name_mapping = {} current_user = "A" user_count = 1 - + person_info_manager = get_person_info_manager() # 遍历消息,构建映射 for msg in messages: await person_info_manager.get_or_create_person( @@ -410,6 +411,7 @@ class MessageRetrievalScript: async def update_person_impression_from_segment(self, person_id: str, readable_messages: str, segment_time: float): """从消息段落更新用户印象,使用和relationship_manager相同的流程""" + person_info_manager = get_person_info_manager() person_name = await person_info_manager.get_value(person_id, "person_name") nickname = await person_info_manager.get_value(person_id, "nickname") @@ -659,6 +661,7 @@ class MessageRetrievalScript: """处理分段消息并更新用户印象到数据库""" # 获取目标用户信息 target_person_id = get_person_id("qq", user_qq) + person_info_manager = get_person_info_manager() target_person_name = await person_info_manager.get_value(target_person_id, "person_name") if not target_person_name: diff --git a/src/chat/__init__.py b/src/chat/__init__.py index d4da12037..c69d5205e 100644 --- a/src/chat/__init__.py +++ b/src/chat/__init__.py @@ -3,13 +3,13 @@ MaiBot模块系统 包含聊天、情绪、记忆、日程等功能模块 """ -from src.chat.message_receive.chat_stream import chat_manager -from src.chat.emoji_system.emoji_manager import emoji_manager -from src.chat.normal_chat.willing.willing_manager import willing_manager +from src.chat.message_receive.chat_stream import get_chat_manager +from src.chat.emoji_system.emoji_manager import get_emoji_manager +from src.chat.normal_chat.willing.willing_manager import get_willing_manager # 导出主要组件供外部使用 __all__ = [ - "chat_manager", - "emoji_manager", - "willing_manager", + "get_chat_manager", + "get_emoji_manager", + "get_willing_manager", ] diff --git a/src/chat/emoji_system/emoji_manager.py b/src/chat/emoji_system/emoji_manager.py index 2681077af..bd160135c 100644 --- a/src/chat/emoji_system/emoji_manager.py +++ b/src/chat/emoji_system/emoji_manager.py @@ -15,7 +15,7 @@ import re from src.common.database.database_model import Emoji from src.common.database.database import db as peewee_db from src.config.config import global_config -from src.chat.utils.utils_image import image_path_to_base64, image_manager +from src.chat.utils.utils_image import image_path_to_base64, get_image_manager from src.llm_models.utils_model import LLMRequest from src.common.logger import get_logger from rich.traceback import install @@ -844,7 +844,7 @@ class EmojiManager: # 调用AI获取描述 if image_format == "gif" or image_format == "GIF": - image_base64 = image_manager.transform_gif(image_base64) + image_base64 = get_image_manager().transform_gif(image_base64) prompt = "这是一个动态图表情包,每一张图代表了动态图的某一帧,黑色背景代表透明,描述一下表情包表达的情感和内容,描述细节,从互联网梗,meme的角度去分析" description, _ = await self.vlm.generate_response_for_image(prompt, image_base64, "jpg") else: @@ -1000,5 +1000,11 @@ class EmojiManager: return False -# 创建全局单例 -emoji_manager = EmojiManager() +emoji_manager = None + + +def get_emoji_manager(): + global emoji_manager + if emoji_manager is None: + emoji_manager = EmojiManager() + return emoji_manager diff --git a/src/chat/focus_chat/expressors/default_expressor.py b/src/chat/focus_chat/expressors/default_expressor.py index b419b01b1..816ff7347 100644 --- a/src/chat/focus_chat/expressors/default_expressor.py +++ b/src/chat/focus_chat/expressors/default_expressor.py @@ -1,15 +1,17 @@ import traceback from typing import List, Optional, Dict, Any, Tuple + +from src.chat.focus_chat.expressors.exprssion_learner import get_expression_learner from src.chat.message_receive.message import MessageRecv, MessageThinking, MessageSending from src.chat.message_receive.message import Seg # Local import needed after move from src.chat.message_receive.message import UserInfo -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.common.logger import get_logger from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.chat.utils.utils_image import image_path_to_base64 # Local import needed after move from src.chat.utils.timer_calculator import Timer # <--- Import Timer -from src.chat.emoji_system.emoji_manager import emoji_manager +from src.chat.emoji_system.emoji_manager import get_emoji_manager from src.chat.focus_chat.heartFC_sender import HeartFCSender from src.chat.utils.utils import process_llm_response from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info @@ -18,7 +20,6 @@ from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat import time -from src.chat.focus_chat.expressors.exprssion_learner import expression_learner import random logger = get_logger("expressor") @@ -274,6 +275,7 @@ class DefaultExpressor: truncate=True, ) + expression_learner = get_expression_learner() ( learnt_style_expressions, learnt_grammar_expressions, @@ -365,7 +367,7 @@ class DefaultExpressor: logger.error(f"{self.log_prefix} 无法发送回复,anchor_message 为空。") return None - stream_name = chat_manager.get_stream_name(chat_id) or chat_id # 获取流名称用于日志 + stream_name = get_chat_manager().get_stream_name(chat_id) or chat_id # 获取流名称用于日志 # 检查思考过程是否仍在进行,并获取开始时间 if thinking_id: @@ -454,7 +456,7 @@ class DefaultExpressor: 选择表情,根据send_emoji文本选择表情,返回表情base64 """ emoji_base64 = "" - emoji_raw = await emoji_manager.get_emoji_for_text(send_emoji) + emoji_raw = await get_emoji_manager().get_emoji_for_text(send_emoji) if emoji_raw: emoji_path, _description, _emotion = emoji_raw emoji_base64 = image_path_to_base64(emoji_path) diff --git a/src/chat/focus_chat/expressors/exprssion_learner.py b/src/chat/focus_chat/expressors/exprssion_learner.py index 93420d0af..2d36b4935 100644 --- a/src/chat/focus_chat/expressors/exprssion_learner.py +++ b/src/chat/focus_chat/expressors/exprssion_learner.py @@ -7,7 +7,7 @@ from src.config.config import global_config from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_random, build_anonymous_messages from src.chat.utils.prompt_builder import Prompt, global_prompt_manager import os -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager import json @@ -220,7 +220,7 @@ class ExpressionLearner: return [] learnt_expressions, chat_id = res - chat_stream = chat_manager.get_stream(chat_id) + chat_stream = get_chat_manager().get_stream(chat_id) if chat_stream.group_info: group_name = chat_stream.group_info.group_name else: @@ -399,4 +399,11 @@ class ExpressionLearner: init_prompt() -expression_learner = ExpressionLearner() +expression_learner = None + + +def get_expression_learner(): + global expression_learner + if expression_learner is None: + expression_learner = ExpressionLearner() + return expression_learner diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index 8d368c073..52218b0db 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -4,7 +4,7 @@ import time import traceback from collections import deque from typing import List, Optional, Dict, Any, Deque, Callable, Awaitable -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from rich.traceback import install from src.chat.utils.prompt_builder import global_prompt_manager from src.common.logger import get_logger @@ -97,8 +97,8 @@ class HeartFChatting: """ # 基础属性 self.stream_id: str = chat_id # 聊天流ID - self.chat_stream = chat_manager.get_stream(self.stream_id) - self.log_prefix = f"[{chat_manager.get_stream_name(self.stream_id) or self.stream_id}]" + self.chat_stream = get_chat_manager().get_stream(self.stream_id) + self.log_prefix = f"[{get_chat_manager().get_stream_name(self.stream_id) or self.stream_id}]" self.memory_activator = MemoryActivator() diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index ea9ce674c..f3aeec9cb 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -3,11 +3,10 @@ from src.config.config import global_config from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.storage import MessageStorage from src.chat.heart_flow.heartflow import heartflow -from src.chat.message_receive.chat_stream import chat_manager, ChatStream +from src.chat.message_receive.chat_stream import get_chat_manager, ChatStream from src.chat.utils.utils import is_mentioned_bot_in_message from src.chat.utils.timer_calculator import Timer from src.common.logger import get_logger -from src.person_info.relationship_manager import relationship_manager import math import re @@ -15,6 +14,8 @@ import traceback from typing import Optional, Tuple, Dict, Any from maim_message import UserInfo +from src.person_info.relationship_manager import get_relationship_manager + # from ..message_receive.message_buffer import message_buffer logger = get_logger("chat") @@ -45,6 +46,7 @@ async def _process_relationship(message: MessageRecv) -> None: nickname = message.message_info.user_info.user_nickname cardname = message.message_info.user_info.user_cardname or nickname + relationship_manager = get_relationship_manager() is_known = await relationship_manager.is_known_some_one(platform, user_id) if not is_known: @@ -181,7 +183,7 @@ class HeartFCMessageReceiver: userinfo = message.message_info.user_info messageinfo = message.message_info - chat = await chat_manager.get_or_create_stream( + chat = await get_chat_manager().get_or_create_stream( platform=messageinfo.platform, user_info=userinfo, group_info=groupinfo, diff --git a/src/chat/focus_chat/info_processors/mind_processor.py b/src/chat/focus_chat/info_processors/mind_processor.py index 1e36bb6be..f63d086dc 100644 --- a/src/chat/focus_chat/info_processors/mind_processor.py +++ b/src/chat/focus_chat/info_processors/mind_processor.py @@ -5,11 +5,11 @@ from src.config.config import global_config import time import traceback from src.common.logger import get_logger -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.json_utils import safe_json_dumps -from src.chat.message_receive.chat_stream import chat_manager -from src.person_info.relationship_manager import relationship_manager +from src.chat.message_receive.chat_stream import get_chat_manager +from src.person_info.relationship_manager import get_relationship_manager from .base_processor import BaseProcessor from src.chat.focus_chat.info.mind_info import MindInfo from typing import List, Optional @@ -77,7 +77,7 @@ class MindProcessor(BaseProcessor): self.structured_info = [] self.structured_info_str = "" - name = chat_manager.get_stream_name(self.subheartflow_id) + name = get_chat_manager().get_stream_name(self.subheartflow_id) self.log_prefix = f"[{name}] " self._update_structured_info_str() @@ -195,13 +195,14 @@ class MindProcessor(BaseProcessor): relation_prompt = "" if global_config.relationship.enable_relationship: for person in person_list: + relationship_manager = get_relationship_manager() relation_prompt += await relationship_manager.build_relationship_info(person, is_id=True) template_name = "sub_heartflow_prompt_before" if is_group_chat else "sub_heartflow_prompt_private_before" logger.debug(f"{self.log_prefix} 使用{'群聊' if is_group_chat else '私聊'}思考模板") prompt = (await global_prompt_manager.get_prompt_async(template_name)).format( - bot_name=individuality.name, + bot_name=get_individuality().name, memory_str=memory_str, extra_info=self.structured_info_str, relation_prompt=relation_prompt, diff --git a/src/chat/focus_chat/info_processors/relationship_processor.py b/src/chat/focus_chat/info_processors/relationship_processor.py index 70ad994ac..599e1d04c 100644 --- a/src/chat/focus_chat/info_processors/relationship_processor.py +++ b/src/chat/focus_chat/info_processors/relationship_processor.py @@ -6,19 +6,20 @@ import time import traceback from src.common.logger import get_logger from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.chat.message_receive.chat_stream import chat_manager -from src.person_info.relationship_manager import relationship_manager +from src.chat.message_receive.chat_stream import get_chat_manager +from src.person_info.relationship_manager import get_relationship_manager from .base_processor import BaseProcessor from typing import List, Optional from typing import Dict from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info.relation_info import RelationInfo from json_repair import repair_json -from src.person_info.person_info import person_info_manager +from src.person_info.person_info import get_person_info_manager import json import asyncio from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_with_chat + # 配置常量:是否启用小模型即时信息提取 # 开启时:使用小模型并行即时提取,速度更快,但精度可能略低 # 关闭时:使用原来的异步模式,精度更高但速度较慢 @@ -110,7 +111,7 @@ class RelationshipProcessor(BaseProcessor): request_type="focus.relationship.instant", ) - name = chat_manager.get_stream_name(self.subheartflow_id) + name = get_chat_manager().get_stream_name(self.subheartflow_id) self.log_prefix = f"[{name}] " async def process_info( @@ -241,6 +242,7 @@ class RelationshipProcessor(BaseProcessor): instant_tasks = [] async_tasks = [] + person_info_manager = get_person_info_manager() for person_name, info_type in content_json.items(): person_id = person_info_manager.get_person_id_by_person_name(person_name) if person_id: @@ -366,6 +368,7 @@ class RelationshipProcessor(BaseProcessor): """ 使用小模型提取单个信息类型 """ + person_info_manager = get_person_info_manager() nickname_str = ",".join(global_config.bot.alias_names) name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。" @@ -453,6 +456,7 @@ class RelationshipProcessor(BaseProcessor): nickname_str = ",".join(global_config.bot.alias_names) name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。" + person_info_manager = get_person_info_manager() person_name = await person_info_manager.get_value(person_id, "person_name") info_type_str = "" @@ -534,6 +538,7 @@ class RelationshipProcessor(BaseProcessor): impression_messages = get_raw_msg_by_timestamp_with_chat(chat_id, start_time, end_time) if impression_messages: logger.info(f"为 {person_id} 获取到 {len(impression_messages)} 条消息用于印象更新。") + relationship_manager = get_relationship_manager() await relationship_manager.update_person_impression( person_id=person_id, timestamp=end_time, bot_engaged_messages=impression_messages ) diff --git a/src/chat/focus_chat/info_processors/self_processor.py b/src/chat/focus_chat/info_processors/self_processor.py index 892c6713a..c7f03f34a 100644 --- a/src/chat/focus_chat/info_processors/self_processor.py +++ b/src/chat/focus_chat/info_processors/self_processor.py @@ -5,9 +5,9 @@ from src.config.config import global_config import time import traceback from src.common.logger import get_logger -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from .base_processor import BaseProcessor from typing import List, Optional from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation @@ -59,7 +59,7 @@ class SelfProcessor(BaseProcessor): request_type="focus.processor.self_identify", ) - name = chat_manager.get_stream_name(self.subheartflow_id) + name = get_chat_manager().get_stream_name(self.subheartflow_id) self.log_prefix = f"[{name}] " async def process_info( @@ -123,9 +123,9 @@ class SelfProcessor(BaseProcessor): nickname_str += f"{nicknames}," name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。" - personality_block = individuality.get_personality_prompt(x_person=2, level=2) + personality_block = get_individuality().get_personality_prompt(x_person=2, level=2) - identity_block = individuality.get_identity_prompt(x_person=2, level=2) + identity_block = get_individuality().get_identity_prompt(x_person=2, level=2) prompt = (await global_prompt_manager.get_prompt_async("indentify_prompt")).format( name_block=name_block, diff --git a/src/chat/focus_chat/info_processors/tool_processor.py b/src/chat/focus_chat/info_processors/tool_processor.py index 15856a8de..d0151d362 100644 --- a/src/chat/focus_chat/info_processors/tool_processor.py +++ b/src/chat/focus_chat/info_processors/tool_processor.py @@ -3,7 +3,7 @@ from src.llm_models.utils_model import LLMRequest from src.config.config import global_config import time from src.common.logger import get_logger -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.tools.tool_use import ToolUser from src.chat.utils.json_utils import process_llm_tool_calls @@ -132,7 +132,7 @@ class ToolProcessor(BaseProcessor): memory_str=memory_str, chat_observe_info=chat_observe_info, is_group_chat=is_group_chat, - bot_name=individuality.name, + bot_name=get_individuality().name, time_now=time_now, ) diff --git a/src/chat/focus_chat/info_processors/working_memory_processor.py b/src/chat/focus_chat/info_processors/working_memory_processor.py index 9a83dd7dd..9d7a50e2c 100644 --- a/src/chat/focus_chat/info_processors/working_memory_processor.py +++ b/src/chat/focus_chat/info_processors/working_memory_processor.py @@ -6,7 +6,7 @@ import time import traceback from src.common.logger import get_logger from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from .base_processor import BaseProcessor from src.chat.focus_chat.info.mind_info import MindInfo from typing import List, Optional @@ -64,7 +64,7 @@ class WorkingMemoryProcessor(BaseProcessor): request_type="focus.processor.working_memory", ) - name = chat_manager.get_stream_name(self.subheartflow_id) + name = get_chat_manager().get_stream_name(self.subheartflow_id) self.log_prefix = f"[{name}] " async def process_info( diff --git a/src/chat/focus_chat/planners/modify_actions.py b/src/chat/focus_chat/planners/modify_actions.py index f6461bb35..547e379ef 100644 --- a/src/chat/focus_chat/planners/modify_actions.py +++ b/src/chat/focus_chat/planners/modify_actions.py @@ -3,7 +3,7 @@ from src.chat.heart_flow.observation.observation import Observation from src.common.logger import get_logger from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation from src.chat.heart_flow.observation.chatting_observation import ChattingObservation -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.config.config import global_config from src.llm_models.utils_model import LLMRequest from src.chat.actions.base_action import ActionActivationType, ChatMode @@ -97,7 +97,7 @@ class ActionModifier: if chat_obs: obs = chat_obs # 检查动作的关联类型 - chat_context = chat_manager.get_stream(obs.chat_id).context + chat_context = get_chat_manager().get_stream(obs.chat_id).context type_mismatched_actions = [] for action_name in all_actions.keys(): diff --git a/src/chat/focus_chat/planners/planner_simple.py b/src/chat/focus_chat/planners/planner_simple.py index 5bf159b36..3fc381975 100644 --- a/src/chat/focus_chat/planners/planner_simple.py +++ b/src/chat/focus_chat/planners/planner_simple.py @@ -13,7 +13,7 @@ from src.chat.focus_chat.info.self_info import SelfInfo from src.chat.focus_chat.info.relation_info import RelationInfo from src.common.logger import get_logger from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.focus_chat.planners.action_manager import ActionManager from src.chat.actions.base_action import ChatMode from json_repair import repair_json @@ -109,8 +109,8 @@ class ActionPlanner(BasePlanner): nickname_str += f"{nicknames}," name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。" - personality_block = individuality.get_personality_prompt(x_person=2, level=2) - identity_block = individuality.get_identity_prompt(x_person=2, level=2) + personality_block = get_individuality().get_personality_prompt(x_person=2, level=2) + identity_block = get_individuality().get_identity_prompt(x_person=2, level=2) self_info = name_block + personality_block + identity_block current_mind = "你思考了很久,没有想清晰要做什么" @@ -332,7 +332,7 @@ class ActionPlanner(BasePlanner): # else: # mind_info_block = "你刚参与聊天" - personality_block = individuality.get_prompt(x_person=2, level=2) + personality_block = get_individuality().get_prompt(x_person=2, level=2) action_options_block = "" for using_actions_name, using_actions_info in current_available_actions.items(): diff --git a/src/chat/focus_chat/replyer/default_replyer.py b/src/chat/focus_chat/replyer/default_replyer.py index bfd766169..cf3368799 100644 --- a/src/chat/focus_chat/replyer/default_replyer.py +++ b/src/chat/focus_chat/replyer/default_replyer.py @@ -1,15 +1,17 @@ import traceback from typing import List, Optional, Dict, Any, Tuple + +from src.chat.focus_chat.expressors.exprssion_learner import get_expression_learner from src.chat.message_receive.message import MessageRecv, MessageThinking, MessageSending from src.chat.message_receive.message import Seg # Local import needed after move from src.chat.message_receive.message import UserInfo -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.common.logger import get_logger from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.chat.utils.utils_image import image_path_to_base64 # Local import needed after move from src.chat.utils.timer_calculator import Timer # <--- Import Timer -from src.chat.emoji_system.emoji_manager import emoji_manager +from src.chat.emoji_system.emoji_manager import get_emoji_manager from src.chat.focus_chat.heartFC_sender import HeartFCSender from src.chat.utils.utils import process_llm_response from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info @@ -18,7 +20,6 @@ from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat import time -from src.chat.focus_chat.expressors.exprssion_learner import expression_learner import random from datetime import datetime import re @@ -342,6 +343,7 @@ class DefaultReplyer: show_actions=True, ) + expression_learner = get_expression_learner() ( learnt_style_expressions, learnt_grammar_expressions, @@ -486,7 +488,7 @@ class DefaultReplyer: logger.error(f"{self.log_prefix} 无法发送回复,anchor_message 为空。") return None - stream_name = chat_manager.get_stream_name(chat_id) or chat_id # 获取流名称用于日志 + stream_name = get_chat_manager().get_stream_name(chat_id) or chat_id # 获取流名称用于日志 # 检查思考过程是否仍在进行,并获取开始时间 if thinking_id: @@ -578,7 +580,7 @@ class DefaultReplyer: """ emoji_base64 = "" description = "" - emoji_raw = await emoji_manager.get_emoji_for_text(send_emoji) + emoji_raw = await get_emoji_manager().get_emoji_for_text(send_emoji) if emoji_raw: emoji_path, description, _emotion = emoji_raw emoji_base64 = image_path_to_base64(emoji_path) diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index 1d745384b..95a2d84ea 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -6,7 +6,7 @@ from typing import Optional, List, Dict, Tuple import traceback from src.common.logger import get_logger from src.chat.message_receive.message import MessageRecv -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.focus_chat.heartFC_chat import HeartFChatting from src.chat.normal_chat.normal_chat import NormalChat from src.chat.heart_flow.chat_state_info import ChatState, ChatStateInfo @@ -42,7 +42,7 @@ class SubHeartflow: self.history_chat_state: List[Tuple[ChatState, float]] = [] self.is_group_chat, self.chat_target_info = get_chat_type_and_target_info(self.chat_id) - self.log_prefix = chat_manager.get_stream_name(self.subheartflow_id) or self.subheartflow_id + self.log_prefix = get_chat_manager().get_stream_name(self.subheartflow_id) or self.subheartflow_id # 兴趣消息集合 self.interest_dict: Dict[str, tuple[MessageRecv, float, bool]] = {} @@ -103,7 +103,7 @@ class SubHeartflow: log_prefix = self.log_prefix try: # 获取聊天流并创建 NormalChat 实例 (同步部分) - chat_stream = chat_manager.get_stream(self.chat_id) + chat_stream = get_chat_manager().get_stream(self.chat_id) if not chat_stream: logger.error(f"{log_prefix} 无法获取 chat_stream,无法启动 NormalChat。") return False diff --git a/src/chat/heart_flow/subheartflow_manager.py b/src/chat/heart_flow/subheartflow_manager.py index 32deed530..faaac5ceb 100644 --- a/src/chat/heart_flow/subheartflow_manager.py +++ b/src/chat/heart_flow/subheartflow_manager.py @@ -2,7 +2,7 @@ import asyncio import time from typing import Dict, Any, Optional, List from src.common.logger import get_logger -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.heart_flow.sub_heartflow import SubHeartflow, ChatState @@ -27,7 +27,7 @@ async def _try_set_subflow_absent_internal(subflow: "SubHeartflow", log_prefix: bool: 如果状态成功变为 ABSENT 或原本就是 ABSENT,返回 True;否则返回 False。 """ flow_id = subflow.subheartflow_id - stream_name = chat_manager.get_stream_name(flow_id) or flow_id + stream_name = get_chat_manager().get_stream_name(flow_id) or flow_id if subflow.chat_state.chat_status != ChatState.ABSENT: logger.debug(f"{log_prefix} 设置 {stream_name} 状态为 ABSENT") @@ -106,7 +106,7 @@ class SubHeartflowManager: # 注册子心流 self.subheartflows[subheartflow_id] = new_subflow - heartflow_name = chat_manager.get_stream_name(subheartflow_id) or subheartflow_id + heartflow_name = get_chat_manager().get_stream_name(subheartflow_id) or subheartflow_id logger.info(f"[{heartflow_name}] 开始接收消息") return new_subflow @@ -120,7 +120,7 @@ class SubHeartflowManager: async with self._lock: # 加锁以安全访问字典 subheartflow = self.subheartflows.get(subheartflow_id) - stream_name = chat_manager.get_stream_name(subheartflow_id) or subheartflow_id + stream_name = get_chat_manager().get_stream_name(subheartflow_id) or subheartflow_id logger.info(f"{log_prefix} 正在停止 {stream_name}, 原因: {reason}") # 调用内部方法处理状态变更 @@ -170,7 +170,9 @@ class SubHeartflowManager: changed_count += 1 else: # 这种情况理论上不应发生,如果内部方法返回 True 的话 - stream_name = chat_manager.get_stream_name(subflow.subheartflow_id) or subflow.subheartflow_id + stream_name = ( + get_chat_manager().get_stream_name(subflow.subheartflow_id) or subflow.subheartflow_id + ) logger.warning(f"{log_prefix} 内部方法声称成功但 {stream_name} 状态未变为 ABSENT。") # 锁在此处自动释放 @@ -183,7 +185,7 @@ class SubHeartflowManager: # try: # for sub_hf in list(self.subheartflows.values()): # flow_id = sub_hf.subheartflow_id - # stream_name = chat_manager.get_stream_name(flow_id) or flow_id + # stream_name = get_chat_manager().get_stream_name(flow_id) or flow_id # # 跳过已经是FOCUSED状态的子心流 # if sub_hf.chat_state.chat_status == ChatState.FOCUSED: @@ -229,7 +231,7 @@ class SubHeartflowManager: logger.warning(f"[状态转换请求] 尝试转换不存在的子心流 {subflow_id} 到 NORMAL") return - stream_name = chat_manager.get_stream_name(subflow_id) or subflow_id + stream_name = get_chat_manager().get_stream_name(subflow_id) or subflow_id current_state = subflow.chat_state.chat_status if current_state == ChatState.FOCUSED: @@ -298,7 +300,7 @@ class SubHeartflowManager: # --- 遍历评估每个符合条件的私聊 --- # for sub_hf in eligible_subflows: flow_id = sub_hf.subheartflow_id - stream_name = chat_manager.get_stream_name(flow_id) or flow_id + stream_name = get_chat_manager().get_stream_name(flow_id) or flow_id log_prefix = f"[{stream_name}]({log_prefix_task})" try: diff --git a/src/chat/heart_flow/utils_chat.py b/src/chat/heart_flow/utils_chat.py index 95af96be9..e25ee6b6e 100644 --- a/src/chat/heart_flow/utils_chat.py +++ b/src/chat/heart_flow/utils_chat.py @@ -1,7 +1,7 @@ from typing import Optional, Tuple, Dict from src.common.logger import get_logger -from src.chat.message_receive.chat_stream import chat_manager -from src.person_info.person_info import person_info_manager, PersonInfoManager +from src.chat.message_receive.chat_stream import get_chat_manager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager logger = get_logger("heartflow_utils") @@ -23,7 +23,7 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]: chat_target_info = None try: - chat_stream = chat_manager.get_stream(chat_id) + chat_stream = get_chat_manager().get_stream(chat_id) if chat_stream: if chat_stream.group_info: @@ -51,6 +51,7 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]: person_name = None if person_id: # get_value is async, so await it directly + person_info_manager = get_person_info_manager() person_name = person_info_manager.get_value_sync(person_id, "person_name") target_info["person_id"] = person_id diff --git a/src/chat/message_receive/__init__.py b/src/chat/message_receive/__init__.py index 69d629b2e..a900de6b4 100644 --- a/src/chat/message_receive/__init__.py +++ b/src/chat/message_receive/__init__.py @@ -1,12 +1,12 @@ -from src.chat.emoji_system.emoji_manager import emoji_manager -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.emoji_system.emoji_manager import get_emoji_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.message_sender import message_manager from src.chat.message_receive.storage import MessageStorage __all__ = [ - "emoji_manager", - "chat_manager", + "get_emoji_manager", + "get_chat_manager", "message_manager", "MessageStorage", ] diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index a8885f9bc..5d111b032 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -3,7 +3,7 @@ from typing import Dict, Any from src.common.logger import get_logger from src.manager.mood_manager import mood_manager # 导入情绪管理器 -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.message import MessageRecv from src.experimental.only_message_process import MessageProcessor from src.experimental.PFC.pfc_manager import PFCManager @@ -132,10 +132,10 @@ class ChatBot: message = MessageRecv(message_data) group_info = message.message_info.group_info user_info = message.message_info.user_info - chat_manager.register_message(message) + get_chat_manager().register_message(message) # 创建聊天流 - chat = await chat_manager.get_or_create_stream( + chat = await get_chat_manager().get_or_create_stream( platform=message.message_info.platform, user_info=user_info, group_info=group_info, diff --git a/src/chat/message_receive/chat_stream.py b/src/chat/message_receive/chat_stream.py index 4a9966d9e..abd3f0afd 100644 --- a/src/chat/message_receive/chat_stream.py +++ b/src/chat/message_receive/chat_stream.py @@ -377,5 +377,11 @@ class ChatManager: logger.error(f"从数据库加载所有聊天流失败 (Peewee): {e}", exc_info=True) -# 创建全局单例 -chat_manager = ChatManager() +chat_manager = None + + +def get_chat_manager(): + global chat_manager + if chat_manager is None: + chat_manager = ChatManager() + return chat_manager diff --git a/src/chat/message_receive/message.py b/src/chat/message_receive/message.py index 25ce81d7e..bf71881bc 100644 --- a/src/chat/message_receive/message.py +++ b/src/chat/message_receive/message.py @@ -9,7 +9,7 @@ from src.common.logger import get_logger if TYPE_CHECKING: from .chat_stream import ChatStream -from ..utils.utils_image import image_manager +from ..utils.utils_image import get_image_manager from maim_message import Seg, UserInfo, BaseMessageInfo, MessageBase from rich.traceback import install @@ -138,12 +138,12 @@ class MessageRecv(Message): elif seg.type == "image": # 如果是base64图片数据 if isinstance(seg.data, str): - return await image_manager.get_image_description(seg.data) + return await get_image_manager().get_image_description(seg.data) return "[发了一张图片,网卡了加载不出来]" elif seg.type == "emoji": self.is_emoji = True if isinstance(seg.data, str): - return await image_manager.get_emoji_description(seg.data) + return await get_image_manager().get_emoji_description(seg.data) return "[发了一个表情包,网卡了加载不出来]" else: return f"[{seg.type}:{str(seg.data)}]" @@ -207,11 +207,11 @@ class MessageProcessBase(Message): elif seg.type == "image": # 如果是base64图片数据 if isinstance(seg.data, str): - return await image_manager.get_image_description(seg.data) + return await get_image_manager().get_image_description(seg.data) return "[图片,网卡了加载不出来]" elif seg.type == "emoji": if isinstance(seg.data, str): - return await image_manager.get_emoji_description(seg.data) + return await get_image_manager().get_emoji_description(seg.data) return "[表情,网卡了加载不出来]" elif seg.type == "at": return f"[@{seg.data}]" diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index 5fb969ae1..8b5541b23 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -7,13 +7,13 @@ from maim_message import UserInfo, Seg from src.common.logger import get_logger from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info from src.manager.mood_manager import mood_manager -from src.chat.message_receive.chat_stream import ChatStream, chat_manager +from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager from src.chat.utils.timer_calculator import Timer from src.chat.utils.prompt_builder import global_prompt_manager from .normal_chat_generator import NormalChatGenerator from ..message_receive.message import MessageSending, MessageRecv, MessageThinking, MessageSet from src.chat.message_receive.message_sender import message_manager -from src.chat.normal_chat.willing.willing_manager import willing_manager +from src.chat.normal_chat.willing.willing_manager import get_willing_manager from src.chat.normal_chat.normal_chat_utils import get_recent_message_stats from src.config.config import global_config from src.chat.focus_chat.planners.action_manager import ActionManager @@ -22,6 +22,7 @@ from src.chat.normal_chat.normal_chat_action_modifier import NormalChatActionMod from src.chat.normal_chat.normal_chat_expressor import NormalChatExpressor from src.chat.focus_chat.replyer.default_replyer import DefaultReplyer +willing_manager = get_willing_manager() logger = get_logger("normal_chat") @@ -32,7 +33,7 @@ class NormalChat: self.chat_stream = chat_stream self.stream_id = chat_stream.stream_id - self.stream_name = chat_manager.get_stream_name(self.stream_id) or self.stream_id + self.stream_name = get_chat_manager().get_stream_name(self.stream_id) or self.stream_id # 初始化Normal Chat专用表达器 self.expressor = NormalChatExpressor(self.chat_stream) diff --git a/src/chat/normal_chat/normal_chat_expressor.py b/src/chat/normal_chat/normal_chat_expressor.py index 6c9c1e3fe..d49b1228a 100644 --- a/src/chat/normal_chat/normal_chat_expressor.py +++ b/src/chat/normal_chat/normal_chat_expressor.py @@ -9,7 +9,7 @@ import time from typing import List, Optional, Tuple, Dict, Any from src.chat.message_receive.message import MessageRecv, MessageSending, MessageThinking, Seg from src.chat.message_receive.message import UserInfo -from src.chat.message_receive.chat_stream import ChatStream, chat_manager +from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager from src.chat.message_receive.message_sender import message_manager from src.config.config import global_config from src.common.logger import get_logger @@ -35,7 +35,7 @@ class NormalChatExpressor: stream_name: 流名称 """ self.chat_stream = chat_stream - self.stream_name = chat_manager.get_stream_name(self.chat_stream.stream_id) or self.chat_stream.stream_id + self.stream_name = get_chat_manager().get_stream_name(self.chat_stream.stream_id) or self.chat_stream.stream_id self.log_prefix = f"[{self.stream_name}]Normal表达器" logger.debug(f"{self.log_prefix} 初始化完成") diff --git a/src/chat/normal_chat/normal_chat_generator.py b/src/chat/normal_chat/normal_chat_generator.py index 0dbf38a98..b68cfabb1 100644 --- a/src/chat/normal_chat/normal_chat_generator.py +++ b/src/chat/normal_chat/normal_chat_generator.py @@ -6,7 +6,7 @@ from src.chat.message_receive.message import MessageThinking from src.chat.normal_chat.normal_prompt import prompt_builder from src.chat.utils.timer_calculator import Timer from src.common.logger import get_logger -from src.person_info.person_info import person_info_manager, PersonInfoManager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager from src.chat.utils.utils import process_llm_response @@ -69,7 +69,7 @@ class NormalChatGenerator: person_id = PersonInfoManager.get_person_id( message.chat_stream.user_info.platform, message.chat_stream.user_info.user_id ) - + person_info_manager = get_person_info_manager() person_name = await person_info_manager.get_value(person_id, "person_name") if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname: diff --git a/src/chat/normal_chat/normal_chat_planner.py b/src/chat/normal_chat/normal_chat_planner.py index 1c9395303..448ed2cb7 100644 --- a/src/chat/normal_chat/normal_chat_planner.py +++ b/src/chat/normal_chat/normal_chat_planner.py @@ -5,7 +5,7 @@ from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.common.logger import get_logger from src.chat.utils.prompt_builder import Prompt, global_prompt_manager -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.focus_chat.planners.action_manager import ActionManager from src.chat.actions.base_action import ChatMode from src.chat.message_receive.message import MessageThinking @@ -94,8 +94,8 @@ class NormalChatPlanner: nickname_str += f"{nicknames}," name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。" - personality_block = individuality.get_personality_prompt(x_person=2, level=2) - identity_block = individuality.get_identity_prompt(x_person=2, level=2) + personality_block = get_individuality().get_personality_prompt(x_person=2, level=2) + identity_block = get_individuality().get_identity_prompt(x_person=2, level=2) self_info = name_block + personality_block + identity_block diff --git a/src/chat/normal_chat/normal_prompt.py b/src/chat/normal_chat/normal_prompt.py index de016da38..378ac8b15 100644 --- a/src/chat/normal_chat/normal_prompt.py +++ b/src/chat/normal_chat/normal_prompt.py @@ -1,18 +1,18 @@ +from src.chat.focus_chat.expressors.exprssion_learner import get_expression_learner from src.config.config import global_config from src.common.logger import get_logger -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat -from src.person_info.relationship_manager import relationship_manager import time from src.chat.utils.utils import get_recent_group_speaker from src.manager.mood_manager import mood_manager from src.chat.memory_system.Hippocampus import hippocampus_manager from src.chat.knowledge.knowledge_lib import qa_manager -from src.chat.focus_chat.expressors.exprssion_learner import expression_learner import random import re +from src.person_info.relationship_manager import get_relationship_manager logger = get_logger("prompt") @@ -96,7 +96,7 @@ class PromptBuilder: enable_planner: bool = False, available_actions=None, ) -> str: - prompt_personality = individuality.get_prompt(x_person=2, level=2) + prompt_personality = get_individuality().get_prompt(x_person=2, level=2) is_group_chat = bool(chat_stream.group_info) who_chat_in_group = [] @@ -114,10 +114,11 @@ class PromptBuilder: relation_prompt = "" if global_config.relationship.enable_relationship: for person in who_chat_in_group: + relationship_manager = get_relationship_manager() relation_prompt += await relationship_manager.build_relationship_info(person) mood_prompt = mood_manager.get_mood_prompt() - + expression_learner = get_expression_learner() ( learnt_style_expressions, learnt_grammar_expressions, diff --git a/src/chat/normal_chat/willing/willing_manager.py b/src/chat/normal_chat/willing/willing_manager.py index 201d3d85f..e3230b0a6 100644 --- a/src/chat/normal_chat/willing/willing_manager.py +++ b/src/chat/normal_chat/willing/willing_manager.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from src.config.config import global_config from src.chat.message_receive.chat_stream import ChatStream, GroupInfo from src.chat.message_receive.message import MessageRecv -from src.person_info.person_info import person_info_manager, PersonInfoManager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager from abc import ABC, abstractmethod import importlib from typing import Dict, Optional @@ -33,6 +33,7 @@ set_willing 设置某聊天流意愿 示例: 在 `mode_aggressive.py` 中,类名应为 `AggressiveWillingManager` """ + logger = get_logger("willing") @@ -95,7 +96,7 @@ class BaseWillingManager(ABC): self.ongoing_messages[message.message_info.message_id] = WillingInfo( message=message, chat=chat, - person_info_manager=person_info_manager, + person_info_manager=get_person_info_manager(), chat_id=chat.stream_id, person_id=person_id, group_info=chat.group_info, @@ -172,4 +173,11 @@ def init_willing_manager() -> BaseWillingManager: # 全局willing_manager对象 -willing_manager = init_willing_manager() +willing_manager = None + + +def get_willing_manager(): + global willing_manager + if willing_manager is None: + willing_manager = init_willing_manager() + return willing_manager diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index d4b7d4646..c3b0c8aef 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -4,7 +4,7 @@ import time # 导入 time 模块以获取当前时间 import random import re from src.common.message_repository import find_messages, count_messages -from src.person_info.person_info import person_info_manager, PersonInfoManager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager from src.chat.utils.utils import translate_timestamp_to_human_readable from rich.traceback import install from src.common.database.database_model import ActionRecords @@ -220,6 +220,7 @@ def _build_readable_messages_internal( continue person_id = PersonInfoManager.get_person_id(platform, user_id) + person_info_manager = get_person_info_manager() # 根据 replace_bot_name 参数决定是否替换机器人名称 if replace_bot_name and user_id == global_config.bot.qq_account: person_name = f"{global_config.bot.nickname}(你)" diff --git a/src/chat/utils/utils_image.py b/src/chat/utils/utils_image.py index ded80c052..9fd6019b4 100644 --- a/src/chat/utils/utils_image.py +++ b/src/chat/utils/utils_image.py @@ -362,7 +362,15 @@ class ImageManager: # 创建全局单例 -image_manager = ImageManager() +image_manager = None + + +def get_image_manager() -> ImageManager: + """获取全局图片管理器单例""" + global image_manager + if image_manager is None: + image_manager = ImageManager() + return image_manager def image_path_to_base64(image_path: str) -> str: diff --git a/src/experimental/PFC/action_planner.py b/src/experimental/PFC/action_planner.py index 95c777235..e7045f2aa 100644 --- a/src/experimental/PFC/action_planner.py +++ b/src/experimental/PFC/action_planner.py @@ -5,7 +5,7 @@ from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.experimental.PFC.chat_observer import ChatObserver from src.experimental.PFC.pfc_utils import get_items_from_json -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.experimental.PFC.observation_info import ObservationInfo from src.experimental.PFC.conversation_info import ConversationInfo from src.chat.utils.chat_message_builder import build_readable_messages @@ -112,7 +112,7 @@ class ActionPlanner: temperature=global_config.llm_PFC_action_planner["temp"], request_type="action_planning", ) - self.personality_info = individuality.get_prompt(x_person=2, level=3) + self.personality_info = get_individuality().get_prompt(x_person=2, level=3) self.name = global_config.bot.nickname self.private_name = private_name self.chat_observer = ChatObserver.get_instance(stream_id, private_name) diff --git a/src/experimental/PFC/conversation.py b/src/experimental/PFC/conversation.py index f5044b67d..9be055176 100644 --- a/src/experimental/PFC/conversation.py +++ b/src/experimental/PFC/conversation.py @@ -18,7 +18,7 @@ from .conversation_info import ConversationInfo # 确保导入 ConversationInfo from .reply_generator import ReplyGenerator from src.chat.message_receive.chat_stream import ChatStream from src.chat.message_receive.message import UserInfo -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager from .pfc_KnowledgeFetcher import KnowledgeFetcher from .waiter import Waiter @@ -60,7 +60,7 @@ class Conversation: self.direct_sender = DirectMessageSender(self.private_name) # 获取聊天流信息 - self.chat_stream = chat_manager.get_stream(self.stream_id) + self.chat_stream = get_chat_manager().get_stream(self.stream_id) self.stop_action_planner = False except Exception as e: @@ -248,14 +248,14 @@ class Conversation: def _convert_to_message(self, msg_dict: Dict[str, Any]) -> Message: """将消息字典转换为Message对象""" try: - # 尝试从 msg_dict 直接获取 chat_stream,如果失败则从全局 chat_manager 获取 + # 尝试从 msg_dict 直接获取 chat_stream,如果失败则从全局 get_chat_manager 获取 chat_info = msg_dict.get("chat_info") if chat_info and isinstance(chat_info, dict): chat_stream = ChatStream.from_dict(chat_info) elif self.chat_stream: # 使用实例变量中的 chat_stream chat_stream = self.chat_stream else: # Fallback: 尝试从 manager 获取 (可能需要 stream_id) - chat_stream = chat_manager.get_stream(self.stream_id) + chat_stream = get_chat_manager().get_stream(self.stream_id) if not chat_stream: raise ValueError(f"无法确定 ChatStream for stream_id {self.stream_id}") diff --git a/src/experimental/PFC/pfc.py b/src/experimental/PFC/pfc.py index 893d47937..4050ae58e 100644 --- a/src/experimental/PFC/pfc.py +++ b/src/experimental/PFC/pfc.py @@ -4,7 +4,7 @@ from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.experimental.PFC.chat_observer import ChatObserver from src.experimental.PFC.pfc_utils import get_items_from_json -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from src.experimental.PFC.conversation_info import ConversationInfo from src.experimental.PFC.observation_info import ObservationInfo from src.chat.utils.chat_message_builder import build_readable_messages @@ -47,7 +47,7 @@ class GoalAnalyzer: model=global_config.model.utils, temperature=0.7, max_tokens=1000, request_type="conversation_goal" ) - self.personality_info = individuality.get_prompt(x_person=2, level=3) + self.personality_info = get_individuality().get_prompt(x_person=2, level=3) self.name = global_config.bot.nickname self.nick_name = global_config.bot.alias_names self.private_name = private_name diff --git a/src/experimental/PFC/reply_generator.py b/src/experimental/PFC/reply_generator.py index 75a475ff4..530eba6c7 100644 --- a/src/experimental/PFC/reply_generator.py +++ b/src/experimental/PFC/reply_generator.py @@ -4,7 +4,7 @@ from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.experimental.PFC.chat_observer import ChatObserver from src.experimental.PFC.reply_checker import ReplyChecker -from src.individuality.individuality import individuality +from src.individuality.individuality import get_individuality from .observation_info import ObservationInfo from .conversation_info import ConversationInfo from src.chat.utils.chat_message_builder import build_readable_messages @@ -91,7 +91,7 @@ class ReplyGenerator: temperature=global_config.llm_PFC_chat["temp"], request_type="reply_generation", ) - self.personality_info = individuality.get_prompt(x_person=2, level=3) + self.personality_info = get_individuality().get_prompt(x_person=2, level=3) self.name = global_config.bot.nickname self.private_name = private_name self.chat_observer = ChatObserver.get_instance(stream_id, private_name) diff --git a/src/experimental/PFC/waiter.py b/src/experimental/PFC/waiter.py index 83f21424e..530a48a4e 100644 --- a/src/experimental/PFC/waiter.py +++ b/src/experimental/PFC/waiter.py @@ -2,7 +2,7 @@ from src.common.logger import get_logger from .chat_observer import ChatObserver from .conversation_info import ConversationInfo -# from src.individuality.individuality import individuality,Individuality # 不再需要 +# from src.individuality.individuality get_individuality,Individuality # 不再需要 from src.config.config import global_config import time import asyncio diff --git a/src/individuality/individuality.py b/src/individuality/individuality.py index d6682fd0d..d1f728fb4 100644 --- a/src/individuality/individuality.py +++ b/src/individuality/individuality.py @@ -213,4 +213,11 @@ class Individuality: return None -individuality = Individuality() +individuality = None + + +def get_individuality(): + global individuality + if individuality is None: + individuality = Individuality() + return individuality diff --git a/src/main.py b/src/main.py index 2c70b695c..023818e6e 100644 --- a/src/main.py +++ b/src/main.py @@ -1,23 +1,24 @@ import asyncio import time from maim_message import MessageServer + +from src.chat.focus_chat.expressors.exprssion_learner import get_expression_learner from src.common.remote import TelemetryHeartBeatTask from src.manager.async_task_manager import async_task_manager from src.chat.utils.statistic import OnlineTimeRecordTask, StatisticOutputTask from src.manager.mood_manager import MoodPrintTask, MoodUpdateTask -from src.chat.emoji_system.emoji_manager import emoji_manager -from src.chat.normal_chat.willing.willing_manager import willing_manager -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.emoji_system.emoji_manager import get_emoji_manager +from src.chat.normal_chat.willing.willing_manager import get_willing_manager +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.heart_flow.heartflow import heartflow from src.chat.message_receive.message_sender import message_manager from src.chat.message_receive.storage import MessageStorage from src.config.config import global_config from src.chat.message_receive.bot import chat_bot from src.common.logger import get_logger -from src.individuality.individuality import individuality, Individuality +from src.individuality.individuality import get_individuality, Individuality from src.common.server import get_global_server, Server from rich.traceback import install -from src.chat.focus_chat.expressors.exprssion_learner import expression_learner from src.api.main import start_api_server # 导入新的插件管理器 @@ -34,6 +35,8 @@ if global_config.memory.enable_memory: install(extra_lines=3) +willing_manager = get_willing_manager() + logger = get_logger("main") @@ -45,7 +48,7 @@ class MainSystem: else: self.hippocampus_manager = None - self.individuality: Individuality = individuality + self.individuality: Individuality = get_individuality() # 使用消息API替代直接的FastAPI实例 self.app: MessageServer = get_global_api() @@ -82,7 +85,7 @@ class MainSystem: logger.info(f"插件系统加载成功: {plugin_count} 个插件,{component_count} 个组件") # 初始化表情管理器 - emoji_manager.initialize() + get_emoji_manager.initialize() logger.info("表情包管理器初始化成功") # 添加情绪衰减任务 @@ -94,8 +97,8 @@ class MainSystem: await willing_manager.async_task_starter() # 初始化聊天管理器 - await chat_manager._initialize() - asyncio.create_task(chat_manager._auto_save_task()) + await get_chat_manager()._initialize() + asyncio.create_task(get_chat_manager()._auto_save_task()) # 根据配置条件性地初始化记忆系统 if global_config.memory.enable_memory: @@ -138,7 +141,7 @@ class MainSystem: """调度定时任务""" while True: tasks = [ - emoji_manager.start_periodic_check_register(), + get_emoji_manager().start_periodic_check_register(), self.remove_recalled_message_task(), self.app.run(), self.server.run(), @@ -184,6 +187,7 @@ class MainSystem: @staticmethod async def learn_and_store_expression_task(): """学习并存储表达方式任务""" + expression_learner = get_expression_learner() while True: await asyncio.sleep(global_config.expression.learning_interval) if global_config.expression.enable_expression_learning: diff --git a/src/manager/mood_manager.py b/src/manager/mood_manager.py index b73fa7112..a62a64fcb 100644 --- a/src/manager/mood_manager.py +++ b/src/manager/mood_manager.py @@ -7,7 +7,7 @@ from typing import Dict, Tuple from ..config.config import global_config from ..common.logger import get_logger from ..manager.async_task_manager import AsyncTask -from ..individuality.individuality import individuality +from ..individuality.individuality import get_individuality logger = get_logger("mood") @@ -54,7 +54,7 @@ class MoodUpdateTask(AsyncTask): agreeableness_bias = 0 # 宜人性偏置 neuroticism_factor = 0.5 # 神经质系数 # 获取人格特质 - personality = individuality.personality + personality = get_individuality().personality if personality: # 神经质:影响情绪变化速度 neuroticism_factor = 1 + (personality.neuroticism - 0.5) * 0.4 diff --git a/src/person_info/impression_update_task.py b/src/person_info/impression_update_task.py index 27271c544..116df49c2 100644 --- a/src/person_info/impression_update_task.py +++ b/src/person_info/impression_update_task.py @@ -1,14 +1,15 @@ from src.manager.async_task_manager import AsyncTask from src.common.logger import get_logger from src.person_info.person_info import PersonInfoManager -from src.person_info.relationship_manager import relationship_manager from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp from src.config.config import global_config -from src.chat.message_receive.chat_stream import chat_manager +from src.chat.message_receive.chat_stream import get_chat_manager import time import random from collections import defaultdict +from src.person_info.relationship_manager import get_relationship_manager + logger = get_logger("relation") @@ -50,7 +51,7 @@ class ImpressionUpdateTask(AsyncTask): logger.info(f"聊天组 {chat_id} 消息数小于30,跳过处理") continue - chat_stream = chat_manager.get_stream(chat_id) + chat_stream = get_chat_manager().get_stream(chat_id) if not chat_stream: logger.warning(f"未找到聊天组 {chat_id} 的chat_stream,跳过处理") continue @@ -149,7 +150,7 @@ class ImpressionUpdateTask(AsyncTask): logger.info( f"开始进一步了解用户: {[msg[1]['messages'][0]['user_nickname'] for msg in selected_users]}" ) - + relationship_manager = get_relationship_manager() # 更新选中用户的印象 for person_id, data in selected_users: user_nickname = data["messages"][0]["user_nickname"] diff --git a/src/person_info/person_info.py b/src/person_info/person_info.py index f57bfb090..ba79327cb 100644 --- a/src/person_info/person_info.py +++ b/src/person_info/person_info.py @@ -277,7 +277,7 @@ class PersonInfoManager: current_name_set = set(self.person_name_list.values()) while current_try < max_retries: - # prompt_personality = individuality.get_prompt(x_person=2, level=1) + # prompt_personality =get_individuality().get_prompt(x_person=2, level=1) bot_name = global_config.bot.nickname qv_name_prompt = f"你是{bot_name},一个伪装成人类的AI,你不能让别人发现这一点," @@ -601,4 +601,11 @@ class PersonInfoManager: return None -person_info_manager = PersonInfoManager() +person_info_manager = None + + +def get_person_info_manager(): + global person_info_manager + if person_info_manager is None: + person_info_manager = PersonInfoManager() + return person_info_manager diff --git a/src/person_info/relationship_manager.py b/src/person_info/relationship_manager.py index 3e51583d5..663c71762 100644 --- a/src/person_info/relationship_manager.py +++ b/src/person_info/relationship_manager.py @@ -1,6 +1,6 @@ from src.common.logger import get_logger import math -from src.person_info.person_info import person_info_manager, PersonInfoManager +from src.person_info.person_info import PersonInfoManager, get_person_info_manager import time import random from src.llm_models.utils_model import LLMRequest @@ -16,6 +16,7 @@ import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity + logger = get_logger("relation") @@ -85,6 +86,7 @@ class RelationshipManager: @staticmethod async def is_known_some_one(platform, user_id): """判断是否认识某人""" + person_info_manager = get_person_info_manager() is_known = await person_info_manager.is_person_known(platform, user_id) return is_known @@ -93,6 +95,7 @@ class RelationshipManager: """判断是否认识某人""" person_id = PersonInfoManager.get_person_id(platform, user_id) # 生成唯一的 person_name + person_info_manager = get_person_info_manager() unique_nickname = await person_info_manager._generate_unique_person_name(user_nickname) data = { "platform": platform, @@ -117,7 +120,7 @@ class RelationshipManager: person_id = person else: person_id = PersonInfoManager.get_person_id(person[0], person[1]) - + person_info_manager = get_person_info_manager() person_name = await person_info_manager.get_value(person_id, "person_name") if not person_name or person_name == "none": return "" @@ -157,6 +160,7 @@ class RelationshipManager: field_name: 字段名称 new_items: 新的项目列表 """ + person_info_manager = get_person_info_manager() old_items = await person_info_manager.get_value(person_id, field_name) or [] updated_items = list(set(old_items + [item for item in new_items if isinstance(item, str) and item])) await person_info_manager.update_one_field(person_id, field_name, updated_items) @@ -171,12 +175,13 @@ class RelationshipManager: timestamp: 时间戳 (用于记录交互时间) bot_engaged_messages: bot参与的消息列表 """ + person_info_manager = get_person_info_manager() person_name = await person_info_manager.get_value(person_id, "person_name") nickname = await person_info_manager.get_value(person_id, "nickname") alias_str = ", ".join(global_config.bot.alias_names) - # personality_block = individuality.get_personality_prompt(x_person=2, level=2) - # identity_block = individuality.get_identity_prompt(x_person=2, level=2) + # personality_block =get_individuality().get_personality_prompt(x_person=2, level=2) + # identity_block =get_individuality().get_identity_prompt(x_person=2, level=2) user_messages = bot_engaged_messages @@ -602,4 +607,11 @@ class RelationshipManager: return tfidf_sim > tfidf_threshold or seq_sim > seq_threshold -relationship_manager = RelationshipManager() +relationship_manager = None + + +def get_relationship_manager(): + global relationship_manager + if relationship_manager is None: + relationship_manager = RelationshipManager() + return relationship_manager diff --git a/src/plugin_system/apis/config_api.py b/src/plugin_system/apis/config_api.py index af1aa61a5..9ced746a6 100644 --- a/src/plugin_system/apis/config_api.py +++ b/src/plugin_system/apis/config_api.py @@ -1,7 +1,7 @@ from typing import Any from src.common.logger import get_logger from src.config.config import global_config -from src.person_info.person_info import person_info_manager +from src.person_info.person_info import get_person_info_manager logger = get_logger("config_api") @@ -63,6 +63,7 @@ class ConfigAPI: Returns: tuple[str, str]: (平台, 用户ID) """ + person_info_manager = get_person_info_manager() person_id = person_info_manager.get_person_id_by_person_name(person_name) user_id = await person_info_manager.get_value(person_id, "user_id") platform = await person_info_manager.get_value(person_id, "platform") @@ -79,4 +80,5 @@ class ConfigAPI: Returns: Any: 用户信息值或默认值 """ + person_info_manager = get_person_info_manager() return await person_info_manager.get_value(person_id, key, default) diff --git a/src/plugin_system/apis/message_api.py b/src/plugin_system/apis/message_api.py index cd0ce4bfb..0ab32a442 100644 --- a/src/plugin_system/apis/message_api.py +++ b/src/plugin_system/apis/message_api.py @@ -5,7 +5,7 @@ from src.common.logger import get_logger from src.chat.focus_chat.hfc_utils import create_empty_anchor_message # 以下为类型注解需要 -from src.chat.message_receive.chat_stream import ChatStream, chat_manager +from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager from src.chat.focus_chat.info.obs_info import ObsInfo # 新增导入 @@ -50,7 +50,7 @@ class MessageAPI: if is_group: # 群聊:从数据库查找对应的聊天流 target_stream = None - for _, stream in chat_manager.streams.items(): + for _, stream in get_chat_manager().streams.items(): if ( stream.group_info and str(stream.group_info.group_id) == str(target_id) @@ -65,7 +65,7 @@ class MessageAPI: else: # 私聊:从数据库查找对应的聊天流 target_stream = None - for _, stream in chat_manager.streams.items(): + for _, stream in get_chat_manager().streams.items(): if ( not stream.group_info and str(stream.user_info.user_id) == str(target_id) diff --git a/src/tools/tool_can_use/rename_person_tool.py b/src/tools/tool_can_use/rename_person_tool.py index 84e048ef6..71bdc0f76 100644 --- a/src/tools/tool_can_use/rename_person_tool.py +++ b/src/tools/tool_can_use/rename_person_tool.py @@ -1,8 +1,9 @@ from src.tools.tool_can_use.base_tool import BaseTool, register_tool -from src.person_info.person_info import person_info_manager +from src.person_info.person_info import get_person_info_manager from src.common.logger import get_logger import time + logger = get_logger("rename_person_tool") @@ -39,7 +40,7 @@ class RenamePersonTool(BaseTool): if not person_name_to_find: return {"name": self.name, "content": "错误:必须提供需要重命名的用户昵称 (person_name)。"} - + person_info_manager = get_person_info_manager() try: # 1. 根据昵称查找用户信息 logger.debug(f"尝试根据昵称 '{person_name_to_find}' 查找用户...")