emoji_api_doc
This commit is contained in:
@@ -6,11 +6,13 @@
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
from src.plugin_system.apis import emoji_api
|
from src.plugin_system.apis import emoji_api
|
||||||
|
# 或者
|
||||||
|
from src.plugin_system import emoji_api
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🆕 **二步走识别优化**
|
## 二步走识别优化
|
||||||
|
|
||||||
从最新版本开始,表情包识别系统采用了**二步走识别 + 智能缓存**的优化方案:
|
从新版本开始,表情包识别系统采用了**二步走识别 + 智能缓存**的优化方案:
|
||||||
|
|
||||||
### **收到表情包时的识别流程**
|
### **收到表情包时的识别流程**
|
||||||
1. **第一步**:VLM视觉分析 - 生成详细描述
|
1. **第一步**:VLM视觉分析 - 生成详细描述
|
||||||
@@ -30,217 +32,84 @@ from src.plugin_system.apis import emoji_api
|
|||||||
## 主要功能
|
## 主要功能
|
||||||
|
|
||||||
### 1. 表情包获取
|
### 1. 表情包获取
|
||||||
|
```python
|
||||||
#### `get_by_description(description: str) -> Optional[Tuple[str, str, str]]`
|
async def get_by_description(description: str) -> Optional[Tuple[str, str, str]]:
|
||||||
|
```
|
||||||
根据场景描述选择表情包
|
根据场景描述选择表情包
|
||||||
|
|
||||||
**参数:**
|
**Args:**
|
||||||
- `description`:场景描述文本,例如"开心的大笑"、"轻微的讽刺"、"表示无奈和沮丧"等
|
- `description`:表情包的描述文本,例如"开心"、"难过"、"愤怒"等
|
||||||
|
|
||||||
**返回:**
|
**Returns:**
|
||||||
- `Optional[Tuple[str, str, str]]`:(base64编码, 表情包描述, 匹配的场景) 或 None
|
- `Optional[Tuple[str, str, str]]`:一个元组: (表情包的base64编码, 描述, 情感标签),如果未找到匹配的表情包则返回None
|
||||||
|
|
||||||
**示例:**
|
#### 示例
|
||||||
```python
|
```python
|
||||||
emoji_result = await emoji_api.get_by_description("开心的大笑")
|
emoji_result = await emoji_api.get_by_description("大笑")
|
||||||
if emoji_result:
|
if emoji_result:
|
||||||
emoji_base64, description, matched_scene = emoji_result
|
emoji_base64, description, matched_scene = emoji_result
|
||||||
print(f"获取到表情包: {description}, 场景: {matched_scene}")
|
print(f"获取到表情包: {description}, 场景: {matched_scene}")
|
||||||
# 可以将emoji_base64用于发送表情包
|
# 可以将emoji_base64用于发送表情包
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_random() -> Optional[Tuple[str, str, str]]`
|
### 2. 随机获取表情包
|
||||||
随机获取表情包
|
|
||||||
|
|
||||||
**返回:**
|
|
||||||
- `Optional[Tuple[str, str, str]]`:(base64编码, 表情包描述, 随机场景) 或 None
|
|
||||||
|
|
||||||
**示例:**
|
|
||||||
```python
|
```python
|
||||||
random_emoji = await emoji_api.get_random()
|
async def get_random(count: Optional[int] = 1) -> List[Tuple[str, str, str]]:
|
||||||
if random_emoji:
|
|
||||||
emoji_base64, description, scene = random_emoji
|
|
||||||
print(f"随机表情包: {description}")
|
|
||||||
```
|
```
|
||||||
|
随机获取指定数量的表情包
|
||||||
|
|
||||||
#### `get_by_emotion(emotion: str) -> Optional[Tuple[str, str, str]]`
|
**Args:**
|
||||||
根据场景关键词获取表情包
|
- `count`:要获取的表情包数量,默认为1
|
||||||
|
|
||||||
**参数:**
|
**Returns:**
|
||||||
- `emotion`:场景关键词,如"大笑"、"讽刺"、"无奈"等
|
- `List[Tuple[str, str, str]]`:一个包含多个表情包的列表,每个元素是一个元组: (表情包的base64编码, 描述, 情感标签),如果未找到或出错则返回空列表
|
||||||
|
|
||||||
**返回:**
|
### 3. 根据情感获取表情包
|
||||||
- `Optional[Tuple[str, str, str]]`:(base64编码, 表情包描述, 匹配的场景) 或 None
|
|
||||||
|
|
||||||
**示例:**
|
|
||||||
```python
|
```python
|
||||||
emoji_result = await emoji_api.get_by_emotion("讽刺")
|
async def get_by_emotion(emotion: str) -> Optional[Tuple[str, str, str]]:
|
||||||
if emoji_result:
|
|
||||||
emoji_base64, description, scene = emoji_result
|
|
||||||
# 发送讽刺表情包
|
|
||||||
```
|
```
|
||||||
|
根据情感标签获取表情包
|
||||||
|
|
||||||
### 2. 表情包信息查询
|
**Args:**
|
||||||
|
- `emotion`:情感标签,例如"开心"、"悲伤"、"愤怒"等
|
||||||
|
|
||||||
#### `get_count() -> int`
|
**Returns:**
|
||||||
获取表情包数量
|
- `Optional[Tuple[str, str, str]]`:一个元组: (表情包的base64编码, 描述, 情感标签),如果未找到则返回None
|
||||||
|
|
||||||
**返回:**
|
### 4. 获取表情包数量
|
||||||
- `int`:当前可用的表情包数量
|
```python
|
||||||
|
def get_count() -> int:
|
||||||
|
```
|
||||||
|
获取当前可用表情包的数量
|
||||||
|
|
||||||
#### `get_info() -> dict`
|
### 5. 获取表情包系统信息
|
||||||
获取表情包系统信息
|
```python
|
||||||
|
def get_info() -> Dict[str, Any]:
|
||||||
|
```
|
||||||
|
获取表情包系统的基本信息
|
||||||
|
|
||||||
**返回:**
|
**Returns:**
|
||||||
- `dict`:包含表情包数量、最大数量等信息
|
- `Dict[str, Any]`:包含表情包数量、描述等信息的字典,包含以下键:
|
||||||
|
- `current_count`:当前表情包数量
|
||||||
|
- `max_count`:最大表情包数量
|
||||||
|
- `available_emojis`:当前可用的表情包数量
|
||||||
|
|
||||||
**返回字典包含:**
|
### 6. 获取所有可用的情感标签
|
||||||
- `current_count`:当前表情包数量
|
```python
|
||||||
- `max_count`:最大表情包数量
|
def get_emotions() -> List[str]:
|
||||||
- `available_emojis`:可用表情包数量
|
```
|
||||||
|
获取所有可用的情感标签 **(已经去重)**
|
||||||
|
|
||||||
#### `get_emotions() -> list`
|
### 7. 获取所有表情包描述
|
||||||
获取所有可用的场景关键词
|
```python
|
||||||
|
def get_descriptions() -> List[str]:
|
||||||
**返回:**
|
```
|
||||||
- `list`:所有表情包的场景关键词列表(去重)
|
|
||||||
|
|
||||||
#### `get_descriptions() -> list`
|
|
||||||
获取所有表情包的描述列表
|
获取所有表情包的描述列表
|
||||||
|
|
||||||
**返回:**
|
|
||||||
- `list`:所有表情包的描述文本列表
|
|
||||||
|
|
||||||
## 使用示例
|
|
||||||
|
|
||||||
### 1. 智能表情包选择
|
|
||||||
|
|
||||||
```python
|
|
||||||
from src.plugin_system.apis import emoji_api
|
|
||||||
|
|
||||||
async def send_emotion_response(message_text: str, chat_stream):
|
|
||||||
"""根据消息内容智能选择表情包回复"""
|
|
||||||
|
|
||||||
# 分析消息场景
|
|
||||||
if "哈哈" in message_text or "好笑" in message_text:
|
|
||||||
emoji_result = await emoji_api.get_by_description("开心的大笑")
|
|
||||||
elif "无语" in message_text or "算了" in message_text:
|
|
||||||
emoji_result = await emoji_api.get_by_description("表示无奈和沮丧")
|
|
||||||
elif "呵呵" in message_text or "是吗" in message_text:
|
|
||||||
emoji_result = await emoji_api.get_by_description("轻微的讽刺")
|
|
||||||
elif "生气" in message_text or "愤怒" in message_text:
|
|
||||||
emoji_result = await emoji_api.get_by_description("愤怒和不满")
|
|
||||||
else:
|
|
||||||
# 随机选择一个表情包
|
|
||||||
emoji_result = await emoji_api.get_random()
|
|
||||||
|
|
||||||
if emoji_result:
|
|
||||||
emoji_base64, description, scene = emoji_result
|
|
||||||
# 使用send_api发送表情包
|
|
||||||
from src.plugin_system.apis import send_api
|
|
||||||
success = await send_api.emoji_to_group(emoji_base64, chat_stream.group_info.group_id)
|
|
||||||
return success
|
|
||||||
|
|
||||||
return False
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 表情包管理功能
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def show_emoji_stats():
|
|
||||||
"""显示表情包统计信息"""
|
|
||||||
|
|
||||||
# 获取基本信息
|
|
||||||
count = emoji_api.get_count()
|
|
||||||
info = emoji_api.get_info()
|
|
||||||
scenes = emoji_api.get_emotions() # 实际返回的是场景关键词
|
|
||||||
|
|
||||||
stats = f"""
|
|
||||||
📊 表情包统计信息:
|
|
||||||
- 总数量: {count}
|
|
||||||
- 可用数量: {info['available_emojis']}
|
|
||||||
- 最大容量: {info['max_count']}
|
|
||||||
- 支持场景: {len(scenes)}种
|
|
||||||
|
|
||||||
🎭 支持的场景关键词: {', '.join(scenes[:10])}{'...' if len(scenes) > 10 else ''}
|
|
||||||
"""
|
|
||||||
|
|
||||||
return stats
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 表情包测试功能
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def test_emoji_system():
|
|
||||||
"""测试表情包系统的各种功能"""
|
|
||||||
|
|
||||||
print("=== 表情包系统测试 ===")
|
|
||||||
|
|
||||||
# 测试场景描述查找
|
|
||||||
test_descriptions = ["开心的大笑", "轻微的讽刺", "表示无奈和沮丧", "愤怒和不满"]
|
|
||||||
for desc in test_descriptions:
|
|
||||||
result = await emoji_api.get_by_description(desc)
|
|
||||||
if result:
|
|
||||||
_, description, scene = result
|
|
||||||
print(f"✅ 场景'{desc}' -> {description} ({scene})")
|
|
||||||
else:
|
|
||||||
print(f"❌ 场景'{desc}' -> 未找到")
|
|
||||||
|
|
||||||
# 测试关键词查找
|
|
||||||
scenes = emoji_api.get_emotions()
|
|
||||||
if scenes:
|
|
||||||
test_scene = scenes[0]
|
|
||||||
result = await emoji_api.get_by_emotion(test_scene)
|
|
||||||
if result:
|
|
||||||
print(f"✅ 关键词'{test_scene}' -> 找到匹配表情包")
|
|
||||||
|
|
||||||
# 测试随机获取
|
|
||||||
random_result = await emoji_api.get_random()
|
|
||||||
if random_result:
|
|
||||||
print("✅ 随机获取 -> 成功")
|
|
||||||
|
|
||||||
print(f"📊 系统信息: {emoji_api.get_info()}")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 在Action中使用表情包
|
|
||||||
|
|
||||||
```python
|
|
||||||
from src.plugin_system.base import BaseAction
|
|
||||||
|
|
||||||
class EmojiAction(BaseAction):
|
|
||||||
async def execute(self, action_data, chat_stream):
|
|
||||||
# 从action_data获取场景描述或关键词
|
|
||||||
scene_keyword = action_data.get("scene", "")
|
|
||||||
scene_description = action_data.get("description", "")
|
|
||||||
|
|
||||||
emoji_result = None
|
|
||||||
|
|
||||||
# 优先使用具体的场景描述
|
|
||||||
if scene_description:
|
|
||||||
emoji_result = await emoji_api.get_by_description(scene_description)
|
|
||||||
# 其次使用场景关键词
|
|
||||||
elif scene_keyword:
|
|
||||||
emoji_result = await emoji_api.get_by_emotion(scene_keyword)
|
|
||||||
# 最后随机选择
|
|
||||||
else:
|
|
||||||
emoji_result = await emoji_api.get_random()
|
|
||||||
|
|
||||||
if emoji_result:
|
|
||||||
emoji_base64, description, scene = emoji_result
|
|
||||||
return {
|
|
||||||
"success": True,
|
|
||||||
"emoji_base64": emoji_base64,
|
|
||||||
"description": description,
|
|
||||||
"scene": scene
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"success": False, "message": "未找到合适的表情包"}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 场景描述说明
|
## 场景描述说明
|
||||||
|
|
||||||
### 常用场景描述
|
### 常用场景描述
|
||||||
表情包系统支持多种具体的场景描述,常见的包括:
|
表情包系统支持多种具体的场景描述,举例如下:
|
||||||
|
|
||||||
- **开心类场景**:开心的大笑、满意的微笑、兴奋的手舞足蹈
|
- **开心类场景**:开心的大笑、满意的微笑、兴奋的手舞足蹈
|
||||||
- **无奈类场景**:表示无奈和沮丧、轻微的讽刺、无语的摇头
|
- **无奈类场景**:表示无奈和沮丧、轻微的讽刺、无语的摇头
|
||||||
@@ -248,8 +117,8 @@ class EmojiAction(BaseAction):
|
|||||||
- **惊讶类场景**:震惊的表情、意外的发现、困惑的思考
|
- **惊讶类场景**:震惊的表情、意外的发现、困惑的思考
|
||||||
- **可爱类场景**:卖萌的表情、撒娇的动作、害羞的样子
|
- **可爱类场景**:卖萌的表情、撒娇的动作、害羞的样子
|
||||||
|
|
||||||
### 场景关键词示例
|
### 情感关键词示例
|
||||||
系统支持的场景关键词包括:
|
系统支持的情感关键词举例如下:
|
||||||
- 大笑、微笑、兴奋、手舞足蹈
|
- 大笑、微笑、兴奋、手舞足蹈
|
||||||
- 无奈、沮丧、讽刺、无语、摇头
|
- 无奈、沮丧、讽刺、无语、摇头
|
||||||
- 愤怒、不满、生气、瞪视、抓狂
|
- 愤怒、不满、生气、瞪视、抓狂
|
||||||
@@ -263,9 +132,9 @@ class EmojiAction(BaseAction):
|
|||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
1. **异步函数**:获取表情包的函数都是异步的,需要使用 `await`
|
1. **异步函数**:部分函数是异步的,需要使用 `await`
|
||||||
2. **返回格式**:表情包以base64编码返回,可直接用于发送
|
2. **返回格式**:表情包以base64编码返回,可直接用于发送
|
||||||
3. **错误处理**:所有函数都有错误处理,失败时返回None或默认值
|
3. **错误处理**:所有函数都有错误处理,失败时返回None,空列表或默认值
|
||||||
4. **使用统计**:系统会记录表情包的使用次数
|
4. **使用统计**:系统会记录表情包的使用次数
|
||||||
5. **文件依赖**:表情包依赖于本地文件,确保表情包文件存在
|
5. **文件依赖**:表情包依赖于本地文件,确保表情包文件存在
|
||||||
6. **编码格式**:返回的是base64编码的图片数据,可直接用于网络传输
|
6. **编码格式**:返回的是base64编码的图片数据,可直接用于网络传输
|
||||||
|
|||||||
@@ -65,14 +65,14 @@ async def get_by_description(description: str) -> Optional[Tuple[str, str, str]]
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def get_random(count: Optional[int] = 1) -> Optional[List[Tuple[str, str, str]]]:
|
async def get_random(count: Optional[int] = 1) -> List[Tuple[str, str, str]]:
|
||||||
"""随机获取指定数量的表情包
|
"""随机获取指定数量的表情包
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
count: 要获取的表情包数量,默认为1
|
count: 要获取的表情包数量,默认为1
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[List[Tuple[str, str, str]]]: 包含(base64编码, 表情包描述, 随机情感标签)的元组列表,如果失败则为None
|
List[Tuple[str, str, str]]: 包含(base64编码, 表情包描述, 随机情感标签)的元组列表,失败则返回空列表
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: 如果count不是整数类型
|
TypeError: 如果count不是整数类型
|
||||||
@@ -94,13 +94,13 @@ async def get_random(count: Optional[int] = 1) -> Optional[List[Tuple[str, str,
|
|||||||
|
|
||||||
if not all_emojis:
|
if not all_emojis:
|
||||||
logger.warning("[EmojiAPI] 没有可用的表情包")
|
logger.warning("[EmojiAPI] 没有可用的表情包")
|
||||||
return None
|
return []
|
||||||
|
|
||||||
# 过滤有效表情包
|
# 过滤有效表情包
|
||||||
valid_emojis = [emoji for emoji in all_emojis if not emoji.is_deleted]
|
valid_emojis = [emoji for emoji in all_emojis if not emoji.is_deleted]
|
||||||
if not valid_emojis:
|
if not valid_emojis:
|
||||||
logger.warning("[EmojiAPI] 没有有效的表情包")
|
logger.warning("[EmojiAPI] 没有有效的表情包")
|
||||||
return None
|
return []
|
||||||
|
|
||||||
if len(valid_emojis) < count:
|
if len(valid_emojis) < count:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -127,14 +127,14 @@ async def get_random(count: Optional[int] = 1) -> Optional[List[Tuple[str, str,
|
|||||||
|
|
||||||
if not results and count > 0:
|
if not results and count > 0:
|
||||||
logger.warning("[EmojiAPI] 随机获取表情包失败,没有一个可以成功处理")
|
logger.warning("[EmojiAPI] 随机获取表情包失败,没有一个可以成功处理")
|
||||||
return None
|
return []
|
||||||
|
|
||||||
logger.info(f"[EmojiAPI] 成功获取 {len(results)} 个随机表情包")
|
logger.info(f"[EmojiAPI] 成功获取 {len(results)} 个随机表情包")
|
||||||
return results
|
return results
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[EmojiAPI] 获取随机表情包失败: {e}")
|
logger.error(f"[EmojiAPI] 获取随机表情包失败: {e}")
|
||||||
return None
|
return []
|
||||||
|
|
||||||
|
|
||||||
async def get_by_emotion(emotion: str) -> Optional[Tuple[str, str, str]]:
|
async def get_by_emotion(emotion: str) -> Optional[Tuple[str, str, str]]:
|
||||||
@@ -162,10 +162,11 @@ async def get_by_emotion(emotion: str) -> Optional[Tuple[str, str, str]]:
|
|||||||
|
|
||||||
# 筛选匹配情感的表情包
|
# 筛选匹配情感的表情包
|
||||||
matching_emojis = []
|
matching_emojis = []
|
||||||
for emoji_obj in all_emojis:
|
matching_emojis.extend(
|
||||||
if not emoji_obj.is_deleted and emotion.lower() in [e.lower() for e in emoji_obj.emotion]:
|
emoji_obj
|
||||||
matching_emojis.append(emoji_obj)
|
for emoji_obj in all_emojis
|
||||||
|
if not emoji_obj.is_deleted and emotion.lower() in [e.lower() for e in emoji_obj.emotion]
|
||||||
|
)
|
||||||
if not matching_emojis:
|
if not matching_emojis:
|
||||||
logger.warning(f"[EmojiAPI] 未找到匹配情感 '{emotion}' 的表情包")
|
logger.warning(f"[EmojiAPI] 未找到匹配情感 '{emotion}' 的表情包")
|
||||||
return None
|
return None
|
||||||
@@ -256,10 +257,11 @@ def get_descriptions() -> List[str]:
|
|||||||
emoji_manager = get_emoji_manager()
|
emoji_manager = get_emoji_manager()
|
||||||
descriptions = []
|
descriptions = []
|
||||||
|
|
||||||
for emoji_obj in emoji_manager.emoji_objects:
|
descriptions.extend(
|
||||||
if not emoji_obj.is_deleted and emoji_obj.description:
|
emoji_obj.description
|
||||||
descriptions.append(emoji_obj.description)
|
for emoji_obj in emoji_manager.emoji_objects
|
||||||
|
if not emoji_obj.is_deleted and emoji_obj.description
|
||||||
|
)
|
||||||
return descriptions
|
return descriptions
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[EmojiAPI] 获取表情包描述失败: {e}")
|
logger.error(f"[EmojiAPI] 获取表情包描述失败: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user