diff --git a/src/chat/memory_system/memory_system.py b/src/chat/memory_system/memory_system.py index 9da9c793d..adb7ff355 100644 --- a/src/chat/memory_system/memory_system.py +++ b/src/chat/memory_system/memory_system.py @@ -138,6 +138,7 @@ class MemorySystem: self.config = config or MemorySystemConfig.from_global_config() self.llm_model = llm_model self.status = MemorySystemStatus.INITIALIZING + logger.info(f"MemorySystem __init__ called, id: {id(self)}") # 核心组件(简化版) self.memory_builder: MemoryBuilder | None = None @@ -170,6 +171,7 @@ class MemorySystem: async def initialize(self): """异步初始化记忆系统""" + logger.info(f"MemorySystem initialize started, id: {id(self)}") try: # 初始化LLM模型 fallback_task = getattr(self.llm_model, "model_for_task", None) if self.llm_model else None @@ -222,8 +224,13 @@ class MemorySystem: ) try: - self.unified_storage = VectorMemoryStorage(storage_config) - logger.info("✅ Vector DB存储系统初始化成功") + try: + 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: logger.error(f"❌ Vector DB存储系统初始化失败: {storage_error}", exc_info=True) raise @@ -282,7 +289,7 @@ class MemorySystem: # 统一存储已经自动加载数据,无需额外加载 self.status = MemorySystemStatus.READY - + logger.info(f"MemorySystem initialize finished, id: {id(self)}") except Exception as e: self.status = MemorySystemStatus.ERROR logger.error(f"❌ 记忆系统初始化失败: {e}", exc_info=True) @@ -405,6 +412,8 @@ class MemorySystem: logger.debug(f"海马体采样模式:使用价值评分 {value_score:.2f}") # 2. 构建记忆块(所有记忆统一使用 global 作用域,实现完全共享) + if not self.memory_builder: + raise RuntimeError("Memory builder is not initialized.") memory_chunks = await self.memory_builder.build_memories( conversation_text, normalized_context, @@ -419,6 +428,8 @@ class MemorySystem: # 3. 记忆融合与去重(包含与历史记忆的融合) 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) # 4. 存储记忆到统一存储 @@ -537,7 +548,12 @@ class MemorySystem: if isinstance(result, Exception): logger.warning("融合候选向量搜索失败: %s", result) 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: continue if similarity is None or similarity < min_threshold: @@ -810,7 +826,11 @@ class MemorySystem: importance_score = (importance_enum.value - 1) / 3.0 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次以上得满分) 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) # 解析响应 @@ -1488,10 +1511,11 @@ class MemorySystem: def _populate_memory_fingerprints(self) -> None: """基于当前缓存构建记忆指纹映射""" self._memory_fingerprints.clear() - for memory in self.unified_storage.memory_cache.values(): - fingerprint = self._build_memory_fingerprint(memory) - key = self._fingerprint_key(memory.user_id, fingerprint) - self._memory_fingerprints[key] = memory.memory_id + if self.unified_storage: + for memory in self.unified_storage.memory_cache.values(): + fingerprint = self._build_memory_fingerprint(memory) + key = self._fingerprint_key(memory.user_id, fingerprint) + self._memory_fingerprints[key] = memory.memory_id def _register_memory_fingerprints(self, memories: list[MemoryChunk]) -> None: for memory in memories: @@ -1573,7 +1597,7 @@ class MemorySystem: # 保存存储数据 if self.unified_storage: - await self.unified_storage.save_storage() + pass # 记忆融合引擎维护 if self.fusion_engine: @@ -1653,7 +1677,7 @@ class MemorySystem: """重建向量存储(如果需要)""" 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("无记忆缓存数据,跳过向量存储重建") return @@ -1682,7 +1706,8 @@ class MemorySystem: for i in range(0, len(memories_to_rebuild), batch_size): batch = memories_to_rebuild[i : i + batch_size] try: - await self.unified_storage.store_memories(batch) + if self.unified_storage: + await self.unified_storage.store_memories(batch) rebuild_count += len(batch) 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: """获取全局记忆系统实例""" global memory_system if memory_system is None: + logger.warning("Global memory_system is None. Creating new uninitialized instance. This might be a problem.") memory_system = MemorySystem() + logger.info(f"get_memory_system() called, returning instance with id: {id(memory_system)}") return memory_system async def initialize_memory_system(llm_model: LLMRequest | None = None): """初始化全局记忆系统""" global memory_system + logger.info("initialize_memory_system() called.") if memory_system is None: + logger.info("Global memory_system is None, creating new instance for initialization.") 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() # 根据配置启动海马体采样 diff --git a/src/common/vector_db/chromadb_impl.py b/src/common/vector_db/chromadb_impl.py index 911e9fd3e..e4a2911ae 100644 --- a/src/common/vector_db/chromadb_impl.py +++ b/src/common/vector_db/chromadb_impl.py @@ -46,6 +46,7 @@ class ChromaDBImpl(VectorDBBase): logger.error(f"ChromaDB 初始化失败: {e}") self.client = None self._initialized = False + raise ConnectionError(f"ChromaDB 初始化失败: {e}") from e def get_or_create_collection(self, name: str, **kwargs: Any) -> Any: if not self.client: diff --git a/src/main.py b/src/main.py index b4bbbb65b..a7a32b497 100644 --- a/src/main.py +++ b/src/main.py @@ -446,7 +446,9 @@ MoFox_Bot(第三方修改版) # 初始化增强记忆系统 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: logger.info("记忆系统已禁用,跳过初始化") diff --git a/src/plugin_system/apis/tool_api.py b/src/plugin_system/apis/tool_api.py index 82174e642..163b67385 100644 --- a/src/plugin_system/apis/tool_api.py +++ b/src/plugin_system/apis/tool_api.py @@ -1,3 +1,4 @@ +from typing import Any from src.common.logger import get_logger from src.plugin_system.base.base_tool import BaseTool 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 -def get_llm_available_tool_definitions(): +def get_llm_available_tool_definitions() -> list[dict[str, Any]]: """获取LLM可用的工具定义列表 Returns: - List[Tuple[str, Dict[str, Any]]]: 工具定义列表,为[("tool_name", 定义)] + list[dict[str, Any]]: 工具定义列表 """ from src.plugin_system.core import component_registry 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 diff --git a/src/plugin_system/core/tool_use.py b/src/plugin_system/core/tool_use.py index 789d16ab9..5d07c2cd6 100644 --- a/src/plugin_system/core/tool_use.py +++ b/src/plugin_system/core/tool_use.py @@ -113,10 +113,14 @@ class ToolExecutor: logger.debug(f"{self.log_prefix}开始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 ) + 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) @@ -133,7 +137,9 @@ class ToolExecutor: 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", {}) @@ -282,20 +288,7 @@ class ToolExecutor: ) # 检查是否是MCP工具 - try: - 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}") + pass function_args["llm_called"] = True # 标记为LLM调用