插件系统info修复,见changes.md
This commit is contained in:
18
changes.md
Normal file
18
changes.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# 插件API与规范修改
|
||||||
|
|
||||||
|
1. 现在`plugin_system`的`__init__.py`文件中包含了所有插件API的导入,用户可以直接使用`from plugin_system import *`来导入所有API。
|
||||||
|
|
||||||
|
2. register_plugin函数现在转移到了`plugin_system.apis.plugin_register_api`模块中,用户可以通过`from plugin_system.apis.plugin_register_api import register_plugin`来导入。
|
||||||
|
|
||||||
|
3. 现在强制要求的property如下:
|
||||||
|
- `plugin_name`: 插件名称,必须是唯一的。(与文件夹相同)
|
||||||
|
- `enable_plugin`: 是否启用插件,默认为`True`。
|
||||||
|
- `dependencies`: 插件依赖的其他插件列表,默认为空。**现在并不检查(也许)**
|
||||||
|
- `python_dependencies`: 插件依赖的Python包列表,默认为空。**现在并不检查**
|
||||||
|
- `config_file_name`: 插件配置文件名,默认为`config.toml`。
|
||||||
|
- `config_schema`: 插件配置文件的schema,用于自动生成配置文件。
|
||||||
|
|
||||||
|
# 插件系统修改
|
||||||
|
1. 现在所有的匹配模式不再是关键字了,而是枚举类。**(可能有遗漏)**
|
||||||
|
2. 修复了一下显示插件信息不显示的问题。同时精简了一下显示内容
|
||||||
|
3. 修复了插件系统混用了`plugin_name`和`display_name`的问题。现在所有的插件信息都使用`display_name`来显示,而内部标识仍然使用`plugin_name`。**(可能有遗漏)**
|
||||||
@@ -103,6 +103,8 @@ class HelloWorldPlugin(BasePlugin):
|
|||||||
# 插件基本信息
|
# 插件基本信息
|
||||||
plugin_name = "hello_world_plugin" # 内部标识符
|
plugin_name = "hello_world_plugin" # 内部标识符
|
||||||
enable_plugin = True
|
enable_plugin = True
|
||||||
|
dependencies = [] # 插件依赖列表
|
||||||
|
python_dependencies = [] # Python包依赖列表
|
||||||
config_file_name = "config.toml" # 配置文件名
|
config_file_name = "config.toml" # 配置文件名
|
||||||
|
|
||||||
# 配置节描述
|
# 配置节描述
|
||||||
|
|||||||
@@ -443,6 +443,8 @@ class TakePicturePlugin(BasePlugin):
|
|||||||
|
|
||||||
plugin_name = "take_picture_plugin" # 内部标识符
|
plugin_name = "take_picture_plugin" # 内部标识符
|
||||||
enable_plugin = True
|
enable_plugin = True
|
||||||
|
dependencies = [] # 插件依赖列表
|
||||||
|
python_dependencies = [] # Python包依赖列表
|
||||||
config_file_name = "config.toml"
|
config_file_name = "config.toml"
|
||||||
|
|
||||||
# 配置节描述
|
# 配置节描述
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class ChatMessageContext:
|
|||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
def check_types(self, types: list) -> bool:
|
def check_types(self, types: list) -> bool:
|
||||||
|
# sourcery skip: invert-any-all, use-any, use-next
|
||||||
"""检查消息类型"""
|
"""检查消息类型"""
|
||||||
if not self.message.message_info.format_info.accept_format:
|
if not self.message.message_info.format_info.accept_format:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -561,7 +561,9 @@ class NormalChat:
|
|||||||
available_actions = None
|
available_actions = None
|
||||||
if self.enable_planner:
|
if self.enable_planner:
|
||||||
try:
|
try:
|
||||||
await self.action_modifier.modify_actions(mode=ChatMode.NORMAL, message_content=message.processed_plain_text)
|
await self.action_modifier.modify_actions(
|
||||||
|
mode=ChatMode.NORMAL, message_content=message.processed_plain_text
|
||||||
|
)
|
||||||
available_actions = self.action_manager.get_using_actions_for_mode(ChatMode.NORMAL)
|
available_actions = self.action_manager.get_using_actions_for_mode(ChatMode.NORMAL)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[{self.stream_name}] 获取available_actions失败: {e}")
|
logger.warning(f"[{self.stream_name}] 获取available_actions失败: {e}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Dict, List, Optional, Type, Any
|
from typing import Dict, List, Optional, Type
|
||||||
from src.plugin_system.base.base_action import BaseAction
|
from src.plugin_system.base.base_action import BaseAction
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
@@ -7,6 +7,7 @@ from src.plugin_system.base.component_types import ComponentType, ActionActivati
|
|||||||
|
|
||||||
logger = get_logger("action_manager")
|
logger = get_logger("action_manager")
|
||||||
|
|
||||||
|
|
||||||
class ActionManager:
|
class ActionManager:
|
||||||
"""
|
"""
|
||||||
动作管理器,用于管理各种类型的动作
|
动作管理器,用于管理各种类型的动作
|
||||||
@@ -73,7 +74,7 @@ class ActionManager:
|
|||||||
"activation_keywords": action_info.activation_keywords,
|
"activation_keywords": action_info.activation_keywords,
|
||||||
"keyword_case_sensitive": action_info.keyword_case_sensitive,
|
"keyword_case_sensitive": action_info.keyword_case_sensitive,
|
||||||
# 模式和并行设置
|
# 模式和并行设置
|
||||||
"mode_enable": action_info.mode_enable.value,
|
"mode_enable": action_info.mode_enable,
|
||||||
"parallel_action": action_info.parallel_action,
|
"parallel_action": action_info.parallel_action,
|
||||||
# 插件信息
|
# 插件信息
|
||||||
"_plugin_name": getattr(action_info, "plugin_name", ""),
|
"_plugin_name": getattr(action_info, "plugin_name", ""),
|
||||||
@@ -187,7 +188,7 @@ class ActionManager:
|
|||||||
enabled_actions = {}
|
enabled_actions = {}
|
||||||
|
|
||||||
for action_name, action_info in self._using_actions.items():
|
for action_name, action_info in self._using_actions.items():
|
||||||
action_mode = action_info.mode_enable
|
action_mode = action_info["mode_enable"]
|
||||||
|
|
||||||
# 检查动作是否在当前模式下启用
|
# 检查动作是否在当前模式下启用
|
||||||
if action_mode in [ChatMode.ALL, mode]:
|
if action_mode in [ChatMode.ALL, mode]:
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ import random
|
|||||||
import asyncio
|
import asyncio
|
||||||
import hashlib
|
import hashlib
|
||||||
import time
|
import time
|
||||||
from typing import List, Optional, Any, Dict
|
from typing import List, Any, Dict
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from src.llm_models.utils_model import LLMRequest
|
from src.llm_models.utils_model import LLMRequest
|
||||||
from src.chat.focus_chat.focus_loop_info import FocusLoopInfo
|
from src.chat.focus_chat.focus_loop_info import FocusLoopInfo
|
||||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
from src.chat.message_receive.chat_stream import get_chat_manager, ChatMessageContext
|
||||||
from src.chat.planner_actions.action_manager import ActionManager
|
from src.chat.planner_actions.action_manager import ActionManager
|
||||||
from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat, build_readable_messages
|
from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat, build_readable_messages
|
||||||
from src.plugin_system.base.component_types import ChatMode
|
from src.plugin_system.base.component_types import ChatMode, ActionInfo
|
||||||
|
|
||||||
logger = get_logger("action_manager")
|
logger = get_logger("action_manager")
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ class ActionModifier:
|
|||||||
loop_info=None,
|
loop_info=None,
|
||||||
mode: ChatMode = ChatMode.FOCUS,
|
mode: ChatMode = ChatMode.FOCUS,
|
||||||
message_content: str = "",
|
message_content: str = "",
|
||||||
):
|
): # sourcery skip: use-named-expression
|
||||||
"""
|
"""
|
||||||
动作修改流程,整合传统观察处理和新的激活类型判定
|
动作修改流程,整合传统观察处理和新的激活类型判定
|
||||||
|
|
||||||
@@ -129,11 +129,10 @@ class ActionModifier:
|
|||||||
f"{self.log_prefix}{mode}模式动作修改流程结束,最终可用动作: {list(self.action_manager.get_using_actions_for_mode(mode).keys())}||移除记录: {removals_summary}"
|
f"{self.log_prefix}{mode}模式动作修改流程结束,最终可用动作: {list(self.action_manager.get_using_actions_for_mode(mode).keys())}||移除记录: {removals_summary}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _check_action_associated_types(self, all_actions, chat_context):
|
def _check_action_associated_types(self, all_actions: Dict[str, ActionInfo], chat_context: ChatMessageContext):
|
||||||
type_mismatched_actions = []
|
type_mismatched_actions = []
|
||||||
for action_name, data in all_actions.items():
|
for action_name, data in all_actions.items():
|
||||||
if data.get("associated_types"):
|
if data["associated_types"] and not chat_context.check_types(data["associated_types"]):
|
||||||
if not chat_context.check_types(data["associated_types"]):
|
|
||||||
associated_types_str = ", ".join(data["associated_types"])
|
associated_types_str = ", ".join(data["associated_types"])
|
||||||
reason = f"适配器不支持(需要: {associated_types_str})"
|
reason = f"适配器不支持(需要: {associated_types_str})"
|
||||||
type_mismatched_actions.append((action_name, reason))
|
type_mismatched_actions.append((action_name, reason))
|
||||||
@@ -205,35 +204,6 @@ class ActionModifier:
|
|||||||
|
|
||||||
return deactivated_actions
|
return deactivated_actions
|
||||||
|
|
||||||
async def process_actions_for_planner(
|
|
||||||
self, observed_messages_str: str = "", chat_context: Optional[str] = None, extra_context: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
[已废弃] 此方法现在已被整合到 modify_actions() 中
|
|
||||||
|
|
||||||
为了保持向后兼容性而保留,但建议直接使用 ActionManager.get_using_actions()
|
|
||||||
规划器应该直接从 ActionManager 获取最终的可用动作集,而不是调用此方法
|
|
||||||
|
|
||||||
新的架构:
|
|
||||||
1. 主循环调用 modify_actions() 处理完整的动作管理流程
|
|
||||||
2. 规划器直接使用 ActionManager.get_using_actions() 获取最终动作集
|
|
||||||
"""
|
|
||||||
logger.warning(
|
|
||||||
f"{self.log_prefix}process_actions_for_planner() 已废弃,建议规划器直接使用 ActionManager.get_using_actions()"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 为了向后兼容,仍然返回当前使用的动作集
|
|
||||||
current_using_actions = self.action_manager.get_using_actions()
|
|
||||||
all_registered_actions = self.action_manager.get_registered_actions()
|
|
||||||
|
|
||||||
# 构建完整的动作信息
|
|
||||||
result = {}
|
|
||||||
for action_name in current_using_actions.keys():
|
|
||||||
if action_name in all_registered_actions:
|
|
||||||
result[action_name] = all_registered_actions[action_name]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _generate_context_hash(self, chat_content: str) -> str:
|
def _generate_context_hash(self, chat_content: str) -> str:
|
||||||
"""生成上下文的哈希值用于缓存"""
|
"""生成上下文的哈希值用于缓存"""
|
||||||
context_content = f"{chat_content}"
|
context_content = f"{chat_content}"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Tuple, Optional
|
from typing import Tuple, Optional
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType
|
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType
|
||||||
from src.plugin_system.apis import send_api, database_api, message_api
|
from src.plugin_system.apis import send_api, database_api, message_api
|
||||||
import time
|
import time
|
||||||
@@ -31,7 +32,7 @@ class BaseAction(ABC):
|
|||||||
reasoning: str,
|
reasoning: str,
|
||||||
cycle_timers: dict,
|
cycle_timers: dict,
|
||||||
thinking_id: str,
|
thinking_id: str,
|
||||||
chat_stream=None,
|
chat_stream: ChatStream = None,
|
||||||
log_prefix: str = "",
|
log_prefix: str = "",
|
||||||
shutting_down: bool = False,
|
shutting_down: bool = False,
|
||||||
plugin_config: dict = None,
|
plugin_config: dict = None,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Dict, List, Type, Optional, Any, Union
|
from typing import Dict, List, Type, Any, Union
|
||||||
import os
|
import os
|
||||||
import inspect
|
import inspect
|
||||||
import toml
|
import toml
|
||||||
@@ -29,18 +29,41 @@ class BasePlugin(ABC):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# 插件基本信息(子类必须定义)
|
# 插件基本信息(子类必须定义)
|
||||||
plugin_name: str = "" # 插件内部标识符(如 "hello_world_plugin")
|
@property
|
||||||
enable_plugin: bool = False # 是否启用插件
|
@abstractmethod
|
||||||
dependencies: List[str] = [] # 依赖的其他插件
|
def plugin_name(self) -> str:
|
||||||
python_dependencies: List[PythonDependency] = [] # Python包依赖
|
return "" # 插件内部标识符(如 "hello_world_plugin")
|
||||||
config_file_name: Optional[str] = None # 配置文件名
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def enable_plugin(self) -> bool:
|
||||||
|
return True # 是否启用插件
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def dependencies(self) -> List[str]:
|
||||||
|
return [] # 依赖的其他插件
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def python_dependencies(self) -> List[PythonDependency]:
|
||||||
|
return [] # Python包依赖
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def config_file_name(self) -> str:
|
||||||
|
return "" # 配置文件名
|
||||||
|
|
||||||
# manifest文件相关
|
# manifest文件相关
|
||||||
manifest_file_name: str = "_manifest.json" # manifest文件名
|
manifest_file_name: str = "_manifest.json" # manifest文件名
|
||||||
manifest_data: Dict[str, Any] = {} # manifest数据
|
manifest_data: Dict[str, Any] = {} # manifest数据
|
||||||
|
|
||||||
# 配置定义
|
# 配置定义
|
||||||
config_schema: Dict[str, Union[Dict[str, ConfigField], str]] = {}
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def config_schema(self) -> Dict[str, Union[Dict[str, ConfigField], str]]:
|
||||||
|
return {}
|
||||||
|
|
||||||
config_section_descriptions: Dict[str, str] = {}
|
config_section_descriptions: Dict[str, str] = {}
|
||||||
|
|
||||||
def __init__(self, plugin_dir: str = None):
|
def __init__(self, plugin_dir: str = None):
|
||||||
@@ -70,7 +93,8 @@ class BasePlugin(ABC):
|
|||||||
|
|
||||||
# 创建插件信息对象
|
# 创建插件信息对象
|
||||||
self.plugin_info = PluginInfo(
|
self.plugin_info = PluginInfo(
|
||||||
name=self.display_name, # 使用显示名称
|
name=self.plugin_name,
|
||||||
|
display_name=self.display_name,
|
||||||
description=self.plugin_description,
|
description=self.plugin_description,
|
||||||
version=self.plugin_version,
|
version=self.plugin_version,
|
||||||
author=self.plugin_author,
|
author=self.plugin_author,
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ class CommandInfo(ComponentInfo):
|
|||||||
class PluginInfo:
|
class PluginInfo:
|
||||||
"""插件信息"""
|
"""插件信息"""
|
||||||
|
|
||||||
|
display_name: str # 插件显示名称
|
||||||
name: str # 插件名称
|
name: str # 插件名称
|
||||||
description: str # 插件描述
|
description: str # 插件描述
|
||||||
version: str = "1.0.0" # 插件版本
|
version: str = "1.0.0" # 插件版本
|
||||||
|
|||||||
@@ -85,16 +85,17 @@ class PluginManager:
|
|||||||
total_failed_registration = 0
|
total_failed_registration = 0
|
||||||
|
|
||||||
for plugin_name in self.plugin_classes.keys():
|
for plugin_name in self.plugin_classes.keys():
|
||||||
if self.load_registered_plugin_classes(plugin_name):
|
load_status, count = self.load_registered_plugin_classes(plugin_name)
|
||||||
|
if load_status:
|
||||||
total_registered += 1
|
total_registered += 1
|
||||||
else:
|
else:
|
||||||
total_failed_registration += 1
|
total_failed_registration += count
|
||||||
|
|
||||||
self._show_stats(total_registered, total_failed_registration)
|
self._show_stats(total_registered, total_failed_registration)
|
||||||
|
|
||||||
return total_registered, total_failed_registration
|
return total_registered, total_failed_registration
|
||||||
|
|
||||||
def load_registered_plugin_classes(self, plugin_name: str) -> bool:
|
def load_registered_plugin_classes(self, plugin_name: str) -> Tuple[bool, int]:
|
||||||
# sourcery skip: extract-duplicate-method, extract-method
|
# sourcery skip: extract-duplicate-method, extract-method
|
||||||
"""
|
"""
|
||||||
加载已经注册的插件类
|
加载已经注册的插件类
|
||||||
@@ -102,7 +103,7 @@ class PluginManager:
|
|||||||
plugin_class: Type[BasePlugin] = self.plugin_classes.get(plugin_name)
|
plugin_class: Type[BasePlugin] = self.plugin_classes.get(plugin_name)
|
||||||
if not plugin_class:
|
if not plugin_class:
|
||||||
logger.error(f"插件 {plugin_name} 的插件类未注册或不存在")
|
logger.error(f"插件 {plugin_name} 的插件类未注册或不存在")
|
||||||
return False
|
return False, 1
|
||||||
try:
|
try:
|
||||||
# 使用记录的插件目录路径
|
# 使用记录的插件目录路径
|
||||||
plugin_dir = self.plugin_paths.get(plugin_name)
|
plugin_dir = self.plugin_paths.get(plugin_name)
|
||||||
@@ -116,7 +117,7 @@ class PluginManager:
|
|||||||
# 检查插件是否启用
|
# 检查插件是否启用
|
||||||
if not plugin_instance.enable_plugin:
|
if not plugin_instance.enable_plugin:
|
||||||
logger.info(f"插件 {plugin_name} 已禁用,跳过加载")
|
logger.info(f"插件 {plugin_name} 已禁用,跳过加载")
|
||||||
return False
|
return False, 0
|
||||||
|
|
||||||
# 检查版本兼容性
|
# 检查版本兼容性
|
||||||
is_compatible, compatibility_error = self._check_plugin_version_compatibility(
|
is_compatible, compatibility_error = self._check_plugin_version_compatibility(
|
||||||
@@ -125,22 +126,22 @@ class PluginManager:
|
|||||||
if not is_compatible:
|
if not is_compatible:
|
||||||
self.failed_plugins[plugin_name] = compatibility_error
|
self.failed_plugins[plugin_name] = compatibility_error
|
||||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {compatibility_error}")
|
logger.error(f"❌ 插件加载失败: {plugin_name} - {compatibility_error}")
|
||||||
return False
|
return False, 1
|
||||||
if plugin_instance.register_plugin():
|
if plugin_instance.register_plugin():
|
||||||
self.loaded_plugins[plugin_name] = plugin_instance
|
self.loaded_plugins[plugin_name] = plugin_instance
|
||||||
self._show_plugin_components(plugin_name)
|
self._show_plugin_components(plugin_name)
|
||||||
return True
|
return True, 1
|
||||||
else:
|
else:
|
||||||
self.failed_plugins[plugin_name] = "插件注册失败"
|
self.failed_plugins[plugin_name] = "插件注册失败"
|
||||||
logger.error(f"❌ 插件注册失败: {plugin_name}")
|
logger.error(f"❌ 插件注册失败: {plugin_name}")
|
||||||
return False
|
return False, 1
|
||||||
|
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
# manifest文件缺失
|
# manifest文件缺失
|
||||||
error_msg = f"缺少manifest文件: {str(e)}"
|
error_msg = f"缺少manifest文件: {str(e)}"
|
||||||
self.failed_plugins[plugin_name] = error_msg
|
self.failed_plugins[plugin_name] = error_msg
|
||||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
||||||
return False
|
return False, 1
|
||||||
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
# manifest文件格式错误或验证失败
|
# manifest文件格式错误或验证失败
|
||||||
@@ -148,7 +149,7 @@ class PluginManager:
|
|||||||
error_msg = f"manifest验证失败: {str(e)}"
|
error_msg = f"manifest验证失败: {str(e)}"
|
||||||
self.failed_plugins[plugin_name] = error_msg
|
self.failed_plugins[plugin_name] = error_msg
|
||||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
||||||
return False
|
return False, 1
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# 其他错误
|
# 其他错误
|
||||||
@@ -156,7 +157,7 @@ class PluginManager:
|
|||||||
self.failed_plugins[plugin_name] = error_msg
|
self.failed_plugins[plugin_name] = error_msg
|
||||||
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
logger.error(f"❌ 插件加载失败: {plugin_name} - {error_msg}")
|
||||||
logger.debug("详细错误信息: ", exc_info=True)
|
logger.debug("详细错误信息: ", exc_info=True)
|
||||||
return False
|
return False, 1
|
||||||
|
|
||||||
def unload_registered_plugin_module(self, plugin_name: str) -> None:
|
def unload_registered_plugin_module(self, plugin_name: str) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -489,14 +490,16 @@ class PluginManager:
|
|||||||
info_parts = [part for part in [version_info, author_info, license_info] if part]
|
info_parts = [part for part in [version_info, author_info, license_info] if part]
|
||||||
extra_info = f" ({', '.join(info_parts)})" if info_parts else ""
|
extra_info = f" ({', '.join(info_parts)})" if info_parts else ""
|
||||||
|
|
||||||
logger.info(f" 📦 {plugin_name}{extra_info}")
|
logger.info(f" 📦 {plugin_info.display_name}{extra_info}")
|
||||||
|
|
||||||
# Manifest信息
|
# Manifest信息
|
||||||
if plugin_info.manifest_data:
|
if plugin_info.manifest_data:
|
||||||
|
"""
|
||||||
if plugin_info.keywords:
|
if plugin_info.keywords:
|
||||||
logger.info(f" 🏷️ 关键词: {', '.join(plugin_info.keywords)}")
|
logger.info(f" 🏷️ 关键词: {', '.join(plugin_info.keywords)}")
|
||||||
if plugin_info.categories:
|
if plugin_info.categories:
|
||||||
logger.info(f" 📁 分类: {', '.join(plugin_info.categories)}")
|
logger.info(f" 📁 分类: {', '.join(plugin_info.categories)}")
|
||||||
|
"""
|
||||||
if plugin_info.homepage_url:
|
if plugin_info.homepage_url:
|
||||||
logger.info(f" 🌐 主页: {plugin_info.homepage_url}")
|
logger.info(f" 🌐 主页: {plugin_info.homepage_url}")
|
||||||
|
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ class CoreActionsPlugin(BasePlugin):
|
|||||||
# 插件基本信息
|
# 插件基本信息
|
||||||
plugin_name = "core_actions" # 内部标识符
|
plugin_name = "core_actions" # 内部标识符
|
||||||
enable_plugin = True
|
enable_plugin = True
|
||||||
|
dependencies = [] # 插件依赖列表
|
||||||
|
python_dependencies = [] # Python包依赖列表
|
||||||
config_file_name = "config.toml"
|
config_file_name = "config.toml"
|
||||||
|
|
||||||
# 配置节描述
|
# 配置节描述
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ class TTSPlugin(BasePlugin):
|
|||||||
# 插件基本信息
|
# 插件基本信息
|
||||||
plugin_name = "tts_plugin" # 内部标识符
|
plugin_name = "tts_plugin" # 内部标识符
|
||||||
enable_plugin = True
|
enable_plugin = True
|
||||||
|
dependencies = [] # 插件依赖列表
|
||||||
|
python_dependencies = [] # Python包依赖列表
|
||||||
config_file_name = "config.toml"
|
config_file_name = "config.toml"
|
||||||
|
|
||||||
# 配置节描述
|
# 配置节描述
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ class VTBPlugin(BasePlugin):
|
|||||||
# 插件基本信息
|
# 插件基本信息
|
||||||
plugin_name = "vtb_plugin" # 内部标识符
|
plugin_name = "vtb_plugin" # 内部标识符
|
||||||
enable_plugin = True
|
enable_plugin = True
|
||||||
|
dependencies = [] # 插件依赖列表
|
||||||
|
python_dependencies = [] # Python包依赖列表
|
||||||
config_file_name = "config.toml"
|
config_file_name = "config.toml"
|
||||||
|
|
||||||
# 配置节描述
|
# 配置节描述
|
||||||
|
|||||||
Reference in New Issue
Block a user