-
{{ tm('title') }}
+
+
{{ tm('title') }}
+
+ {{ tm('debugHint.text') }}
+
+
\ No newline at end of file
+
From 36432c43615867972a5ae6d1e912b15d2814d18a Mon Sep 17 00:00:00 2001
From: Gao Jinzhe <2968474907@qq.com>
Date: Wed, 4 Feb 2026 15:06:03 +0800
Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8F=92=E4=BB=B6?=
=?UTF-8?q?=E7=83=AD=E9=87=8D=E8=BD=BD=E6=97=B6=E5=B9=B3=E5=8F=B0=E9=80=82?=
=?UTF-8?q?=E9=85=8D=E5=99=A8=E6=9C=AA=E6=B8=85=E7=90=86=E5=AF=BC=E8=87=B4?=
=?UTF-8?q?=E6=B3=A8=E5=86=8C=E5=86=B2=E7=AA=81=E7=9A=84=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=20(#4859)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
astrbot/core/platform/platform_metadata.py | 3 ++
astrbot/core/platform/register.py | 32 ++++++++++++++++++++++
astrbot/core/star/star_manager.py | 13 +++++++++
3 files changed, 48 insertions(+)
diff --git a/astrbot/core/platform/platform_metadata.py b/astrbot/core/platform/platform_metadata.py
index b5f11ca15..00e7dc966 100644
--- a/astrbot/core/platform/platform_metadata.py
+++ b/astrbot/core/platform/platform_metadata.py
@@ -21,3 +21,6 @@ class PlatformMetadata:
"""平台是否支持真实流式传输"""
support_proactive_message: bool = True
"""平台是否支持主动消息推送(非用户触发)"""
+
+ module_path: str | None = None
+ """注册该适配器的模块路径,用于插件热重载时清理"""
diff --git a/astrbot/core/platform/register.py b/astrbot/core/platform/register.py
index 5f550ecd1..3bbec4809 100644
--- a/astrbot/core/platform/register.py
+++ b/astrbot/core/platform/register.py
@@ -37,6 +37,9 @@ def register_platform_adapter(
if "id" not in default_config_tmpl:
default_config_tmpl["id"] = adapter_name
+ # Get the module path of the class being decorated
+ module_path = cls.__module__
+
pm = PlatformMetadata(
name=adapter_name,
description=desc,
@@ -45,6 +48,7 @@ def register_platform_adapter(
adapter_display_name=adapter_display_name,
logo_path=logo_path,
support_streaming_message=support_streaming_message,
+ module_path=module_path,
)
platform_registry.append(pm)
platform_cls_map[adapter_name] = cls
@@ -52,3 +56,31 @@ def register_platform_adapter(
return cls
return decorator
+
+
+def unregister_platform_adapters_by_module(module_path_prefix: str) -> list[str]:
+ """根据模块路径前缀注销平台适配器。
+
+ 在插件热重载时调用,用于清理该插件注册的所有平台适配器。
+
+ Args:
+ module_path_prefix: 模块路径前缀,如 "data.plugins.my_plugin"
+
+ Returns:
+ 被注销的平台适配器名称列表
+ """
+ unregistered = []
+ to_remove = []
+
+ for pm in platform_registry:
+ if pm.module_path and pm.module_path.startswith(module_path_prefix):
+ to_remove.append(pm)
+ unregistered.append(pm.name)
+
+ for pm in to_remove:
+ platform_registry.remove(pm)
+ if pm.name in platform_cls_map:
+ del platform_cls_map[pm.name]
+ logger.debug(f"平台适配器 {pm.name} 已注销 (来自模块 {pm.module_path})")
+
+ return unregistered
diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py
index c59fa314e..567397107 100644
--- a/astrbot/core/star/star_manager.py
+++ b/astrbot/core/star/star_manager.py
@@ -15,6 +15,7 @@ import yaml
from astrbot.core import logger, pip_installer, sp
from astrbot.core.agent.handoff import FunctionTool, HandoffTool
from astrbot.core.config.astrbot_config import AstrBotConfig
+from astrbot.core.platform.register import unregister_platform_adapters_by_module
from astrbot.core.provider.register import llm_tools
from astrbot.core.utils.astrbot_path import (
get_astrbot_config_path,
@@ -842,6 +843,18 @@ class PluginManager:
for func_tool in to_remove:
llm_tools.func_list.remove(func_tool)
+ # Unregister platform adapters registered by this plugin
+ # module_path is like "data.plugins.my_plugin.main", extract prefix like "data.plugins.my_plugin"
+ module_prefix = ".".join(plugin_module_path.split(".")[:-1])
+ if module_prefix:
+ unregistered_adapters = unregister_platform_adapters_by_module(
+ module_prefix
+ )
+ for adapter_name in unregistered_adapters:
+ logger.info(
+ f"移除了插件 {plugin_name} 的平台适配器 {adapter_name}",
+ )
+
if plugin is None:
return