Merge branch 'dev' of https://github.com/MoFox-Studio/MoFox_Bot into dev
This commit is contained in:
@@ -138,6 +138,7 @@ class MemorySystem:
|
|||||||
self.config = config or MemorySystemConfig.from_global_config()
|
self.config = config or MemorySystemConfig.from_global_config()
|
||||||
self.llm_model = llm_model
|
self.llm_model = llm_model
|
||||||
self.status = MemorySystemStatus.INITIALIZING
|
self.status = MemorySystemStatus.INITIALIZING
|
||||||
|
logger.info(f"MemorySystem __init__ called, id: {id(self)}")
|
||||||
|
|
||||||
# 核心组件(简化版)
|
# 核心组件(简化版)
|
||||||
self.memory_builder: MemoryBuilder | None = None
|
self.memory_builder: MemoryBuilder | None = None
|
||||||
@@ -170,6 +171,7 @@ class MemorySystem:
|
|||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
"""异步初始化记忆系统"""
|
"""异步初始化记忆系统"""
|
||||||
|
logger.info(f"MemorySystem initialize started, id: {id(self)}")
|
||||||
try:
|
try:
|
||||||
# 初始化LLM模型
|
# 初始化LLM模型
|
||||||
fallback_task = getattr(self.llm_model, "model_for_task", None) if self.llm_model else None
|
fallback_task = getattr(self.llm_model, "model_for_task", None) if self.llm_model else None
|
||||||
@@ -222,8 +224,13 @@ class MemorySystem:
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.unified_storage = VectorMemoryStorage(storage_config)
|
try:
|
||||||
logger.info("✅ Vector DB存储系统初始化成功")
|
self.unified_storage = VectorMemoryStorage(storage_config)
|
||||||
|
logger.info("✅ Vector DB存储系统初始化成功")
|
||||||
|
except Exception as storage_error:
|
||||||
|
logger.error(f"❌ Vector DB存储系统初始化失败: {storage_error}", exc_info=True)
|
||||||
|
self.unified_storage = None # 确保在失败时为None
|
||||||
|
raise
|
||||||
except Exception as storage_error:
|
except Exception as storage_error:
|
||||||
logger.error(f"❌ Vector DB存储系统初始化失败: {storage_error}", exc_info=True)
|
logger.error(f"❌ Vector DB存储系统初始化失败: {storage_error}", exc_info=True)
|
||||||
raise
|
raise
|
||||||
@@ -282,7 +289,7 @@ class MemorySystem:
|
|||||||
# 统一存储已经自动加载数据,无需额外加载
|
# 统一存储已经自动加载数据,无需额外加载
|
||||||
|
|
||||||
self.status = MemorySystemStatus.READY
|
self.status = MemorySystemStatus.READY
|
||||||
|
logger.info(f"MemorySystem initialize finished, id: {id(self)}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.status = MemorySystemStatus.ERROR
|
self.status = MemorySystemStatus.ERROR
|
||||||
logger.error(f"❌ 记忆系统初始化失败: {e}", exc_info=True)
|
logger.error(f"❌ 记忆系统初始化失败: {e}", exc_info=True)
|
||||||
@@ -405,6 +412,8 @@ class MemorySystem:
|
|||||||
logger.debug(f"海马体采样模式:使用价值评分 {value_score:.2f}")
|
logger.debug(f"海马体采样模式:使用价值评分 {value_score:.2f}")
|
||||||
|
|
||||||
# 2. 构建记忆块(所有记忆统一使用 global 作用域,实现完全共享)
|
# 2. 构建记忆块(所有记忆统一使用 global 作用域,实现完全共享)
|
||||||
|
if not self.memory_builder:
|
||||||
|
raise RuntimeError("Memory builder is not initialized.")
|
||||||
memory_chunks = await self.memory_builder.build_memories(
|
memory_chunks = await self.memory_builder.build_memories(
|
||||||
conversation_text,
|
conversation_text,
|
||||||
normalized_context,
|
normalized_context,
|
||||||
@@ -419,6 +428,8 @@ class MemorySystem:
|
|||||||
|
|
||||||
# 3. 记忆融合与去重(包含与历史记忆的融合)
|
# 3. 记忆融合与去重(包含与历史记忆的融合)
|
||||||
existing_candidates = await self._collect_fusion_candidates(memory_chunks)
|
existing_candidates = await self._collect_fusion_candidates(memory_chunks)
|
||||||
|
if not self.fusion_engine:
|
||||||
|
raise RuntimeError("Fusion engine is not initialized.")
|
||||||
fused_chunks = await self.fusion_engine.fuse_memories(memory_chunks, existing_candidates)
|
fused_chunks = await self.fusion_engine.fuse_memories(memory_chunks, existing_candidates)
|
||||||
|
|
||||||
# 4. 存储记忆到统一存储
|
# 4. 存储记忆到统一存储
|
||||||
@@ -537,7 +548,12 @@ class MemorySystem:
|
|||||||
if isinstance(result, Exception):
|
if isinstance(result, Exception):
|
||||||
logger.warning("融合候选向量搜索失败: %s", result)
|
logger.warning("融合候选向量搜索失败: %s", result)
|
||||||
continue
|
continue
|
||||||
for memory_id, similarity in result:
|
if not result or not isinstance(result, list):
|
||||||
|
continue
|
||||||
|
for item in result:
|
||||||
|
if not isinstance(item, tuple) or len(item) != 2:
|
||||||
|
continue
|
||||||
|
memory_id, similarity = item
|
||||||
if memory_id in new_memory_ids:
|
if memory_id in new_memory_ids:
|
||||||
continue
|
continue
|
||||||
if similarity is None or similarity < min_threshold:
|
if similarity is None or similarity < min_threshold:
|
||||||
@@ -810,7 +826,11 @@ class MemorySystem:
|
|||||||
importance_score = (importance_enum.value - 1) / 3.0
|
importance_score = (importance_enum.value - 1) / 3.0
|
||||||
else:
|
else:
|
||||||
# 如果已经是数值,直接使用
|
# 如果已经是数值,直接使用
|
||||||
importance_score = float(importance_enum) if importance_enum else 0.5
|
importance_score = (
|
||||||
|
float(importance_enum.value)
|
||||||
|
if hasattr(importance_enum, "value")
|
||||||
|
else (float(importance_enum) if isinstance(importance_enum, int) else 0.5)
|
||||||
|
)
|
||||||
|
|
||||||
# 4. 访问频率得分(归一化,访问10次以上得满分)
|
# 4. 访问频率得分(归一化,访问10次以上得满分)
|
||||||
access_count = memory.metadata.access_count
|
access_count = memory.metadata.access_count
|
||||||
@@ -1395,6 +1415,9 @@ class MemorySystem:
|
|||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not self.value_assessment_model:
|
||||||
|
logger.warning("Value assessment model is not initialized, returning default value.")
|
||||||
|
return 0.5
|
||||||
response, _ = await self.value_assessment_model.generate_response_async(prompt, temperature=0.3)
|
response, _ = await self.value_assessment_model.generate_response_async(prompt, temperature=0.3)
|
||||||
|
|
||||||
# 解析响应
|
# 解析响应
|
||||||
@@ -1488,10 +1511,11 @@ class MemorySystem:
|
|||||||
def _populate_memory_fingerprints(self) -> None:
|
def _populate_memory_fingerprints(self) -> None:
|
||||||
"""基于当前缓存构建记忆指纹映射"""
|
"""基于当前缓存构建记忆指纹映射"""
|
||||||
self._memory_fingerprints.clear()
|
self._memory_fingerprints.clear()
|
||||||
for memory in self.unified_storage.memory_cache.values():
|
if self.unified_storage:
|
||||||
fingerprint = self._build_memory_fingerprint(memory)
|
for memory in self.unified_storage.memory_cache.values():
|
||||||
key = self._fingerprint_key(memory.user_id, fingerprint)
|
fingerprint = self._build_memory_fingerprint(memory)
|
||||||
self._memory_fingerprints[key] = memory.memory_id
|
key = self._fingerprint_key(memory.user_id, fingerprint)
|
||||||
|
self._memory_fingerprints[key] = memory.memory_id
|
||||||
|
|
||||||
def _register_memory_fingerprints(self, memories: list[MemoryChunk]) -> None:
|
def _register_memory_fingerprints(self, memories: list[MemoryChunk]) -> None:
|
||||||
for memory in memories:
|
for memory in memories:
|
||||||
@@ -1573,7 +1597,7 @@ class MemorySystem:
|
|||||||
|
|
||||||
# 保存存储数据
|
# 保存存储数据
|
||||||
if self.unified_storage:
|
if self.unified_storage:
|
||||||
await self.unified_storage.save_storage()
|
pass
|
||||||
|
|
||||||
# 记忆融合引擎维护
|
# 记忆融合引擎维护
|
||||||
if self.fusion_engine:
|
if self.fusion_engine:
|
||||||
@@ -1653,7 +1677,7 @@ class MemorySystem:
|
|||||||
"""重建向量存储(如果需要)"""
|
"""重建向量存储(如果需要)"""
|
||||||
try:
|
try:
|
||||||
# 检查是否有记忆缓存数据
|
# 检查是否有记忆缓存数据
|
||||||
if not hasattr(self.unified_storage, "memory_cache") or not self.unified_storage.memory_cache:
|
if not self.unified_storage or not hasattr(self.unified_storage, "memory_cache") or not self.unified_storage.memory_cache:
|
||||||
logger.info("无记忆缓存数据,跳过向量存储重建")
|
logger.info("无记忆缓存数据,跳过向量存储重建")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1682,7 +1706,8 @@ class MemorySystem:
|
|||||||
for i in range(0, len(memories_to_rebuild), batch_size):
|
for i in range(0, len(memories_to_rebuild), batch_size):
|
||||||
batch = memories_to_rebuild[i : i + batch_size]
|
batch = memories_to_rebuild[i : i + batch_size]
|
||||||
try:
|
try:
|
||||||
await self.unified_storage.store_memories(batch)
|
if self.unified_storage:
|
||||||
|
await self.unified_storage.store_memories(batch)
|
||||||
rebuild_count += len(batch)
|
rebuild_count += len(batch)
|
||||||
|
|
||||||
if rebuild_count % 50 == 0:
|
if rebuild_count % 50 == 0:
|
||||||
@@ -1705,22 +1730,28 @@ class MemorySystem:
|
|||||||
|
|
||||||
|
|
||||||
# 全局记忆系统实例
|
# 全局记忆系统实例
|
||||||
memory_system: MemorySystem = None
|
memory_system: MemorySystem | None = None
|
||||||
|
|
||||||
|
|
||||||
def get_memory_system() -> MemorySystem:
|
def get_memory_system() -> MemorySystem:
|
||||||
"""获取全局记忆系统实例"""
|
"""获取全局记忆系统实例"""
|
||||||
global memory_system
|
global memory_system
|
||||||
if memory_system is None:
|
if memory_system is None:
|
||||||
|
logger.warning("Global memory_system is None. Creating new uninitialized instance. This might be a problem.")
|
||||||
memory_system = MemorySystem()
|
memory_system = MemorySystem()
|
||||||
|
logger.info(f"get_memory_system() called, returning instance with id: {id(memory_system)}")
|
||||||
return memory_system
|
return memory_system
|
||||||
|
|
||||||
|
|
||||||
async def initialize_memory_system(llm_model: LLMRequest | None = None):
|
async def initialize_memory_system(llm_model: LLMRequest | None = None):
|
||||||
"""初始化全局记忆系统"""
|
"""初始化全局记忆系统"""
|
||||||
global memory_system
|
global memory_system
|
||||||
|
logger.info("initialize_memory_system() called.")
|
||||||
if memory_system is None:
|
if memory_system is None:
|
||||||
|
logger.info("Global memory_system is None, creating new instance for initialization.")
|
||||||
memory_system = MemorySystem(llm_model=llm_model)
|
memory_system = MemorySystem(llm_model=llm_model)
|
||||||
|
else:
|
||||||
|
logger.info(f"Global memory_system already exists (id: {id(memory_system)}). Initializing it.")
|
||||||
await memory_system.initialize()
|
await memory_system.initialize()
|
||||||
|
|
||||||
# 根据配置启动海马体采样
|
# 根据配置启动海马体采样
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class ChromaDBImpl(VectorDBBase):
|
|||||||
logger.error(f"ChromaDB 初始化失败: {e}")
|
logger.error(f"ChromaDB 初始化失败: {e}")
|
||||||
self.client = None
|
self.client = None
|
||||||
self._initialized = False
|
self._initialized = False
|
||||||
|
raise ConnectionError(f"ChromaDB 初始化失败: {e}") from e
|
||||||
|
|
||||||
def get_or_create_collection(self, name: str, **kwargs: Any) -> Any:
|
def get_or_create_collection(self, name: str, **kwargs: Any) -> Any:
|
||||||
if not self.client:
|
if not self.client:
|
||||||
|
|||||||
@@ -446,7 +446,9 @@ MoFox_Bot(第三方修改版)
|
|||||||
|
|
||||||
# 初始化增强记忆系统
|
# 初始化增强记忆系统
|
||||||
if global_config.memory.enable_memory:
|
if global_config.memory.enable_memory:
|
||||||
await self._safe_init("增强记忆系统", self.memory_manager.initialize)()
|
from src.chat.memory_system.memory_system import initialize_memory_system
|
||||||
|
await self._safe_init("增强记忆系统", initialize_memory_system)()
|
||||||
|
await self._safe_init("记忆管理器", self.memory_manager.initialize)()
|
||||||
else:
|
else:
|
||||||
logger.info("记忆系统已禁用,跳过初始化")
|
logger.info("记忆系统已禁用,跳过初始化")
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from typing import Any
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.plugin_system.base.base_tool import BaseTool
|
from src.plugin_system.base.base_tool import BaseTool
|
||||||
from src.plugin_system.base.component_types import ComponentType
|
from src.plugin_system.base.component_types import ComponentType
|
||||||
@@ -20,13 +21,22 @@ def get_tool_instance(tool_name: str) -> BaseTool | None:
|
|||||||
return tool_class(plugin_config) if tool_class else None
|
return tool_class(plugin_config) if tool_class else None
|
||||||
|
|
||||||
|
|
||||||
def get_llm_available_tool_definitions():
|
def get_llm_available_tool_definitions() -> list[dict[str, Any]]:
|
||||||
"""获取LLM可用的工具定义列表
|
"""获取LLM可用的工具定义列表
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Tuple[str, Dict[str, Any]]]: 工具定义列表,为[("tool_name", 定义)]
|
list[dict[str, Any]]: 工具定义列表
|
||||||
"""
|
"""
|
||||||
from src.plugin_system.core import component_registry
|
from src.plugin_system.core import component_registry
|
||||||
|
|
||||||
llm_available_tools = component_registry.get_llm_available_tools()
|
llm_available_tools = component_registry.get_llm_available_tools()
|
||||||
|
tool_definitions = []
|
||||||
|
for tool_name, tool_class in llm_available_tools.items():
|
||||||
|
try:
|
||||||
|
# 调用类方法 get_tool_definition 获取定义
|
||||||
|
definition = tool_class.get_tool_definition()
|
||||||
|
tool_definitions.append(definition)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取工具 {tool_name} 的定义失败: {e}")
|
||||||
|
return tool_definitions
|
||||||
|
|
||||||
|
|||||||
@@ -113,10 +113,14 @@ class ToolExecutor:
|
|||||||
logger.debug(f"{self.log_prefix}开始LLM工具调用分析")
|
logger.debug(f"{self.log_prefix}开始LLM工具调用分析")
|
||||||
|
|
||||||
# 调用LLM进行工具决策
|
# 调用LLM进行工具决策
|
||||||
response, (reasoning_content, model_name, tool_calls) = await self.llm_model.generate_response_async(
|
response, llm_extra_info = await self.llm_model.generate_response_async(
|
||||||
prompt=prompt, tools=tools, raise_when_empty=False
|
prompt=prompt, tools=tools, raise_when_empty=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tool_calls = None
|
||||||
|
if llm_extra_info and isinstance(llm_extra_info, tuple) and len(llm_extra_info) == 3:
|
||||||
|
_, _, tool_calls = llm_extra_info
|
||||||
|
|
||||||
# 执行工具调用
|
# 执行工具调用
|
||||||
tool_results, used_tools = await self.execute_tool_calls(tool_calls)
|
tool_results, used_tools = await self.execute_tool_calls(tool_calls)
|
||||||
|
|
||||||
@@ -133,7 +137,9 @@ class ToolExecutor:
|
|||||||
user_disabled_tools = global_announcement_manager.get_disabled_chat_tools(self.chat_id)
|
user_disabled_tools = global_announcement_manager.get_disabled_chat_tools(self.chat_id)
|
||||||
|
|
||||||
# 获取基础工具定义(包括二步工具的第一步)
|
# 获取基础工具定义(包括二步工具的第一步)
|
||||||
tool_definitions = [definition for name, definition in all_tools if name not in user_disabled_tools]
|
tool_definitions = [
|
||||||
|
definition for definition in all_tools if definition.get("function", {}).get("name") not in user_disabled_tools
|
||||||
|
]
|
||||||
|
|
||||||
# 检查是否有待处理的二步工具第二步调用
|
# 检查是否有待处理的二步工具第二步调用
|
||||||
pending_step_two = getattr(self, "_pending_step_two_tools", {})
|
pending_step_two = getattr(self, "_pending_step_two_tools", {})
|
||||||
@@ -282,20 +288,7 @@ class ToolExecutor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 检查是否是MCP工具
|
# 检查是否是MCP工具
|
||||||
try:
|
pass
|
||||||
from src.plugin_system.utils.mcp_tool_provider import mcp_tool_provider
|
|
||||||
if function_name in mcp_tool_provider.mcp_tools:
|
|
||||||
logger.info(f"{self.log_prefix}执行MCP工具: {function_name}")
|
|
||||||
result = await mcp_tool_provider.call_mcp_tool(function_name, function_args)
|
|
||||||
return {
|
|
||||||
"tool_call_id": tool_call.call_id,
|
|
||||||
"role": "tool",
|
|
||||||
"name": function_name,
|
|
||||||
"type": "function",
|
|
||||||
"content": result.get("content", ""),
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug(f"检查MCP工具时出错: {e}")
|
|
||||||
|
|
||||||
function_args["llm_called"] = True # 标记为LLM调用
|
function_args["llm_called"] = True # 标记为LLM调用
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user