From d2df4d0cce9c517df2d682113a9d757acd9ba13d Mon Sep 17 00:00:00 2001 From: Soulter <37870767+Soulter@users.noreply.github.com> Date: Wed, 20 Aug 2025 15:25:41 +0800 Subject: [PATCH] =?UTF-8?q?Feature:=20=E6=94=AF=E6=8C=81=E5=9C=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E9=85=8D=E7=BD=AE=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=8F=92=E4=BB=B6=E7=BB=84=20(#2505)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 增加可用插件集合配置项 * remove: 旧版平台可用性配置 已经基于多配置文件实现。 * feat: 应用配置文件插件可用性配置 * perf: hoist if from if --- astrbot/core/agent/handoff.py | 5 +- astrbot/core/config/default.py | 28 ++- astrbot/core/pipeline/__init__.py | 3 - astrbot/core/pipeline/context_utils.py | 5 +- .../pipeline/platform_compatibility/stage.py | 56 ----- .../process_stage/method/llm_request.py | 12 + .../process_stage/method/star_request.py | 10 - astrbot/core/pipeline/respond/stage.py | 2 +- .../core/pipeline/result_decorate/stage.py | 2 +- astrbot/core/pipeline/waking_check/stage.py | 11 +- astrbot/core/platform/astr_message_event.py | 5 + astrbot/core/star/register/star_handler.py | 6 +- astrbot/core/star/star.py | 24 -- astrbot/core/star/star_handler.py | 50 ++-- astrbot/core/star/star_manager.py | 28 --- astrbot/dashboard/routes/plugin.py | 89 ------- .../src/components/shared/AstrBotConfigV4.vue | 48 ++++ .../components/shared/PluginSetSelector.vue | 226 ++++++++++++++++++ .../locales/en-US/features/extension.json | 15 -- .../locales/zh-CN/features/extension.json | 15 -- dashboard/src/views/ExtensionPage.vue | 196 --------------- 21 files changed, 351 insertions(+), 485 deletions(-) delete mode 100644 astrbot/core/pipeline/platform_compatibility/stage.py create mode 100644 dashboard/src/components/shared/PluginSetSelector.vue diff --git a/astrbot/core/agent/handoff.py b/astrbot/core/agent/handoff.py index 5cc4da9b9..d26463147 100644 --- a/astrbot/core/agent/handoff.py +++ b/astrbot/core/agent/handoff.py @@ -7,12 +7,15 @@ from .run_context import TContext class HandoffTool(FunctionTool, Generic[TContext]): """Handoff tool for delegating tasks to another agent.""" - def __init__(self, agent: Agent[TContext], parameters: dict | None = None): + def __init__( + self, agent: Agent[TContext], parameters: dict | None = None, **kwargs + ): self.agent = agent super().__init__( name=f"transfer_to_{agent.name}", parameters=parameters or self.default_parameters(), description=agent.instructions or self.default_description(agent.name), + **kwargs, ) def default_parameters(self) -> dict: diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index dcd95c8ef..cfcb74362 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -13,7 +13,6 @@ DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db") DEFAULT_CONFIG = { "config_version": 2, "platform_settings": { - "plugin_enable": {}, "unique_session": False, "rate_limit": { "time": 60, @@ -53,7 +52,7 @@ DEFAULT_CONFIG = { "default_provider_id": "", "default_image_caption_provider_id": "", "image_caption_prompt": "Please describe the image using Chinese.", - "provider_pool": ["all"], # "all" 表示使用所有可用的提供者 + "provider_pool": ["*"], # "*" 表示使用所有可用的提供者 "wake_prefix": "", "web_search": False, "websearch_provider": "default", @@ -63,7 +62,7 @@ DEFAULT_CONFIG = { "identifier": False, "datetime_system_prompt": True, "default_personality": "default", - "persona_pool": ["all"], + "persona_pool": ["*"], "prompt_prefix": "", "max_context_length": -1, "dequeue_context_length": 1, @@ -122,6 +121,7 @@ DEFAULT_CONFIG = { "timezone": "Asia/Shanghai", "callback_api_base": "", "default_kb_collection": "", # 默认知识库名称 + "plugin_set": ["*"], # "*" 表示使用所有可用的插件, 空列表表示不使用任何插件 } @@ -387,9 +387,6 @@ CONFIG_METADATA_2 = { "platform_settings": { "type": "object", "items": { - "plugin_enable": { - "invisible": True, # 隐藏插件启用配置 - }, "unique_session": { "type": "bool", }, @@ -2129,8 +2126,25 @@ CONFIG_METADATA_3 = { }, }, }, + "plugin_group": { + "name": "插件配置", + "metadata": { + "plugin": { + "description": "插件", + "type": "object", + "items": { + "plugin_set": { + "description": "可用插件", + "type": "bool", + "hint": "默认启用全部未被禁用的插件。若插件在插件页面被禁用,则此处的选择不会生效。", + "_special": "select_plugin_set", + }, + }, + }, + }, + }, "ext_group": { - "name": "扩展配置", + "name": "扩展功能", "metadata": { "segmented_reply": { "description": "分段回复", diff --git a/astrbot/core/pipeline/__init__.py b/astrbot/core/pipeline/__init__.py index 3501a5271..29a324a1d 100644 --- a/astrbot/core/pipeline/__init__.py +++ b/astrbot/core/pipeline/__init__.py @@ -4,7 +4,6 @@ from astrbot.core.message.message_event_result import ( ) from .content_safety_check.stage import ContentSafetyCheckStage -from .platform_compatibility.stage import PlatformCompatibilityStage from .preprocess_stage.stage import PreProcessStage from .process_stage.stage import ProcessStage from .rate_limit_check.stage import RateLimitStage @@ -21,7 +20,6 @@ STAGES_ORDER = [ "SessionStatusCheckStage", # 检查会话是否整体启用 "RateLimitStage", # 检查会话是否超过频率限制 "ContentSafetyCheckStage", # 检查内容安全 - "PlatformCompatibilityStage", # 检查所有处理器的平台兼容性 "PreProcessStage", # 预处理 "ProcessStage", # 交由 Stars 处理(a.k.a 插件),或者 LLM 调用 "ResultDecorateStage", # 处理结果,比如添加回复前缀、t2i、转换为语音 等 @@ -34,7 +32,6 @@ __all__ = [ "SessionStatusCheckStage", "RateLimitStage", "ContentSafetyCheckStage", - "PlatformCompatibilityStage", "PreProcessStage", "ProcessStage", "ResultDecorateStage", diff --git a/astrbot/core/pipeline/context_utils.py b/astrbot/core/pipeline/context_utils.py index a33acf70d..02e87e6d0 100644 --- a/astrbot/core/pipeline/context_utils.py +++ b/astrbot/core/pipeline/context_utils.py @@ -77,10 +77,9 @@ async def call_event_hook( Returns: bool: 如果事件被终止,返回 True - """ - platform_id = event.get_platform_id() + # """ handlers = star_handlers_registry.get_handlers_by_event_type( - hook_type, platform_id=platform_id + hook_type, plugins_name=event.plugins_name ) for handler in handlers: try: diff --git a/astrbot/core/pipeline/platform_compatibility/stage.py b/astrbot/core/pipeline/platform_compatibility/stage.py deleted file mode 100644 index 644912c26..000000000 --- a/astrbot/core/pipeline/platform_compatibility/stage.py +++ /dev/null @@ -1,56 +0,0 @@ -from ..stage import Stage, register_stage -from ..context import PipelineContext -from typing import Union, AsyncGenerator -from astrbot.core.platform.astr_message_event import AstrMessageEvent -from astrbot.core.star.star import star_map -from astrbot.core.star.star_handler import StarHandlerMetadata -from astrbot.core import logger - - -@register_stage -class PlatformCompatibilityStage(Stage): - """检查所有处理器的平台兼容性。 - - 这个阶段会检查所有处理器是否在当前平台启用,如果未启用则设置platform_compatible属性为False。 - """ - - async def initialize(self, ctx: PipelineContext) -> None: - """初始化平台兼容性检查阶段 - - Args: - ctx (PipelineContext): 消息管道上下文对象, 包括配置和插件管理器 - """ - self.ctx = ctx - - async def process( - self, event: AstrMessageEvent - ) -> Union[None, AsyncGenerator[None, None]]: - # 获取当前平台ID - platform_id = event.get_platform_id() - - # 获取已激活的处理器 - activated_handlers = event.get_extra("activated_handlers") - if activated_handlers is None: - activated_handlers = [] - - # 标记不兼容的处理器 - for handler in activated_handlers: - if not isinstance(handler, StarHandlerMetadata): - continue - # 检查处理器是否在当前平台启用 - enabled = handler.is_enabled_for_platform(platform_id) - if not enabled: - if handler.handler_module_path in star_map: - plugin_name = star_map[handler.handler_module_path].name - logger.debug( - f"[PlatformCompatibilityStage] 插件 {plugin_name} 在平台 {platform_id} 未启用,标记处理器 {handler.handler_name} 为平台不兼容" - ) - # 设置处理器为平台不兼容状态 - # TODO: 更好的标记方式 - handler.platform_compatible = False - else: - # 确保处理器为平台兼容状态 - handler.platform_compatible = True - - # 更新已激活的处理器列表 - event.set_extra("activated_handlers", activated_handlers) diff --git a/astrbot/core/pipeline/process_stage/method/llm_request.py b/astrbot/core/pipeline/process_stage/method/llm_request.py index 8ae02dc63..b65c58238 100644 --- a/astrbot/core/pipeline/process_stage/method/llm_request.py +++ b/astrbot/core/pipeline/process_stage/method/llm_request.py @@ -32,6 +32,7 @@ from astrbot.core.utils.metrics import Metric from ...context import PipelineContext, call_event_hook, call_handler from ..stage import Stage from astrbot.core.provider.register import llm_tools +from astrbot.core.star.star_handler import star_map from astrbot.core.astr_agent_context import AstrAgentContext try: @@ -422,9 +423,20 @@ class LLMRequestSubStage(Stage): req.image_urls = [] if req.func_tool: provider_cfg = provider.provider_config.get("modalities", ["tool_use"]) + # 如果模型不支持工具使用,但请求中包含工具列表,则清空。 if "tool_use" not in provider_cfg: logger.debug(f"用户设置提供商 {provider} 不支持工具使用,清空工具列表。") req.func_tool = None + # 插件可用性设置 + if event.plugins_name is not None and req.func_tool: + new_tool_set = ToolSet() + for tool in req.func_tool.tools: + plugin = star_map.get(tool.handler_module_path) + if not plugin: + continue + if plugin.name in event.plugins_name or plugin.reserved: + new_tool_set.add_tool(tool) + req.func_tool = new_tool_set # run agent agent_runner = AgentRunner() diff --git a/astrbot/core/pipeline/process_stage/method/star_request.py b/astrbot/core/pipeline/process_stage/method/star_request.py index 8dc153960..c5c0f5738 100644 --- a/astrbot/core/pipeline/process_stage/method/star_request.py +++ b/astrbot/core/pipeline/process_stage/method/star_request.py @@ -33,16 +33,6 @@ class StarRequestSubStage(Stage): handlers_parsed_params = {} for handler in activated_handlers: - # 检查处理器是否在当前平台兼容 - if ( - hasattr(handler, "platform_compatible") - and handler.platform_compatible is False - ): - logger.debug( - f"处理器 {handler.handler_name} 在当前平台不兼容,跳过执行" - ) - continue - params = handlers_parsed_params.get(handler.handler_full_name, {}) try: if handler.handler_module_path not in star_map: diff --git a/astrbot/core/pipeline/respond/stage.py b/astrbot/core/pipeline/respond/stage.py index 14ec16076..ebbba7ed3 100644 --- a/astrbot/core/pipeline/respond/stage.py +++ b/astrbot/core/pipeline/respond/stage.py @@ -214,7 +214,7 @@ class RespondStage(Stage): ) handlers = star_handlers_registry.get_handlers_by_event_type( - EventType.OnAfterMessageSentEvent, platform_id=event.get_platform_id() + EventType.OnAfterMessageSentEvent, plugins_name=event.plugins_name ) for handler in handlers: try: diff --git a/astrbot/core/pipeline/result_decorate/stage.py b/astrbot/core/pipeline/result_decorate/stage.py index 658327d08..f87f7bbc0 100644 --- a/astrbot/core/pipeline/result_decorate/stage.py +++ b/astrbot/core/pipeline/result_decorate/stage.py @@ -99,7 +99,7 @@ class ResultDecorateStage(Stage): # 发送消息前事件钩子 handlers = star_handlers_registry.get_handlers_by_event_type( - EventType.OnDecoratingResultEvent, platform_id=event.get_platform_id() + EventType.OnDecoratingResultEvent, plugins_name=event.plugins_name ) for handler in handlers: try: diff --git a/astrbot/core/pipeline/waking_check/stage.py b/astrbot/core/pipeline/waking_check/stage.py index 2345b6466..63bc8b52d 100644 --- a/astrbot/core/pipeline/waking_check/stage.py +++ b/astrbot/core/pipeline/waking_check/stage.py @@ -112,8 +112,17 @@ class WakingCheckStage(Stage): activated_handlers = [] handlers_parsed_params = {} # 注册了指令的 handler + # 将 plugins_name 设置到 event 中 + enabled_plugins_name = self.ctx.astrbot_config.get("plugin_set", ["*"]) + if enabled_plugins_name == ["*"]: + # 如果是 *,则表示所有插件都启用 + event.plugins_name = None + else: + event.plugins_name = enabled_plugins_name + logger.debug(f"enabled_plugins_name: {enabled_plugins_name}") + for handler in star_handlers_registry.get_handlers_by_event_type( - EventType.AdapterMessageEvent + EventType.AdapterMessageEvent, plugins_name=event.plugins_name ): # filter 需满足 AND 逻辑关系 passed = True diff --git a/astrbot/core/platform/astr_message_event.py b/astrbot/core/platform/astr_message_event.py index 73ec81420..75ea317ad 100644 --- a/astrbot/core/platform/astr_message_event.py +++ b/astrbot/core/platform/astr_message_event.py @@ -6,6 +6,7 @@ import uuid from typing import List, Union, Optional, AsyncGenerator +from astrbot import logger from astrbot.core.db.po import Conversation from astrbot.core.message.components import ( Plain, @@ -64,6 +65,9 @@ class AstrMessageEvent(abc.ABC): self.call_llm = False """是否在此消息事件中禁止默认的 LLM 请求""" + self.plugins_name: list[str] | None = None + """该事件启用的插件名称列表。None 表示所有插件都启用。空列表表示没有启用任何插件。""" + # back_compability self.platform = platform_meta @@ -181,6 +185,7 @@ class AstrMessageEvent(abc.ABC): """ 清除额外的信息。 """ + logger.info(f"清除 {self.get_platform_name()} 的额外信息: {self._extras}") self._extras.clear() def is_private_chat(self) -> bool: diff --git a/astrbot/core/star/register/star_handler.py b/astrbot/core/star/register/star_handler.py index 813333741..101f3a95f 100644 --- a/astrbot/core/star/register/star_handler.py +++ b/astrbot/core/star/register/star_handler.py @@ -412,7 +412,7 @@ def register_agent( """ tools_ = tools or [] - def decorator(_): + def decorator(awaitable: Awaitable): AstrAgent = Agent[AstrAgentContext] agent = AstrAgent( name=name, @@ -420,7 +420,9 @@ def register_agent( tools=tools_, run_hooks=run_hooks or BaseAgentRunHooks[AstrAgentContext](), ) - llm_tools.func_list.append(HandoffTool(agent=agent)) + handoff_tool = HandoffTool(agent=agent) + handoff_tool.handler=awaitable + llm_tools.func_list.append(handoff_tool) return RegisteringAgent(agent) return decorator diff --git a/astrbot/core/star/star.py b/astrbot/core/star/star.py index 2fe9dd7f3..0563e8cc8 100644 --- a/astrbot/core/star/star.py +++ b/astrbot/core/star/star.py @@ -56,32 +56,8 @@ class StarMetadata: star_handler_full_names: list[str] = field(default_factory=list) """注册的 Handler 的全名列表""" - supported_platforms: dict[str, bool] = field(default_factory=dict) - """插件支持的平台ID字典,key为平台ID,value为是否支持""" - def __str__(self) -> str: return f"Plugin {self.name} ({self.version}) by {self.author}: {self.desc}" def __repr__(self) -> str: return f"Plugin {self.name} ({self.version}) by {self.author}: {self.desc}" - - def update_platform_compatibility(self, plugin_enable_config: dict) -> None: - """更新插件支持的平台列表 - - Args: - plugin_enable_config: 平台插件启用配置,即platform_settings.plugin_enable配置项 - """ - if not plugin_enable_config: - return - - # 清空之前的配置 - self.supported_platforms.clear() - - # 遍历所有平台配置 - for platform_id, plugins in plugin_enable_config.items(): - # 检查该插件在当前平台的配置 - if self.name in plugins: - self.supported_platforms[platform_id] = plugins[self.name] - else: - # 如果没有明确配置,默认为启用 - self.supported_platforms[platform_id] = True diff --git a/astrbot/core/star/star_handler.py b/astrbot/core/star/star_handler.py index d375091e5..43a74396a 100644 --- a/astrbot/core/star/star_handler.py +++ b/astrbot/core/star/star_handler.py @@ -7,6 +7,7 @@ from .star import star_map T = TypeVar("T", bound="StarHandlerMetadata") + class StarHandlerRegistry(Generic[T]): def __init__(self): self.star_handlers_map: Dict[str, StarHandlerMetadata] = {} @@ -26,7 +27,10 @@ class StarHandlerRegistry(Generic[T]): print(handler.handler_full_name) def get_handlers_by_event_type( - self, event_type: EventType, only_activated=True, platform_id=None + self, + event_type: EventType, + only_activated=True, + plugins_name: list[str] | None = None, ) -> List[StarHandlerMetadata]: handlers = [] for handler in self._handlers: @@ -36,8 +40,15 @@ class StarHandlerRegistry(Generic[T]): plugin = star_map.get(handler.handler_module_path) if not (plugin and plugin.activated): continue - if platform_id and event_type != EventType.OnAstrBotLoadedEvent: - if not handler.is_enabled_for_platform(platform_id): + if plugins_name is not None and plugins_name != ["*"]: + plugin = star_map.get(handler.handler_module_path) + if not plugin: + continue + if ( + plugin.name not in plugins_name + and event_type != EventType.OnAstrBotLoadedEvent + and not plugin.reserved + ): continue handlers.append(handler) return handlers @@ -49,7 +60,8 @@ class StarHandlerRegistry(Generic[T]): self, module_name: str ) -> List[StarHandlerMetadata]: return [ - handler for handler in self._handlers + handler + for handler in self._handlers if handler.handler_module_path == module_name ] @@ -67,6 +79,7 @@ class StarHandlerRegistry(Generic[T]): def __len__(self): return len(self._handlers) + star_handlers_registry = StarHandlerRegistry() @@ -119,32 +132,3 @@ class StarHandlerMetadata: return self.extras_configs.get("priority", 0) < other.extras_configs.get( "priority", 0 ) - - def is_enabled_for_platform(self, platform_id: str) -> bool: - """检查插件是否在指定平台启用 - - Args: - platform_id: 平台ID,这是从event.get_platform_id()获取的,用于唯一标识平台实例 - - Returns: - bool: 是否启用,True表示启用,False表示禁用 - """ - plugin = star_map.get(self.handler_module_path) - - # 如果插件元数据不存在,默认允许执行 - if not plugin or not plugin.name: - return True - - # 先检查插件是否被激活 - if not plugin.activated: - return False - - # 直接使用StarMetadata中缓存的supported_platforms判断平台兼容性 - if ( - hasattr(plugin, "supported_platforms") - and platform_id in plugin.supported_platforms - ): - return plugin.supported_platforms[platform_id] - - # 如果没有缓存数据,默认允许执行 - return True diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 13460d8d7..5fb1b1dfa 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -337,30 +337,8 @@ class PluginManager: result = await self.load(specified_module_path) - # 更新所有插件的平台兼容性 - await self.update_all_platform_compatibility() - return result - async def update_all_platform_compatibility(self): - """更新所有插件的平台兼容性设置""" - # 获取最新的平台插件启用配置 - plugin_enable_config = self.config.get("platform_settings", {}).get( - "plugin_enable", {} - ) - logger.debug( - f"更新所有插件的平台兼容性设置,平台数量: {len(plugin_enable_config)}" - ) - - # 遍历所有插件,更新平台兼容性 - for plugin in self.context.get_all_stars(): - plugin.update_platform_compatibility(plugin_enable_config) - logger.debug( - f"插件 {plugin.name} 支持的平台: {list(plugin.supported_platforms.keys())}" - ) - - return True - async def load(self, specified_module_path=None, specified_dir_name=None): """载入插件。 当 specified_module_path 或者 specified_dir_name 不为 None 时,只载入指定的插件。 @@ -480,12 +458,6 @@ class PluginManager: metadata.root_dir_name = root_dir_name metadata.reserved = reserved - # 更新插件的平台兼容性 - plugin_enable_config = self.config.get("platform_settings", {}).get( - "plugin_enable", {} - ) - metadata.update_platform_compatibility(plugin_enable_config) - assert metadata.module_path is not None, ( f"插件 {metadata.name} 的模块路径为空。" ) diff --git a/astrbot/dashboard/routes/plugin.py b/astrbot/dashboard/routes/plugin.py index c02767672..849339698 100644 --- a/astrbot/dashboard/routes/plugin.py +++ b/astrbot/dashboard/routes/plugin.py @@ -40,8 +40,6 @@ class PluginRoute(Route): "/plugin/on": ("POST", self.on_plugin), "/plugin/reload": ("POST", self.reload_plugins), "/plugin/readme": ("GET", self.get_plugin_readme), - "/plugin/platform_enable/get": ("GET", self.get_plugin_platform_enable), - "/plugin/platform_enable/set": ("POST", self.set_plugin_platform_enable), } self.core_lifecycle = core_lifecycle self.plugin_manager = plugin_manager @@ -482,90 +480,3 @@ class PluginRoute(Route): except Exception as e: logger.error(f"/api/plugin/readme: {traceback.format_exc()}") return Response().error(f"读取README文件失败: {str(e)}").__dict__ - - async def get_plugin_platform_enable(self): - """获取插件在各平台的可用性配置""" - try: - platform_enable = self.core_lifecycle.astrbot_config.get( - "platform_settings", {} - ).get("plugin_enable", {}) - - # 获取所有可用平台 - platforms = [] - - for platform in self.core_lifecycle.astrbot_config.get("platform", []): - platform_type = platform.get("type", "") - platform_id = platform.get("id", "") - - platforms.append( - { - "name": platform_id, # 使用type作为name,这是系统内部使用的平台名称 - "id": platform_id, # 保留id字段以便前端可以显示 - "type": platform_type, - "display_name": f"{platform_type}({platform_id})", - } - ) - - adjusted_platform_enable = {} - for platform_id, plugins in platform_enable.items(): - adjusted_platform_enable[platform_id] = plugins - - # 获取所有插件,包括系统内部插件 - plugins = [] - for plugin in self.plugin_manager.context.get_all_stars(): - plugins.append( - { - "name": plugin.name, - "desc": plugin.desc, - "reserved": plugin.reserved, # 添加reserved标志 - } - ) - - logger.debug( - f"获取插件平台配置: 原始配置={platform_enable}, 调整后={adjusted_platform_enable}" - ) - - return ( - Response() - .ok( - { - "platforms": platforms, - "plugins": plugins, - "platform_enable": adjusted_platform_enable, - } - ) - .__dict__ - ) - except Exception as e: - logger.error(f"/api/plugin/platform_enable/get: {traceback.format_exc()}") - return Response().error(str(e)).__dict__ - - async def set_plugin_platform_enable(self): - """设置插件在各平台的可用性配置""" - if DEMO_MODE: - return ( - Response() - .error("You are not permitted to do this operation in demo mode") - .__dict__ - ) - - try: - data = await request.json - platform_enable = data.get("platform_enable", {}) - - # 更新配置 - config = self.core_lifecycle.astrbot_config - platform_settings = config.get("platform_settings", {}) - platform_settings["plugin_enable"] = platform_enable - config["platform_settings"] = platform_settings - config.save_config() - - # 更新插件的平台兼容性缓存 - await self.plugin_manager.update_all_platform_compatibility() - - logger.info(f"插件平台可用性配置已更新: {platform_enable}") - - return Response().ok(None, "插件平台可用性配置已更新").__dict__ - except Exception as e: - logger.error(f"/api/plugin/platform_enable/set: {traceback.format_exc()}") - return Response().error(str(e)).__dict__ diff --git a/dashboard/src/components/shared/AstrBotConfigV4.vue b/dashboard/src/components/shared/AstrBotConfigV4.vue index a1c1d485b..b5f418b5c 100644 --- a/dashboard/src/components/shared/AstrBotConfigV4.vue +++ b/dashboard/src/components/shared/AstrBotConfigV4.vue @@ -5,6 +5,7 @@ import ListConfigItem from './ListConfigItem.vue' import ProviderSelector from './ProviderSelector.vue' import PersonaSelector from './PersonaSelector.vue' import KnowledgeBaseSelector from './KnowledgeBaseSelector.vue' +import PluginSetSelector from './PluginSetSelector.vue' import { useI18n } from '@/i18n/composables' @@ -240,7 +241,34 @@ function hasVisibleItemsAfter(items, currentIndex) { v-model="createSelectorModel(itemKey).value" /> +
暂无可用的插件
+{{ tm('dialogs.platformConfig.description') }}
- -