1+ from src .plugin_system .base .base_plugin import BasePlugin , register_plugin
2+ from src .plugin_system .base .component_types import ComponentInfo
3+ from src .common .logger import get_logger
4+ from src .plugin_system .base .base_action import BaseAction , ActionActivationType , ChatMode
5+ from typing import Tuple , List , Type
6+
7+ logger = get_logger ("tts" )
8+
9+ class TTSAction (BaseAction ):
10+ """TTS语音转换动作处理类"""
11+
12+ action_name = "tts"
13+ action_description = "将文本转换为语音进行播放,适用于需要语音输出的场景"
14+ action_parameters = {
15+ "text" : "需要转换为语音的文本内容,必填,内容应当适合语音播报,语句流畅、清晰" ,
16+ }
17+ action_require = [
18+ "当需要发送语音信息时使用" ,
19+ "当用户明确要求使用语音功能时使用" ,
20+ "当表达内容更适合用语音而不是文字传达时使用" ,
21+ "当用户想听到语音回答而非阅读文本时使用" ,
22+ ]
23+ enable_plugin = True # 启用插件
24+ associated_types = ["tts_text" ]
25+
26+ # 模式和并行控制
27+ mode_enable = ChatMode .ALL
28+ parallel_action = False
29+
30+ focus_activation_type = ActionActivationType .LLM_JUDGE
31+ normal_activation_type = ActionActivationType .KEYWORD
32+
33+ # 关键词配置 - Normal模式下使用关键词触发
34+ activation_keywords = ["语音" , "tts" , "播报" , "读出来" , "语音播放" , "听" , "朗读" ]
35+ keyword_case_sensitive = False
36+
37+ # 并行执行设置 - TTS可以与回复并行执行,不覆盖回复内容
38+ parallel_action = False
39+
40+ async def execute (self ) -> Tuple [bool , str ]:
41+ """处理TTS文本转语音动作"""
42+ logger .info (f"{ self .log_prefix } 执行TTS动作: { self .reasoning } " )
43+
44+ # 获取要转换的文本
45+ text = self .action_data .get ("text" )
46+
47+ if not text :
48+ logger .error (f"{ self .log_prefix } 执行TTS动作时未提供文本内容" )
49+ return False , "执行TTS动作失败:未提供文本内容"
50+
51+ # 确保文本适合TTS使用
52+ processed_text = self ._process_text_for_tts (text )
53+
54+ try :
55+ # 发送TTS消息
56+ await self .send_type (type = "tts_text" , text = processed_text )
57+
58+ logger .info (f"{ self .log_prefix } TTS动作执行成功,文本长度: { len (processed_text )} " )
59+ return True , "TTS动作执行成功"
60+
61+ except Exception as e :
62+ logger .error (f"{ self .log_prefix } 执行TTS动作时出错: { e } " )
63+ return False , f"执行TTS动作时出错: { e } "
64+
65+ def _process_text_for_tts (self , text : str ) -> str :
66+ """
67+ 处理文本使其更适合TTS使用
68+ - 移除不必要的特殊字符和表情符号
69+ - 修正标点符号以提高语音质量
70+ - 优化文本结构使语音更流畅
71+ """
72+ # 这里可以添加文本处理逻辑
73+ # 例如:移除多余的标点、表情符号,优化语句结构等
74+
75+ # 简单示例实现
76+ processed_text = text
77+
78+ # 移除多余的标点符号
79+ import re
80+
81+ processed_text = re .sub (r"([!?,.;:。!?,、;:])\1+" , r"\1" , processed_text )
82+
83+ # 确保句子结尾有合适的标点
84+ if not any (processed_text .endswith (end ) for end in ["." , "?" , "!" , "。" , "!" , "?" ]):
85+ processed_text = processed_text + "。"
86+
87+ return processed_text
88+
89+ @register_plugin
90+ class TTSPlugin (BasePlugin ):
91+ """TTS插件
92+ - 这是文字转语音插件
93+ - Normal模式下依靠关键词触发
94+ - Focus模式下由LLM判断触发
95+ - 具有一定的文本预处理能力
96+ """
97+
98+ # 插件基本信息
99+ plugin_name = "tts_plugin"
100+ plugin_description = "文字转语音插件"
101+ plugin_version = "0.1.0"
102+ plugin_author = "MaiBot开发团队"
103+ enable_plugin = True
104+ config_file_name = "config.toml"
105+
106+ def get_plugin_components (self ) -> List [Tuple [ComponentInfo , Type ]]:
107+ """返回插件包含的组件列表"""
108+
109+ # 从配置获取组件启用状态
110+ enable_tts = self .get_config ("components.enable_tts" , True )
111+ components = []
112+
113+ # 添加Action组件
114+ if enable_tts :
115+ components .append (
116+ (
117+ TTSAction .get_action_info (
118+ name = "tarots_action" , description = "文字转语音插件"
119+ ),
120+ TTSAction ,
121+ )
122+ )
123+
124+ return components
0 commit comments