Coverage for agentos/plugin_manager.py: 52%
44 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-09 09:19 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-09 09:19 +0800
1"""
2AgentOS 插件系统兼容层 — 统一入口,委托到 agentos.plugins 模块。
4v1.14.3 版本存在两套并行插件体系(顶层 plugin_manager.py + plugins/ 目录),
5v1.14.6 将 plugin_manager.py 改为 plugins/ 的兼容性包装,消除碎片化。
6"""
8from __future__ import annotations
10import warnings
12from agentos.plugins import (
13 AuditLoggerPlugin,
14 BasePlugin,
15 HealthCheckPlugin,
16 PluginFileWatcher,
17 PluginManifest,
18 PluginRegistry,
19 PluginStatus,
20 create_registry_with_builtins,
21)
23# ── 兼容性导出 ────────────────────────────
24# 保留旧 PluginManager 接口但内部委托到 PluginRegistry
27class PluginManager:
28 """兼容性包装:旧 PluginManager API 委托到 PluginRegistry。
30 Deprecated: 请直接使用 agentos.plugins.PluginRegistry。
31 """
33 def __init__(self, plugin_dirs: list[str] | None = None):
34 warnings.warn(
35 "agentos.plugin_manager.PluginManager is deprecated. "
36 "Use agentos.plugins.PluginRegistry directly.",
37 DeprecationWarning,
38 stacklevel=2,
39 )
40 self._registry = PluginRegistry()
41 self._plugin_dirs = plugin_dirs or ["./plugins"]
43 def discover(self):
44 discovered = []
45 for d in self._plugin_dirs:
46 names = self._registry.discover(d)
47 discovered.extend(
48 PluginInfo(
49 name=name,
50 version=self._registry._manifests[name].version,
51 description=self._registry._manifests[name].description,
52 entry_point=self._registry._manifests[name].entry_point,
53 )
54 for name in names
55 )
56 return discovered
58 def register(self, plugin):
59 if isinstance(plugin, BasePlugin):
60 return self._registry.register(plugin)
61 elif isinstance(plugin, PluginInfo):
62 manifest = PluginManifest(
63 name=plugin.name,
64 version=plugin.version,
65 description=plugin.description,
66 entry_point=plugin.entry_point,
67 )
68 self._registry._manifests[plugin.name] = manifest
69 return True
71 def load(self, name: str):
72 return self._registry.load(name)
74 def unload(self, name: str):
75 plugin = self._registry.get_plugin(name)
76 if plugin:
77 plugin.unload()
79 def add_hook(self, hook_name, callback):
80 pass # PluginRegistry uses middleware model instead
82 def call_hook(self, hook_name, *args, **kwargs):
83 pass # PluginRegistry uses middleware model instead
85 @property
86 def loaded_plugins(self) -> list[str]:
87 return [n for n, p in self._registry._plugins.items() if p.status == PluginStatus.ACTIVE]
90# ── 兼容类型 ───────────────────────────────
92from dataclasses import dataclass # noqa: E402
95@dataclass
96class PluginInfo:
97 """旧版 PluginInfo 兼容类型。"""
99 name: str
100 version: str
101 description: str
102 entry_point: str
103 author: str = ""
104 path: str = ""
107# ── 公开 API ───────────────────────────────
109__all__ = [
110 # 新 API(推荐)
111 "PluginRegistry",
112 "PluginManifest",
113 "PluginStatus",
114 "BasePlugin",
115 "PluginFileWatcher",
116 "AuditLoggerPlugin",
117 "HealthCheckPlugin",
118 "create_registry_with_builtins",
119 # 兼容旧 API
120 "PluginManager",
121 "PluginInfo",
122]