refactor(notice): 移除硬编码的notice作用域判定逻辑
- 重构notice系统,作用域完全由additional_config中的is_public_notice字段决定 - 移除_determine_notice_scope方法中的硬编码notice类型检查 - 提供更灵活和可控的notice管理方式,支持显式配置公共notice - 更新相关文档说明新的使用方式 BREAKING CHANGE: 之前依赖特定notice类型自动成为公共notice的插件需要显式设置is_public_notice=true
This commit is contained in:
@@ -1,3 +1,50 @@
|
||||
# Notice 系统重构 (2025-10-19)
|
||||
|
||||
## 🔧 核心改进
|
||||
1. **移除硬编码的 Notice 类型判定**
|
||||
- 之前某些 `notice_type` 会被硬编码为公共 notice(如 `group_whole_ban`、`system_announcement` 等)
|
||||
- 现在 notice 的作用域完全由 `additional_config` 中的 `is_public_notice` 字段决定
|
||||
- 提供了更灵活和可控的 notice 管理方式
|
||||
|
||||
2. **修改的文件**
|
||||
- `src/chat/message_manager/message_manager.py`: 移除 `_determine_notice_scope` 方法中的硬编码逻辑
|
||||
- `src/chat/utils/prompt_params.py`: 添加缺失的 `notice_block` 字段
|
||||
|
||||
3. **新增文档**
|
||||
- `docs/guides/notice_system_guide.md`: 完整的 Notice 系统使用指南
|
||||
|
||||
## 💡 使用方式
|
||||
|
||||
### 流级 Notice(默认)
|
||||
```python
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"is_public_notice": False, # 或者不设置
|
||||
"notice_type": "group_ban"
|
||||
}
|
||||
```
|
||||
|
||||
### 公共 Notice
|
||||
```python
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"is_public_notice": True, # 显式设置为公共
|
||||
"notice_type": "system_announcement"
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 迁移注意
|
||||
|
||||
如果你的插件依赖以下 notice 类型自动成为公共 notice:
|
||||
- `group_whole_ban`
|
||||
- `group_whole_lift_ban`
|
||||
- `system_announcement`
|
||||
- `platform_maintenance`
|
||||
|
||||
请在 `additional_config` 中显式添加 `"is_public_notice": True`。
|
||||
|
||||
---
|
||||
|
||||
# 插件API与规范修改
|
||||
|
||||
1. 现在`plugin_system`的`__init__.py`文件中包含了所有插件API的导入,用户可以直接使用`from src.plugin_system import *`来导入所有API。
|
||||
|
||||
248
docs/guides/notice_system_guide.md
Normal file
248
docs/guides/notice_system_guide.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Notice 系统使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
Notice 系统用于管理和展示系统通知消息,支持两种作用域:
|
||||
- **公共 Notice(Public)**: 对所有聊天流可见
|
||||
- **流级 Notice(Stream)**: 仅对特定聊天流可见
|
||||
|
||||
## Notice 配置
|
||||
|
||||
### 1. 消息标记为 Notice
|
||||
|
||||
在消息的 `additional_config` 中设置以下字段:
|
||||
|
||||
```python
|
||||
additional_config = {
|
||||
"is_notice": True, # 标记为notice消息
|
||||
"notice_type": "group_ban", # notice类型(可选)
|
||||
"is_public_notice": False, # 是否为公共notice
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Notice 作用域
|
||||
|
||||
Notice 的作用域完全由 `is_public_notice` 字段决定:
|
||||
|
||||
#### 流级 Notice(默认)
|
||||
```python
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"is_public_notice": False, # 或者不设置该字段
|
||||
}
|
||||
```
|
||||
- 仅在消息所属的聊天流中可见
|
||||
- 适用于:群禁言、群解禁、戳一戳等群内事件
|
||||
|
||||
#### 公共 Notice
|
||||
```python
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"is_public_notice": True, # 明确设置为公共
|
||||
}
|
||||
```
|
||||
- 在所有聊天流中可见
|
||||
- 适用于:系统公告、平台维护通知等全局事件
|
||||
|
||||
### 3. Notice 类型
|
||||
|
||||
通过 `notice_type` 字段可以对 notice 进行分类:
|
||||
|
||||
```python
|
||||
# 常见的 notice 类型
|
||||
notice_types = {
|
||||
"group_ban": "群禁言",
|
||||
"group_lift_ban": "群解禁",
|
||||
"group_whole_ban": "全员禁言",
|
||||
"group_whole_lift_ban": "全员解禁",
|
||||
"poke": "戳一戳",
|
||||
"system_announcement": "系统公告",
|
||||
"platform_maintenance": "平台维护",
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Notice 生存时间(TTL)
|
||||
|
||||
Notice 消息会在一定时间后自动过期,默认为 1 小时(3600 秒)。
|
||||
|
||||
不同类型的 notice 可以有不同的 TTL:
|
||||
- 临时事件(戳一戳): 5 分钟
|
||||
- 群管理事件(禁言/解禁): 1 小时
|
||||
- 重要公告: 24 小时
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 示例 1: 群禁言通知(流级)
|
||||
|
||||
```python
|
||||
from src.common.data_models.database_data_model import DatabaseMessages
|
||||
|
||||
message = DatabaseMessages(
|
||||
chat_id="group_123456",
|
||||
sender_id="10001",
|
||||
raw_message="用户 张三 被管理员禁言 10 分钟",
|
||||
additional_config={
|
||||
"is_notice": True,
|
||||
"is_public_notice": False, # 仅该群可见
|
||||
"notice_type": "group_ban",
|
||||
"target_id": "user_12345",
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 示例 2: 系统维护公告(公共)
|
||||
|
||||
```python
|
||||
message = DatabaseMessages(
|
||||
chat_id="system",
|
||||
sender_id="system",
|
||||
raw_message="系统将于今晚 23:00 进行维护,预计 1 小时",
|
||||
additional_config={
|
||||
"is_notice": True,
|
||||
"is_public_notice": True, # 所有聊天流可见
|
||||
"notice_type": "platform_maintenance",
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 示例 3: 在插件中发送 Notice
|
||||
|
||||
```python
|
||||
from src.api import send_private_message, send_group_message
|
||||
|
||||
# 发送群内 notice
|
||||
await send_group_message(
|
||||
group_id=123456,
|
||||
message="管理员已开启全员禁言",
|
||||
additional_config={
|
||||
"is_notice": True,
|
||||
"is_public_notice": False,
|
||||
"notice_type": "group_whole_ban",
|
||||
}
|
||||
)
|
||||
|
||||
# 发送公共 notice
|
||||
await send_group_message(
|
||||
group_id=123456, # 任意有效的群号
|
||||
message="🔔 Bot 将在 5 分钟后重启进行更新",
|
||||
additional_config={
|
||||
"is_notice": True,
|
||||
"is_public_notice": True,
|
||||
"notice_type": "system_announcement",
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Notice 在 Prompt 中的展示
|
||||
|
||||
当启用 `notice_in_prompt` 配置时,notice 消息会被自动添加到 AI 的提示词中:
|
||||
|
||||
```
|
||||
## 📢 最近的系统通知
|
||||
|
||||
[群禁言] 用户 张三 被管理员禁言 10 分钟 (5分钟前)
|
||||
[戳一戳] 李四 戳了戳 你 (刚刚)
|
||||
[系统公告] Bot 将在 5 分钟后重启进行更新 (2分钟前)
|
||||
```
|
||||
|
||||
## 配置选项
|
||||
|
||||
在 `bot_config.toml` 中配置 notice 系统:
|
||||
|
||||
```toml
|
||||
[notice]
|
||||
# 是否在 prompt 中显示 notice
|
||||
notice_in_prompt = true
|
||||
|
||||
# prompt 中显示的 notice 数量限制
|
||||
notice_prompt_limit = 5
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **作用域控制**:
|
||||
- `is_public_notice` 字段是唯一决定 notice 作用域的因素
|
||||
- 不要依赖 `notice_type` 来控制作用域
|
||||
|
||||
2. **性能考虑**:
|
||||
- Notice 消息会自动过期清理
|
||||
- 每种类型最多存储 100 条 notice
|
||||
- 每 5 分钟自动清理过期消息
|
||||
|
||||
3. **兼容性**:
|
||||
- 如果不设置 `is_public_notice`,默认为流级 notice
|
||||
- 旧代码中基于 `notice_type` 的判断已被移除
|
||||
|
||||
## 迁移指南
|
||||
|
||||
如果你的代码中依赖了以下 notice 类型自动成为公共 notice 的行为:
|
||||
- `group_whole_ban`
|
||||
- `group_whole_lift_ban`
|
||||
- `system_announcement`
|
||||
- `platform_maintenance`
|
||||
|
||||
请在消息的 `additional_config` 中显式设置:
|
||||
|
||||
```python
|
||||
# 修改前(依赖硬编码)
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"notice_type": "system_announcement",
|
||||
# 会自动成为公共 notice
|
||||
}
|
||||
|
||||
# 修改后(显式指定)
|
||||
additional_config = {
|
||||
"is_notice": True,
|
||||
"notice_type": "system_announcement",
|
||||
"is_public_notice": True, # 显式设置
|
||||
}
|
||||
```
|
||||
|
||||
## API 参考
|
||||
|
||||
### GlobalNoticeManager
|
||||
|
||||
```python
|
||||
from src.chat.message_manager.global_notice_manager import global_notice_manager
|
||||
|
||||
# 添加 notice
|
||||
success = global_notice_manager.add_notice(
|
||||
message=db_message,
|
||||
scope=NoticeScope.PUBLIC, # 或 NoticeScope.STREAM
|
||||
target_stream_id="group_123456", # STREAM 模式必需
|
||||
ttl=3600 # 生存时间(秒)
|
||||
)
|
||||
|
||||
# 获取可访问的 notice
|
||||
notices = global_notice_manager.get_accessible_notices(
|
||||
stream_id="group_123456",
|
||||
limit=10
|
||||
)
|
||||
|
||||
# 获取格式化的 notice 文本
|
||||
text = global_notice_manager.get_notice_text(
|
||||
stream_id="group_123456",
|
||||
limit=5
|
||||
)
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: Notice 不显示在 prompt 中?
|
||||
A: 检查配置:
|
||||
1. `bot_config.toml` 中 `notice.notice_in_prompt = true`
|
||||
2. 确认消息的 `is_notice = True`
|
||||
3. 确认 notice 未过期
|
||||
|
||||
### Q: 如何让 notice 对所有群可见?
|
||||
A: 在 `additional_config` 中设置 `is_public_notice = True`
|
||||
|
||||
### Q: 如何设置自定义的 notice 类型?
|
||||
A: 在 `additional_config` 中设置任意字符串作为 `notice_type`
|
||||
|
||||
### Q: Notice 什么时候会被清理?
|
||||
A:
|
||||
1. 超过 TTL 时间后自动清理
|
||||
2. 每种类型超过 100 条时,移除最旧的
|
||||
3. 手动调用清理 API
|
||||
@@ -678,7 +678,12 @@ class MessageManager:
|
||||
logger.error(f"处理notice消息失败: {e}")
|
||||
|
||||
def _determine_notice_scope(self, message: DatabaseMessages, stream_id: str) -> NoticeScope:
|
||||
"""确定notice的作用域"""
|
||||
"""确定notice的作用域
|
||||
|
||||
作用域完全由 additional_config 中的 is_public_notice 字段决定:
|
||||
- is_public_notice=True: 公共notice,所有聊天流可见
|
||||
- is_public_notice=False 或未设置: 特定聊天流notice
|
||||
"""
|
||||
try:
|
||||
# 检查附加配置中的公共notice标志
|
||||
if hasattr(message, 'additional_config') and message.additional_config:
|
||||
@@ -692,20 +697,9 @@ class MessageManager:
|
||||
is_public = False
|
||||
|
||||
if is_public:
|
||||
logger.debug(f"Notice被标记为公共: message_id={message.message_id}")
|
||||
return NoticeScope.PUBLIC
|
||||
|
||||
# 检查notice类型来决定作用域
|
||||
notice_type = self._get_notice_type(message)
|
||||
|
||||
# 某些类型的notice默认为公共notice
|
||||
public_notice_types = {
|
||||
"group_whole_ban", "group_whole_lift_ban",
|
||||
"system_announcement", "platform_maintenance"
|
||||
}
|
||||
|
||||
if notice_type in public_notice_types:
|
||||
return NoticeScope.PUBLIC
|
||||
|
||||
# 默认为特定聊天流notice
|
||||
return NoticeScope.STREAM
|
||||
|
||||
|
||||
Reference in New Issue
Block a user