🤖 自动格式化代码 [skip ci]

pull/937/head
github-actions[bot] 2025-05-14 14:41:11 +00:00
parent d6fbef7fc6
commit a8f45e7c06
12 changed files with 118 additions and 84 deletions

View File

@ -116,12 +116,14 @@ class DefaultExpressor:
# 为 trigger_nickname_analysis 准备 bot_reply 参数 # 为 trigger_nickname_analysis 准备 bot_reply 参数
bot_reply_for_analysis = [] bot_reply_for_analysis = []
if reply: # reply 是 List[Tuple[str, str]] if reply: # reply 是 List[Tuple[str, str]]
for seg_type, seg_data in reply: for seg_type, seg_data in reply:
if seg_type == "text": # 只取文本类型的数据 if seg_type == "text": # 只取文本类型的数据
bot_reply_for_analysis.append(seg_data) bot_reply_for_analysis.append(seg_data)
await nickname_manager.trigger_nickname_analysis(anchor_message, bot_reply_for_analysis, self.chat_stream) await nickname_manager.trigger_nickname_analysis(
anchor_message, bot_reply_for_analysis, self.chat_stream
)
else: else:
logger.warning(f"{self.log_prefix} 文本回复生成失败") logger.warning(f"{self.log_prefix} 文本回复生成失败")

View File

@ -925,7 +925,9 @@ class HeartFChatting:
if action == "reply" and emoji: if action == "reply" and emoji:
logger.debug(f"{self.log_prefix}[Planner] 大模型建议文字回复带表情: '{emoji}'") logger.debug(f"{self.log_prefix}[Planner] 大模型建议文字回复带表情: '{emoji}'")
if random.random() > EMOJI_SEND_PRO: if random.random() > EMOJI_SEND_PRO:
logger.info(f"{self.log_prefix}但是麦麦这次不想加表情 ({1 - EMOJI_SEND_PRO:.0%}),忽略表情 '{emoji}'") logger.info(
f"{self.log_prefix}但是麦麦这次不想加表情 ({1 - EMOJI_SEND_PRO:.0%}),忽略表情 '{emoji}'"
)
action_data["emojis"] = "" # 清空表情请求 action_data["emojis"] = "" # 清空表情请求
else: else:
logger.info(f"{self.log_prefix}好吧,加上表情 '{emoji}'") logger.info(f"{self.log_prefix}好吧,加上表情 '{emoji}'")

View File

@ -424,7 +424,7 @@ async def build_anonymous_messages(messages: List[Dict[str, Any]]) -> str:
# 分配占位符 # 分配占位符
person_map = {} person_map = {}
current_char = ord('A') current_char = ord("A")
output_lines = [] output_lines = []
for msg in messages: for msg in messages:

View File

