From 98b89ebcc55bca36f310b1445048d5d77cd1f01d Mon Sep 17 00:00:00 2001 From: Waterwzy <2916963017@qq.com> Date: Thu, 26 Feb 2026 10:02:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:fix=20the=20issue=20where=20incomplete=20cl?= =?UTF-8?q?eanup=20of=20residual=20plugins=20occurs=E2=80=A6=20(#5462)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:fix the issue where incomplete cleanup of residual plugins occurs in the failed loading of plugins * fix:ruff format,apply bot suggestions * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- astrbot/core/star/star_manager.py | 51 +++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 815b306aa..13251d2ba 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -388,6 +388,33 @@ class PluginManager: except KeyError: logger.warning(f"模块 {module_name} 未载入") + def _cleanup_plugin_state(self, dir_name: str) -> None: + plugin_root_name = "data.plugins." + + # 清理 sys.modules + for key in list(sys.modules.keys()): + if key.startswith(f"{plugin_root_name}{dir_name}"): + logger.info(f"清除了插件{dir_name}中的{key}模块") + del sys.modules[key] + + possible_paths = [ + f"{plugin_root_name}{dir_name}.main", + f"{plugin_root_name}{dir_name}.{dir_name}", + ] + + # 清理 handlers + for path in possible_paths: + handlers = star_handlers_registry.get_handlers_by_module_name(path) + for handler in handlers: + star_handlers_registry.remove(handler) + logger.info(f"清理处理器: {handler.handler_name}") + + # 清理工具 + for tool in list(llm_tools.func_list): + if tool.handler_module_path in possible_paths: + llm_tools.func_list.remove(tool) + logger.info(f"清理工具: {tool.name}") + async def reload_failed_plugin(self, dir_name): """ 重新加载未注册(加载失败)的插件 @@ -398,17 +425,21 @@ class PluginManager: - success (bool): 重载是否成功 - error_message (str|None): 错误信息,成功时为 None """ + async with self._pm_lock: - if dir_name in self.failed_plugin_dict: - success, error = await self.load(specified_dir_name=dir_name) - if success: - self.failed_plugin_dict.pop(dir_name, None) - if not self.failed_plugin_dict: - self.failed_plugin_info = "" - return success, None - else: - return False, error - return False, "插件不存在于失败列表中" + if dir_name not in self.failed_plugin_dict: + return False, "插件不存在于失败列表中" + + self._cleanup_plugin_state(dir_name) + + success, error = await self.load(specified_dir_name=dir_name) + if success: + self.failed_plugin_dict.pop(dir_name, None) + if not self.failed_plugin_dict: + self.failed_plugin_info = "" + return success, None + else: + return False, error async def reload(self, specified_plugin_name=None): """重新加载插件