feat: add plugin load&unload hook (#5331)

* 添加了插件的加载完成和卸载完成的钩子事件

* 添加了插件的加载完成和卸载完成的钩子事件

* format code with ruff

* ruff format

---------

Co-authored-by: Soulter <905617992@qq.com>
This commit is contained in:
PyuraMazo
2026-02-23 23:13:41 +08:00
committed by GitHub
parent 351895ae66
commit 28bfb3b8b2
5 changed files with 73 additions and 1 deletions
+4
View File
@@ -25,6 +25,8 @@ from astrbot.core.star.register import (
)
from astrbot.core.star.register import register_on_platform_loaded as on_platform_loaded
from astrbot.core.star.register import register_on_plugin_error as on_plugin_error
from astrbot.core.star.register import register_on_plugin_loaded as on_plugin_loaded
from astrbot.core.star.register import register_on_plugin_unloaded as on_plugin_unloaded
from astrbot.core.star.register import register_on_using_llm_tool as on_using_llm_tool
from astrbot.core.star.register import (
register_on_waiting_llm_request as on_waiting_llm_request,
@@ -54,6 +56,8 @@ __all__ = [
"on_llm_request",
"on_llm_response",
"on_plugin_error",
"on_plugin_loaded",
"on_plugin_unloaded",
"on_platform_loaded",
"on_waiting_llm_request",
"permission_type",
+4
View File
@@ -14,6 +14,8 @@ from .star_handler import (
register_on_llm_tool_respond,
register_on_platform_loaded,
register_on_plugin_error,
register_on_plugin_loaded,
register_on_plugin_unloaded,
register_on_using_llm_tool,
register_on_waiting_llm_request,
register_permission_type,
@@ -34,6 +36,8 @@ __all__ = [
"register_on_llm_request",
"register_on_llm_response",
"register_on_plugin_error",
"register_on_plugin_loaded",
"register_on_plugin_unloaded",
"register_on_platform_loaded",
"register_on_waiting_llm_request",
"register_permission_type",
@@ -357,6 +357,40 @@ def register_on_plugin_error(**kwargs):
return decorator
def register_on_plugin_loaded(**kwargs):
"""当有插件加载完成时
Hook 参数:
metadata
说明:
当有插件加载完成时,触发该事件并获取到该插件的元数据
"""
def decorator(awaitable):
_ = get_handler_or_create(awaitable, EventType.OnPluginLoadedEvent, **kwargs)
return awaitable
return decorator
def register_on_plugin_unloaded(**kwargs):
"""当有插件卸载完成时
Hook 参数:
metadata
说明:
当有插件卸载完成时,触发该事件并获取到该插件的元数据
"""
def decorator(awaitable):
_ = get_handler_or_create(awaitable, EventType.OnPluginUnloadedEvent, **kwargs)
return awaitable
return decorator
def register_on_waiting_llm_request(**kwargs):
"""当等待调用 LLM 时的通知事件(在获取锁之前)
+4
View File
@@ -144,6 +144,8 @@ class StarHandlerRegistry(Generic[T]):
not in (
EventType.OnAstrBotLoadedEvent,
EventType.OnPlatformLoadedEvent,
EventType.OnPluginLoadedEvent,
EventType.OnPluginUnloadedEvent,
)
and not plugin.reserved
):
@@ -201,6 +203,8 @@ class EventType(enum.Enum):
OnLLMToolRespondEvent = enum.auto() # 调用函数工具后
OnAfterMessageSentEvent = enum.auto() # 发送消息后
OnPluginErrorEvent = enum.auto() # 插件处理消息异常时
OnPluginLoadedEvent = enum.auto() # 插件加载完成
OnPluginUnloadedEvent = enum.auto() # 插件卸载完成
H = TypeVar("H", bound=Callable[..., Any])
+27 -1
View File
@@ -33,7 +33,7 @@ from .command_management import sync_command_configs
from .context import Context
from .filter.permission import PermissionType, PermissionTypeFilter
from .star import star_map, star_registry
from .star_handler import star_handlers_registry
from .star_handler import EventType, star_handlers_registry
from .updator import PluginUpdator
try:
@@ -783,6 +783,19 @@ class PluginManager:
if hasattr(metadata.star_cls, "initialize") and metadata.star_cls:
await metadata.star_cls.initialize()
# 触发插件加载事件
handlers = star_handlers_registry.get_handlers_by_event_type(
EventType.OnPluginLoadedEvent,
)
for handler in handlers:
try:
logger.info(
f"hook(on_plugin_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}",
)
await handler.handler(metadata)
except Exception:
logger.error(traceback.format_exc())
except BaseException as e:
logger.error(f"----- 插件 {root_dir_name} 载入失败 -----")
errors = traceback.format_exc()
@@ -1175,6 +1188,19 @@ class PluginManager:
elif "terminate" in star_metadata.star_cls_type.__dict__:
await star_metadata.star_cls.terminate()
# 触发插件卸载事件
handlers = star_handlers_registry.get_handlers_by_event_type(
EventType.OnPluginUnloadedEvent,
)
for handler in handlers:
try:
logger.info(
f"hook(on_plugin_unloaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}",
)
await handler.handler(star_metadata)
except Exception:
logger.error(traceback.format_exc())
async def turn_on_plugin(self, plugin_name: str) -> None:
plugin = self.context.get_registered_star(plugin_name)
if plugin is None: