Skip to content

Commit 6767bd6

Browse files
committed
fix: 懒加载单例以修复环境变量加载问题
1 parent 6d1f5be commit 6767bd6

45 files changed

Lines changed: 243 additions & 155 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bot.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616

1717
from src.manager.async_task_manager import async_task_manager
1818

19+
logger = get_logger("main")
20+
21+
# 直接加载生产环境变量配置
22+
if os.path.exists(".env"):
23+
load_dotenv(".env", override=True)
24+
logger.info("成功加载环境变量配置")
25+
else:
26+
logger.warning("未找到.env文件,请确保程序所需的环境变量被正确设置")
27+
1928
install(extra_lines=3)
2029

2130
# 设置工作目录为脚本所在目录
@@ -24,7 +33,6 @@
2433
print(f"已设置工作目录为: {script_dir}")
2534

2635

27-
logger = get_logger("main")
2836
confirm_logger = get_logger("confirm")
2937
# 获取没有加载env时的环境变量
3038
env_mask = {key: os.getenv(key) for key in os.environ}
@@ -65,15 +73,6 @@ def easter_egg():
6573
print(rainbow_text)
6674

6775

68-
def load_env():
69-
# 直接加载生产环境变量配置
70-
if os.path.exists(".env"):
71-
load_dotenv(".env", override=True)
72-
logger.info("成功加载环境变量配置")
73-
else:
74-
logger.warning("未找到.env文件,请确保程序所需的环境变量被正确设置")
75-
76-
7776
def scan_provider(env_config: dict):
7877
provider = {}
7978

@@ -198,7 +197,6 @@ def check_eula():
198197

199198

200199
def raw_main():
201-
load_env()
202200
# 利用 TZ 环境变量设定程序工作的时区
203201
if platform.system().lower() != "windows":
204202
time.tzset()

scripts/message_retrieval_script.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
from src.common.database.database import db
3737
from src.config.config import global_config
3838
from src.llm_models.utils_model import LLMRequest
39-
from src.person_info.person_info import PersonInfoManager, person_info_manager
39+
from src.person_info.person_info import PersonInfoManager, get_person_info_manager
40+
4041

4142
logger = get_logger("message_retrieval")
4243

