add:新增文档变更
This commit is contained in:
@@ -128,146 +128,21 @@ action_require = [
|
||||
associated_types = ["text", "emoji", "image"]
|
||||
```
|
||||
|
||||
### 4. 新API导入必须项
|
||||
|
||||
使用新插件系统时,必须导入所需的API模块:
|
||||
|
||||
```python
|
||||
# 导入新API模块
|
||||
from src.plugin_system.apis import generator_api, send_api, emoji_api
|
||||
|
||||
# 如果需要使用其他API
|
||||
from src.plugin_system.apis import llm_api, database_api, message_api
|
||||
```
|
||||
|
||||
### 5. 动作记录必须项
|
||||
|
||||
每个 Action 在执行完成后,**必须**使用 `store_action_info` 记录动作信息:
|
||||
### 4. 执行方法必须项
|
||||
|
||||
```python
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# ... 执行动作的代码 ...
|
||||
"""
|
||||
执行Action的主要逻辑
|
||||
|
||||
if success:
|
||||
# 存储动作信息 - 使用新API格式
|
||||
await self.store_action_info(
|
||||
action_build_into_prompt=True, # 让麦麦知道这个动作
|
||||
action_prompt_display=f"执行了xxx动作,参数:{param}", # 动作描述
|
||||
action_done=True, # 动作是否完成
|
||||
)
|
||||
return True, "动作执行成功"
|
||||
```
|
||||
Returns:
|
||||
Tuple[bool, str]: (是否成功, 执行结果描述)
|
||||
"""
|
||||
# 执行动作的代码
|
||||
success = True
|
||||
message = "动作执行成功"
|
||||
|
||||
> ⚠️ **重要提示**:新API格式中不再需要手动传递 `thinking_id` 等参数,BaseAction会自动处理。
|
||||
|
||||
## 🚀 新API使用指南
|
||||
|
||||
### 📨 消息发送API
|
||||
|
||||
新的消息发送API更加简洁,自动处理群聊/私聊逻辑:
|
||||
|
||||
```python
|
||||
class MessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 发送文本消息 - 自动判断群聊/私聊
|
||||
await self.send_text("Hello World!")
|
||||
|
||||
# 发送表情包
|
||||
emoji_base64 = await emoji_api.get_by_description("开心")
|
||||
if emoji_base64:
|
||||
await self.send_emoji(emoji_base64)
|
||||
|
||||
# 发送图片
|
||||
await self.send_image(image_base64)
|
||||
|
||||
# 发送自定义类型消息
|
||||
await self.send_custom("video", video_data, typing=True)
|
||||
|
||||
return True, "消息发送完成"
|
||||
```
|
||||
|
||||
### 🤖 智能生成API (replyer_1)
|
||||
|
||||
使用replyer_1生成个性化内容:
|
||||
|
||||
```python
|
||||
class SmartReplyAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 构建生成参数
|
||||
reply_data = {
|
||||
"text": "请生成一个友好的回复",
|
||||
"style": "casual",
|
||||
"topic": "日常聊天",
|
||||
"replyer_name": "replyer_1" # 指定使用replyer_1
|
||||
}
|
||||
|
||||
# 使用generator_api生成回复
|
||||
success, reply_set = await generator_api.generate_reply(
|
||||
chat_stream=self.chat_stream,
|
||||
action_data=reply_data,
|
||||
platform=self.platform,
|
||||
chat_id=self.chat_id,
|
||||
is_group=self.is_group
|
||||
)
|
||||
|
||||
if success and reply_set:
|
||||
# 提取并发送文本回复
|
||||
for reply_type, reply_content in reply_set:
|
||||
if reply_type == "text":
|
||||
await self.send_text(reply_content)
|
||||
elif reply_type == "emoji":
|
||||
await self.send_emoji(reply_content)
|
||||
|
||||
# 记录动作
|
||||
await self.store_action_info(
|
||||
action_build_into_prompt=True,
|
||||
action_prompt_display=f"使用replyer_1生成了智能回复",
|
||||
action_done=True
|
||||
)
|
||||
|
||||
return True, "智能回复生成成功"
|
||||
else:
|
||||
return False, "回复生成失败"
|
||||
```
|
||||
|
||||
### ⚙️ 配置访问API
|
||||
|
||||
使用便捷的配置访问方法:
|
||||
|
||||
```python
|
||||
class ConfigurableAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 获取插件配置 - 支持嵌套键访问
|
||||
enable_feature = self.get_config("features.enable_smart_mode", False)
|
||||
max_length = self.get_config("limits.max_text_length", 200)
|
||||
style = self.get_config("behavior.response_style", "friendly")
|
||||
|
||||
if enable_feature:
|
||||
# 启用高级功能
|
||||
pass
|
||||
|
||||
return True, "配置获取成功"
|
||||
```
|
||||
|
||||
### 📊 数据库API
|
||||
|
||||
使用新的数据库API存储和查询数据:
|
||||
|
||||
```python
|
||||
class DataAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 使用database_api
|
||||
from src.plugin_system.apis import database_api
|
||||
|
||||
# 存储数据
|
||||
await database_api.store_action_info(
|
||||
chat_stream=self.chat_stream,
|
||||
action_name=self.action_name,
|
||||
action_data=self.action_data,
|
||||
# ... 其他参数
|
||||
)
|
||||
|
||||
return True, "数据存储完成"
|
||||
return success, message
|
||||
```
|
||||
|
||||
## 🔧 激活类型详解
|
||||
@@ -286,28 +161,8 @@ class GreetingAction(BaseAction):
|
||||
keyword_case_sensitive = False # 不区分大小写
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 可选:使用replyer_1生成个性化问候
|
||||
if self.get_config("greeting.use_smart_reply", False):
|
||||
greeting_data = {
|
||||
"text": "生成一个友好的问候语",
|
||||
"replyer_name": "replyer_1"
|
||||
}
|
||||
|
||||
success, reply_set = await generator_api.generate_reply(
|
||||
chat_stream=self.chat_stream,
|
||||
action_data=greeting_data
|
||||
)
|
||||
|
||||
if success:
|
||||
for reply_type, content in reply_set:
|
||||
if reply_type == "text":
|
||||
await self.send_text(content)
|
||||
break
|
||||
return True, "发送智能问候"
|
||||
|
||||
# 传统问候方式
|
||||
await self.send_text("你好!很高兴见到你!")
|
||||
return True, "发送问候"
|
||||
# 执行问候逻辑
|
||||
return True, "发送了问候"
|
||||
```
|
||||
|
||||
### LLM_JUDGE激活
|
||||
@@ -330,26 +185,8 @@ class HelpAction(BaseAction):
|
||||
"""
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 使用replyer_1生成帮助内容
|
||||
help_data = {
|
||||
"text": "用户需要帮助,请提供适当的帮助信息",
|
||||
"help_type": self.action_data.get("help_type", "general"),
|
||||
"replyer_name": "replyer_1"
|
||||
}
|
||||
|
||||
success, reply_set = await generator_api.generate_reply(
|
||||
chat_stream=self.chat_stream,
|
||||
action_data=help_data
|
||||
)
|
||||
|
||||
if success:
|
||||
for reply_type, content in reply_set:
|
||||
if reply_type == "text":
|
||||
await self.send_text(content)
|
||||
# 执行帮助逻辑
|
||||
return True, "提供了帮助"
|
||||
else:
|
||||
await self.send_text("我来帮助你!有什么问题吗?")
|
||||
return True, "提供了默认帮助"
|
||||
```
|
||||
|
||||
### RANDOM激活
|
||||
@@ -365,11 +202,181 @@ class SurpriseAction(BaseAction):
|
||||
random_activation_probability = 0.1 # 10%概率激活
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
import random
|
||||
|
||||
surprises = ["🎉", "✨", "🌟", "💝", "🎈"]
|
||||
selected = random.choice(surprises)
|
||||
|
||||
await self.send_emoji(selected)
|
||||
return True, f"发送了惊喜表情: {selected}"
|
||||
# 执行惊喜动作
|
||||
return True, "发送了惊喜内容"
|
||||
```
|
||||
|
||||
### ALWAYS激活
|
||||
|
||||
永远激活,常用于核心功能:
|
||||
|
||||
```python
|
||||
class CoreAction(BaseAction):
|
||||
focus_activation_type = ActionActivationType.ALWAYS
|
||||
normal_activation_type = ActionActivationType.ALWAYS
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 执行核心功能
|
||||
return True, "执行了核心功能"
|
||||
```
|
||||
|
||||
### NEVER激活
|
||||
|
||||
从不激活,用于临时禁用:
|
||||
|
||||
```python
|
||||
class DisabledAction(BaseAction):
|
||||
focus_activation_type = ActionActivationType.NEVER
|
||||
normal_activation_type = ActionActivationType.NEVER
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 这个方法不会被调用
|
||||
return False, "已禁用"
|
||||
```
|
||||
|
||||
## 📚 BaseAction内置属性和方法
|
||||
|
||||
### 内置属性
|
||||
|
||||
```python
|
||||
class MyAction(BaseAction):
|
||||
def __init__(self):
|
||||
# 消息相关属性
|
||||
self.message # 当前消息对象
|
||||
self.chat_stream # 聊天流对象
|
||||
self.user_id # 用户ID
|
||||
self.user_nickname # 用户昵称
|
||||
self.platform # 平台类型 (qq, telegram等)
|
||||
self.chat_id # 聊天ID
|
||||
self.is_group # 是否群聊
|
||||
|
||||
# Action相关属性
|
||||
self.action_data # Action执行时的数据
|
||||
self.thinking_id # 思考ID
|
||||
self.matched_groups # 匹配到的组(如果有正则匹配)
|
||||
```
|
||||
|
||||
### 内置方法
|
||||
|
||||
```python
|
||||
class MyAction(BaseAction):
|
||||
# 配置相关
|
||||
def get_config(self, key: str, default=None):
|
||||
"""获取配置值"""
|
||||
pass
|
||||
|
||||
# 消息发送相关
|
||||
async def send_text(self, text: str):
|
||||
"""发送文本消息"""
|
||||
pass
|
||||
|
||||
async def send_emoji(self, emoji_base64: str):
|
||||
"""发送表情包"""
|
||||
pass
|
||||
|
||||
async def send_image(self, image_base64: str):
|
||||
"""发送图片"""
|
||||
pass
|
||||
|
||||
# 动作记录相关
|
||||
async def store_action_info(self, **kwargs):
|
||||
"""记录动作信息"""
|
||||
pass
|
||||
```
|
||||
|
||||
## 🎯 完整Action示例
|
||||
|
||||
```python
|
||||
from src.plugin_system import BaseAction, ActionActivationType, ChatMode
|
||||
from typing import Tuple
|
||||
|
||||
class ExampleAction(BaseAction):
|
||||
"""示例Action - 展示完整的Action结构"""
|
||||
|
||||
# === 激活控制 ===
|
||||
focus_activation_type = ActionActivationType.LLM_JUDGE
|
||||
normal_activation_type = ActionActivationType.KEYWORD
|
||||
mode_enable = ChatMode.ALL
|
||||
parallel_action = False
|
||||
|
||||
# 关键词激活配置
|
||||
activation_keywords = ["示例", "测试", "example"]
|
||||
keyword_case_sensitive = False
|
||||
|
||||
# LLM判断提示词
|
||||
llm_judge_prompt = "当用户需要示例或测试功能时激活"
|
||||
|
||||
# 随机激活概率(如果使用RANDOM类型)
|
||||
random_activation_probability = 0.2
|
||||
|
||||
# === 基本信息 ===
|
||||
action_name = "example_action"
|
||||
action_description = "这是一个示例Action,用于演示Action的完整结构"
|
||||
|
||||
# === 功能定义 ===
|
||||
action_parameters = {
|
||||
"content": "要处理的内容",
|
||||
"type": "处理类型",
|
||||
"options": "可选配置"
|
||||
}
|
||||
|
||||
action_require = [
|
||||
"用户需要示例功能时使用",
|
||||
"适合用于测试和演示",
|
||||
"不要在正式对话中频繁使用"
|
||||
]
|
||||
|
||||
associated_types = ["text", "emoji"]
|
||||
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
"""执行示例Action"""
|
||||
try:
|
||||
# 获取Action参数
|
||||
content = self.action_data.get("content", "默认内容")
|
||||
action_type = self.action_data.get("type", "default")
|
||||
|
||||
# 获取配置
|
||||
enable_feature = self.get_config("example.enable_advanced", False)
|
||||
max_length = self.get_config("example.max_length", 100)
|
||||
|
||||
# 执行具体逻辑
|
||||
if action_type == "greeting":
|
||||
await self.send_text(f"你好!这是示例内容:{content}")
|
||||
elif action_type == "info":
|
||||
await self.send_text(f"信息:{content[:max_length]}")
|
||||
else:
|
||||
await self.send_text("执行了示例Action")
|
||||
|
||||
# 记录动作信息
|
||||
await self.store_action_info(
|
||||
action_build_into_prompt=True,
|
||||
action_prompt_display=f"执行了示例动作:{action_type}",
|
||||
action_done=True
|
||||
)
|
||||
|
||||
return True, f"示例Action执行成功,类型:{action_type}"
|
||||
|
||||
except Exception as e:
|
||||
return False, f"执行失败:{str(e)}"
|
||||
```
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 1. Action设计原则
|
||||
|
||||
- **单一职责**:每个Action只负责一个明确的功能
|
||||
- **智能激活**:合理选择激活类型,避免过度激活
|
||||
- **清晰描述**:提供准确的`action_require`帮助LLM决策
|
||||
- **错误处理**:妥善处理执行过程中的异常情况
|
||||
|
||||
### 2. 性能优化
|
||||
|
||||
- **激活控制**:使用合适的激活类型减少不必要的LLM调用
|
||||
- **并行执行**:谨慎设置`parallel_action`,避免冲突
|
||||
- **资源管理**:及时释放占用的资源
|
||||
|
||||
### 3. 调试技巧
|
||||
|
||||
- **日志记录**:在关键位置添加日志
|
||||
- **参数验证**:检查`action_data`的有效性
|
||||
- **配置测试**:测试不同配置下的行为
|
||||
|
||||
@@ -1,398 +1,311 @@
|
||||
# 📡 消息API
|
||||
# 消息API
|
||||
|
||||
## 📖 概述
|
||||
> 消息API提供了强大的消息查询、计数和格式化功能,让你轻松处理聊天消息数据。
|
||||
|
||||
消息API提供了发送各种类型消息的接口,支持文本、表情、图片等多种消息类型。新版API格式更加简洁直观,自动处理群聊/私聊判断。
|
||||
|
||||
## 🔄 基础消息发送
|
||||
|
||||
### 发送文本消息
|
||||
## 导入方式
|
||||
|
||||
```python
|
||||
# 新API格式 - 自动判断群聊/私聊
|
||||
await self.send_text("这是一条文本消息")
|
||||
|
||||
# 发送多行文本
|
||||
message = """
|
||||
这是第一行
|
||||
这是第二行
|
||||
这是第三行
|
||||
"""
|
||||
await self.send_text(message.strip())
|
||||
from src.plugin_system.apis import message_api
|
||||
```
|
||||
|
||||
### 发送表情消息
|
||||
## 功能概述
|
||||
|
||||
消息API主要提供三大类功能:
|
||||
- **消息查询** - 按时间、聊天、用户等条件查询消息
|
||||
- **消息计数** - 统计新消息数量
|
||||
- **消息格式化** - 将消息转换为可读格式
|
||||
|
||||
---
|
||||
|
||||
## 消息查询API
|
||||
|
||||
### 按时间查询消息
|
||||
|
||||
#### `get_messages_by_time(start_time, end_time, limit=0, limit_mode="latest")`
|
||||
|
||||
获取指定时间范围内的消息
|
||||
|
||||
**参数:**
|
||||
- `start_time` (float): 开始时间戳
|
||||
- `end_time` (float): 结束时间戳
|
||||
- `limit` (int): 限制返回消息数量,0为不限制
|
||||
- `limit_mode` (str): 限制模式,`"earliest"`获取最早记录,`"latest"`获取最新记录
|
||||
|
||||
**返回:** `List[Dict[str, Any]]` - 消息列表
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 新API格式 - 发送表情
|
||||
await self.send_emoji("😊")
|
||||
await self.send_emoji("🎉")
|
||||
await self.send_emoji("👋")
|
||||
import time
|
||||
|
||||
# 获取最近24小时的消息
|
||||
now = time.time()
|
||||
yesterday = now - 24 * 3600
|
||||
messages = message_api.get_messages_by_time(yesterday, now, limit=50)
|
||||
```
|
||||
|
||||
### 发送特定类型消息
|
||||
### 按聊天查询消息
|
||||
|
||||
#### `get_messages_by_time_in_chat(chat_id, start_time, end_time, limit=0, limit_mode="latest")`
|
||||
|
||||
获取指定聊天中指定时间范围内的消息
|
||||
|
||||
**参数:**
|
||||
- `chat_id` (str): 聊天ID
|
||||
- 其他参数同上
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 发送图片
|
||||
await self.send_type("image", "https://example.com/image.jpg")
|
||||
|
||||
# 发送音频
|
||||
await self.send_type("audio", "audio_file_path")
|
||||
|
||||
# 发送视频
|
||||
await self.send_type("video", "video_file_path")
|
||||
|
||||
# 发送文件
|
||||
await self.send_type("file", "file_path")
|
||||
```
|
||||
|
||||
## 🎯 跨目标消息发送
|
||||
|
||||
### 使用send_api模块发送消息
|
||||
|
||||
```python
|
||||
# 导入send_api
|
||||
from src.plugin_system.apis import send_api
|
||||
|
||||
# 向指定群聊发送文本消息
|
||||
success = await send_api.text_to_group(
|
||||
text="这是发送到群聊的消息",
|
||||
group_id="123456789",
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
# 向指定用户发送私聊消息
|
||||
success = await send_api.text_to_user(
|
||||
text="这是私聊消息",
|
||||
user_id="987654321",
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
# 向指定群聊发送表情
|
||||
success = await send_api.emoji_to_group(
|
||||
emoji="😊",
|
||||
group_id="123456789",
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
# 向指定用户发送表情
|
||||
success = await send_api.emoji_to_user(
|
||||
emoji="🎉",
|
||||
user_id="987654321",
|
||||
platform="qq"
|
||||
# 获取某个群聊最近的100条消息
|
||||
messages = message_api.get_messages_by_time_in_chat(
|
||||
chat_id="123456789",
|
||||
start_time=yesterday,
|
||||
end_time=now,
|
||||
limit=100
|
||||
)
|
||||
```
|
||||
|
||||
### 通用目标消息发送
|
||||
#### `get_messages_by_time_in_chat_inclusive(chat_id, start_time, end_time, limit=0, limit_mode="latest")`
|
||||
|
||||
获取指定聊天中指定时间范围内的消息(包含边界时间点)
|
||||
|
||||
与 `get_messages_by_time_in_chat` 类似,但包含边界时间戳的消息。
|
||||
|
||||
#### `get_recent_messages(chat_id, hours=24.0, limit=100, limit_mode="latest")`
|
||||
|
||||
获取指定聊天中最近一段时间的消息(便捷方法)
|
||||
|
||||
**参数:**
|
||||
- `chat_id` (str): 聊天ID
|
||||
- `hours` (float): 最近多少小时,默认24小时
|
||||
- `limit` (int): 限制返回消息数量,默认100条
|
||||
- `limit_mode` (str): 限制模式
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 向任意目标发送任意类型消息
|
||||
success = await send_api.message_to_target(
|
||||
message_type="text", # 消息类型
|
||||
content="消息内容", # 消息内容
|
||||
platform="qq", # 平台
|
||||
target_id="123456789", # 目标ID
|
||||
is_group=True, # 是否为群聊
|
||||
display_message="显示消息" # 可选:显示消息
|
||||
# 获取最近6小时的消息
|
||||
recent_messages = message_api.get_recent_messages(
|
||||
chat_id="123456789",
|
||||
hours=6.0,
|
||||
limit=50
|
||||
)
|
||||
```
|
||||
|
||||
## 📨 消息类型支持
|
||||
### 按用户查询消息
|
||||
|
||||
### 支持的消息类型
|
||||
#### `get_messages_by_time_in_chat_for_users(chat_id, start_time, end_time, person_ids, limit=0, limit_mode="latest")`
|
||||
|
||||
| 类型 | 说明 | 新API方法 | send_api方法 |
|
||||
|-----|------|----------|-------------|
|
||||
| `text` | 普通文本消息 | `await self.send_text()` | `await send_api.text_to_group()` |
|
||||
| `emoji` | 表情消息 | `await self.send_emoji()` | `await send_api.emoji_to_group()` |
|
||||
| `image` | 图片消息 | `await self.send_type("image", url)` | `await send_api.message_to_target()` |
|
||||
| `audio` | 音频消息 | `await self.send_type("audio", path)` | `await send_api.message_to_target()` |
|
||||
| `video` | 视频消息 | `await self.send_type("video", path)` | `await send_api.message_to_target()` |
|
||||
| `file` | 文件消息 | `await self.send_type("file", path)` | `await send_api.message_to_target()` |
|
||||
获取指定聊天中指定用户在指定时间范围内的消息
|
||||
|
||||
### 新API格式示例
|
||||
**参数:**
|
||||
- `chat_id` (str): 聊天ID
|
||||
- `start_time` (float): 开始时间戳
|
||||
- `end_time` (float): 结束时间戳
|
||||
- `person_ids` (list): 用户ID列表
|
||||
- `limit` (int): 限制返回消息数量
|
||||
- `limit_mode` (str): 限制模式
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
class ExampleAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 文本消息 - 最常用
|
||||
await self.send_text("普通文本消息")
|
||||
|
||||
# 表情消息 - 直接方法
|
||||
await self.send_emoji("🎉")
|
||||
|
||||
# 图片消息
|
||||
await self.send_type("image", "/path/to/image.jpg")
|
||||
|
||||
# 音频消息
|
||||
await self.send_type("audio", "/path/to/audio.mp3")
|
||||
|
||||
# 文件消息
|
||||
await self.send_type("file", "/path/to/document.pdf")
|
||||
|
||||
return True, "发送了多种类型的消息"
|
||||
# 获取特定用户的消息
|
||||
user_messages = message_api.get_messages_by_time_in_chat_for_users(
|
||||
chat_id="123456789",
|
||||
start_time=yesterday,
|
||||
end_time=now,
|
||||
person_ids=["user1", "user2"]
|
||||
)
|
||||
```
|
||||
|
||||
## 🔍 消息信息获取
|
||||
#### `get_messages_by_time_for_users(start_time, end_time, person_ids, limit=0, limit_mode="latest")`
|
||||
|
||||
### 获取当前消息信息
|
||||
获取指定用户在所有聊天中指定时间范围内的消息
|
||||
|
||||
### 其他查询方法
|
||||
|
||||
#### `get_random_chat_messages(start_time, end_time, limit=0, limit_mode="latest")`
|
||||
|
||||
随机选择一个聊天,返回该聊天在指定时间范围内的消息
|
||||
|
||||
#### `get_messages_before_time(timestamp, limit=0)`
|
||||
|
||||
获取指定时间戳之前的消息
|
||||
|
||||
#### `get_messages_before_time_in_chat(chat_id, timestamp, limit=0)`
|
||||
|
||||
获取指定聊天中指定时间戳之前的消息
|
||||
|
||||
#### `get_messages_before_time_for_users(timestamp, person_ids, limit=0)`
|
||||
|
||||
获取指定用户在指定时间戳之前的消息
|
||||
|
||||
---
|
||||
|
||||
## 消息计数API
|
||||
|
||||
### `count_new_messages(chat_id, start_time=0.0, end_time=None)`
|
||||
|
||||
计算指定聊天中从开始时间到结束时间的新消息数量
|
||||
|
||||
**参数:**
|
||||
- `chat_id` (str): 聊天ID
|
||||
- `start_time` (float): 开始时间戳
|
||||
- `end_time` (float): 结束时间戳,如果为None则使用当前时间
|
||||
|
||||
**返回:** `int` - 新消息数量
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 新API格式 - 直接属性访问
|
||||
class ExampleCommand(BaseCommand):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 用户信息
|
||||
user_id = self.user_id
|
||||
user_nickname = self.user_nickname
|
||||
|
||||
# 聊天信息
|
||||
is_group_chat = self.is_group
|
||||
chat_id = self.chat_id
|
||||
platform = self.platform
|
||||
|
||||
# 消息内容
|
||||
message_text = self.message.processed_plain_text
|
||||
|
||||
# 构建信息显示
|
||||
info = f"""
|
||||
👤 用户: {user_nickname}({user_id})
|
||||
💬 类型: {'群聊' if is_group_chat else '私聊'}
|
||||
📱 平台: {platform}
|
||||
📝 内容: {message_text}
|
||||
""".strip()
|
||||
|
||||
await self.send_text(info)
|
||||
return True, "显示了消息信息"
|
||||
# 计算最近1小时的新消息数
|
||||
import time
|
||||
now = time.time()
|
||||
hour_ago = now - 3600
|
||||
new_count = message_api.count_new_messages("123456789", hour_ago, now)
|
||||
print(f"最近1小时有{new_count}条新消息")
|
||||
```
|
||||
|
||||
### 获取群聊信息(如果适用)
|
||||
### `count_new_messages_for_users(chat_id, start_time, end_time, person_ids)`
|
||||
|
||||
计算指定聊天中指定用户从开始时间到结束时间的新消息数量
|
||||
|
||||
---
|
||||
|
||||
## 消息格式化API
|
||||
|
||||
### `build_readable_messages_to_str(messages, **options)`
|
||||
|
||||
将消息列表构建成可读的字符串
|
||||
|
||||
**参数:**
|
||||
- `messages` (List[Dict[str, Any]]): 消息列表
|
||||
- `replace_bot_name` (bool): 是否将机器人的名称替换为"你",默认True
|
||||
- `merge_messages` (bool): 是否合并连续消息,默认False
|
||||
- `timestamp_mode` (str): 时间戳显示模式,`"relative"`或`"absolute"`,默认`"relative"`
|
||||
- `read_mark` (float): 已读标记时间戳,用于分割已读和未读消息,默认0.0
|
||||
- `truncate` (bool): 是否截断长消息,默认False
|
||||
- `show_actions` (bool): 是否显示动作记录,默认False
|
||||
|
||||
**返回:** `str` - 格式化后的可读字符串
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 在Action或Command中检查群聊信息
|
||||
if self.is_group:
|
||||
group_info = self.message.message_info.group_info
|
||||
if group_info:
|
||||
group_id = group_info.group_id
|
||||
group_name = getattr(group_info, 'group_name', '未知群聊')
|
||||
|
||||
await self.send_text(f"当前群聊: {group_name}({group_id})")
|
||||
else:
|
||||
await self.send_text("当前是私聊对话")
|
||||
# 获取消息并格式化为可读文本
|
||||
messages = message_api.get_recent_messages("123456789", hours=2)
|
||||
readable_text = message_api.build_readable_messages_to_str(
|
||||
messages,
|
||||
replace_bot_name=True,
|
||||
merge_messages=True,
|
||||
timestamp_mode="relative"
|
||||
)
|
||||
print(readable_text)
|
||||
```
|
||||
|
||||
## 🌐 平台支持
|
||||
### `build_readable_messages_with_details(messages, **options)` 异步
|
||||
|
||||
### 支持的平台
|
||||
将消息列表构建成可读的字符串,并返回详细信息
|
||||
|
||||
| 平台 | 标识 | 说明 |
|
||||
|-----|------|------|
|
||||
| QQ | `qq` | QQ聊天平台 |
|
||||
| 微信 | `wechat` | 微信聊天平台 |
|
||||
| Discord | `discord` | Discord聊天平台 |
|
||||
**参数:** 与 `build_readable_messages_to_str` 类似,但不包含 `read_mark` 和 `show_actions`
|
||||
|
||||
### 平台适配示例
|
||||
**返回:** `Tuple[str, List[Tuple[float, str, str]]]` - 格式化字符串和详细信息元组列表(时间戳, 昵称, 内容)
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
class PlatformAdaptiveAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 获取当前平台
|
||||
current_platform = self.platform
|
||||
# 异步获取详细格式化信息
|
||||
readable_text, details = await message_api.build_readable_messages_with_details(
|
||||
messages,
|
||||
timestamp_mode="absolute"
|
||||
)
|
||||
|
||||
# 根据平台调整消息格式
|
||||
if current_platform == "qq":
|
||||
await self.send_text("[QQ] 这是QQ平台的消息")
|
||||
await self.send_emoji("🐧") # QQ企鹅表情
|
||||
elif current_platform == "wechat":
|
||||
await self.send_text("【微信】这是微信平台的消息")
|
||||
await self.send_emoji("💬") # 微信气泡表情
|
||||
elif current_platform == "discord":
|
||||
await self.send_text("**Discord** 这是Discord平台的消息")
|
||||
await self.send_emoji("🎮") # Discord游戏表情
|
||||
else:
|
||||
await self.send_text(f"未知平台: {current_platform}")
|
||||
|
||||
return True, f"发送了{current_platform}平台适配消息"
|
||||
for timestamp, nickname, content in details:
|
||||
print(f"{timestamp}: {nickname} 说: {content}")
|
||||
```
|
||||
|
||||
## 🎨 消息格式化和高级功能
|
||||
### `get_person_ids_from_messages(messages)` 异步
|
||||
|
||||
### 长消息分割
|
||||
从消息列表中提取不重复的用户ID列表
|
||||
|
||||
**参数:**
|
||||
- `messages` (List[Dict[str, Any]]): 消息列表
|
||||
|
||||
**返回:** `List[str]` - 用户ID列表
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
# 自动处理长消息分割
|
||||
long_message = "这是一条很长的消息..." * 100
|
||||
|
||||
# 新API会自动处理长消息分割
|
||||
await self.send_text(long_message)
|
||||
# 获取参与对话的所有用户ID
|
||||
messages = message_api.get_recent_messages("123456789")
|
||||
person_ids = await message_api.get_person_ids_from_messages(messages)
|
||||
print(f"参与对话的用户: {person_ids}")
|
||||
```
|
||||
|
||||
### 消息模板和格式化
|
||||
---
|
||||
|
||||
## 完整使用示例
|
||||
|
||||
### 场景1:统计活跃度
|
||||
|
||||
```python
|
||||
class TemplateMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 使用配置中的消息模板
|
||||
template = self.get_config("messages.greeting_template", "你好 {username}!")
|
||||
import time
|
||||
from src.plugin_system.apis import message_api
|
||||
|
||||
# 格式化消息
|
||||
formatted_message = template.format(
|
||||
username=self.user_nickname,
|
||||
time=datetime.now().strftime("%H:%M"),
|
||||
platform=self.platform
|
||||
async def analyze_chat_activity(chat_id: str):
|
||||
"""分析聊天活跃度"""
|
||||
now = time.time()
|
||||
day_ago = now - 24 * 3600
|
||||
|
||||
# 获取最近24小时的消息
|
||||
messages = message_api.get_recent_messages(chat_id, hours=24)
|
||||
|
||||
# 统计消息数量
|
||||
total_count = len(messages)
|
||||
|
||||
# 获取参与用户
|
||||
person_ids = await message_api.get_person_ids_from_messages(messages)
|
||||
|
||||
# 格式化消息内容
|
||||
readable_text = message_api.build_readable_messages_to_str(
|
||||
messages[-10:], # 最后10条消息
|
||||
merge_messages=True,
|
||||
timestamp_mode="relative"
|
||||
)
|
||||
|
||||
await self.send_text(formatted_message)
|
||||
|
||||
# 根据配置决定是否发送表情
|
||||
if self.get_config("messages.include_emoji", True):
|
||||
await self.send_emoji("😊")
|
||||
|
||||
return True, "发送了模板化消息"
|
||||
return {
|
||||
"total_messages": total_count,
|
||||
"active_users": len(person_ids),
|
||||
"recent_chat": readable_text
|
||||
}
|
||||
```
|
||||
|
||||
### 条件消息发送
|
||||
### 场景2:查看特定用户的历史消息
|
||||
|
||||
```python
|
||||
class ConditionalMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 根据用户类型发送不同消息
|
||||
if self.is_group:
|
||||
await self.send_text(f"群聊消息 - 当前群成员: @{self.user_nickname}")
|
||||
else:
|
||||
await self.send_text(f"私聊消息 - 你好 {self.user_nickname}!")
|
||||
def get_user_history(chat_id: str, user_id: str, days: int = 7):
|
||||
"""获取用户最近N天的消息历史"""
|
||||
now = time.time()
|
||||
start_time = now - days * 24 * 3600
|
||||
|
||||
# 根据时间发送不同表情
|
||||
from datetime import datetime
|
||||
hour = datetime.now().hour
|
||||
# 获取特定用户的消息
|
||||
user_messages = message_api.get_messages_by_time_in_chat_for_users(
|
||||
chat_id=chat_id,
|
||||
start_time=start_time,
|
||||
end_time=now,
|
||||
person_ids=[user_id],
|
||||
limit=100
|
||||
)
|
||||
|
||||
if 6 <= hour < 12:
|
||||
await self.send_emoji("🌅") # 早上
|
||||
elif 12 <= hour < 18:
|
||||
await self.send_emoji("☀️") # 下午
|
||||
else:
|
||||
await self.send_emoji("🌙") # 晚上
|
||||
# 格式化为可读文本
|
||||
readable_history = message_api.build_readable_messages_to_str(
|
||||
user_messages,
|
||||
replace_bot_name=False,
|
||||
timestamp_mode="absolute"
|
||||
)
|
||||
|
||||
return True, "发送了条件化消息"
|
||||
return readable_history
|
||||
```
|
||||
|
||||
## 🛠️ 高级消息发送功能
|
||||
---
|
||||
|
||||
### 批量消息发送
|
||||
## 注意事项
|
||||
|
||||
```python
|
||||
class BatchMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
messages = [
|
||||
("text", "第一条消息"),
|
||||
("emoji", "🎉"),
|
||||
("text", "第二条消息"),
|
||||
("emoji", "✨")
|
||||
]
|
||||
|
||||
for msg_type, content in messages:
|
||||
if msg_type == "text":
|
||||
await self.send_text(content)
|
||||
elif msg_type == "emoji":
|
||||
await self.send_emoji(content)
|
||||
|
||||
# 可选:添加延迟避免消息发送过快
|
||||
import asyncio
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
return True, "发送了批量消息"
|
||||
```
|
||||
|
||||
### 错误处理和重试
|
||||
|
||||
```python
|
||||
class ReliableMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
max_retries = 3
|
||||
retry_count = 0
|
||||
|
||||
while retry_count < max_retries:
|
||||
try:
|
||||
await self.send_text("重要消息")
|
||||
return True, "消息发送成功"
|
||||
except Exception as e:
|
||||
retry_count += 1
|
||||
logger.warning(f"消息发送失败 (尝试 {retry_count}/{max_retries}): {e}")
|
||||
|
||||
if retry_count < max_retries:
|
||||
import asyncio
|
||||
await asyncio.sleep(1) # 等待1秒后重试
|
||||
|
||||
return False, "消息发送失败,已达到最大重试次数"
|
||||
```
|
||||
|
||||
## 📝 最佳实践
|
||||
|
||||
### 1. 消息发送最佳实践
|
||||
|
||||
```python
|
||||
# ✅ 好的做法
|
||||
class GoodMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 1. 检查配置
|
||||
if not self.get_config("features.enable_messages", True):
|
||||
return True, "消息功能已禁用"
|
||||
|
||||
# 2. 简洁的消息发送
|
||||
await self.send_text("简洁明了的消息")
|
||||
|
||||
# 3. 适当的表情使用
|
||||
if self.get_config("features.enable_emoji", True):
|
||||
await self.send_emoji("😊")
|
||||
|
||||
return True, "消息发送完成"
|
||||
|
||||
# ❌ 避免的做法
|
||||
class BadMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 避免:过长的消息
|
||||
await self.send_text("这是一条非常非常长的消息" * 50)
|
||||
|
||||
# 避免:过多的表情
|
||||
for emoji in ["😊", "🎉", "✨", "🌟", "💫"]:
|
||||
await self.send_emoji(emoji)
|
||||
|
||||
return True, "发送了糟糕的消息"
|
||||
```
|
||||
|
||||
### 2. 错误处理
|
||||
|
||||
```python
|
||||
# ✅ 推荐的错误处理
|
||||
class SafeMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
try:
|
||||
message = self.get_config("messages.default", "默认消息")
|
||||
await self.send_text(message)
|
||||
return True, "消息发送成功"
|
||||
except Exception as e:
|
||||
logger.error(f"消息发送失败: {e}")
|
||||
# 可选:发送备用消息
|
||||
await self.send_text("消息发送遇到问题,请稍后再试")
|
||||
return False, f"发送失败: {str(e)}"
|
||||
```
|
||||
|
||||
### 3. 性能优化
|
||||
|
||||
```python
|
||||
# ✅ 性能友好的消息发送
|
||||
class OptimizedMessageAction(BaseAction):
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
# 合并多个短消息为一条长消息
|
||||
parts = [
|
||||
"第一部分信息",
|
||||
"第二部分信息",
|
||||
"第三部分信息"
|
||||
]
|
||||
|
||||
combined_message = "\n".join(parts)
|
||||
await self.send_text(combined_message)
|
||||
|
||||
return True, "发送了优化的消息"
|
||||
```
|
||||
|
||||
通过新的API格式,消息发送变得更加简洁高效!
|
||||
1. **时间戳格式**:所有时间参数都使用Unix时间戳(float类型)
|
||||
2. **异步函数**:`build_readable_messages_with_details` 和 `get_person_ids_from_messages` 是异步函数,需要使用 `await`
|
||||
3. **性能考虑**:查询大量消息时建议设置合理的 `limit` 参数
|
||||
4. **消息格式**:返回的消息是字典格式,包含时间戳、发送者、内容等信息
|
||||
5. **用户ID**:`person_ids` 参数接受字符串列表,用于筛选特定用户的消息
|
||||
@@ -15,7 +15,7 @@ Command是直接响应用户明确指令的组件,与Action不同,Command是
|
||||
## 🆚 Action vs Command 核心区别
|
||||
|
||||
| 特征 | Action | Command |
|
||||
|-----|-------|---------|
|
||||
| ------------------ | --------------------- | ---------------- |
|
||||
| **触发方式** | 麦麦主动决策使用 | 用户主动触发 |
|
||||
| **决策机制** | 两层决策(激活+使用) | 直接匹配执行 |
|
||||
| **随机性** | 有随机性和智能性 | 确定性执行 |
|
||||
@@ -51,7 +51,7 @@ class MyCommand(BaseCommand):
|
||||
### 属性说明
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|-----|------|------|
|
||||
| --------------------- | --------- | -------------------- |
|
||||
| `command_pattern` | str | 正则表达式匹配模式 |
|
||||
| `command_help` | str | 命令帮助说明 |
|
||||
| `command_examples` | List[str] | 使用示例列表 |
|
||||
@@ -148,7 +148,7 @@ class LogCommand(BaseCommand):
|
||||
### 拦截控制的用途
|
||||
|
||||
| 场景 | intercept_message | 说明 |
|
||||
|-----|------------------|------|
|
||||
| -------- | ----------------- | -------------------------- |
|
||||
| 系统命令 | True | 防止命令被当作普通消息处理 |
|
||||
| 查询命令 | True | 直接返回结果,无需后续处理 |
|
||||
| 日志命令 | False | 记录但允许消息继续流转 |
|
||||
@@ -386,55 +386,6 @@ class CustomPrefixCommand(BaseCommand):
|
||||
return True, f"投掷了{count}面骰子,结果{result}"
|
||||
```
|
||||
|
||||
## 🔧 新API格式使用指南
|
||||
|
||||
### 消息发送
|
||||
|
||||
```python
|
||||
# 新API格式 ✅
|
||||
await self.send_text("消息内容")
|
||||
await self.send_emoji("😊")
|
||||
|
||||
# 旧API格式 ❌
|
||||
await self.api.send_text_to_group("消息内容", group_id, "qq")
|
||||
```
|
||||
|
||||
### 配置访问
|
||||
|
||||
```python
|
||||
# 新API格式 ✅
|
||||
config_value = self.get_config("section.key", "default_value")
|
||||
|
||||
# 旧API格式 ❌
|
||||
config_value = self.api.get_config("section.key", "default_value")
|
||||
```
|
||||
|
||||
### 用户信息获取
|
||||
|
||||
```python
|
||||
# 新API格式 ✅
|
||||
user_id = self.user_id
|
||||
user_nickname = self.user_nickname
|
||||
is_group_chat = self.is_group
|
||||
|
||||
# 旧API格式 ❌
|
||||
user_id = self.message.message_info.user_info.user_id
|
||||
```
|
||||
|
||||
### 动作记录
|
||||
|
||||
```python
|
||||
# 新API格式 ✅ (在Action中)
|
||||
await self.store_action_info(
|
||||
action_build_into_prompt=True,
|
||||
action_prompt_display="执行了某操作",
|
||||
action_done=True
|
||||
)
|
||||
|
||||
# 旧API格式 ❌
|
||||
await self.api.store_action_info(...)
|
||||
```
|
||||
|
||||
## 📊 性能优化建议
|
||||
|
||||
### 1. 正则表达式优化
|
||||
@@ -479,8 +430,6 @@ async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
return False, f"执行失败: {e}"
|
||||
```
|
||||
|
||||
通过新的API格式,Command开发变得更加简洁和直观!
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 1. 命令设计原则
|
||||
@@ -535,8 +484,8 @@ async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
```python
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
# 从配置读取设置
|
||||
max_items = self.api.get_config("command.max_items", 10)
|
||||
timeout = self.api.get_config("command.timeout", 30)
|
||||
max_items = self.get_config("command.max_items", 10)
|
||||
timeout = self.get_config("command.timeout", 30)
|
||||
|
||||
# 使用配置进行处理
|
||||
...
|
||||
|
||||
@@ -8,10 +8,28 @@
|
||||
|
||||
## 📖 目录
|
||||
|
||||
1. [配置定义:Schema驱动的配置系统](#配置定义schema驱动的配置系统)
|
||||
2. [配置访问:在Action和Command中使用配置](#配置访问在action和command中使用配置)
|
||||
3. [完整示例:从定义到使用](#完整示例从定义到使用)
|
||||
4. [最佳实践与注意事项](#最佳实践与注意事项)
|
||||
1. [配置架构变更说明](#配置架构变更说明)
|
||||
2. [配置定义:Schema驱动的配置系统](#配置定义schema驱动的配置系统)
|
||||
3. [配置访问:在Action和Command中使用配置](#配置访问在action和command中使用配置)
|
||||
4. [完整示例:从定义到使用](#完整示例从定义到使用)
|
||||
5. [最佳实践与注意事项](#最佳实践与注意事项)
|
||||
|
||||
---
|
||||
|
||||
## 配置架构变更说明
|
||||
|
||||
- **`_manifest.json`** - 负责插件的**元数据信息**(静态)
|
||||
- 插件名称、版本、描述
|
||||
- 作者信息、许可证
|
||||
- 仓库链接、关键词、分类
|
||||
- 组件列表、兼容性信息
|
||||
|
||||
- **`config.toml`** - 负责插件的**运行时配置**(动态)
|
||||
- `enabled` - 是否启用插件
|
||||
- 功能参数配置
|
||||
- 组件启用开关
|
||||
- 用户可调整的行为参数
|
||||
|
||||
|
||||
---
|
||||
|
||||
@@ -101,7 +119,7 @@ class MutePlugin(BasePlugin):
|
||||
|
||||
# 步骤1: 定义配置节的描述
|
||||
config_section_descriptions = {
|
||||
"plugin": "插件基本信息配置",
|
||||
"plugin": "插件启用配置",
|
||||
"components": "组件启用控制",
|
||||
"mute": "核心禁言功能配置",
|
||||
"smart_mute": "智能禁言Action的专属配置",
|
||||
@@ -111,10 +129,7 @@ class MutePlugin(BasePlugin):
|
||||
# 步骤2: 使用ConfigField定义详细的配置Schema
|
||||
config_schema = {
|
||||
"plugin": {
|
||||
"name": ConfigField(type=str, default="mute_plugin", description="插件名称", required=True),
|
||||
"version": ConfigField(type=str, default="2.0.0", description="插件版本号"),
|
||||
"enabled": ConfigField(type=bool, default=False, description="是否启用插件"),
|
||||
"description": ConfigField(type=str, default="群聊禁言管理插件", description="插件描述", required=True)
|
||||
"enabled": ConfigField(type=bool, default=False, description="是否启用插件")
|
||||
},
|
||||
"components": {
|
||||
"enable_smart_mute": ConfigField(type=bool, default=True, description="是否启用智能禁言Action"),
|
||||
@@ -170,21 +185,12 @@ class MutePlugin(BasePlugin):
|
||||
# mute_plugin - 自动生成的配置文件
|
||||
# 群聊禁言管理插件,提供智能禁言功能
|
||||
|
||||
# 插件基本信息配置
|
||||
# 插件启用配置
|
||||
[plugin]
|
||||
|
||||
# 插件名称 (必需)
|
||||
name = "mute_plugin"
|
||||
|
||||
# 插件版本号
|
||||
version = "2.0.0"
|
||||
|
||||
# 是否启用插件
|
||||
enabled = false
|
||||
|
||||
# 插件描述 (必需)
|
||||
description = "群聊禁言管理插件"
|
||||
|
||||
|
||||
# 组件启用控制
|
||||
[components]
|
||||
@@ -378,7 +384,7 @@ class GreetingPlugin(BasePlugin):
|
||||
|
||||
# 配置节描述
|
||||
config_section_descriptions = {
|
||||
"plugin": "插件基本信息",
|
||||
"plugin": "插件启用配置",
|
||||
"greeting": "问候功能配置",
|
||||
"features": "功能开关配置",
|
||||
"messages": "消息模板配置"
|
||||
@@ -387,8 +393,7 @@ class GreetingPlugin(BasePlugin):
|
||||
# 配置Schema定义
|
||||
config_schema = {
|
||||
"plugin": {
|
||||
"enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
||||
"version": ConfigField(type=str, default="1.0.0", description="插件版本")
|
||||
"enabled": ConfigField(type=bool, default=True, description="是否启用插件")
|
||||
},
|
||||
"greeting": {
|
||||
"template": ConfigField(
|
||||
|
||||
@@ -10,31 +10,43 @@
|
||||
|
||||
- [🧱 Action组件详解](action-components.md) - 掌握最核心的Action组件
|
||||
- [💻 Command组件详解](command-components.md) - 学习直接响应命令的组件
|
||||
- [⚙️ 配置管理指南](configuration-guide.md) - 学会使用配置驱动开发
|
||||
|
||||
- [🔧 工具系统详解](tool-system.md) - 工具系统的使用和开发(非主要功能)
|
||||
- [⚙️ 配置管理指南](configuration-guide.md) - 学会使用自动生成的插件配置文件
|
||||
- [📄 Manifest系统指南](manifest-guide.md) - 了解插件元数据管理和配置架构
|
||||
|
||||
## API浏览
|
||||
|
||||
### 🔗 核心通信API
|
||||
- [📡 消息API](api/message-api.md) - 消息接收和处理接口
|
||||
### 消息发送与处理API
|
||||
- [📤 发送API](api/send-api.md) - 各种类型消息发送接口
|
||||
- [💬 聊天API](api/chat-api.md) - 聊天流管理和查询接口
|
||||
- [消息API](api/message-api.md) - 消息获取,消息构建,消息查询接口
|
||||
- [聊天流API](api/chat-api.md) - 聊天流管理和查询接口
|
||||
|
||||
### 🤖 AI与生成API
|
||||
- [🧠 LLM API](api/llm-api.md) - 大语言模型交互接口
|
||||
- [✨ 回复生成器API](api/generator-api.md) - 智能回复生成接口
|
||||
### AI与生成API
|
||||
- [LLM API](api/llm-api.md) - 大语言模型交互接口,可以使用内置LLM生成内容
|
||||
- [✨ 回复生成器API](api/generator-api.md) - 智能回复生成接口,可以使用内置风格化生成器
|
||||
|
||||
### 表情包api
|
||||
- [😊 表情包API](api/emoji-api.md) - 表情包选择和管理接口
|
||||
|
||||
### 📊 数据与配置API
|
||||
### 关系系统api
|
||||
- [人物信息API](api/person-api.md) - 用户信息,处理麦麦认识的人和关系的接口
|
||||
|
||||
### 数据与配置API
|
||||
- [🗄️ 数据库API](api/database-api.md) - 数据库操作接口
|
||||
- [⚙️ 配置API](api/config-api.md) - 配置读取和用户信息接口
|
||||
- [👤 个人信息API](api/person-api.md) - 用户信息查询接口
|
||||
|
||||
### 🛠️ 工具API
|
||||
- [🔧 工具API](api/utils-api.md) - 文件操作、时间处理等工具函数
|
||||
### 工具API
|
||||
- [工具API](api/utils-api.md) - 文件操作、时间处理等工具函数
|
||||
|
||||
|
||||
## 实验性
|
||||
|
||||
这些功能将在未来重构或移除
|
||||
- [🔧 工具系统详解](tool-system.md) - 工具系统的使用和开发
|
||||
|
||||
|
||||
|
||||
## 支持
|
||||
|
||||
> 如果你在文档中发现错误或需要补充,请:
|
||||
|
||||
1. 检查最新的文档版本
|
||||
@@ -4,6 +4,26 @@
|
||||
|
||||
MaiBot插件系统现在强制要求每个插件都必须包含一个 `_manifest.json` 文件。这个文件描述了插件的基本信息、依赖关系、组件等重要元数据。
|
||||
|
||||
### 🔄 配置架构:Manifest与Config的职责分离
|
||||
|
||||
为了避免信息重复和提高维护性,我们采用了**双文件架构**:
|
||||
|
||||
- **`_manifest.json`** - 插件的**静态元数据**
|
||||
- 插件身份信息(名称、版本、描述)
|
||||
- 开发者信息(作者、许可证、仓库)
|
||||
- 系统信息(兼容性、组件列表、分类)
|
||||
|
||||
- **`config.toml`** - 插件的**运行时配置**
|
||||
- 启用状态 (`enabled`)
|
||||
- 功能参数配置
|
||||
- 用户可调整的行为设置
|
||||
|
||||
这种分离确保了:
|
||||
- ✅ 元数据信息统一管理
|
||||
- ✅ 运行时配置灵活调整
|
||||
- ✅ 避免重复维护
|
||||
- ✅ 更清晰的职责划分
|
||||
|
||||
## 🔧 Manifest文件结构
|
||||
|
||||
### 必需字段
|
||||
|
||||
@@ -217,6 +217,20 @@ class ActionPlanner(BasePlanner):
|
||||
# 如果repair_json直接返回了字典对象,直接使用
|
||||
parsed_json = fixed_json_string
|
||||
|
||||
# 处理repair_json可能返回列表的情况
|
||||
if isinstance(parsed_json, list):
|
||||
if parsed_json:
|
||||
# 取列表中最后一个元素(通常是最完整的)
|
||||
parsed_json = parsed_json[-1]
|
||||
logger.warning(f"{self.log_prefix}LLM返回了多个JSON对象,使用最后一个: {parsed_json}")
|
||||
else:
|
||||
parsed_json = {}
|
||||
|
||||
# 确保parsed_json是字典
|
||||
if not isinstance(parsed_json, dict):
|
||||
logger.error(f"{self.log_prefix}解析后的JSON不是字典类型: {type(parsed_json)}")
|
||||
parsed_json = {}
|
||||
|
||||
# 提取决策,提供默认值
|
||||
extracted_action = parsed_json.get("action", "no_reply")
|
||||
extracted_reasoning = ""
|
||||
|
||||
@@ -3,6 +3,7 @@ import os
|
||||
import importlib
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import traceback
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.plugin_system.base.base_plugin import BasePlugin
|
||||
@@ -151,6 +152,7 @@ class PluginManager:
|
||||
|
||||
except ValueError as e:
|
||||
# manifest文件格式错误或验证失败
|
||||
traceback.print_exc()
|
||||
total_failed_registration += 1
|
||||
error_msg = f"manifest验证失败: {str(e)}"
|
||||
self.failed_plugins[plugin_name] = error_msg
|
||||
|
||||
@@ -351,7 +351,7 @@ class CoreActionsPlugin(BasePlugin):
|
||||
|
||||
# 配置节描述
|
||||
config_section_descriptions = {
|
||||
"plugin": "插件基本信息配置",
|
||||
"plugin": "插件启用配置",
|
||||
"components": "核心组件启用配置",
|
||||
"no_reply": "不回复动作配置",
|
||||
"emoji": "表情动作配置",
|
||||
@@ -360,12 +360,7 @@ class CoreActionsPlugin(BasePlugin):
|
||||
# 配置Schema定义
|
||||
config_schema = {
|
||||
"plugin": {
|
||||
"name": ConfigField(type=str, default="core_actions", description="插件名称", required=True),
|
||||
"version": ConfigField(type=str, default="1.0.0", description="插件版本号"),
|
||||
"enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
||||
"description": ConfigField(
|
||||
type=str, default="系统核心动作插件,提供基础聊天交互功能", description="插件描述", required=True
|
||||
),
|
||||
},
|
||||
"components": {
|
||||
"enable_reply": ConfigField(type=bool, default=True, description="是否启用'回复'动作"),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[inner]
|
||||
version = "2.23.0"
|
||||
version = "2.24.0"
|
||||
|
||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||
@@ -43,7 +43,7 @@ identity_detail = [
|
||||
expression_style = "描述麦麦说话的表达风格,表达习惯,例如:(回复尽量简短一些。可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,平淡一些。不要有额外的符号,尽量简单简短)"
|
||||
enable_expression_learning = false # 是否启用表达学习,麦麦会学习不同群里人类说话风格(群之间不互通)
|
||||
learning_interval = 600 # 学习间隔 单位秒
|
||||
selection_mode = "llm" # 专注模式下 表达方式选择模式:'llm' 使用LLM智能选择,'random' 使用传统随机选择
|
||||
selection_mode = "random" # 专注模式下 表达方式选择模式:'llm' 使用LLM智能选择,'random' 使用传统随机选择
|
||||
|
||||
[relationship]
|
||||
enable_relationship = true # 是否启用关系系统
|
||||
@@ -320,12 +320,12 @@ temp = 0.2
|
||||
|
||||
|
||||
[model.lpmm_qa] # 问答模型
|
||||
name = "Pro/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B"
|
||||
name = "Qwen/Qwen3-30B-A3B"
|
||||
provider = "SILICONFLOW"
|
||||
pri_in = 4.0
|
||||
pri_out = 16.0
|
||||
pri_in = 0.7
|
||||
pri_out = 2.8
|
||||
temp = 0.7
|
||||
|
||||
enable_thinking = false # 是否启用思考
|
||||
|
||||
[maim_message]
|
||||
auth_token = [] # 认证令牌,用于API验证,为空则不启用验证
|
||||
|
||||
Reference in New Issue
Block a user