Merge branch 'dev' of https://github.com/MaiM-with-u/MaiBot into dev
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MaiM-with-u/MaiBot/">
|
<a href="https://github.com/MaiM-with-u/MaiBot/">
|
||||||
<img src="depends-data/maimai.png" alt="Logo" width="200">
|
<img src="depends-data/maimai.png" alt="Logo" style="max-width: 200px">
|
||||||
</a>
|
</a>
|
||||||
<br />
|
<br />
|
||||||
<a href="https://space.bilibili.com/1344099355">
|
<a href="https://space.bilibili.com/1344099355">
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
·
|
·
|
||||||
<a href="https://github.com/MaiM-with-u/MaiBot/issues">提出新特性</a>
|
<a href="https://github.com/MaiM-with-u/MaiBot/issues">提出新特性</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 新版0.6.x部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a
|
## 新版0.6.x部署前先阅读:https://docs.mai-mai.org/manual/usage/mmc_q_a
|
||||||
@@ -53,7 +52,7 @@
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://www.bilibili.com/video/BV1amAneGE3P" target="_blank">
|
<a href="https://www.bilibili.com/video/BV1amAneGE3P" target="_blank">
|
||||||
<img src="depends-data/video.png" width="200" alt="麦麦演示视频">
|
<img src="depends-data/video.png" style="max-width: 200px" alt="麦麦演示视频">
|
||||||
<br>
|
<br>
|
||||||
👆 点击观看麦麦演示视频 👆
|
👆 点击观看麦麦演示视频 👆
|
||||||
</a>
|
</a>
|
||||||
@@ -186,7 +185,7 @@ MaiCore是一个开源项目,我们非常欢迎你的参与。你的贡献,
|
|||||||
感谢各位大佬!
|
感谢各位大佬!
|
||||||
|
|
||||||
<a href="https://github.com/MaiM-with-u/MaiBot/graphs/contributors">
|
<a href="https://github.com/MaiM-with-u/MaiBot/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=MaiM-with-u/MaiBot" />
|
<img alt="contributors" src="https://contrib.rocks/image?repo=MaiM-with-u/MaiBot" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
**也感谢每一位给麦麦发展提出宝贵意见与建议的用户,感谢陪伴麦麦走到现在的你们**
|
**也感谢每一位给麦麦发展提出宝贵意见与建议的用户,感谢陪伴麦麦走到现在的你们**
|
||||||
|
|||||||
@@ -105,3 +105,4 @@ class Individuality:
|
|||||||
return self.personality.agreeableness
|
return self.personality.agreeableness
|
||||||
elif factor == "neuroticism":
|
elif factor == "neuroticism":
|
||||||
return self.personality.neuroticism
|
return self.personality.neuroticism
|
||||||
|
return None
|
||||||
|
|||||||
@@ -118,11 +118,8 @@ class MainSystem:
|
|||||||
await interest_manager.start_background_tasks()
|
await interest_manager.start_background_tasks()
|
||||||
logger.success("兴趣管理器后台任务启动成功")
|
logger.success("兴趣管理器后台任务启动成功")
|
||||||
|
|
||||||
# 初始化 ReasoningChat 单例 (确保它在需要之前被创建)
|
# 初始化并独立启动 HeartFC_Chat
|
||||||
ReasoningChat.get_instance()
|
HeartFC_Controller()
|
||||||
logger.success("ReasoningChat 单例初始化成功")
|
|
||||||
|
|
||||||
# 初始化并独立启动 HeartFC_Chat 控制器 (使用 get_instance 获取单例)
|
|
||||||
heartfc_chat_instance = HeartFC_Controller.get_instance()
|
heartfc_chat_instance = HeartFC_Controller.get_instance()
|
||||||
if heartfc_chat_instance:
|
if heartfc_chat_instance:
|
||||||
await heartfc_chat_instance.start()
|
await heartfc_chat_instance.start()
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ class Conversation:
|
|||||||
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
"time": datetime.datetime.now().strftime("%H:%M:%S"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
elif action == "fetch_knowledge":
|
elif action == "fetch_knowledge":
|
||||||
self.waiter.wait_accumulated_time = 0
|
self.waiter.wait_accumulated_time = 0
|
||||||
@@ -193,28 +194,35 @@ class Conversation:
|
|||||||
if knowledge:
|
if knowledge:
|
||||||
if topic not in self.conversation_info.knowledge_list:
|
if topic not in self.conversation_info.knowledge_list:
|
||||||
self.conversation_info.knowledge_list.append({"topic": topic, "knowledge": knowledge})
|
self.conversation_info.knowledge_list.append({"topic": topic, "knowledge": knowledge})
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
self.conversation_info.knowledge_list[topic] += knowledge
|
self.conversation_info.knowledge_list[topic] += knowledge
|
||||||
|
return None
|
||||||
|
return None
|
||||||
|
|
||||||
elif action == "rethink_goal":
|
elif action == "rethink_goal":
|
||||||
self.waiter.wait_accumulated_time = 0
|
self.waiter.wait_accumulated_time = 0
|
||||||
|
|
||||||
self.state = ConversationState.RETHINKING
|
self.state = ConversationState.RETHINKING
|
||||||
await self.goal_analyzer.analyze_goal(conversation_info, observation_info)
|
await self.goal_analyzer.analyze_goal(conversation_info, observation_info)
|
||||||
|
return None
|
||||||
|
|
||||||
elif action == "listening":
|
elif action == "listening":
|
||||||
self.state = ConversationState.LISTENING
|
self.state = ConversationState.LISTENING
|
||||||
logger.info("倾听对方发言...")
|
logger.info("倾听对方发言...")
|
||||||
await self.waiter.wait_listening(conversation_info)
|
await self.waiter.wait_listening(conversation_info)
|
||||||
|
return None
|
||||||
|
|
||||||
elif action == "end_conversation":
|
elif action == "end_conversation":
|
||||||
self.should_continue = False
|
self.should_continue = False
|
||||||
logger.info("决定结束对话...")
|
logger.info("决定结束对话...")
|
||||||
|
return None
|
||||||
|
|
||||||
else: # wait
|
else: # wait
|
||||||
self.state = ConversationState.WAITING
|
self.state = ConversationState.WAITING
|
||||||
logger.info("等待更多信息...")
|
logger.info("等待更多信息...")
|
||||||
await self.waiter.wait(self.conversation_info)
|
await self.waiter.wait(self.conversation_info)
|
||||||
|
return None
|
||||||
|
|
||||||
async def _send_timeout_message(self):
|
async def _send_timeout_message(self):
|
||||||
"""发送超时结束消息"""
|
"""发送超时结束消息"""
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from ..chat_module.only_process.only_message_process import MessageProcessor
|
|||||||
|
|
||||||
from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig
|
from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig
|
||||||
from ..chat_module.reasoning_chat.reasoning_chat import ReasoningChat
|
from ..chat_module.reasoning_chat.reasoning_chat import ReasoningChat
|
||||||
from ..chat_module.heartFC_chat.heartFC_processor import HeartFC_Processor
|
from ..chat_module.heartFC_chat.heartFC_processor import HeartFCProcessor
|
||||||
from ..utils.prompt_builder import Prompt, global_prompt_manager
|
from ..utils.prompt_builder import Prompt, global_prompt_manager
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ class ChatBot:
|
|||||||
self.mood_manager = MoodManager.get_instance() # 获取情绪管理器单例
|
self.mood_manager = MoodManager.get_instance() # 获取情绪管理器单例
|
||||||
self.mood_manager.start_mood_update() # 启动情绪更新
|
self.mood_manager.start_mood_update() # 启动情绪更新
|
||||||
self.reasoning_chat = ReasoningChat()
|
self.reasoning_chat = ReasoningChat()
|
||||||
self.heartFC_processor = HeartFC_Processor() # 新增
|
self.heartFC_processor = HeartFCProcessor() # 新增
|
||||||
|
|
||||||
# 创建初始化PFC管理器的任务,会在_ensure_started时执行
|
# 创建初始化PFC管理器的任务,会在_ensure_started时执行
|
||||||
self.only_process_chat = MessageProcessor()
|
self.only_process_chat = MessageProcessor()
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import time
|
import time
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional, Union
|
||||||
|
|
||||||
import urllib3
|
import urllib3
|
||||||
|
|
||||||
from .utils_image import image_manager
|
|
||||||
|
|
||||||
from ..message.message_base import Seg, UserInfo, BaseMessageInfo, MessageBase
|
|
||||||
from .chat_stream import ChatStream
|
|
||||||
from src.common.logger import get_module_logger
|
from src.common.logger import get_module_logger
|
||||||
|
from .chat_stream import ChatStream
|
||||||
|
from .utils_image import image_manager
|
||||||
|
from ..message.message_base import Seg, UserInfo, BaseMessageInfo, MessageBase
|
||||||
|
|
||||||
logger = get_module_logger("chat_message")
|
logger = get_module_logger("chat_message")
|
||||||
|
|
||||||
@@ -207,7 +206,7 @@ class MessageProcessBase(Message):
|
|||||||
# 处理单个消息段
|
# 处理单个消息段
|
||||||
return await self._process_single_segment(segment)
|
return await self._process_single_segment(segment)
|
||||||
|
|
||||||
async def _process_single_segment(self, seg: Seg) -> str:
|
async def _process_single_segment(self, seg: Seg) -> Union[str, None]:
|
||||||
"""处理单个消息段
|
"""处理单个消息段
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -233,6 +232,7 @@ class MessageProcessBase(Message):
|
|||||||
elif seg.type == "reply":
|
elif seg.type == "reply":
|
||||||
if self.reply and hasattr(self.reply, "processed_plain_text"):
|
if self.reply and hasattr(self.reply, "processed_plain_text"):
|
||||||
return f"[回复:{self.reply.processed_plain_text}]"
|
return f"[回复:{self.reply.processed_plain_text}]"
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
return f"[{seg.type}:{str(seg.data)}]"
|
return f"[{seg.type}:{str(seg.data)}]"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import random
|
|||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import Dict, List
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
import jieba
|
import jieba
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -688,7 +688,7 @@ def count_messages_between(start_time: float, end_time: float, stream_id: str) -
|
|||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
|
|
||||||
def translate_timestamp_to_human_readable(timestamp: float, mode: str = "normal") -> str:
|
def translate_timestamp_to_human_readable(timestamp: float, mode: str = "normal") -> Optional[str]:
|
||||||
"""将时间戳转换为人类可读的时间格式
|
"""将时间戳转换为人类可读的时间格式
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -716,6 +716,7 @@ def translate_timestamp_to_human_readable(timestamp: float, mode: str = "normal"
|
|||||||
return f"{int(diff / 86400)}天前:\n"
|
return f"{int(diff / 86400)}天前:\n"
|
||||||
else:
|
else:
|
||||||
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)) + ":\n"
|
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)) + ":\n"
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_text_timestamps(text: str, mode: str = "normal") -> str:
|
def parse_text_timestamps(text: str, mode: str = "normal") -> str:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import traceback
|
|||||||
from typing import Optional, Dict
|
from typing import Optional, Dict
|
||||||
import asyncio
|
import asyncio
|
||||||
from asyncio import Lock
|
from asyncio import Lock
|
||||||
|
import threading # 导入 threading
|
||||||
from ...moods.moods import MoodManager
|
from ...moods.moods import MoodManager
|
||||||
from ...chat.emoji_manager import emoji_manager
|
from ...chat.emoji_manager import emoji_manager
|
||||||
from .heartFC_generator import ResponseGenerator
|
from .heartFC_generator import ResponseGenerator
|
||||||
@@ -13,7 +14,7 @@ from src.do_tool.tool_use import ToolUser
|
|||||||
from .interest import InterestManager
|
from .interest import InterestManager
|
||||||
from src.plugins.chat.chat_stream import chat_manager
|
from src.plugins.chat.chat_stream import chat_manager
|
||||||
from .pf_chatting import PFChatting
|
from .pf_chatting import PFChatting
|
||||||
import threading # 导入 threading
|
|
||||||
|
|
||||||
# 定义日志配置
|
# 定义日志配置
|
||||||
chat_config = LogConfig(
|
chat_config = LogConfig(
|
||||||
@@ -21,51 +22,73 @@ chat_config = LogConfig(
|
|||||||
file_format=CHAT_STYLE_CONFIG["file_format"],
|
file_format=CHAT_STYLE_CONFIG["file_format"],
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = get_module_logger("HeartFC_Controller", config=chat_config)
|
logger = get_module_logger("HeartFCController", config=chat_config)
|
||||||
|
|
||||||
# 检测群聊兴趣的间隔时间
|
# 检测群聊兴趣的间隔时间
|
||||||
INTEREST_MONITOR_INTERVAL_SECONDS = 1
|
INTEREST_MONITOR_INTERVAL_SECONDS = 1
|
||||||
|
|
||||||
|
|
||||||
class HeartFC_Controller:
|
# 合并后的版本:使用 __new__ + threading.Lock 实现线程安全单例,类名为 HeartFCController
|
||||||
|
class HeartFCController:
|
||||||
_instance = None
|
_instance = None
|
||||||
_lock = threading.Lock() # 使用 threading.Lock 替代 asyncio.Lock 以兼容 __new__
|
_lock = threading.Lock() # 使用 threading.Lock 保证 __new__ 线程安全
|
||||||
_initialized = False
|
_initialized = False
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
with cls._lock:
|
with cls._lock:
|
||||||
|
# Double-checked locking
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
|
logger.debug("创建 HeartFCController 单例实例...")
|
||||||
cls._instance = super().__new__(cls)
|
cls._instance = super().__new__(cls)
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
# 使用 _initialized 标志确保 __init__ 只执行一次
|
||||||
if self._initialized:
|
if self._initialized:
|
||||||
return
|
return
|
||||||
with self.__class__._lock: # 使用类锁确保初始化线程安全
|
# 虽然 __new__ 保证了只有一个实例,但为了防止意外重入或多线程下的初始化竞争,
|
||||||
if self._initialized:
|
# 再次使用类锁保护初始化过程是更严谨的做法。
|
||||||
|
# 如果确定 __init__ 逻辑本身是幂等的或非关键的,可以省略这里的锁。
|
||||||
|
# 但为了保持原始逻辑的意图(防止重复初始化),这里保留检查。
|
||||||
|
with self.__class__._lock: # 确保初始化逻辑线程安全
|
||||||
|
if self._initialized: # 再次检查,防止锁等待期间其他线程已完成初始化
|
||||||
return
|
return
|
||||||
logger.info("正在初始化 HeartFC_Controller 单例...")
|
|
||||||
|
logger.info("正在初始化 HeartFCController 单例...")
|
||||||
self.gpt = ResponseGenerator()
|
self.gpt = ResponseGenerator()
|
||||||
self.mood_manager = MoodManager.get_instance()
|
self.mood_manager = MoodManager.get_instance()
|
||||||
|
# 注意:mood_manager 的 start_mood_update 可能需要在应用主循环启动后调用,
|
||||||
|
# 或者确保其内部实现是安全的。这里保持原状。
|
||||||
self.mood_manager.start_mood_update()
|
self.mood_manager.start_mood_update()
|
||||||
self.tool_user = ToolUser()
|
self.tool_user = ToolUser()
|
||||||
|
# 注意:InterestManager() 可能是另一个单例或需要特定初始化。
|
||||||
|
# 假设 InterestManager() 返回的是正确配置的实例。
|
||||||
self.interest_manager = InterestManager()
|
self.interest_manager = InterestManager()
|
||||||
self._interest_monitor_task: Optional[asyncio.Task] = None
|
self._interest_monitor_task: Optional[asyncio.Task] = None
|
||||||
self.pf_chatting_instances: Dict[str, PFChatting] = {}
|
self.pf_chatting_instances: Dict[str, PFChatting] = {}
|
||||||
self._pf_chatting_lock = Lock() # 这个可以是 asyncio.Lock,用于异步上下文
|
# _pf_chatting_lock 用于保护 pf_chatting_instances 的异步操作
|
||||||
self.emoji_manager = emoji_manager
|
self._pf_chatting_lock = asyncio.Lock() # 这个是 asyncio.Lock,用于异步上下文
|
||||||
self.relationship_manager = relationship_manager
|
self.emoji_manager = emoji_manager # 假设是全局或已初始化的实例
|
||||||
|
self.relationship_manager = relationship_manager # 假设是全局或已初始化的实例
|
||||||
|
# MessageManager 可能是类本身或单例实例,根据其设计确定
|
||||||
self.MessageManager = MessageManager
|
self.MessageManager = MessageManager
|
||||||
self._initialized = True
|
self._initialized = True
|
||||||
logger.info("HeartFC_Controller 单例初始化完成。")
|
logger.info("HeartFCController 单例初始化完成。")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_instance(cls):
|
def get_instance(cls):
|
||||||
"""获取 HeartFC_Controller 的单例实例。"""
|
"""获取 HeartFCController 的单例实例。"""
|
||||||
|
# 如果实例尚未创建,调用构造函数(这将触发 __new__ 和 __init__)
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
logger.warning("HeartFC_Controller 实例在首次 get_instance 时创建,可能未在 main 中正确初始化。")
|
# 在首次调用 get_instance 时创建实例。
|
||||||
cls() # 调用构造函数创建
|
# __new__ 中的锁会确保线程安全。
|
||||||
|
cls()
|
||||||
|
# 添加日志记录,说明实例是在 get_instance 调用时创建的
|
||||||
|
logger.info("HeartFCController 实例在首次 get_instance 时创建。")
|
||||||
|
elif not cls._initialized:
|
||||||
|
# 实例已创建但可能未初始化完成(理论上不太可能发生,除非 __init__ 异常)
|
||||||
|
logger.warning("HeartFCController 实例存在但尚未完成初始化。")
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
# --- 新增:检查 PFChatting 状态的方法 --- #
|
# --- 新增:检查 PFChatting 状态的方法 --- #
|
||||||
@@ -83,9 +106,9 @@ class HeartFC_Controller:
|
|||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""启动异步任务,如回复启动器"""
|
"""启动异步任务,如回复启动器"""
|
||||||
logger.debug("HeartFC_Controller 正在启动异步任务...")
|
logger.debug("HeartFCController 正在启动异步任务...")
|
||||||
self._initialize_monitor_task()
|
self._initialize_monitor_task()
|
||||||
logger.info("HeartFC_Controller 异步任务启动完成")
|
logger.info("HeartFCController 异步任务启动完成")
|
||||||
|
|
||||||
def _initialize_monitor_task(self):
|
def _initialize_monitor_task(self):
|
||||||
"""启动后台兴趣监控任务,可以检查兴趣是否足以开启心流对话"""
|
"""启动后台兴趣监控任务,可以检查兴趣是否足以开启心流对话"""
|
||||||
@@ -105,7 +128,7 @@ class HeartFC_Controller:
|
|||||||
async with self._pf_chatting_lock:
|
async with self._pf_chatting_lock:
|
||||||
if stream_id not in self.pf_chatting_instances:
|
if stream_id not in self.pf_chatting_instances:
|
||||||
logger.info(f"为流 {stream_id} 创建新的PFChatting实例")
|
logger.info(f"为流 {stream_id} 创建新的PFChatting实例")
|
||||||
# 传递 self (HeartFC_Controller 实例) 进行依赖注入
|
# 传递 self (HeartFCController 实例) 进行依赖注入
|
||||||
instance = PFChatting(stream_id, self)
|
instance = PFChatting(stream_id, self)
|
||||||
# 执行异步初始化
|
# 执行异步初始化
|
||||||
if not await instance._initialize():
|
if not await instance._initialize():
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ logger = get_module_logger("heartFC_processor", config=processor_config)
|
|||||||
# INTEREST_INCREASE_THRESHOLD = 0.5
|
# INTEREST_INCREASE_THRESHOLD = 0.5
|
||||||
|
|
||||||
|
|
||||||
class HeartFC_Processor:
|
class HeartFCProcessor:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.storage = MessageStorage()
|
self.storage = MessageStorage()
|
||||||
self.interest_manager = InterestManager()
|
self.interest_manager = InterestManager()
|
||||||
@@ -97,21 +97,21 @@ class HeartFC_Processor:
|
|||||||
|
|
||||||
# 处理缓冲器结果 (Bombing logic)
|
# 处理缓冲器结果 (Bombing logic)
|
||||||
if not buffer_result:
|
if not buffer_result:
|
||||||
F_type = "seglist"
|
f_type = "seglist"
|
||||||
if message.message_segment.type != "seglist":
|
if message.message_segment.type != "seglist":
|
||||||
F_type = message.message_segment.type
|
f_type = message.message_segment.type
|
||||||
else:
|
else:
|
||||||
if (
|
if (
|
||||||
isinstance(message.message_segment.data, list)
|
isinstance(message.message_segment.data, list)
|
||||||
and all(isinstance(x, Seg) for x in message.message_segment.data)
|
and all(isinstance(x, Seg) for x in message.message_segment.data)
|
||||||
and len(message.message_segment.data) == 1
|
and len(message.message_segment.data) == 1
|
||||||
):
|
):
|
||||||
F_type = message.message_segment.data[0].type
|
f_type = message.message_segment.data[0].type
|
||||||
if F_type == "text":
|
if f_type == "text":
|
||||||
logger.debug(f"触发缓冲,消息:{message.processed_plain_text}")
|
logger.debug(f"触发缓冲,消息:{message.processed_plain_text}")
|
||||||
elif F_type == "image":
|
elif f_type == "image":
|
||||||
logger.debug("触发缓冲,表情包/图片等待中")
|
logger.debug("触发缓冲,表情包/图片等待中")
|
||||||
elif F_type == "seglist":
|
elif f_type == "seglist":
|
||||||
logger.debug("触发缓冲,消息列表等待中")
|
logger.debug("触发缓冲,消息列表等待中")
|
||||||
return # 被缓冲器拦截,不生成回复
|
return # 被缓冲器拦截,不生成回复
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ logger = get_module_logger("PFCLoop", config=interest_log_config) # Logger Name
|
|||||||
|
|
||||||
# Forward declaration for type hinting
|
# Forward declaration for type hinting
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .heartFC_controler import HeartFC_Controller
|
from .heartFC_controler import HeartFCController
|
||||||
|
|
||||||
PLANNER_TOOL_DEFINITION = [
|
PLANNER_TOOL_DEFINITION = [
|
||||||
{
|
{
|
||||||
@@ -64,7 +64,7 @@ class PFChatting:
|
|||||||
只要计时器>0,循环就会继续。
|
只要计时器>0,循环就会继续。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, chat_id: str, heartfc_controller_instance: "HeartFC_Controller"):
|
def __init__(self, chat_id: str, heartfc_controller_instance: "HeartFCController"):
|
||||||
"""
|
"""
|
||||||
初始化PFChatting实例。
|
初始化PFChatting实例。
|
||||||
|
|
||||||
@@ -377,6 +377,22 @@ class PFChatting:
|
|||||||
)
|
)
|
||||||
action_taken_this_cycle = False
|
action_taken_this_cycle = False
|
||||||
|
|
||||||
|
# --- Print Timer Results --- #
|
||||||
|
if cycle_timers: # 先检查cycle_timers是否非空
|
||||||
|
timer_strings = []
|
||||||
|
for name, elapsed in cycle_timers.items():
|
||||||
|
# 直接格式化存储在字典中的浮点数 elapsed
|
||||||
|
formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}秒"
|
||||||
|
timer_strings.append(f"{name}: {formatted_time}")
|
||||||
|
|
||||||
|
if timer_strings: # 如果有有效计时器数据才打印
|
||||||
|
logger.debug(
|
||||||
|
f"{log_prefix} test testtesttesttesttesttesttesttesttesttest Cycle Timers: {'; '.join(timer_strings)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Timer Decrement --- #
|
||||||
|
cycle_duration = time.monotonic() - loop_cycle_start_time
|
||||||
|
|
||||||
except Exception as e_cycle:
|
except Exception as e_cycle:
|
||||||
logger.error(f"{log_prefix} 循环周期执行时发生错误: {e_cycle}")
|
logger.error(f"{log_prefix} 循环周期执行时发生错误: {e_cycle}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
@@ -390,21 +406,6 @@ class PFChatting:
|
|||||||
self._processing_lock.release()
|
self._processing_lock.release()
|
||||||
logger.trace(f"{log_prefix} 循环释放了处理锁.")
|
logger.trace(f"{log_prefix} 循环释放了处理锁.")
|
||||||
|
|
||||||
# --- Print Timer Results --- #
|
|
||||||
if cycle_timers: # 先检查cycle_timers是否非空
|
|
||||||
timer_strings = []
|
|
||||||
for name, elapsed in cycle_timers.items():
|
|
||||||
# 直接格式化存储在字典中的浮点数 elapsed
|
|
||||||
formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}秒"
|
|
||||||
timer_strings.append(f"{name}: {formatted_time}")
|
|
||||||
|
|
||||||
if timer_strings: # 如果有有效计时器数据才打印
|
|
||||||
logger.debug(
|
|
||||||
f"{log_prefix} test testtesttesttesttesttesttesttesttesttest Cycle Timers: {'; '.join(timer_strings)}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# --- Timer Decrement --- #
|
|
||||||
cycle_duration = time.monotonic() - loop_cycle_start_time
|
|
||||||
async with self._timer_lock:
|
async with self._timer_lock:
|
||||||
self._loop_timer -= cycle_duration
|
self._loop_timer -= cycle_duration
|
||||||
# Log timer decrement less aggressively
|
# Log timer decrement less aggressively
|
||||||
@@ -774,7 +775,7 @@ class PFChatting:
|
|||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# --- Methods moved from HeartFC_Controller start ---
|
# --- Methods moved from HeartFCController start ---
|
||||||
async def _create_thinking_message(self, anchor_message: Optional[MessageRecv]) -> Optional[str]:
|
async def _create_thinking_message(self, anchor_message: Optional[MessageRecv]) -> Optional[str]:
|
||||||
"""创建思考消息 (尝试锚定到 anchor_message)"""
|
"""创建思考消息 (尝试锚定到 anchor_message)"""
|
||||||
if not anchor_message or not anchor_message.chat_stream:
|
if not anchor_message or not anchor_message.chat_stream:
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
import time
|
import time
|
||||||
from random import random
|
|
||||||
import traceback
|
import traceback
|
||||||
from typing import List
|
from random import random
|
||||||
from ...memory_system.Hippocampus import HippocampusManager
|
from typing import List, Optional
|
||||||
from ...moods.moods import MoodManager
|
|
||||||
from ....config.config import global_config
|
from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig
|
||||||
from ...chat.emoji_manager import emoji_manager
|
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
||||||
from .reasoning_generator import ResponseGenerator
|
from .reasoning_generator import ResponseGenerator
|
||||||
|
from ...chat.chat_stream import chat_manager
|
||||||
|
from ...chat.emoji_manager import emoji_manager
|
||||||
from ...chat.message import MessageSending, MessageRecv, MessageThinking, MessageSet
|
from ...chat.message import MessageSending, MessageRecv, MessageThinking, MessageSet
|
||||||
|
from ...chat.message_buffer import message_buffer
|
||||||
from ...chat.messagesender import message_manager
|
from ...chat.messagesender import message_manager
|
||||||
from ...storage.storage import MessageStorage
|
|
||||||
from ...chat.utils import is_mentioned_bot_in_message
|
from ...chat.utils import is_mentioned_bot_in_message
|
||||||
from ...chat.utils_image import image_path_to_base64
|
from ...chat.utils_image import image_path_to_base64
|
||||||
from ...willing.willing_manager import willing_manager
|
from ...memory_system.Hippocampus import HippocampusManager
|
||||||
from ...message import UserInfo, Seg
|
from ...message import UserInfo, Seg
|
||||||
from src.common.logger import get_module_logger, CHAT_STYLE_CONFIG, LogConfig
|
from ...moods.moods import MoodManager
|
||||||
from ...chat.chat_stream import chat_manager
|
|
||||||
from ...person_info.relationship_manager import relationship_manager
|
from ...person_info.relationship_manager import relationship_manager
|
||||||
from ...chat.message_buffer import message_buffer
|
from ...storage.storage import MessageStorage
|
||||||
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
|
|
||||||
from ...utils.timer_calculater import Timer
|
from ...utils.timer_calculater import Timer
|
||||||
|
from ...willing.willing_manager import willing_manager
|
||||||
|
from ....config.config import global_config
|
||||||
|
|
||||||
# 定义日志配置
|
# 定义日志配置
|
||||||
chat_config = LogConfig(
|
chat_config = LogConfig(
|
||||||
@@ -61,7 +62,7 @@ class ReasoningChat:
|
|||||||
return thinking_id
|
return thinking_id
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _send_response_messages(message, chat, response_set: List[str], thinking_id) -> MessageSending:
|
async def _send_response_messages(message, chat, response_set: List[str], thinking_id) -> Optional[MessageSending]:
|
||||||
"""发送回复消息"""
|
"""发送回复消息"""
|
||||||
container = message_manager.get_container(chat.stream_id)
|
container = message_manager.get_container(chat.stream_id)
|
||||||
thinking_message = None
|
thinking_message = None
|
||||||
@@ -74,7 +75,7 @@ class ReasoningChat:
|
|||||||
|
|
||||||
if not thinking_message:
|
if not thinking_message:
|
||||||
logger.warning("未找到对应的思考消息,可能已超时被移除")
|
logger.warning("未找到对应的思考消息,可能已超时被移除")
|
||||||
return
|
return None
|
||||||
|
|
||||||
thinking_start_time = thinking_message.thinking_start_time
|
thinking_start_time = thinking_message.thinking_start_time
|
||||||
message_set = MessageSet(chat, thinking_id)
|
message_set = MessageSet(chat, thinking_id)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,8 @@ import time
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import datetime
|
import datetime
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from memory_manual_build import Memory_graph, Hippocampus # 海马体和记忆图
|
from Hippocampus import Hippocampus # 海马体和记忆图
|
||||||
|
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
@@ -45,13 +46,13 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
# 查询节点信息
|
# 查询节点信息
|
||||||
def query_mem_info(memory_graph: Memory_graph):
|
def query_mem_info(hippocampus: Hippocampus):
|
||||||
while True:
|
while True:
|
||||||
query = input("\n请输入新的查询概念(输入'退出'以结束):")
|
query = input("\n请输入新的查询概念(输入'退出'以结束):")
|
||||||
if query.lower() == "退出":
|
if query.lower() == "退出":
|
||||||
break
|
break
|
||||||
|
|
||||||
items_list = memory_graph.get_related_item(query)
|
items_list = hippocampus.memory_graph.get_related_item(query)
|
||||||
if items_list:
|
if items_list:
|
||||||
have_memory = False
|
have_memory = False
|
||||||
first_layer, second_layer = items_list
|
first_layer, second_layer = items_list
|
||||||
@@ -312,14 +313,11 @@ def alter_mem_edge(hippocampus: Hippocampus):
|
|||||||
async def main():
|
async def main():
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
# 创建记忆图
|
|
||||||
memory_graph = Memory_graph()
|
|
||||||
|
|
||||||
# 创建海马体
|
# 创建海马体
|
||||||
hippocampus = Hippocampus(memory_graph)
|
hippocampus = Hippocampus()
|
||||||
|
|
||||||
# 从数据库同步数据
|
# 从数据库同步数据
|
||||||
hippocampus.sync_memory_from_db()
|
hippocampus.entorhinal_cortex.sync_memory_from_db()
|
||||||
|
|
||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
logger.info(f"\033[32m[加载海马体耗时: {end_time - start_time:.2f} 秒]\033[0m")
|
logger.info(f"\033[32m[加载海马体耗时: {end_time - start_time:.2f} 秒]\033[0m")
|
||||||
@@ -338,7 +336,7 @@ async def main():
|
|||||||
query = -1
|
query = -1
|
||||||
|
|
||||||
if query == 0:
|
if query == 0:
|
||||||
query_mem_info(memory_graph)
|
query_mem_info(hippocampus.memory_graph)
|
||||||
elif query == 1:
|
elif query == 1:
|
||||||
add_mem_node(hippocampus)
|
add_mem_node(hippocampus)
|
||||||
elif query == 2:
|
elif query == 2:
|
||||||
@@ -355,7 +353,7 @@ async def main():
|
|||||||
print("已结束操作")
|
print("已结束操作")
|
||||||
break
|
break
|
||||||
|
|
||||||
hippocampus.sync_memory_to_db()
|
hippocampus.entorhinal_cortex.sync_memory_to_db()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ class Seg:
|
|||||||
- 对于 text 类型,data 是字符串
|
- 对于 text 类型,data 是字符串
|
||||||
- 对于 image 类型,data 是 base64 字符串
|
- 对于 image 类型,data 是 base64 字符串
|
||||||
- 对于 seglist 类型,data 是 Seg 列表
|
- 对于 seglist 类型,data 是 Seg 列表
|
||||||
translated_data: 经过翻译处理的数据(可选)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: str
|
type: str
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class PersonInfoManager:
|
|||||||
"""给某个用户取名"""
|
"""给某个用户取名"""
|
||||||
if not person_id:
|
if not person_id:
|
||||||
logger.debug("取名失败:person_id不能为空")
|
logger.debug("取名失败:person_id不能为空")
|
||||||
return
|
return None
|
||||||
|
|
||||||
old_name = await self.get_value(person_id, "person_name")
|
old_name = await self.get_value(person_id, "person_name")
|
||||||
old_reason = await self.get_value(person_id, "name_reason")
|
old_reason = await self.get_value(person_id, "name_reason")
|
||||||
|
|||||||
@@ -134,3 +134,4 @@ def main():
|
|||||||
heartbeat_thread.start()
|
heartbeat_thread.start()
|
||||||
|
|
||||||
return heartbeat_thread # 返回线程对象,便于外部控制
|
return heartbeat_thread # 返回线程对象,便于外部控制
|
||||||
|
return None
|
||||||
|
|||||||
@@ -29,8 +29,18 @@ CHAT_ANY_WHERE_KEY=
|
|||||||
SILICONFLOW_KEY=
|
SILICONFLOW_KEY=
|
||||||
|
|
||||||
# 定义日志相关配置
|
# 定义日志相关配置
|
||||||
SIMPLE_OUTPUT=true # 精简控制台输出格式
|
|
||||||
CONSOLE_LOG_LEVEL=INFO # 自定义日志的默认控制台输出日志级别
|
# 精简控制台输出格式
|
||||||
FILE_LOG_LEVEL=DEBUG # 自定义日志的默认文件输出日志级别
|
SIMPLE_OUTPUT=true
|
||||||
DEFAULT_CONSOLE_LOG_LEVEL=SUCCESS # 原生日志的控制台输出日志级别(nonebot就是这一类)
|
|
||||||
DEFAULT_FILE_LOG_LEVEL=DEBUG # 原生日志的默认文件输出日志级别(nonebot就是这一类)
|
# 自定义日志的默认控制台输出日志级别
|
||||||
|
CONSOLE_LOG_LEVEL=INFO
|
||||||
|
|
||||||
|
# 自定义日志的默认文件输出日志级别
|
||||||
|
FILE_LOG_LEVEL=DEBUG
|
||||||
|
|
||||||
|
# 原生日志的控制台输出日志级别(nonebot就是这一类)
|
||||||
|
DEFAULT_CONSOLE_LOG_LEVEL=SUCCESS
|
||||||
|
|
||||||
|
# 原生日志的默认文件输出日志级别(nonebot就是这一类)
|
||||||
|
DEFAULT_FILE_LOG_LEVEL=DEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user