🤖 自动格式化代码 [skip ci]
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
from typing import List, Tuple, Type
|
||||
from src.plugin_system import (
|
||||
BasePlugin, register_plugin, BaseAction, BaseCommand,
|
||||
ComponentInfo, ActionActivationType, ChatMode,
|
||||
ConfigField
|
||||
BasePlugin,
|
||||
register_plugin,
|
||||
BaseAction,
|
||||
BaseCommand,
|
||||
ComponentInfo,
|
||||
ActionActivationType,
|
||||
ConfigField,
|
||||
)
|
||||
|
||||
# ===== Action组件 =====
|
||||
|
||||
|
||||
class HelloAction(BaseAction):
|
||||
"""问候Action - 简单的问候动作"""
|
||||
|
||||
@@ -15,26 +20,21 @@ class HelloAction(BaseAction):
|
||||
action_description = "向用户发送问候消息"
|
||||
|
||||
# === 功能描述(必须填写)===
|
||||
action_parameters = {
|
||||
"greeting_message": "要发送的问候消息"
|
||||
}
|
||||
action_require = [
|
||||
"需要发送友好问候时使用",
|
||||
"当有人向你问好时使用",
|
||||
"当你遇见没有见过的人时使用"
|
||||
]
|
||||
action_parameters = {"greeting_message": "要发送的问候消息"}
|
||||
action_require = ["需要发送友好问候时使用", "当有人向你问好时使用", "当你遇见没有见过的人时使用"]
|
||||
associated_types = ["text"]
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
"""执行问候动作 - 这是核心功能"""
|
||||
# 发送问候消息
|
||||
greeting_message = self.action_data.get("greeting_message","")
|
||||
greeting_message = self.action_data.get("greeting_message", "")
|
||||
base_message = self.get_config("greeting.message", "嗨!很开心见到你!😊")
|
||||
message = base_message + greeting_message
|
||||
await self.send_text(message)
|
||||
|
||||
return True, "发送了问候消息"
|
||||
|
||||
|
||||
class ByeAction(BaseAction):
|
||||
"""告别Action - 只在用户说再见时激活"""
|
||||
|
||||
@@ -54,16 +54,17 @@ class ByeAction(BaseAction):
|
||||
"用户要告别时使用",
|
||||
"当有人要离开时使用",
|
||||
"当有人和你说再见时使用",
|
||||
]
|
||||
]
|
||||
associated_types = ["text"]
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
bye_message = self.action_data.get("bye_message","")
|
||||
bye_message = self.action_data.get("bye_message", "")
|
||||
|
||||
message = "再见!期待下次聊天!👋" + bye_message
|
||||
await self.send_text(message)
|
||||
return True, "发送了告别消息"
|
||||
|
||||
|
||||
class TimeCommand(BaseCommand):
|
||||
"""时间查询Command - 响应/time命令"""
|
||||
|
||||
@@ -94,6 +95,7 @@ class TimeCommand(BaseCommand):
|
||||
|
||||
# ===== 插件注册 =====
|
||||
|
||||
|
||||
@register_plugin
|
||||
class HelloWorldPlugin(BasePlugin):
|
||||
"""Hello World插件 - 你的第一个MaiCore插件"""
|
||||
@@ -107,34 +109,20 @@ class HelloWorldPlugin(BasePlugin):
|
||||
config_file_name = "config.toml" # 配置文件名
|
||||
|
||||
# 配置节描述
|
||||
config_section_descriptions = {
|
||||
"plugin": "插件基本信息",
|
||||
"greeting": "问候功能配置",
|
||||
"time": "时间查询配置"
|
||||
}
|
||||
config_section_descriptions = {"plugin": "插件基本信息", "greeting": "问候功能配置", "time": "时间查询配置"}
|
||||
|
||||
# 配置Schema定义
|
||||
config_schema = {
|
||||
"plugin": {
|
||||
"name": ConfigField(type=str, default="hello_world_plugin", description="插件名称"),
|
||||
"version": ConfigField(type=str, default="1.0.0", description="插件版本"),
|
||||
"enabled": ConfigField(type=bool, default=False, description="是否启用插件")
|
||||
"enabled": ConfigField(type=bool, default=False, description="是否启用插件"),
|
||||
},
|
||||
"greeting": {
|
||||
"message": ConfigField(
|
||||
type=str,
|
||||
default="嗨!很开心见到你!😊",
|
||||
description="默认问候消息"
|
||||
),
|
||||
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用表情符号")
|
||||
"message": ConfigField(type=str, default="嗨!很开心见到你!😊", description="默认问候消息"),
|
||||
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用表情符号"),
|
||||
},
|
||||
"time": {
|
||||
"format": ConfigField(
|
||||
type=str,
|
||||
default="%Y-%m-%d %H:%M:%S",
|
||||
description="时间显示格式"
|
||||
)
|
||||
}
|
||||
"time": {"format": ConfigField(type=str, default="%Y-%m-%d %H:%M:%S", description="时间显示格式")},
|
||||
}
|
||||
|
||||
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
- 拍照Action - 生成自拍照
|
||||
- 展示照片Command - 展示最近生成的照片
|
||||
"""
|
||||
|
||||
from typing import List, Tuple, Type, Optional
|
||||
import random
|
||||
import datetime
|
||||
@@ -67,13 +68,9 @@ class TakePictureAction(BaseAction):
|
||||
|
||||
action_parameters = {}
|
||||
|
||||
action_require = [
|
||||
"当用户想看你的照片时使用",
|
||||
"当用户让你发自拍时使用"
|
||||
"当想随手拍眼前的场景时使用"
|
||||
]
|
||||
action_require = ["当用户想看你的照片时使用", "当用户让你发自拍时使用当想随手拍眼前的场景时使用"]
|
||||
|
||||
associated_types = ["text","image"]
|
||||
associated_types = ["text", "image"]
|
||||
|
||||
# 内置的Prompt模板,如果配置文件中没有定义,将使用这些模板
|
||||
DEFAULT_PROMPT_TEMPLATES = [
|
||||
@@ -108,16 +105,12 @@ class TakePictureAction(BaseAction):
|
||||
bot_nickname = self.api.get_global_config("bot.nickname", "麦麦")
|
||||
bot_personality = self.api.get_global_config("personality.personality_core", "")
|
||||
|
||||
|
||||
personality_sides = self.api.get_global_config("personality.personality_sides", [])
|
||||
if personality_sides:
|
||||
bot_personality += random.choice(personality_sides)
|
||||
|
||||
# 准备模板变量
|
||||
template_vars = {
|
||||
"name": bot_nickname,
|
||||
"personality": bot_personality
|
||||
}
|
||||
template_vars = {"name": bot_nickname, "personality": bot_personality}
|
||||
|
||||
logger.info(f"{self.log_prefix} 使用的全局配置: name={bot_nickname}, personality={bot_personality}")
|
||||
|
||||
@@ -229,7 +222,7 @@ class TakePictureAction(BaseAction):
|
||||
async with file_lock:
|
||||
try:
|
||||
if os.path.exists(log_path):
|
||||
with open(log_path, 'r', encoding='utf-8') as f:
|
||||
with open(log_path, "r", encoding="utf-8") as f:
|
||||
log_data = json.load(f)
|
||||
else:
|
||||
log_data = []
|
||||
@@ -237,18 +230,16 @@ class TakePictureAction(BaseAction):
|
||||
log_data = []
|
||||
|
||||
# 添加新照片
|
||||
log_data.append({
|
||||
"prompt": prompt,
|
||||
"image_url": image_url,
|
||||
"timestamp": datetime.datetime.now().isoformat()
|
||||
})
|
||||
log_data.append(
|
||||
{"prompt": prompt, "image_url": image_url, "timestamp": datetime.datetime.now().isoformat()}
|
||||
)
|
||||
|
||||
# 如果超过最大数量,删除最旧的
|
||||
if len(log_data) > max_photos:
|
||||
log_data = sorted(log_data, key=lambda x: x.get('timestamp', ''), reverse=True)[:max_photos]
|
||||
log_data = sorted(log_data, key=lambda x: x.get("timestamp", ""), reverse=True)[:max_photos]
|
||||
|
||||
try:
|
||||
with open(log_path, 'w', encoding='utf-8') as f:
|
||||
with open(log_path, "w", encoding="utf-8") as f:
|
||||
json.dump(log_data, f, ensure_ascii=False, indent=4)
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 写入照片日志文件失败: {e}", exc_info=True)
|
||||
@@ -324,7 +315,7 @@ class TakePictureAction(BaseAction):
|
||||
with urllib.request.urlopen(image_url) as response:
|
||||
image_data = response.read()
|
||||
|
||||
base64_encoded = base64.b64encode(image_data).decode('utf-8')
|
||||
base64_encoded = base64.b64encode(image_data).decode("utf-8")
|
||||
return True, base64_encoded
|
||||
except Exception as e:
|
||||
logger.error(f"图片下载编码失败: {e}", exc_info=True)
|
||||
@@ -403,7 +394,7 @@ class ShowRecentPicturesCommand(BaseCommand):
|
||||
await self.send_text("最近还没有拍过照片哦,快让我自拍一张吧!")
|
||||
return True, "没有照片日志文件"
|
||||
|
||||
with open(log_path, 'r', encoding='utf-8') as f:
|
||||
with open(log_path, "r", encoding="utf-8") as f:
|
||||
log_data = json.load(f)
|
||||
|
||||
if not log_data:
|
||||
@@ -411,7 +402,7 @@ class ShowRecentPicturesCommand(BaseCommand):
|
||||
return True, "没有照片"
|
||||
|
||||
# 获取最新的5张照片
|
||||
recent_pics = sorted(log_data, key=lambda x: x['timestamp'], reverse=True)[:5]
|
||||
recent_pics = sorted(log_data, key=lambda x: x["timestamp"], reverse=True)[:5]
|
||||
|
||||
# 先发送文本消息
|
||||
await self.send_text("这是我最近拍的几张照片~")
|
||||
@@ -419,19 +410,17 @@ class ShowRecentPicturesCommand(BaseCommand):
|
||||
# 逐个发送图片
|
||||
for pic in recent_pics:
|
||||
# 尝试获取图片URL
|
||||
image_url = pic.get('image_url')
|
||||
image_url = pic.get("image_url")
|
||||
if image_url:
|
||||
try:
|
||||
# 下载图片并转换为Base64
|
||||
with urllib.request.urlopen(image_url) as response:
|
||||
image_data = response.read()
|
||||
base64_encoded = base64.b64encode(image_data).decode('utf-8')
|
||||
base64_encoded = base64.b64encode(image_data).decode("utf-8")
|
||||
|
||||
# 发送图片
|
||||
await self.send_type(
|
||||
message_type="image",
|
||||
content=base64_encoded,
|
||||
display_message="发送最近的照片"
|
||||
message_type="image", content=base64_encoded, display_message="发送最近的照片"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 下载或发送照片失败: {e}", exc_info=True)
|
||||
@@ -450,6 +439,7 @@ class ShowRecentPicturesCommand(BaseCommand):
|
||||
@register_plugin
|
||||
class TakePicturePlugin(BasePlugin):
|
||||
"""拍照插件"""
|
||||
|
||||
plugin_name = "take_picture_plugin"
|
||||
plugin_description = "提供生成自拍照和展示最近照片的功能"
|
||||
plugin_version = "1.0.0"
|
||||
@@ -472,7 +462,9 @@ class TakePicturePlugin(BasePlugin):
|
||||
"name": ConfigField(type=str, default="take_picture_plugin", description="插件名称", required=True),
|
||||
"version": ConfigField(type=str, default="1.3.0", description="插件版本号"),
|
||||
"enabled": ConfigField(type=bool, default=False, description="是否启用插件"),
|
||||
"description": ConfigField(type=str, default="提供生成自拍照和展示最近照片的功能", description="插件描述", required=True),
|
||||
"description": ConfigField(
|
||||
type=str, default="提供生成自拍照和展示最近照片的功能", description="插件描述", required=True
|
||||
),
|
||||
},
|
||||
"api": {
|
||||
"base_url": ConfigField(
|
||||
@@ -509,9 +501,7 @@ class TakePicturePlugin(BasePlugin):
|
||||
),
|
||||
"default_seed": ConfigField(type=int, default=42, description="随机种子,用于复现图片"),
|
||||
"prompt_templates": ConfigField(
|
||||
type=list,
|
||||
default=TakePictureAction.DEFAULT_PROMPT_TEMPLATES,
|
||||
description="用于生成自拍照的prompt模板"
|
||||
type=list, default=TakePictureAction.DEFAULT_PROMPT_TEMPLATES, description="用于生成自拍照的prompt模板"
|
||||
),
|
||||
},
|
||||
"storage": {
|
||||
@@ -519,7 +509,7 @@ class TakePicturePlugin(BasePlugin):
|
||||
"log_file": ConfigField(type=str, default="picture_log.json", description="照片日志文件名"),
|
||||
"enable_cache": ConfigField(type=bool, default=True, description="是否启用请求缓存"),
|
||||
"max_cache_size": ConfigField(type=int, default=10, description="最大缓存数量"),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
||||
|
||||
Reference in New Issue
Block a user