Merge branch 'MoFox-Studio:dev' into dev

This commit is contained in:
喵吃鸟
2025-11-28 12:41:48 +08:00
committed by GitHub
11 changed files with 302 additions and 52 deletions

View File

@@ -60,10 +60,9 @@ decision_prompt_template_group = Prompt(
- 心情影响:心情会影响你冒泡的方式和内容。
**选项3发起一次有目的的互动 (throw_topic)**
- 适用场景:你想延续对话表达关心、或深入讨论某个具体话题
- 适用场景:你想延续对话表达关心。
- **【互动类型1延续约定或提醒】(最高优先级)**:检查最近的聊天记录,是否存在可以延续的互动。例如,如果昨晚的最后一条消息是“晚安”,现在是早上,一个“早安”的回应是绝佳的选择。如果之前提到过某个约定(如“待会聊”),现在可以主动跟进。
- **【互动类型2展现真诚的关心】(次高优先级)**:如果不存在可延续的约定,请仔细阅读聊天记录,寻找**群友**提及的个人状况(如天气、出行、身体、情绪、工作学习等),并主动表达关心。
- **【互动类型3开启新话题】**:当以上两点都不适用时,可以考虑开启一个你感兴趣的新话题。
- 心情影响:心情会影响你想发起互动的方式和内容。
请以JSON格式回复你的决策
@@ -138,14 +137,9 @@ throw_topic_reply_prompt_template_group = Prompt(
- 如果意图是**延续约定**(如回应“晚安”),请直接生成对应的问候。
- 如果意图是**表达关心**(如跟进群友提到的事),请生成自然、真诚的关心话语。
- 如果意图是**开启新话题**:请严格遵守以下“新话题构思三步法”:
1. **寻找灵感****首选**从【最近的聊天记录】中寻找一个可以自然延续的**生活化**细节。**严禁**引入与聊天记录完全无关的、凭空出现的话题。如果记录为空,可以根据你的【人设】,提出一个**非常普适、开放式**的生活化问题或感想。
2. **确定风格**:请**确保新话题与最近的聊天内容有关联**,自然地引入话题,避免过于跳脱。
3. **最终检查**:你提出的话题是否合理?是否贴近现实和聊天内容?说话方式是否正常?是否像一个真正的人类?
请根据这个意图,生成一条消息,要求:
1. 要与最近的聊天记录相关,自然地引入话题或表达关心。
2. 长度适中(20-40字)。
2. 长度适中(15-25字左右)。
3. 结合最近的聊天记录确保对话连贯,不要显得突兀。
4. 符合你的人设和当前聊天风格。
5. **你的心情会影响你的表达方式**。
@@ -189,10 +183,9 @@ decision_prompt_template_private = Prompt(
- 心情影响:心情会影响你问候的方式和内容。
**选项3发起一次有目的的互动 (throw_topic)**
- 适用场景:你想延续对话表达关心、或深入讨论某个具体话题
- 适用场景:你想延续对话表达关心。
- **【互动类型1延续约定或提醒】(最高优先级)**:检查最近的聊天记录,是否存在可以延续的互动。例如,如果昨晚的最后一条消息是“晚安”,现在是早上,一个“早安”的回应是绝佳的选择。如果之前提到过某个约定(如“待会聊”),现在可以主动跟进。
- **【互动类型2展现真诚的关心】(次高优先级)**:如果不存在可延续的约定,请仔细阅读聊天记录,寻找**对方**提及的个人状况(如天气、出行、身体、情绪、工作学习等),并主动表达关心。
- **【互动类型3开启新话题】**:当以上两点都不适用时,可以考虑开启一个你感兴趣的新话题。
- 心情影响:心情会影响你想发起互动的方式和内容。
请以JSON格式回复你的决策
@@ -266,14 +259,9 @@ throw_topic_reply_prompt_template_private = Prompt(
请根据你的互动意图,并参考最近的聊天记录,生成一条有温度的、**适合在私聊中说**的消息。
- 如果意图是**延续约定**(如回应“晚安”),请直接生成对应的问候。
- 如果意ت意图是**表达关心**(如跟进对方提到的事),请生成自然、真诚的关心话语。
- 如果意图是**开启新话题**:请严格遵守以下“新话题构思三步法”:
1. **寻找灵感****首选**从【最近的聊天记录】中寻找一个可以自然延续的**生活化**细节。**严禁**引入与聊天记录完全无关的、凭空出现的话题。如果记录为空,可以根据你的【人设】,提出一个**非常普适、开放式**的生活化问题或感想。
2. **确定风格**:请**确保新话题与最近的聊天内容有关联**,自然地引入话题,避免过于跳脱。
3. **最终检查**:你提出的话题是否合理?是否贴近现实和聊天内容?说话方式是否正常?是否像一个真正的人类?
请根据这个意图,生成一条消息,要求:
1. 要与最近的聊天记录相关,自然地引入话题或表达关心。
2. 长度适中(20-40字)。
2. 长度适中(15-25字左右)。
3. 结合最近的聊天记录确保对话连贯,不要显得突兀。
4. 符合你的人设和当前聊天风格。
5. **你的心情会影响你的表达方式**。

View File

@@ -317,6 +317,9 @@ class NapcatAdapterPlugin(BasePlugin):
"ignore_non_self_poke": ConfigField(type=bool, default=False, description="是否忽略不是针对自己的戳一戳消息"),
"poke_debounce_seconds": ConfigField(type=float, default=2.0, description="戳一戳防抖时间(秒)"),
"enable_emoji_like": ConfigField(type=bool, default=True, description="是否启用群聊表情回复处理"),
"enable_reply_at": ConfigField(type=bool, default=True, description="是否在回复时自动@原消息发送者"),
"reply_at_rate": ConfigField(type=float, default=0.5, description="回复时@的概率0.0-1.0"),
"enable_video_processing": ConfigField(type=bool, default=True, description="是否启用视频消息处理(下载和解析)"),
},
}

View File

@@ -214,6 +214,9 @@ class MessageHandler:
case RealMessageType.record:
return await self._handle_record_message(segment)
case RealMessageType.video:
if not config_api.get_plugin_config(self.plugin_config, "features.enable_video_processing", False):
logger.debug("视频消息处理已禁用,跳过")
return {"type": "text", "data": "[视频消息]"}
return await self._handle_video_message(segment)
case RealMessageType.rps:
return await self._handle_rps_message(segment)

View File

@@ -370,14 +370,8 @@ class SendHandler:
def handle_voice_message(self, encoded_voice: str) -> dict:
"""处理语音消息"""
use_tts = False
if self.plugin_config:
use_tts = config_api.get_plugin_config(self.plugin_config, "voice.use_tts", False)
if not use_tts:
logger.warning("未启用语音消息处理")
return {}
if not encoded_voice:
logger.warning("接收到空的语音消息,跳过处理")
return {}
return {
"type": "record",

View File

@@ -50,6 +50,106 @@ class TTSVoicePlugin(BasePlugin):
super().__init__(*args, **kwargs)
self.tts_service = None
def _create_default_config(self, config_file: Path):
"""
如果配置文件不存在,则创建一个默认的配置文件。
"""
if config_file.is_file():
return
logger.info(f"TTS 配置文件不存在,正在创建默认配置文件于: {config_file}")
default_config_content = """# 插件基础配置
[plugin]
enable = true
keywords = [
"发语音", "语音", "说句话", "用语音说", "听你", "听声音", "想听你", "想听声音",
"讲个话", "说段话", "念一下", "读一下", "用嘴说", "", "能发语音吗","亲口"
]
# 组件启用控制
[components]
action_enabled = true
command_enabled = true
# TTS 语音合成基础配置
[tts]
server = "http://127.0.0.1:9880"
timeout = 180
max_text_length = 1000
# TTS 风格参数配置
# 每个 [[tts_styles]] 代表一个独立的语音风格配置
[[tts_styles]]
# 风格的唯一标识符,必须有一个名为 "default"
style_name = "default"
# 显示名称
name = "默认"
# 参考音频路径
refer_wav_path = "C:/path/to/your/reference.wav"
# 参考音频文本
prompt_text = "这是一个示例文本,请替换为您自己的参考音频文本。"
# 参考音频语言
prompt_language = "zh"
# GPT 模型路径
gpt_weights = "C:/path/to/your/gpt_weights.ckpt"
# SoVITS 模型路径
sovits_weights = "C:/path/to/your/sovits_weights.pth"
# 语速
speed_factor = 1.0
# TTS 高级参数配置
[tts_advanced]
media_type = "wav"
top_k = 9
top_p = 0.8
temperature = 0.8
batch_size = 6
batch_threshold = 0.75
text_split_method = "cut5"
repetition_penalty = 1.4
sample_steps = 150
super_sampling = true
# 空间音效配置
[spatial_effects]
# 是否启用空间音效处理
enabled = false
# 是否启用标准混响效果
reverb_enabled = false
# 混响的房间大小 (建议范围 0.0-1.0)
room_size = 0.2
# 混响的阻尼/高频衰减 (建议范围 0.0-1.0)
damping = 0.6
# 混响的湿声(效果声)比例 (建议范围 0.0-1.0)
wet_level = 0.3
# 混响的干声(原声)比例 (建议范围 0.0-1.0)
dry_level = 0.8
# 混响的立体声宽度 (建议范围 0.0-1.0)
width = 1.0
# 是否启用卷积混响需要assets/small_room_ir.wav文件
convolution_enabled = false
# 卷积混响的干湿比 (建议范围 0.0-1.0)
convolution_mix = 0.7
"""
try:
config_file.parent.mkdir(parents=True, exist_ok=True)
with open(config_file, "w", encoding="utf-8") as f:
f.write(default_config_content.strip())
logger.info("默认 TTS 配置文件创建成功。")
except Exception as e:
logger.error(f"创建默认 TTS 配置文件失败: {e}")
def _get_config_wrapper(self, key: str, default: Any = None) -> Any:
"""
配置获取的包装器,用于解决 get_config 无法直接获取动态表(如 tts_styles和未在 schema 中定义的节的问题。
@@ -93,6 +193,11 @@ class TTSVoicePlugin(BasePlugin):
"""
logger.info("初始化 TTSVoicePlugin...")
plugin_file = Path(__file__).resolve()
bot_root = plugin_file.parent.parent.parent.parent.parent
config_file = bot_root / "config" / "plugins" / self.plugin_name / self.config_file_name
self._create_default_config(config_file)
# 实例化 TTSService并传入 get_config 方法
self.tts_service = TTSService(self._get_config_wrapper)