diff --git a/plugins/hello_world_plugin/_manifest.json b/plugins/hello_world_plugin/_manifest.json index c5826ed38..86f01afc3 100644 --- a/plugins/hello_world_plugin/_manifest.json +++ b/plugins/hello_world_plugin/_manifest.json @@ -1,19 +1,54 @@ { "manifest_version": 1, - "name": "hello_world_plugin", + "name": "Hello World 示例插件 (Hello World Plugin)", "version": "1.0.0", - "description": "我的第一个MaiCore插件,包含问候功能", + "description": "我的第一个MaiCore插件,包含问候功能和时间查询等基础示例", "author": { - "name": "你的名字", - "url": "" + "name": "MaiBot开发团队", + "url": "https://github.com/MaiM-with-u" }, "license": "GPL-v3.0-or-later", + "host_application": { "min_version": "0.8.0", "max_version": "0.8.0" }, - "keywords": [], - "categories": [], + "homepage_url": "https://github.com/MaiM-with-u/maibot", + "repository_url": "https://github.com/MaiM-with-u/maibot", + "keywords": ["demo", "example", "hello", "greeting", "tutorial"], + "categories": ["Examples", "Tutorial"], + "default_locale": "zh-CN", - "locales_path": "_locales" + "locales_path": "_locales", + + "plugin_info": { + "is_built_in": false, + "plugin_type": "example", + "components": [ + { + "type": "action", + "name": "hello_greeting", + "description": "向用户发送问候消息" + }, + { + "type": "action", + "name": "bye_greeting", + "description": "向用户发送告别消息", + "activation_modes": ["keyword"], + "keywords": ["再见", "bye", "88", "拜拜"] + }, + { + "type": "command", + "name": "time", + "description": "查询当前时间", + "pattern": "/time" + } + ], + "features": [ + "问候和告别功能", + "时间查询命令", + "配置文件示例", + "新手教程代码" + ] + } } \ No newline at end of file diff --git a/plugins/hello_world_plugin/plugin.py b/plugins/hello_world_plugin/plugin.py index 60723e227..ec44ca623 100644 --- a/plugins/hello_world_plugin/plugin.py +++ b/plugins/hello_world_plugin/plugin.py @@ -101,10 +101,7 @@ class HelloWorldPlugin(BasePlugin): """Hello World插件 - 你的第一个MaiCore插件""" # 插件基本信息 - plugin_name = "hello_world_plugin" - plugin_description = "我的第一个MaiCore插件,包含问候功能" - plugin_version = "1.0.0" - plugin_author = "你的名字" + plugin_name = "hello_world_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml" # 配置文件名 diff --git a/plugins/take_picture_plugin/_manifest.json b/plugins/take_picture_plugin/_manifest.json index 8f16c756c..ac7113148 100644 --- a/plugins/take_picture_plugin/_manifest.json +++ b/plugins/take_picture_plugin/_manifest.json @@ -1,19 +1,51 @@ { "manifest_version": 1, - "name": "take_picture_plugin", + "name": "AI拍照插件 (Take Picture Plugin)", "version": "1.0.0", - "description": "提供生成自拍照和展示最近照片的功能", + "description": "基于AI图像生成的拍照插件,可以生成逼真的自拍照片,支持照片存储和展示功能。", "author": { "name": "SengokuCola", - "url": "" + "url": "https://github.com/SengokuCola" }, "license": "GPL-v3.0-or-later", + "host_application": { "min_version": "0.8.0", "max_version": "0.8.0" }, - "keywords": [], - "categories": [], + "homepage_url": "https://github.com/MaiM-with-u/maibot", + "repository_url": "https://github.com/MaiM-with-u/maibot", + "keywords": ["camera", "photo", "selfie", "ai", "image", "generation"], + "categories": ["AI Tools", "Image Processing", "Entertainment"], + "default_locale": "zh-CN", - "locales_path": "_locales" + "locales_path": "_locales", + + "plugin_info": { + "is_built_in": false, + "plugin_type": "image_generator", + "api_dependencies": ["volcengine"], + "components": [ + { + "type": "action", + "name": "take_picture", + "description": "生成一张用手机拍摄的照片,比如自拍或者近照", + "activation_modes": ["keyword"], + "keywords": ["拍张照", "自拍", "发张照片", "看看你", "你的照片"] + }, + { + "type": "command", + "name": "show_recent_pictures", + "description": "展示最近生成的5张照片", + "pattern": "/show_pics" + } + ], + "features": [ + "AI驱动的自拍照生成", + "个性化照片风格", + "照片历史记录", + "缓存机制优化", + "火山引擎API集成" + ] + } } \ No newline at end of file diff --git a/plugins/take_picture_plugin/plugin.py b/plugins/take_picture_plugin/plugin.py index ef28140a9..1a84a824a 100644 --- a/plugins/take_picture_plugin/plugin.py +++ b/plugins/take_picture_plugin/plugin.py @@ -440,10 +440,7 @@ class ShowRecentPicturesCommand(BaseCommand): class TakePicturePlugin(BasePlugin): """拍照插件""" - plugin_name = "take_picture_plugin" - plugin_description = "提供生成自拍照和展示最近照片的功能" - plugin_version = "1.0.0" - plugin_author = "SengokuCola" + plugin_name = "take_picture_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml" @@ -460,7 +457,7 @@ class TakePicturePlugin(BasePlugin): config_schema = { "plugin": { "name": ConfigField(type=str, default="take_picture_plugin", description="插件名称", required=True), - "version": ConfigField(type=str, default="1.3.0", description="插件版本号"), + "version": ConfigField(type=str, default="1.0.0", description="插件版本号"), "enabled": ConfigField(type=bool, default=False, description="是否启用插件"), "description": ConfigField( type=str, default="提供生成自拍照和展示最近照片的功能", description="插件描述", required=True diff --git a/scripts/test_version_compatibility.py b/scripts/test_version_compatibility.py index 298267c0a..d08ad277e 100644 --- a/scripts/test_version_compatibility.py +++ b/scripts/test_version_compatibility.py @@ -7,12 +7,13 @@ import sys import os +from src.plugin_system.utils.manifest_utils import VersionComparator # 添加项目根目录到Python路径 project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, project_root) -from src.plugin_system.utils.manifest_utils import VersionComparator + def test_version_normalization(): diff --git a/src/plugin_system/base/base_plugin.py b/src/plugin_system/base/base_plugin.py index 24aa35353..7a85e59e5 100644 --- a/src/plugin_system/base/base_plugin.py +++ b/src/plugin_system/base/base_plugin.py @@ -29,20 +29,17 @@ class BasePlugin(ABC): """ # 插件基本信息(子类必须定义) - plugin_name: str = "" # 插件名称 - plugin_description: str = "" # 插件描述 - plugin_version: str = "1.0.0" # 插件版本 - plugin_author: str = "" # 插件作者 + plugin_name: str = "" # 插件内部标识符(如 "doubao_pic_plugin") enable_plugin: bool = False # 是否启用插件 dependencies: List[str] = [] # 依赖的其他插件 python_dependencies: List[PythonDependency] = [] # Python包依赖 config_file_name: Optional[str] = None # 配置文件名 - # 新增:manifest文件相关 + # manifest文件相关 manifest_file_name: str = "_manifest.json" # manifest文件名 manifest_data: Dict[str, Any] = {} # manifest数据 - # 新增:配置定义 + # 配置定义 config_schema: Dict[str, Union[Dict[str, ConfigField], str]] = {} config_section_descriptions: Dict[str, str] = {} @@ -63,9 +60,17 @@ class BasePlugin(ABC): self._validate_plugin_info() # 加载插件配置 - self._load_plugin_config() # 创建插件信息对象 + self._load_plugin_config() + + # 从manifest获取显示信息 + self.display_name = self.get_manifest_info("name", self.plugin_name) + self.plugin_version = self.get_manifest_info("version", "1.0.0") + self.plugin_description = self.get_manifest_info("description", "") + self.plugin_author = self._get_author_name() + + # 创建插件信息对象 self.plugin_info = PluginInfo( - name=self.plugin_name, + name=self.display_name, # 使用显示名称 description=self.plugin_description, version=self.plugin_version, author=self.plugin_author, @@ -74,7 +79,7 @@ class BasePlugin(ABC): config_file=self.config_file_name or "", dependencies=self.dependencies.copy(), python_dependencies=self.python_dependencies.copy(), - # 新增:manifest相关信息 + # manifest相关信息 manifest_data=self.manifest_data.copy(), license=self.get_manifest_info("license", ""), homepage_url=self.get_manifest_info("homepage_url", ""), @@ -91,8 +96,12 @@ class BasePlugin(ABC): """验证插件基本信息""" if not self.plugin_name: raise ValueError(f"插件类 {self.__class__.__name__} 必须定义 plugin_name") - if not self.plugin_description: - raise ValueError(f"插件 {self.plugin_name} 必须定义 plugin_description") + + # 验证manifest中的必需信息 + if not self.get_manifest_info("name"): + raise ValueError(f"插件 {self.plugin_name} 的manifest中缺少name字段") + if not self.get_manifest_info("description"): + raise ValueError(f"插件 {self.plugin_name} 的manifest中缺少description字段") def _load_manifest(self): """加载manifest文件(强制要求)""" @@ -128,26 +137,21 @@ class BasePlugin(ABC): raise IOError(error_msg) # noqa def _apply_manifest_overrides(self): - """从manifest文件覆盖插件信息""" + """从manifest文件覆盖插件信息(现在只处理内部标识符的fallback)""" if not self.manifest_data: return - # 如果插件类中的信息为空,则从manifest中获取 + # 只有当插件类中没有定义plugin_name时,才从manifest中获取作为fallback if not self.plugin_name: - self.plugin_name = self.manifest_data.get("name", "") - - if not self.plugin_description: - self.plugin_description = self.manifest_data.get("description", "") - - if self.plugin_version == "1.0.0": # 默认版本 - self.plugin_version = self.manifest_data.get("version", "1.0.0") - - if not self.plugin_author: - author_info = self.manifest_data.get("author", {}) - if isinstance(author_info, dict): - self.plugin_author = author_info.get("name", "") - else: - self.plugin_author = str(author_info) + self.plugin_name = self.manifest_data.get("name", "").replace(" ", "_").lower() + + def _get_author_name(self) -> str: + """从manifest获取作者名称""" + author_info = self.get_manifest_info("author", {}) + if isinstance(author_info, dict): + return author_info.get("name", "") + else: + return str(author_info) if author_info else "" def _validate_manifest(self): """验证manifest文件格式(使用强化的验证器)""" @@ -178,12 +182,15 @@ class BasePlugin(ABC): logger.debug(f"{self.log_prefix} 插件名称未定义,无法生成默认manifest") return + # 从plugin_name生成友好的显示名称 + display_name = self.plugin_name.replace("_", " ").title() + default_manifest = { "manifest_version": 1, - "name": self.plugin_name, - "version": self.plugin_version, - "description": self.plugin_description or "插件描述", - "author": {"name": self.plugin_author or "Unknown", "url": ""}, + "name": display_name, + "version": "1.0.0", + "description": "插件描述", + "author": {"name": "Unknown", "url": ""}, "license": "MIT", "host_application": {"min_version": "1.0.0", "max_version": "4.0.0"}, "keywords": [], diff --git a/src/plugin_system/core/plugin_manager.py b/src/plugin_system/core/plugin_manager.py index 1afdda7dd..47edec4af 100644 --- a/src/plugin_system/core/plugin_manager.py +++ b/src/plugin_system/core/plugin_manager.py @@ -166,13 +166,12 @@ class PluginManager: # 获取组件统计信息 stats = component_registry.get_registry_stats() + action_count = stats.get("action_components", 0) + command_count = stats.get("command_components", 0) + total_components = stats.get("total_components", 0) # 📋 显示插件加载总览 if total_registered > 0: - action_count = stats.get("action_components", 0) - command_count = stats.get("command_components", 0) - total_components = stats.get("total_components", 0) - logger.info("🎉 插件系统加载完成!") logger.info( f"📊 总览: {total_registered}个插件, {total_components}个组件 (Action: {action_count}, Command: {command_count})" diff --git a/src/plugins/built_in/core_actions/plugin.py b/src/plugins/built_in/core_actions/plugin.py index ce5064271..a51d20697 100644 --- a/src/plugins/built_in/core_actions/plugin.py +++ b/src/plugins/built_in/core_actions/plugin.py @@ -344,11 +344,8 @@ class CoreActionsPlugin(BasePlugin): 注意:插件基本信息优先从_manifest.json文件中读取 """ - # 插件基本信息(作为fallback,优先从manifest读取) - plugin_name = "core_actions" - plugin_description = "系统核心动作插件,提供基础聊天交互功能" - plugin_version = "1.0.0" - plugin_author = "MaiBot团队" + # 插件基本信息 + plugin_name = "core_actions" # 内部标识符 enable_plugin = True config_file_name = "config.toml" diff --git a/src/plugins/built_in/doubao_pic_plugin/_manifest.json b/src/plugins/built_in/doubao_pic_plugin/_manifest.json index 4211227b2..92912c400 100644 --- a/src/plugins/built_in/doubao_pic_plugin/_manifest.json +++ b/src/plugins/built_in/doubao_pic_plugin/_manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "豆包图片生成插件 (Doubao Image Generator)", - "version": "1.2.0", + "version": "2.0.0", "description": "基于火山引擎豆包模型的AI图片生成插件,支持智能LLM判定、高质量图片生成、结果缓存和多尺寸支持。", "author": { "name": "MaiBot团队", diff --git a/src/plugins/built_in/doubao_pic_plugin/plugin.py b/src/plugins/built_in/doubao_pic_plugin/plugin.py index 65c499a81..28d37e88f 100644 --- a/src/plugins/built_in/doubao_pic_plugin/plugin.py +++ b/src/plugins/built_in/doubao_pic_plugin/plugin.py @@ -399,10 +399,7 @@ class DoubaoImagePlugin(BasePlugin): """ # 插件基本信息 - plugin_name = "doubao_pic_plugin" - plugin_description = "基于火山引擎豆包模型的AI图片生成插件" - plugin_version = "2.0.0" - plugin_author = "MaiBot开发团队" + plugin_name = "doubao_pic_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml" diff --git a/src/plugins/built_in/mute_plugin/_manifest.json b/src/plugins/built_in/mute_plugin/_manifest.json index 32e0aa70f..32f848aeb 100644 --- a/src/plugins/built_in/mute_plugin/_manifest.json +++ b/src/plugins/built_in/mute_plugin/_manifest.json @@ -1,19 +1,19 @@ { "manifest_version": 1, - "name": "mute_plugin", + "name": "群聊禁言管理插件 (Mute Plugin)", "version": "2.0.0", "description": "群聊禁言管理插件,提供智能禁言功能", "author": { "name": "MaiBot开发团队", - "url": "" + "url": "https://github.com/MaiM-with-u" }, "license": "GPL-v3.0-or-later", "host_application": { "min_version": "0.8.0", "max_version": "0.8.0" }, - "keywords": [], - "categories": [], + "keywords": ["mute", "ban", "moderation", "admin", "management", "group"], + "categories": ["Moderation", "Group Management", "Admin Tools"], "default_locale": "zh-CN", "locales_path": "_locales" } \ No newline at end of file diff --git a/src/plugins/built_in/mute_plugin/plugin.py b/src/plugins/built_in/mute_plugin/plugin.py index 4e664f944..3f5dc35de 100644 --- a/src/plugins/built_in/mute_plugin/plugin.py +++ b/src/plugins/built_in/mute_plugin/plugin.py @@ -357,10 +357,7 @@ class MutePlugin(BasePlugin): """ # 插件基本信息 - plugin_name = "mute_plugin" - plugin_description = "群聊禁言管理插件,提供智能禁言功能" - plugin_version = "2.0.0" - plugin_author = "MaiBot开发团队" + plugin_name = "mute_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml" diff --git a/src/plugins/built_in/tts_plugin/_manifest.json b/src/plugins/built_in/tts_plugin/_manifest.json index 3726be597..be00637c1 100644 --- a/src/plugins/built_in/tts_plugin/_manifest.json +++ b/src/plugins/built_in/tts_plugin/_manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "文本转语音插件 (Text-to-Speech)", - "version": "1.1.0", + "version": "0.1.0", "description": "将文本转换为语音进行播放的插件,支持多种语音模式和智能语音输出场景判断。", "author": { "name": "MaiBot团队", diff --git a/src/plugins/built_in/tts_plugin/plugin.py b/src/plugins/built_in/tts_plugin/plugin.py index bce8b48f4..d60186a13 100644 --- a/src/plugins/built_in/tts_plugin/plugin.py +++ b/src/plugins/built_in/tts_plugin/plugin.py @@ -101,10 +101,7 @@ class TTSPlugin(BasePlugin): """ # 插件基本信息 - plugin_name = "tts_plugin" - plugin_description = "文字转语音插件" - plugin_version = "0.1.0" - plugin_author = "MaiBot开发团队" + plugin_name = "tts_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml" diff --git a/src/plugins/built_in/vtb_plugin/_manifest.json b/src/plugins/built_in/vtb_plugin/_manifest.json index f8a1442be..338c4a4d4 100644 --- a/src/plugins/built_in/vtb_plugin/_manifest.json +++ b/src/plugins/built_in/vtb_plugin/_manifest.json @@ -1,19 +1,19 @@ { "manifest_version": 1, - "name": "vtb_plugin", + "name": "虚拟主播情感表达插件 (VTB Plugin)", "version": "0.1.0", "description": "虚拟主播情感表达插件", "author": { "name": "MaiBot开发团队", - "url": "" + "url": "https://github.com/MaiM-with-u" }, "license": "GPL-v3.0-or-later", "host_application": { "min_version": "0.8.0", "max_version": "0.8.0" }, - "keywords": [], - "categories": [], + "keywords": ["vtb", "vtuber", "emotion", "expression", "virtual", "streamer"], + "categories": ["Entertainment", "Virtual Assistant", "Emotion"], "default_locale": "zh-CN", "locales_path": "_locales" } \ No newline at end of file diff --git a/src/plugins/built_in/vtb_plugin/plugin.py b/src/plugins/built_in/vtb_plugin/plugin.py index 25e5cc9bf..a87071e63 100644 --- a/src/plugins/built_in/vtb_plugin/plugin.py +++ b/src/plugins/built_in/vtb_plugin/plugin.py @@ -107,10 +107,7 @@ class VTBPlugin(BasePlugin): """ # 插件基本信息 - plugin_name = "vtb_plugin" - plugin_description = "虚拟主播情感表达插件" - plugin_version = "0.1.0" - plugin_author = "MaiBot开发团队" + plugin_name = "vtb_plugin" # 内部标识符 enable_plugin = True config_file_name = "config.toml"