@@ -77,7 +78,7 @@ async def build_name_mapping(messages: List[Dict[str, Any]], target_person_name:
7778
name_mapping = {}
7879
current_user = "A"
7980
user_count = 1
80-
81+
person_info_manager = get_person_info_manager()
8182
# 遍历消息,构建映射
8283
for msg in messages:
8384
await person_info_manager.get_or_create_person(
@@ -410,6 +411,7 @@ def retrieve_messages(self, user_qq: str, time_period: str) -> Dict[str, List[Di
410411

411412
async def update_person_impression_from_segment(self, person_id: str, readable_messages: str, segment_time: float):
412413
"""从消息段落更新用户印象,使用和relationship_manager相同的流程"""
414+
person_info_manager = get_person_info_manager()
413415
person_name = await person_info_manager.get_value(person_id, "person_name")
414416
nickname = await person_info_manager.get_value(person_id, "nickname")
415417

@@ -659,6 +661,7 @@ async def process_segments_and_update_impression(
659661
"""处理分段消息并更新用户印象到数据库"""
660662
# 获取目标用户信息
661663
target_person_id = get_person_id("qq", user_qq)
664+
person_info_manager = get_person_info_manager()
662665
target_person_name = await person_info_manager.get_value(target_person_id, "person_name")
663666

664667
if not target_person_name:

src/chat/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
包含聊天、情绪、记忆、日程等功能模块
44
"""
55

6-
from src.chat.message_receive.chat_stream import chat_manager
7-
from src.chat.emoji_system.emoji_manager import emoji_manager
8-
from src.chat.normal_chat.willing.willing_manager import willing_manager
6+
from src.chat.message_receive.chat_stream import get_chat_manager
7+
from src.chat.emoji_system.emoji_manager import get_emoji_manager
8+
from src.chat.normal_chat.willing.willing_manager import get_willing_manager
99

1010
# 导出主要组件供外部使用
1111
__all__ = [
12-
"chat_manager",
13-
"emoji_manager",
14-
"willing_manager",
12+
"get_chat_manager",
13+
"get_emoji_manager",
14+
"get_willing_manager",
1515
]

src/chat/emoji_system/emoji_manager.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from src.common.database.database_model import Emoji
1616
from src.common.database.database import db as peewee_db
1717
from src.config.config import global_config
18-
from src.chat.utils.utils_image import image_path_to_base64, image_manager
18+
from src.chat.utils.utils_image import image_path_to_base64, get_image_manager
1919
from src.llm_models.utils_model import LLMRequest
2020
from src.common.logger import get_logger
2121
from rich.traceback import install
@@ -844,7 +844,7 @@ async def build_emoji_description(self, image_base64: str) -> Tuple[str, List[st
844844

845845
# 调用AI获取描述
846846
if image_format == "gif" or image_format == "GIF":
847-
image_base64 = image_manager.transform_gif(image_base64)
847+
image_base64 = get_image_manager().transform_gif(image_base64)
848848
prompt = "这是一个动态图表情包,每一张图代表了动态图的某一帧,黑色背景代表透明,描述一下表情包表达的情感和内容,描述细节,从互联网梗,meme的角度去分析"
849849
description, _ = await self.vlm.generate_response_for_image(prompt, image_base64, "jpg")
850850
else:
@@ -1000,5 +1000,11 @@ async def register_emoji_by_filename(self, filename: str) -> bool:
10001000
return False
10011001

10021002

1003-
# 创建全局单例
1004-
emoji_manager = EmojiManager()
1003+
emoji_manager = None
1004+
1005+
1006+
def get_emoji_manager():
1007+
global emoji_manager
1008+
if emoji_manager is None:
1009+
emoji_manager = EmojiManager()
1010+
return emoji_manager

src/chat/focus_chat/expressors/default_expressor.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import traceback
22
from typing import List, Optional, Dict, Any, Tuple
3+
4+
from src.chat.focus_chat.expressors.exprssion_learner import get_expression_learner
35
from src.chat.message_receive.message import MessageRecv, MessageThinking, MessageSending
46
from src.chat.message_receive.message import Seg # Local import needed after move
57
from src.chat.message_receive.message import UserInfo
6-
from src.chat.message_receive.chat_stream import chat_manager
8+
from src.chat.message_receive.chat_stream import get_chat_manager
79
from src.common.logger import get_logger
810
from src.llm_models.utils_model import LLMRequest
911
from src.config.config import global_config
1012
from src.chat.utils.utils_image import image_path_to_base64 # Local import needed after move
1113
from src.chat.utils.timer_calculator import Timer # <--- Import Timer
12-
from src.chat.emoji_system.emoji_manager import emoji_manager
14+
from src.chat.emoji_system.emoji_manager import get_emoji_manager
1315
from src.chat.focus_chat.heartFC_sender import HeartFCSender
1416
from src.chat.utils.utils import process_llm_response
1517
from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info
@@ -18,7 +20,6 @@
1820
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
1921
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
2022
import time
21-
from src.chat.focus_chat.expressors.exprssion_learner import expression_learner
2223
import random
2324

2425
logger = get_logger("expressor")
@@ -274,6 +275,7 @@ async def build_prompt_focus(
274275
truncate=True,
275276
)
276277

278+
expression_learner = get_expression_learner()
277279
(
278280
learnt_style_expressions,
279281
learnt_grammar_expressions,
@@ -365,7 +367,7 @@ async def send_response_messages(
365367
logger.error(f"{self.log_prefix} 无法发送回复,anchor_message 为空。")
366368
return None
367369

368-
stream_name = chat_manager.get_stream_name(chat_id) or chat_id # 获取流名称用于日志
370+
stream_name = get_chat_manager().get_stream_name(chat_id) or chat_id # 获取流名称用于日志
369371

370372
# 检查思考过程是否仍在进行,并获取开始时间
371373
if thinking_id:
@@ -454,7 +456,7 @@ async def _choose_emoji(self, send_emoji: str):
454456
选择表情,根据send_emoji文本选择表情,返回表情base64
455457
"""
456458
emoji_base64 = ""
457-
emoji_raw = await emoji_manager.get_emoji_for_text(send_emoji)
459+
emoji_raw = await get_emoji_manager().get_emoji_for_text(send_emoji)
458460
if emoji_raw:
459461
emoji_path, _description, _emotion = emoji_raw
460462
emoji_base64 = image_path_to_base64(emoji_path)

src/chat/focus_chat/expressors/exprssion_learner.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_random, build_anonymous_messages
88
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
99
import os
10-
from src.chat.message_receive.chat_stream import chat_manager
10+
from src.chat.message_receive.chat_stream import get_chat_manager
1111
import json
1212

1313

@@ -220,7 +220,7 @@ async def learn_and_store(self, type: str, num: int = 10) -> List[Tuple[str, str
220220
return []
221221
learnt_expressions, chat_id = res
222222

223-
chat_stream = chat_manager.get_stream(chat_id)
223+
chat_stream = get_chat_manager().get_stream(chat_id)
224224
if chat_stream.group_info:
225225
group_name = chat_stream.group_info.group_name
226226
else:
@@ -399,4 +399,11 @@ def parse_expression_response(self, response: str, chat_id: str) -> List[Tuple[s
399399

400400
init_prompt()
401401

402-
expression_learner = ExpressionLearner()
402+
expression_learner = None
403+
404+
405+
def get_expression_learner():
406+
global expression_learner
407+
if expression_learner is None:
408+
expression_learner = ExpressionLearner()
409+
return expression_learner

src/chat/focus_chat/heartFC_chat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import traceback
55
from collections import deque
66
from typing import List, Optional, Dict, Any, Deque, Callable, Awaitable
7-
from src.chat.message_receive.chat_stream import chat_manager
7+
from src.chat.message_receive.chat_stream import get_chat_manager
88
from rich.traceback import install
99
from src.chat.utils.prompt_builder import global_prompt_manager
1010
from src.common.logger import get_logger
@@ -97,8 +97,8 @@ def __init__(
9797
"""
9898
# 基础属性
9999
self.stream_id: str = chat_id # 聊天流ID
100-
self.chat_stream = chat_manager.get_stream(self.stream_id)
101-
self.log_prefix = f"[{chat_manager.get_stream_name(self.stream_id) or self.stream_id}]"
100+
self.chat_stream = get_chat_manager().get_stream(self.stream_id)
101+
self.log_prefix = f"[{get_chat_manager().get_stream_name(self.stream_id) or self.stream_id}]"
102102

103103
self.memory_activator = MemoryActivator()
104104

src/chat/focus_chat/heartflow_message_processor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
from src.chat.message_receive.message import MessageRecv
44
from src.chat.message_receive.storage import MessageStorage
55
from src.chat.heart_flow.heartflow import heartflow
6-
from src.chat.message_receive.chat_stream import chat_manager, ChatStream
6+
from src.chat.message_receive.chat_stream import get_chat_manager, ChatStream
77
from src.chat.utils.utils import is_mentioned_bot_in_message
88
from src.chat.utils.timer_calculator import Timer
99
from src.common.logger import get_logger
10-
from src.person_info.relationship_manager import relationship_manager
1110

1211
import math
1312
import re
1413
import traceback
1514
from typing import Optional, Tuple, Dict, Any
1615
from maim_message import UserInfo
1716

17+
from src.person_info.relationship_manager import get_relationship_manager
18+
1819
# from ..message_receive.message_buffer import message_buffer
1920

2021
logger = get_logger("chat")
@@ -45,6 +46,7 @@ async def _process_relationship(message: MessageRecv) -> None:
4546
nickname = message.message_info.user_info.user_nickname
4647
cardname = message.message_info.user_info.user_cardname or nickname
4748

49+
relationship_manager = get_relationship_manager()
4850
is_known = await relationship_manager.is_known_some_one(platform, user_id)
4951

5052
if not is_known:
@@ -181,7 +183,7 @@ async def process_message(self, message_data: Dict[str, Any]) -> None:
181183
userinfo = message.message_info.user_info
182184
messageinfo = message.message_info
183185

184-
chat = await chat_manager.get_or_create_stream(
186+
chat = await get_chat_manager().get_or_create_stream(
185187
platform=messageinfo.platform,
186188
user_info=userinfo,
187189
group_info=groupinfo,

src/chat/focus_chat/info_processors/mind_processor.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
import time
66
import traceback
77
from src.common.logger import get_logger
8-
from src.individuality.individuality import individuality
8+
from src.individuality.individuality import get_individuality
99
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
1010
from src.chat.utils.json_utils import safe_json_dumps
11-
from src.chat.message_receive.chat_stream import chat_manager
12-
from src.person_info.relationship_manager import relationship_manager
11+
from src.chat.message_receive.chat_stream import get_chat_manager
12+
from src.person_info.relationship_manager import get_relationship_manager
1313
from .base_processor import BaseProcessor
1414
from src.chat.focus_chat.info.mind_info import MindInfo
1515
from typing import List, Optional
@@ -77,7 +77,7 @@ def __init__(self, subheartflow_id: str):
7777
self.structured_info = []
7878
self.structured_info_str = ""
7979

80-
name = chat_manager.get_stream_name(self.subheartflow_id)
80+
name = get_chat_manager().get_stream_name(self.subheartflow_id)
8181
self.log_prefix = f"[{name}] "
8282
self._update_structured_info_str()
8383

@@ -195,13 +195,14 @@ async def do_thinking_before_reply(
195195
relation_prompt = ""
196196
if global_config.relationship.enable_relationship:
197197
for person in person_list:
198+
relationship_manager = get_relationship_manager()
198199
relation_prompt += await relationship_manager.build_relationship_info(person, is_id=True)
199200

200201
template_name = "sub_heartflow_prompt_before" if is_group_chat else "sub_heartflow_prompt_private_before"
201202
logger.debug(f"{self.log_prefix} 使用{'群聊' if is_group_chat else '私聊'}思考模板")
202203

203204
prompt = (await global_prompt_manager.get_prompt_async(template_name)).format(
204-
bot_name=individuality.name,
205+
bot_name=get_individuality().name,
205206
memory_str=memory_str,
206207
extra_info=self.structured_info_str,
207208
relation_prompt=relation_prompt,

src/chat/focus_chat/info_processors/relationship_processor.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66
import traceback
77
from src.common.logger import get_logger
88
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
9-
from src.chat.message_receive.chat_stream import chat_manager
10-
from src.person_info.relationship_manager import relationship_manager
9+
from src.chat.message_receive.chat_stream import get_chat_manager
10+
from src.person_info.relationship_manager import get_relationship_manager
1111
from .base_processor import BaseProcessor
1212
from typing import List, Optional
1313
from typing import Dict
1414
from src.chat.focus_chat.info.info_base import InfoBase
1515
from src.chat.focus_chat.info.relation_info import RelationInfo
1616
from json_repair import repair_json
17-
from src.person_info.person_info import person_info_manager
17+
from src.person_info.person_info import get_person_info_manager
1818
import json
1919
import asyncio
2020
from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_with_chat
2121

22+
2223
# 配置常量:是否启用小模型即时信息提取
2324
# 开启时:使用小模型并行即时提取,速度更快,但精度可能略低
2425
# 关闭时:使用原来的异步模式,精度更高但速度较慢
@@ -110,7 +111,7 @@ def __init__(self, subheartflow_id: str):
110111
request_type="focus.relationship.instant",
111112
)
112113

113-
name = chat_manager.get_stream_name(self.subheartflow_id)
114+
name = get_chat_manager().get_stream_name(self.subheartflow_id)
114115
self.log_prefix = f"[{name}] "
115116

116117
async def process_info(
@@ -241,6 +242,7 @@ async def relation_identify(
241242
instant_tasks = []
242243
async_tasks = []
243244

245+
person_info_manager = get_person_info_manager()
244246
for person_name, info_type in content_json.items():
245247
person_id = person_info_manager.get_person_id_by_person_name(person_name)
246248
if person_id:
@@ -366,6 +368,7 @@ async def _fetch_single_info_instant(self, person_id: str, info_type: str, start
366368
"""
367369
使用小模型提取单个信息类型
368370
"""
371+
person_info_manager = get_person_info_manager()
369372
nickname_str = ",".join(global_config.bot.alias_names)
370373
name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。"
371374

@@ -453,6 +456,7 @@ async def fetch_person_info(self, person_id: str, info_types: list[str], start_t
453456
nickname_str = ",".join(global_config.bot.alias_names)
454457
name_block = f"你的名字是{global_config.bot.nickname},你的昵称有{nickname_str},有人也会用这些昵称称呼你。"
455458

459+
person_info_manager = get_person_info_manager()
456460
person_name = await person_info_manager.get_value(person_id, "person_name")
457461

458462
info_type_str = ""
@@ -534,6 +538,7 @@ async def update_impression_on_cache_expiry(self, person_id: str, chat_id: str,
534538
impression_messages = get_raw_msg_by_timestamp_with_chat(chat_id, start_time, end_time)
535539
if impression_messages:
536540
logger.info(f"为 {person_id} 获取到 {len(impression_messages)} 条消息用于印象更新。")
541+
relationship_manager = get_relationship_manager()
537542
await relationship_manager.update_person_impression(
538543
person_id=person_id, timestamp=end_time, bot_engaged_messages=impression_messages
539544
)

0 commit comments

Comments
 (0)