feat: add trigger probability setting for TTS and support to render slider in schema (#4047)

* feat: add trigger probability setting for TTS and support to render slider in schema

* chore: ruff format
This commit is contained in:
Soulter
2025-12-15 16:04:27 +08:00
committed by GitHub
parent 56673ad78f
commit 02cd5e396b
7 changed files with 114 additions and 23 deletions
+13
View File
@@ -108,6 +108,7 @@ DEFAULT_CONFIG = {
"provider_id": "",
"dual_output": False,
"use_file_service": False,
"trigger_probability": 1.0,
},
"provider_ltm_settings": {
"group_icl_enable": False,
@@ -2209,6 +2210,9 @@ CONFIG_METADATA_2 = {
"use_file_service": {
"type": "bool",
},
"trigger_probability": {
"type": "float",
},
},
},
"provider_ltm_settings": {
@@ -2419,6 +2423,14 @@ CONFIG_METADATA_3 = {
"provider_tts_settings.enable": True,
},
},
"provider_tts_settings.trigger_probability": {
"description": "TTS 触发概率",
"type": "float",
"slider": {"min": 0, "max": 1, "step": 0.05},
"condition": {
"provider_tts_settings.enable": True,
},
},
"provider_settings.image_caption_prompt": {
"description": "图片转述提示词",
"type": "text",
@@ -2986,6 +2998,7 @@ CONFIG_METADATA_3 = {
"description": "回复概率",
"type": "float",
"hint": "0.0-1.0 之间的数值",
"slider": {"min": 0, "max": 1, "step": 0.05},
"condition": {
"provider_ltm_settings.active_reply.enable": True,
},
+1
View File
@@ -79,6 +79,7 @@ class ConfigMetadataI18n:
"_special",
"invisible",
"options",
"slider",
]:
if attr in field_data:
field_result[attr] = field_data[attr]
+21 -1
View File
@@ -1,3 +1,4 @@
import random
import re
import time
import traceback
@@ -42,6 +43,18 @@ class ResultDecorateStage(Stage):
"forward_threshold"
]
trigger_probability = ctx.astrbot_config["provider_tts_settings"].get(
"trigger_probability",
1,
)
try:
self.tts_trigger_probability = max(
0.0,
min(float(trigger_probability), 1.0),
)
except (TypeError, ValueError):
self.tts_trigger_probability = 1.0
# 分段回复
self.words_count_threshold = int(
ctx.astrbot_config["platform_settings"]["segmented_reply"][
@@ -246,7 +259,14 @@ class ResultDecorateStage(Stage):
and result.is_llm_result()
and SessionServiceManager.should_process_tts_request(event)
):
if not tts_provider:
should_tts = self.tts_trigger_probability >= 1.0 or (
self.tts_trigger_probability > 0.0
and random.random() <= self.tts_trigger_probability
)
if not should_tts:
logger.debug("跳过 TTS:触发概率未命中。")
elif not tts_provider:
logger.warning(
f"会话 {event.unified_msg_origin} 未配置文本转语音模型。",
)
@@ -304,16 +304,32 @@ function hasVisibleItemsAfter(items, currentIndex) {
hide-details
></v-text-field>
<!-- Numeric input -->
<v-text-field
<!-- Numeric input with optional slider -->
<div
v-else-if="(metadata[metadataKey].items[key]?.type === 'int' || metadata[metadataKey].items[key]?.type === 'float') && !metadata[metadataKey]?.invisible"
v-model="iterable[key]"
density="compact"
variant="outlined"
class="config-field"
type="number"
hide-details
></v-text-field>
class="d-flex align-center gap-3"
>
<v-slider
v-if="metadata[metadataKey].items[key]?.slider"
v-model.number="iterable[key]"
:min="metadata[metadataKey].items[key]?.slider?.min ?? 0"
:max="metadata[metadataKey].items[key]?.slider?.max ?? 100"
:step="metadata[metadataKey].items[key]?.slider?.step ?? 1"
color="primary"
density="compact"
hide-details
class="flex-grow-1"
></v-slider>
<v-text-field
v-model.number="iterable[key]"
density="compact"
variant="outlined"
class="config-field"
type="number"
hide-details
style="max-width: 140px;"
></v-text-field>
</div>
<!-- Text area -->
<v-textarea
@@ -413,16 +429,32 @@ function hasVisibleItemsAfter(items, currentIndex) {
hide-details
></v-text-field>
<!-- Numeric input -->
<v-text-field
<!-- Numeric input with optional slider -->
<div
v-else-if="(metadata[metadataKey]?.type === 'int' || metadata[metadataKey]?.type === 'float') && !metadata[metadataKey]?.invisible"
v-model="iterable[metadataKey]"
density="compact"
variant="outlined"
class="config-field"
type="number"
hide-details
></v-text-field>
class="d-flex align-center gap-3"
>
<v-slider
v-if="metadata[metadataKey]?.slider"
v-model.number="iterable[metadataKey]"
:min="metadata[metadataKey]?.slider?.min ?? 0"
:max="metadata[metadataKey]?.slider?.max ?? 100"
:step="metadata[metadataKey]?.slider?.step ?? 1"
color="primary"
density="compact"
hide-details
class="flex-grow-1"
></v-slider>
<v-text-field
v-model.number="iterable[metadataKey]"
density="compact"
variant="outlined"
class="config-field"
type="number"
hide-details
style="max-width: 140px;"
></v-text-field>
</div>
<!-- Text area -->
<v-textarea
@@ -245,10 +245,29 @@ function getSpecialSubtype(value) {
<v-text-field v-else-if="itemMeta?.type === 'string'" v-model="createSelectorModel(itemKey).value"
density="compact" variant="outlined" class="config-field" hide-details></v-text-field>
<!-- Numeric input for JSON selector -->
<v-text-field v-else-if="itemMeta?.type === 'int' || itemMeta?.type === 'float'"
v-model="createSelectorModel(itemKey).value" density="compact" variant="outlined" class="config-field"
type="number" hide-details></v-text-field>
<!-- Numeric input with optional slider for JSON selector -->
<div v-else-if="itemMeta?.type === 'int' || itemMeta?.type === 'float'" class="d-flex align-center gap-3">
<v-slider
v-if="itemMeta?.slider"
v-model.number="createSelectorModel(itemKey).value"
:min="itemMeta?.slider?.min ?? 0"
:max="itemMeta?.slider?.max ?? 100"
:step="itemMeta?.slider?.step ?? 1"
color="primary"
density="compact"
hide-details
style="flex: 3"
></v-slider>
<v-text-field
v-model.number="createSelectorModel(itemKey).value"
density="compact"
variant="outlined"
class="config-field"
style="flex: 2"
type="number"
hide-details
></v-text-field>
</div>
<!-- Text area for JSON selector -->
<v-textarea v-else-if="itemMeta?.type === 'text'" v-model="createSelectorModel(itemKey).value"
@@ -57,6 +57,9 @@
},
"provider_id": {
"description": "Default Text-to-Speech Model"
},
"trigger_probability": {
"description": "TTS Trigger Probability"
}
}
},
@@ -62,6 +62,9 @@
},
"provider_id": {
"description": "默认文本转语音模型"
},
"trigger_probability": {
"description": "TTS 触发概率"
}
}
},