@ -102,7 +102,7 @@ def _format_online_time(online_seconds: int) -> str:
:param online_seconds: 在线时间 :param online_seconds: 在线时间
:return: 格式化后的在线时间字符串 :return: 格式化后的在线时间字符串
""" """
total_oneline_time = timedelta(seconds=int(online_seconds)) #确保是整数 total_oneline_time = timedelta(seconds=int(online_seconds)) # 确保是整数
days = total_oneline_time.days days = total_oneline_time.days
hours = total_oneline_time.seconds // 3600 hours = total_oneline_time.seconds // 3600
@ -141,7 +141,7 @@ class StatisticOutputTask(AsyncTask):
记录文件路径 记录文件路径
""" """
now = datetime.now() # Renamed to avoid conflict with 'now' in methods now = datetime.now() # Renamed to avoid conflict with 'now' in methods
if "deploy_time" in local_storage: if "deploy_time" in local_storage:
# 如果存在部署时间,则使用该时间作为全量统计的起始时间 # 如果存在部署时间,则使用该时间作为全量统计的起始时间
deploy_time = datetime.fromtimestamp(local_storage["deploy_time"]) deploy_time = datetime.fromtimestamp(local_storage["deploy_time"])
@ -167,7 +167,7 @@ class StatisticOutputTask(AsyncTask):
:param now: 基准当前时间 :param now: 基准当前时间
""" """
# 输出最近一小时的统计数据 # 输出最近一小时的统计数据
last_hour_stats = stats.get("last_hour", {}) # Ensure 'last_hour' key exists last_hour_stats = stats.get("last_hour", {}) # Ensure 'last_hour' key exists
output = [ output = [
self.SEP_LINE, self.SEP_LINE,
@ -191,7 +191,7 @@ class StatisticOutputTask(AsyncTask):
stats = self._collect_all_statistics(now) stats = self._collect_all_statistics(now)
# 输出统计数据到控制台 # 输出统计数据到控制台
if "last_hour" in stats: # Check if stats for last_hour were successfully collected if "last_hour" in stats: # Check if stats for last_hour were successfully collected
self._statistic_console_output(stats, now) self._statistic_console_output(stats, now)
else: else:
logger.warning("无法输出最近一小时统计数据到控制台,因为数据缺失。") logger.warning("无法输出最近一小时统计数据到控制台,因为数据缺失。")
@ -243,14 +243,13 @@ class StatisticOutputTask(AsyncTask):
for record in db.llm_usage.find({"timestamp": {"$gte": overall_earliest_start_time}}): for record in db.llm_usage.find({"timestamp": {"$gte": overall_earliest_start_time}}):
record_timestamp = record.get("timestamp") record_timestamp = record.get("timestamp")
if not isinstance(record_timestamp, datetime): # Ensure timestamp is a datetime object if not isinstance(record_timestamp, datetime): # Ensure timestamp is a datetime object
try: # Attempt conversion if it's a number (e.g. Unix timestamp) try: # Attempt conversion if it's a number (e.g. Unix timestamp)
record_timestamp = datetime.fromtimestamp(float(record_timestamp)) record_timestamp = datetime.fromtimestamp(float(record_timestamp))
except (ValueError, TypeError): except (ValueError, TypeError):
logger.warning(f"Skipping LLM usage record with invalid timestamp: {record.get('_id')}") logger.warning(f"Skipping LLM usage record with invalid timestamp: {record.get('_id')}")
continue continue
for idx, (_current_period_key, period_start_time) in enumerate(collect_period): for idx, (_current_period_key, period_start_time) in enumerate(collect_period):
if record_timestamp >= period_start_time: if record_timestamp >= period_start_time:
for period_key_to_update, _ in collect_period[idx:]: for period_key_to_update, _ in collect_period[idx:]:
@ -370,17 +369,16 @@ class StatisticOutputTask(AsyncTask):
logger.warning(f"Skipping message record with invalid time format: {message.get('_id')}") logger.warning(f"Skipping message record with invalid time format: {message.get('_id')}")
continue continue
group_info = chat_info.get("group_info") group_info = chat_info.get("group_info")
chat_id = None chat_id = None
chat_name = None chat_name = None
if group_info and group_info.get("group_id"): if group_info and group_info.get("group_id"):
gid = group_info.get('group_id') gid = group_info.get("group_id")
chat_id = f"g{gid}" chat_id = f"g{gid}"
chat_name = group_info.get("group_name", f"群聊 {gid}") chat_name = group_info.get("group_name", f"群聊 {gid}")
elif user_info and user_info.get("user_id"): elif user_info and user_info.get("user_id"):
uid = user_info['user_id'] uid = user_info["user_id"]
chat_id = f"u{uid}" chat_id = f"u{uid}"
chat_name = user_info.get("user_nickname", f"用户 {uid}") chat_name = user_info.get("user_nickname", f"用户 {uid}")
@ -394,7 +392,6 @@ class StatisticOutputTask(AsyncTask):
else: else:
self.name_mapping[chat_id] = (chat_name, message_time_ts) self.name_mapping[chat_id] = (chat_name, message_time_ts)
for idx, (_current_period_key, period_start_time) in enumerate(collect_period): for idx, (_current_period_key, period_start_time) in enumerate(collect_period):
if message_datetime >= period_start_time: if message_datetime >= period_start_time:
for period_key_to_update, _ in collect_period[idx:]: for period_key_to_update, _ in collect_period[idx:]:
@ -428,7 +425,7 @@ class StatisticOutputTask(AsyncTask):
("last_24_hours", timedelta(days=1), "最近24小时"), ("last_24_hours", timedelta(days=1), "最近24小时"),
("last_hour", timedelta(hours=1), "最近1小时"), ("last_hour", timedelta(hours=1), "最近1小时"),
] ]
self.stat_period = current_stat_periods_config # Update instance's stat_period if needed elsewhere self.stat_period = current_stat_periods_config # Update instance's stat_period if needed elsewhere
stat_start_timestamp_config = [] stat_start_timestamp_config = []
for period_name, delta, _ in current_stat_periods_config: for period_name, delta, _ in current_stat_periods_config:
@ -448,21 +445,37 @@ class StatisticOutputTask(AsyncTask):
final_stats[period_key].update(message_count_stat.get(period_key, {})) final_stats[period_key].update(message_count_stat.get(period_key, {}))
for stat_field_key in [ for stat_field_key in [
TOTAL_REQ_CNT, REQ_CNT_BY_TYPE, REQ_CNT_BY_USER, REQ_CNT_BY_MODEL, TOTAL_REQ_CNT,
IN_TOK_BY_TYPE, IN_TOK_BY_USER, IN_TOK_BY_MODEL, REQ_CNT_BY_TYPE,
OUT_TOK_BY_TYPE, OUT_TOK_BY_USER, OUT_TOK_BY_MODEL, REQ_CNT_BY_USER,
TOTAL_TOK_BY_TYPE, TOTAL_TOK_BY_USER, TOTAL_TOK_BY_MODEL, REQ_CNT_BY_MODEL,
TOTAL_COST, COST_BY_TYPE, COST_BY_USER, COST_BY_MODEL, IN_TOK_BY_TYPE,
ONLINE_TIME, TOTAL_MSG_CNT, MSG_CNT_BY_CHAT IN_TOK_BY_USER,
IN_TOK_BY_MODEL,
OUT_TOK_BY_TYPE,
OUT_TOK_BY_USER,
OUT_TOK_BY_MODEL,
TOTAL_TOK_BY_TYPE,
TOTAL_TOK_BY_USER,
TOTAL_TOK_BY_MODEL,
TOTAL_COST,
COST_BY_TYPE,
COST_BY_USER,
COST_BY_MODEL,
ONLINE_TIME,
TOTAL_MSG_CNT,
MSG_CNT_BY_CHAT,
]: ]:
if stat_field_key not in final_stats[period_key]: if stat_field_key not in final_stats[period_key]:
# Initialize with appropriate default type if key is missing # Initialize with appropriate default type if key is missing
if "BY_" in stat_field_key: # These are usually defaultdicts if "BY_" in stat_field_key: # These are usually defaultdicts
final_stats[period_key][stat_field_key] = defaultdict(int if "CNT" in stat_field_key or "TOK" in stat_field_key else float) final_stats[period_key][stat_field_key] = defaultdict(
elif "CNT" in stat_field_key or "TOK" in stat_field_key : int if "CNT" in stat_field_key or "TOK" in stat_field_key else float
final_stats[period_key][stat_field_key] = 0 )
elif "CNT" in stat_field_key or "TOK" in stat_field_key:
final_stats[period_key][stat_field_key] = 0
elif "COST" in stat_field_key or ONLINE_TIME == stat_field_key: elif "COST" in stat_field_key or ONLINE_TIME == stat_field_key:
final_stats[period_key][stat_field_key] = 0.0 final_stats[period_key][stat_field_key] = 0.0
return final_stats return final_stats
# -- 以下为统计数据格式化方法 -- # -- 以下为统计数据格式化方法 --
@ -539,16 +552,20 @@ class StatisticOutputTask(AsyncTask):
deploy_time_dt = datetime.fromtimestamp(local_storage["deploy_time"]) deploy_time_dt = datetime.fromtimestamp(local_storage["deploy_time"])
except (TypeError, ValueError): except (TypeError, ValueError):
logger.error("Invalid deploy_time in local_storage for HTML report. Using default.") logger.error("Invalid deploy_time in local_storage for HTML report. Using default.")
deploy_time_dt = datetime(2000,1,1) # Fallback deploy_time_dt = datetime(2000, 1, 1) # Fallback
else: else:
# This should ideally not happen if __init__ or _collect_all_statistics ran # This should ideally not happen if __init__ or _collect_all_statistics ran
logger.warning("deploy_time not found in local_storage for HTML report. Using default.") logger.warning("deploy_time not found in local_storage for HTML report. Using default.")
deploy_time_dt = datetime(2000, 1, 1) # Fallback deploy_time_dt = datetime(2000, 1, 1) # Fallback
tab_list_html = [] tab_list_html = []
tab_content_html_list = [] tab_content_html_list = []
for period_key, period_delta, period_display_name in self.stat_period: # Use self.stat_period as defined by _collect_all_statistics for (
period_key,
period_delta,
period_display_name,
) in self.stat_period: # Use self.stat_period as defined by _collect_all_statistics
tab_list_html.append( tab_list_html.append(
f'<button class="tab-link" onclick="showTab(event, \'{period_key}\')">{period_display_name}</button>' f'<button class="tab-link" onclick="showTab(event, \'{period_key}\')">{period_display_name}</button>'
) )
@ -561,11 +578,12 @@ class StatisticOutputTask(AsyncTask):
# Ensure period_delta is a timedelta object # Ensure period_delta is a timedelta object
if isinstance(period_delta, timedelta): if isinstance(period_delta, timedelta):
start_time_dt_for_period = now - period_delta start_time_dt_for_period = now - period_delta
else: # Fallback if period_delta is not as expected (e.g. from old self.stat_period) else: # Fallback if period_delta is not as expected (e.g. from old self.stat_period)
logger.warning(f"period_delta for {period_key} is not a timedelta. Using 'now'. Type: {type(period_delta)}") logger.warning(
f"period_delta for {period_key} is not a timedelta. Using 'now'. Type: {type(period_delta)}"
)
start_time_dt_for_period = now start_time_dt_for_period = now
html_content_for_tab = f""" html_content_for_tab = f"""
<div id="{period_key}" class="tab-content"> <div id="{period_key}" class="tab-content">
<p class="info-item"> <p class="info-item">
@ -645,7 +663,9 @@ class StatisticOutputTask(AsyncTask):
html_content_for_tab += "<tr><td colspan='6'>无数据</td></tr>" html_content_for_tab += "<tr><td colspan='6'>无数据</td></tr>"
html_content_for_tab += "</tbody></table>" html_content_for_tab += "</tbody></table>"
html_content_for_tab += "<h2>聊天消息统计</h2><table><thead><tr><th>联系人/群组名称</th><th>消息数量</th></tr></thead><tbody>" html_content_for_tab += (
"<h2>聊天消息统计</h2><table><thead><tr><th>联系人/群组名称</th><th>消息数量</th></tr></thead><tbody>"
)
msg_cnt_by_chat = current_period_stats.get(MSG_CNT_BY_CHAT, {}) msg_cnt_by_chat = current_period_stats.get(MSG_CNT_BY_CHAT, {})
if msg_cnt_by_chat: if msg_cnt_by_chat:
for chat_id, count in sorted(msg_cnt_by_chat.items()): for chat_id, count in sorted(msg_cnt_by_chat.items()):
@ -657,7 +677,6 @@ class StatisticOutputTask(AsyncTask):
tab_content_html_list.append(html_content_for_tab) tab_content_html_list.append(html_content_for_tab)
html_template = ( html_template = (
""" """
<!DOCTYPE html> <!DOCTYPE html>

View File

@ -20,8 +20,9 @@ from ...config.config import global_config
logger = get_module_logger("chat_utils") logger = get_module_logger("chat_utils")
# 预编译正则表达式以提高性能 # 预编译正则表达式以提高性能
_L_REGEX = regex.compile(r'\p{L}') # 匹配任何Unicode字母 _L_REGEX = regex.compile(r"\p{L}") # 匹配任何Unicode字母
_HAN_CHAR_REGEX = regex.compile(r'\p{Han}') # 匹配汉字 (Unicode属性) _HAN_CHAR_REGEX = regex.compile(r"\p{Han}") # 匹配汉字 (Unicode属性)
def is_letter_not_han(char_str: str) -> bool: def is_letter_not_han(char_str: str) -> bool:
""" """
@ -40,16 +41,19 @@ def is_letter_not_han(char_str: str) -> bool:
is_han = _HAN_CHAR_REGEX.fullmatch(char_str) is not None is_han = _HAN_CHAR_REGEX.fullmatch(char_str) is not None
return not is_han return not is_han
def is_han_character(char_str: str) -> bool: def is_han_character(char_str: str) -> bool:
"""检查字符是否为汉字 (使用 \p{Han} Unicode 属性)""" """检查字符是否为汉字 (使用 \p{Han} Unicode 属性)"""
if not isinstance(char_str, str) or len(char_str) != 1: if not isinstance(char_str, str) or len(char_str) != 1:
return False return False
return _HAN_CHAR_REGEX.fullmatch(char_str) is not None return _HAN_CHAR_REGEX.fullmatch(char_str) is not None
def is_english_letter(char: str) -> bool: def is_english_letter(char: str) -> bool:
"""检查字符是否为英文字母(忽略大小写)""" """检查字符是否为英文字母(忽略大小写)"""
return "a" <= char.lower() <= "z" return "a" <= char.lower() <= "z"
def db_message_to_str(message_dict: dict) -> str: def db_message_to_str(message_dict: dict) -> str:
logger.debug(f"message_dict: {message_dict}") logger.debug(f"message_dict: {message_dict}")
time_str = time.strftime("%m-%d %H:%M:%S", time.localtime(message_dict["time"])) time_str = time.strftime("%m-%d %H:%M:%S", time.localtime(message_dict["time"]))
@ -101,7 +105,8 @@ def is_mentioned_bot_in_message(message: MessageRecv) -> tuple[bool, float]:
if not is_mentioned: if not is_mentioned:
# 判断是否被回复 # 判断是否被回复
if re.match( if re.match(
f"\\[回复 [\\s\\S]*?\\({str(global_config.BOT_QQ)}\\)[\\s\\S]*?\\],说:", message.processed_plain_text f"\\[回复 [\\s\\S]*?\\({str(global_config.BOT_QQ)}\\)[\\s\\S]*?\\],说:",
message.processed_plain_text,
): ):
is_mentioned = True is_mentioned = True
else: else:
@ -211,6 +216,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
# 2. 处理换行符和其他分隔符的组合 (增加了 . 和 —) # 2. 处理换行符和其他分隔符的组合 (增加了 . 和 —)
text = regex.sub(r"\n\s*([—。.,;\s\xa0])", r"\1", text) text = regex.sub(r"\n\s*([—。.,;\s\xa0])", r"\1", text)
text = regex.sub(r"([—。.,;\s\xa0])\s*\n", r"\1", text) text = regex.sub(r"([—。.,;\s\xa0])\s*\n", r"\1", text)
# 3. 处理两个汉字中间的换行符 # 3. 处理两个汉字中间的换行符
def replace_han_newline(match): def replace_han_newline(match):
char1 = match.group(1) char1 = match.group(1)
@ -218,6 +224,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
if is_han_character(char1) and is_han_character(char2): if is_han_character(char1) and is_han_character(char2):
return char1 + "" + char2 return char1 + "" + char2
return match.group(0) return match.group(0)
text = regex.sub(r"(.)\n(.)", replace_han_newline, text) text = regex.sub(r"(.)\n(.)", replace_han_newline, text)
len_text = len(text) len_text = len(text)
@ -239,7 +246,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
if char in separators: if char in separators:
can_split = True can_split = True
if char == ' ' or char == '\xa0': if char == " " or char == "\xa0":
if 0 < i < len(text) - 1: if 0 < i < len(text) - 1:
prev_char = text[i - 1] prev_char = text[i - 1]
next_char = text[i + 1] next_char = text[i + 1]
@ -251,9 +258,9 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
if can_split: if can_split:
if current_segment: if current_segment:
segments.append((current_segment, char)) segments.append((current_segment, char))
elif char not in [' ', '\xa0']: elif char not in [" ", "\xa0"]:
segments.append(("", char)) segments.append(("", char))
elif char in [' ', '\xa0']: elif char in [" ", "\xa0"]:
segments.append(("", char)) segments.append(("", char))
current_segment = "" current_segment = ""
else: else:
@ -268,9 +275,9 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
temp_segments_for_filter = [] temp_segments_for_filter = []
for content, sep in segments: for content, sep in segments:
if content.strip(): if content.strip():
temp_segments_for_filter.append((content,sep)) temp_segments_for_filter.append((content, sep))
elif sep and sep not in [' ', '\xa0']: elif sep and sep not in [" ", "\xa0"]:
temp_segments_for_filter.append((content,sep)) temp_segments_for_filter.append((content, sep))
segments = temp_segments_for_filter segments = temp_segments_for_filter
if not segments: if not segments:
@ -280,7 +287,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> list[str]:
current_sentence_build = "" current_sentence_build = ""
for content, sep in segments: for content, sep in segments:
current_sentence_build += content current_sentence_build += content
if sep and sep not in [' ', '\xa0']: if sep and sep not in [" ", "\xa0"]:
current_sentence_build += sep current_sentence_build += sep
if current_sentence_build.strip(): if current_sentence_build.strip():
preliminary_final_sentences.append(current_sentence_build.strip()) preliminary_final_sentences.append(current_sentence_build.strip())
@ -448,7 +455,7 @@ def calculate_typing_time(
total_time = 0 total_time = 0
for char in input_string: for char in input_string:
if is_han_character(char): # 使用 is_han_character 进行判断 if is_han_character(char): # 使用 is_han_character 进行判断
total_time += chinese_time total_time += chinese_time
else: else:
total_time += english_time total_time += english_time
@ -462,7 +469,6 @@ def calculate_typing_time(
return total_time return total_time
def cosine_similarity(v1, v2): def cosine_similarity(v1, v2):
"""计算余弦相似度""" """计算余弦相似度"""
dot_product = np.dot(v1, v2) dot_product = np.dot(v1, v2)
@ -578,7 +584,7 @@ def get_western_ratio(paragraph):
if not alnum_chars: if not alnum_chars:
return 0.0 return 0.0
western_count = sum(1 for char in alnum_chars if is_english_letter(char)) # 保持使用 is_english_letter western_count = sum(1 for char in alnum_chars if is_english_letter(char)) # 保持使用 is_english_letter
return western_count / len(alnum_chars) return western_count / len(alnum_chars)

View File

@ -17,7 +17,14 @@ from .heart_flow.sub_mind import SubMind
from .heart_flow.utils_chat import get_chat_type_and_target_info from .heart_flow.utils_chat import get_chat_type_and_target_info
from src.manager.mood_manager import mood_manager 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, chat_manager
from src.chat.message_receive.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending, Seg, UserInfo from src.chat.message_receive.message import (
MessageRecv,
BaseMessageInfo,
MessageThinking,
MessageSending,
Seg,
UserInfo,
)
from src.chat.utils.utils import process_llm_response from src.chat.utils.utils import process_llm_response
from src.chat.utils.utils_image import image_path_to_base64 from src.chat.utils.utils_image import image_path_to_base64
from src.chat.emoji_system.emoji_manager import emoji_manager from src.chat.emoji_system.emoji_manager import emoji_manager

View File

@ -567,7 +567,7 @@ class SubMind:
# ---------- 5. 构建最终提示词 ---------- # ---------- 5. 构建最终提示词 ----------
# --- Choose template based on chat type --- # --- Choose template based on chat type ---
nickname_injection_str = "" # 初始化为空字符串 nickname_injection_str = "" # 初始化为空字符串
if is_group_chat: if is_group_chat:
template_name = "sub_heartflow_prompt_before" template_name = "sub_heartflow_prompt_before"

View File

@ -264,8 +264,6 @@ class IdleChat:
# 获取关系值 # 获取关系值
relationship_value = 0 relationship_value = 0
try: try:
# 尝试获取person_id # 尝试获取person_id
person_id = None person_id = None
try: try:
@ -428,7 +426,6 @@ class IdleChat:
async def _get_chat_stream(self) -> Optional[ChatStream]: async def _get_chat_stream(self) -> Optional[ChatStream]:
"""获取聊天流实例""" """获取聊天流实例"""
try: try:
existing_chat_stream = chat_manager.get_stream(self.stream_id) existing_chat_stream = chat_manager.get_stream(self.stream_id)
if existing_chat_stream: if existing_chat_stream:
logger.debug(f"[私聊][{self.private_name}]从chat_manager找到现有聊天流") logger.debug(f"[私聊][{self.private_name}]从chat_manager找到现有聊天流")

View File

@ -18,6 +18,7 @@ from src.chat.person_info.relationship_manager import relationship_manager
from src.chat.message_receive.chat_stream import ChatStream from src.chat.message_receive.chat_stream import ChatStream
from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.message import MessageRecv
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
logger = get_logger("NicknameManager") logger = get_logger("NicknameManager")
logger_helper = get_logger("AsyncLoopHelper") # 为辅助函数创建单独的 logger logger_helper = get_logger("AsyncLoopHelper") # 为辅助函数创建单独的 logger