Merge branch 'dev' into mofox-bus
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,36 @@ class EventManager:
|
||||
"""
|
||||
return self._event_handlers.copy()
|
||||
|
||||
def remove_event_handler(self, handler_name: str) -> bool:
|
||||
"""
|
||||
完全移除一个事件处理器,包括其所有订阅。
|
||||
|
||||
Args:
|
||||
handler_name (str): 要移除的事件处理器的名称。
|
||||
|
||||
Returns:
|
||||
bool: 如果成功移除则返回 True,否则返回 False。
|
||||
"""
|
||||
if handler_name not in self._event_handlers:
|
||||
logger.warning(f"事件处理器 {handler_name} 未注册,无需移除。")
|
||||
return False
|
||||
|
||||
# 从主注册表中删除
|
||||
del self._event_handlers[handler_name]
|
||||
logger.debug(f"事件处理器 {handler_name} 已从主注册表移除。")
|
||||
|
||||
# 遍历所有事件,取消其订阅
|
||||
for event in self._events.values():
|
||||
# 创建订阅者列表的副本进行迭代,以安全地修改原始列表
|
||||
for subscriber in list(event.subscribers):
|
||||
if getattr(subscriber, 'handler_name', None) == handler_name:
|
||||
event.subscribers.remove(subscriber)
|
||||
logger.debug(f"事件处理器 {handler_name} 已从事件 {event.name} 取消订阅。")
|
||||
|
||||
logger.info(f"事件处理器 {handler_name} 已被完全移除。")
|
||||
return True
|
||||
|
||||
|
||||
def subscribe_handler_to_event(self, handler_name: str, event_name: EventType | str) -> bool:
|
||||
"""订阅事件处理器到指定事件
|
||||
|
||||
|
||||
@@ -146,9 +146,9 @@ class MCPClientManager:
|
||||
try:
|
||||
client = await self._create_client(server_config)
|
||||
self.clients[server_name] = client
|
||||
logger.info(f"✅ MCP 服务器 '{server_name}' 连接成功")
|
||||
logger.info(f" MCP 服务器 '{server_name}' 连接成功")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ 连接 MCP 服务器 '{server_name}' 失败: {e}")
|
||||
logger.error(f" 连接 MCP 服务器 '{server_name}' 失败: {e}")
|
||||
continue
|
||||
|
||||
self._initialized = True
|
||||
|
||||
@@ -47,7 +47,7 @@ class MCPToolAdapter(BaseTool):
|
||||
self.available_for_llm = True # MCP 工具默认可供 LLM 使用
|
||||
|
||||
# 转换参数定义
|
||||
self.parameters = self._convert_parameters(mcp_tool.inputSchema)
|
||||
self.parameters: list[tuple[str, ToolParamType, str, bool, list[str] | None]] = self._convert_parameters(mcp_tool.inputSchema)
|
||||
|
||||
logger.debug(f"创建 MCP 工具适配器: {self.name}")
|
||||
|
||||
@@ -238,9 +238,9 @@ async def load_mcp_tools_as_adapters() -> list[MCPToolAdapter]:
|
||||
try:
|
||||
adapter = MCPToolAdapter.from_mcp_tool(server_name, mcp_tool)
|
||||
adapters.append(adapter)
|
||||
logger.debug(f" ✓ 加载工具: {adapter.name}")
|
||||
logger.debug(f" 加载工具: {adapter.name}")
|
||||
except Exception as e:
|
||||
logger.error(f" ✗ 创建工具适配器失败: {mcp_tool.name} | 错误: {e}")
|
||||
logger.error(f" 创建工具适配器失败: {mcp_tool.name} | 错误: {e}")
|
||||
continue
|
||||
|
||||
logger.info(f"MCP 工具加载完成: 成功 {len(adapters)}/{total_tools} 个")
|
||||
|
||||
@@ -121,7 +121,7 @@ class PluginManager:
|
||||
|
||||
if not module or not hasattr(module, "__plugin_meta__"):
|
||||
self.failed_plugins[plugin_name] = "插件模块中缺少 __plugin_meta__"
|
||||
logger.error(f"❌ 插件加载失败: {plugin_name} - 缺少 __plugin_meta__")
|
||||
logger.error(f" 插件加载失败: {plugin_name} - 缺少 __plugin_meta__")
|
||||
return False, 1
|
||||
|
||||
metadata: PluginMetadata = getattr(module, "__plugin_meta__")
|
||||
@@ -171,7 +171,7 @@ class PluginManager:
|
||||
return True, 1
|
||||
else:
|
||||
self.failed_plugins[plugin_name] = "插件注册失败"
|
||||
logger.error(f"❌ 插件注册失败: {plugin_name}")
|
||||
logger.error(f" 插件注册失败: {plugin_name}")
|
||||
return False, 1
|
||||
|
||||
except Exception as e:
|
||||
@@ -249,13 +249,11 @@ class PluginManager:
|
||||
if plugin_name not in self.loaded_plugins:
|
||||
logger.warning(f"插件 {plugin_name} 未加载")
|
||||
return False
|
||||
plugin_instance = self.loaded_plugins[plugin_name]
|
||||
plugin_info = plugin_instance.plugin_info
|
||||
success = True
|
||||
for component in plugin_info.components:
|
||||
success &= await component_registry.remove_component(component.name, component.component_type, plugin_name)
|
||||
success &= component_registry.remove_plugin_registry(plugin_name)
|
||||
del self.loaded_plugins[plugin_name]
|
||||
# 调用 component_registry 中统一的卸载方法
|
||||
success = await component_registry.unregister_plugin(plugin_name)
|
||||
if success:
|
||||
# 从已加载插件中移除
|
||||
del self.loaded_plugins[plugin_name]
|
||||
return success
|
||||
|
||||
async def reload_registered_plugin(self, plugin_name: str) -> bool:
|
||||
@@ -417,14 +415,14 @@ class PluginManager:
|
||||
if not success:
|
||||
error_msg = f"Python依赖检查失败: {', '.join(errors)}"
|
||||
self.failed_plugins[plugin_name] = error_msg
|
||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
||||
logger.error(f" 插件加载失败: {plugin_name} - {error_msg}")
|
||||
return None # 依赖检查失败,不加载该模块
|
||||
|
||||
# 2. 检查插件依赖
|
||||
if not self._check_plugin_dependencies(metadata):
|
||||
error_msg = f"插件依赖检查失败: 请确保依赖 {metadata.dependencies} 已正确安装并加载。"
|
||||
self.failed_plugins[plugin_name] = error_msg
|
||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
||||
logger.error(f" 插件加载失败: {plugin_name} - {error_msg}")
|
||||
return None # 插件依赖检查失败
|
||||
|
||||
# --- 依赖检查逻辑结束 ---
|
||||
@@ -486,7 +484,7 @@ class PluginManager:
|
||||
|
||||
# 📋 显示插件加载总览
|
||||
if total_registered > 0:
|
||||
logger.info("🎉 插件系统加载完成!")
|
||||
logger.info(" 插件系统加载完成!")
|
||||
logger.info(
|
||||
f"📊 总览: {total_registered}个插件, {total_components}个组件 (Action: {action_count}, Command: {command_count}, Tool: {tool_count}, PlusCommand: {plus_command_count}, EventHandler: {event_handler_count}, Chatter: {chatter_count}, Prompt: {prompt_count}, Router: {router_count}, Adapter: {adapter_count})"
|
||||
)
|
||||
|
||||
@@ -245,7 +245,7 @@ class StreamToolHistoryManager:
|
||||
|
||||
lines = ["## 🔧 最近工具调用记录"]
|
||||
for i, record in enumerate(recent_records, 1):
|
||||
status_icon = "✅" if record.status == "success" else "❌" if record.status == "error" else "⏳"
|
||||
status_icon = "success" if record.status == "success" else "error" if record.status == "error" else "pending"
|
||||
|
||||
# 格式化参数
|
||||
args_preview = self._format_args_preview(record.args)
|
||||
|
||||
@@ -217,12 +217,11 @@ class ToolExecutor:
|
||||
return tool_results, [], ""
|
||||
|
||||
def _get_tool_definitions(self) -> list[dict[str, Any]]:
|
||||
all_tools = get_llm_available_tool_definitions()
|
||||
user_disabled_tools = global_announcement_manager.get_disabled_chat_tools(self.chat_id)
|
||||
all_tools = get_llm_available_tool_definitions(self.chat_id)
|
||||
|
||||
# 获取基础工具定义(包括二步工具的第一步)
|
||||
tool_definitions = [
|
||||
definition for definition in all_tools if definition.get("function", {}).get("name") not in user_disabled_tools
|
||||
definition for definition in all_tools if definition.get("function", {}).get("name")
|
||||
]
|
||||
|
||||
# 检查是否有待处理的二步工具第二步调用
|
||||
|
||||
Reference in New Issue
Block a user