Skip to content

Commit 966a3a8

Browse files
committed
feat: Intent STT TTS node support model reference
1 parent d82fa99 commit 966a3a8

File tree

10 files changed

+203
-72
lines changed

10 files changed

+203
-72
lines changed

apps/application/flow/step_node/intent_node/i_intent_node.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ class IntentBranchSerializer(serializers.Serializer):
1616

1717

1818
class IntentNodeSerializer(serializers.Serializer):
19-
model_id = serializers.CharField(required=True, label=_("Model id"))
19+
model_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Model id"))
20+
model_id_type = serializers.CharField(required=False, default='custom', label=_("Model id type"))
21+
model_id_reference = serializers.ListField(required=False, child=serializers.CharField(), allow_empty=True,
22+
label=_("Reference Field"))
2023
content_list = serializers.ListField(required=True, label=_("Text content"))
2124
dialogue_number = serializers.IntegerField(required=True, label=
2225
_("Number of multi-round conversations"))
@@ -52,5 +55,5 @@ def _run(self):
5255
user_input=str(question))
5356

5457
def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch,
55-
model_params_setting=None, **kwargs) -> NodeResult:
58+
model_params_setting=None, model_id_type=None, model_id_reference=None, **kwargs) -> NodeResult:
5659
pass

apps/application/flow/step_node/intent_node/impl/base_intent_node.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ def save_context(self, details, workflow_manage):
5353
self.context['category'] = details.get('category')
5454

5555
def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch,
56-
model_params_setting=None, **kwargs) -> NodeResult:
56+
model_params_setting=None, model_id_type=None, model_id_reference=None, **kwargs) -> NodeResult:
57+
# 处理引用类型
58+
if model_id_type == 'reference' and model_id_reference:
59+
reference_data = self.workflow_manage.get_reference_field(
60+
model_id_reference[0],
61+
model_id_reference[1:],
62+
)
63+
if reference_data and isinstance(reference_data, dict):
64+
model_id = reference_data.get('model_id', model_id)
65+
model_params_setting = reference_data.get('model_params_setting')
5766

5867
# 设置默认模型参数
59-
if model_params_setting is None:
68+
if model_params_setting is None and model_id:
6069
model_params_setting = get_default_model_params_setting(model_id)
6170

6271
# 获取模型实例

apps/application/flow/step_node/speech_to_text_step_node/i_speech_to_text_node.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010

1111

1212
class SpeechToTextNodeSerializer(serializers.Serializer):
13-
stt_model_id = serializers.CharField(required=True, label=_("Model id"))
14-
13+
stt_model_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Model id"))
14+
stt_model_id_type = serializers.CharField(required=False, default='custom', label=_("Model id type"))
15+
stt_model_id_reference = serializers.ListField(required=False, child=serializers.CharField(), allow_empty=True,
16+
label=_("Reference Field"))
1517
is_result = serializers.BooleanField(required=False,
1618
label=_('Whether to return content'))
1719

@@ -40,6 +42,6 @@ def _run(self):
4042
return self.execute(audio=res, **self.node_params_serializer.data, **self.flow_params_serializer.data)
4143

4244
def execute(self, stt_model_id,
43-
audio, model_params_setting=None,
45+
audio, model_params_setting=None, stt_model_id_type=None, stt_model_id_reference=None,
4446
**kwargs) -> NodeResult:
4547
pass

apps/application/flow/step_node/speech_to_text_step_node/impl/base_speech_to_text_node.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@ def save_context(self, details, workflow_manage):
2121
self.answer_text = details.get('answer')
2222
self.context['exception_message'] = details.get('err_message')
2323

24-
def execute(self, stt_model_id, audio, model_params_setting=None, **kwargs) -> NodeResult:
24+
def execute(self, stt_model_id, audio, model_params_setting=None, stt_model_id_type=None, stt_model_id_reference=None,**kwargs) -> NodeResult:
25+
26+
# 处理引用类型
27+
if stt_model_id_type == 'reference' and stt_model_id_reference:
28+
reference_data = self.workflow_manage.get_reference_field(
29+
stt_model_id_reference[0],
30+
stt_model_id_reference[1:],
31+
)
32+
if reference_data and isinstance(reference_data, dict):
33+
stt_model_id = reference_data.get('stt_model_id', reference_data.get('model_id', stt_model_id))
34+
model_params_setting = reference_data.get('model_params_setting')
35+
2536
workspace_id = self.workflow_manage.get_body().get('workspace_id')
2637
stt_model = get_model_instance_by_model_workspace_id(stt_model_id, workspace_id, **(model_params_setting or {}))
2738
audio_list = audio

apps/application/flow/step_node/text_to_speech_step_node/i_text_to_speech_node.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212

1313
class TextToSpeechNodeSerializer(serializers.Serializer):
14-
tts_model_id = serializers.CharField(required=True, label=_("Model id"))
15-
14+
tts_model_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Model id"))
15+
tts_model_id_type = serializers.CharField(required=False, default='custom', label=_("Model id type"))
16+
tts_model_id_reference = serializers.ListField(required=False, child=serializers.CharField(), allow_empty=True,
17+
label=_("Reference Field"))
1618
is_result = serializers.BooleanField(required=False,
1719
label=_('Whether to return content'))
1820

@@ -35,6 +37,6 @@ def _run(self):
3537
return self.execute(content=content, **self.node_params_serializer.data, **self.flow_params_serializer.data)
3638

3739
def execute(self, tts_model_id,
38-
content, model_params_setting=None,
40+
content, model_params_setting=None, tts_model_id_type=None, tts_model_id_reference=None,
3941
**kwargs) -> NodeResult:
4042
pass

apps/application/flow/step_node/text_to_speech_step_node/impl/base_text_to_speech_node.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,17 @@ def save_context(self, details, workflow_manage):
4545
self.answer_text = details.get('answer')
4646

4747
def execute(self, tts_model_id,
48-
content, model_params_setting=None,
48+
content, model_params_setting=None, tts_model_id_type=None, tts_model_id_reference=None,
4949
max_length=1024, **kwargs) -> NodeResult:
50+
# 处理引用类型
51+
if tts_model_id_type == 'reference' and tts_model_id_reference:
52+
reference_data = self.workflow_manage.get_reference_field(
53+
tts_model_id_reference[0],
54+
tts_model_id_reference[1:],
55+
)
56+
if reference_data and isinstance(reference_data, dict):
57+
tts_model_id = reference_data.get('tts_model_id', reference_data.get('model_id', tts_model_id))
58+
model_params_setting = reference_data.get('model_params_setting')
5059
# 分割文本为合理片段
5160
content = _remove_empty_lines(content)
5261
content_chunks = [content[i:i + max_length]

ui/src/workflow/nodes/ai-chat-node/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@
5858
<div class="ml-8">
5959
<el-button
6060
:disabled="!chat_data.model_id"
61-
type="primary"
62-
link
6361
@click="openAIParamSettingDialog(chat_data.model_id)"
6462
@refreshForm="refreshParam"
6563
>
66-
<AppIcon iconName="app-setting"></AppIcon>
64+
<el-icon>
65+
<Operation />
66+
</el-icon>
6767
</el-button>
6868
</div>
6969
</div>

ui/src/workflow/nodes/intent-classify-node/index.vue

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,68 @@
1313
>
1414
<el-form-item
1515
:label="$t('views.application.form.aiModel.label')"
16-
prop="model_id"
16+
:prop="form_data.model_id_type === 'reference' ? 'model_id_reference' : 'model_id'"
1717
:rules="{
1818
required: true,
19-
message: $t('views.application.form.aiModel.placeholder'),
19+
message:
20+
form_data.model_id_type === 'reference'
21+
? $t('workflow.variable.placeholder')
22+
: $t('views.application.form.aiModel.placeholder'),
2023
trigger: 'change',
2124
}"
2225
>
2326
<template #label>
24-
<div class="flex-between">
27+
<div class="flex-between w-full">
2528
<div>
2629
<span
2730
>{{ $t('views.application.form.aiModel.label')
2831
}}<span class="color-danger">*</span></span
2932
>
3033
</div>
34+
<el-select
35+
v-model="form_data.model_id_type"
36+
:teleported="false"
37+
size="small"
38+
style="width: 85px"
39+
@change="form_data.model_id_reference = []"
40+
>
41+
<el-option :label="$t('workflow.variable.Referencing')" value="reference" />
42+
<el-option :label="$t('common.custom')" value="custom" />
43+
</el-select>
44+
</div>
45+
</template>
46+
<div class="flex-between w-full" v-if="form_data.model_id_type !== 'reference'">
47+
<ModelSelect
48+
@change="model_change"
49+
@wheel="wheel"
50+
:teleported="false"
51+
v-model="form_data.model_id"
52+
:placeholder="$t('views.application.form.aiModel.placeholder')"
53+
:options="modelOptions"
54+
@submitModel="getSelectModel"
55+
showFooter
56+
:model-type="'LLM'"
57+
></ModelSelect>
58+
<div class="ml-8">
3159
<el-button
32-
type="primary"
33-
link
3460
:disabled="!form_data.model_id"
3561
@click="openAIParamSettingDialog(form_data.model_id)"
3662
@refreshForm="refreshParam"
3763
>
38-
<AppIcon iconName="app-setting"></AppIcon>
64+
<el-icon>
65+
<Operation />
66+
</el-icon>
3967
</el-button>
4068
</div>
41-
</template>
42-
<ModelSelect
43-
@change="model_change"
44-
@wheel="wheel"
45-
:teleported="false"
46-
v-model="form_data.model_id"
47-
:placeholder="$t('views.application.form.aiModel.placeholder')"
48-
:options="modelOptions"
49-
@submitModel="getSelectModel"
50-
showFooter
51-
:model-type="'LLM'"
52-
></ModelSelect>
69+
</div>
70+
<NodeCascader
71+
v-else
72+
ref="nodeCascaderRef"
73+
:nodeModel="nodeModel"
74+
class="w-full"
75+
:placeholder="$t('workflow.variable.placeholder')"
76+
v-model="form_data.model_id_reference"
77+
/>
5378
</el-form-item>
5479
<el-form-item
5580
prop="content_list"
@@ -281,6 +306,8 @@ const model_change = (model_id?: string) => {
281306
282307
const form = {
283308
model_id: '',
309+
model_id_type: 'custom',
310+
model_id_reference: [],
284311
branch: [
285312
{
286313
id: randomId(),
@@ -309,6 +336,12 @@ const openAIParamSettingDialog = (modelId: string) => {
309336
const form_data = computed({
310337
get: () => {
311338
if (props.nodeModel.properties.node_data) {
339+
if (!props.nodeModel.properties.node_data.model_id_type) {
340+
set(props.nodeModel.properties.node_data, 'model_id_type', 'custom')
341+
}
342+
if (!props.nodeModel.properties.node_data.model_id_reference) {
343+
set(props.nodeModel.properties.node_data, 'model_id_reference', [])
344+
}
312345
return props.nodeModel.properties.node_data
313346
} else {
314347
set(props.nodeModel.properties, 'node_data', form)

ui/src/workflow/nodes/speech-to-text-node/index.vue

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@
1313
>
1414
<el-form-item
1515
:label="$t('workflow.nodes.speechToTextNode.stt_model.label')"
16-
prop="stt_model_id"
16+
:prop="
17+
form_data.stt_model_id_type === 'reference' ? 'stt_model_id_reference' : 'stt_model_id'
18+
"
1719
:rules="{
1820
required: true,
19-
message: $t('views.application.form.voiceInput.placeholder'),
21+
message:
22+
form_data.stt_model_id_type === 'reference'
23+
? $t('workflow.variable.placeholder')
24+
: $t('views.application.form.voiceInput.placeholder'),
2025
trigger: 'change',
2126
}"
2227
>
@@ -28,27 +33,45 @@
2833
}}<span class="color-danger">*</span></span
2934
>
3035
</div>
31-
<el-button
32-
type="primary"
33-
link
34-
@click="openSTTParamSettingDialog"
35-
:disabled="!form_data.stt_model_id"
36-
class="mr-4"
36+
<el-select
37+
v-model="form_data.stt_model_id_type"
38+
:teleported="false"
39+
size="small"
40+
style="width: 85px"
41+
@change="form_data.stt_model_id_reference = []"
3742
>
38-
<AppIcon iconName="app-setting"></AppIcon>
39-
</el-button>
43+
<el-option :label="$t('workflow.variable.Referencing')" value="reference" />
44+
<el-option :label="$t('common.custom')" value="custom" />
45+
</el-select>
4046
</div>
4147
</template>
42-
<ModelSelect
43-
@wheel="wheel"
44-
:teleported="false"
45-
@change="sttModelChange"
46-
v-model="form_data.stt_model_id"
47-
:placeholder="$t('views.application.form.voiceInput.placeholder')"
48-
:options="modelOptions"
49-
showFooter
50-
:model-type="'STT'"
51-
></ModelSelect>
48+
<div class="flex-between w-full" v-if="form_data.stt_model_id_type !== 'reference'">
49+
<ModelSelect
50+
@wheel="wheel"
51+
:teleported="false"
52+
@change="sttModelChange"
53+
v-model="form_data.stt_model_id"
54+
:placeholder="$t('views.application.form.voiceInput.placeholder')"
55+
:options="modelOptions"
56+
showFooter
57+
:model-type="'STT'"
58+
></ModelSelect>
59+
<div class="ml-8">
60+
<el-button @click="openSTTParamSettingDialog" :disabled="!form_data.stt_model_id">
61+
<el-icon>
62+
<Operation />
63+
</el-icon>
64+
</el-button>
65+
</div>
66+
</div>
67+
<NodeCascader
68+
v-else
69+
ref="nodeCascaderRef"
70+
:nodeModel="nodeModel"
71+
class="w-full"
72+
:placeholder="$t('workflow.variable.placeholder')"
73+
v-model="form_data.stt_model_id_reference"
74+
/>
5275
</el-form-item>
5376
<el-form-item
5477
:label="$t('workflow.nodes.speechToTextNode.audio.label')"
@@ -168,6 +191,8 @@ const wheel = (e: any) => {
168191
169192
const form = {
170193
stt_model_id: '',
194+
stt_model_id_type: 'custom',
195+
stt_model_id_reference: [],
171196
is_result: true,
172197
audio_list: [],
173198
model_params_setting: {},
@@ -176,6 +201,12 @@ const form = {
176201
const form_data = computed({
177202
get: () => {
178203
if (props.nodeModel.properties.node_data) {
204+
if (!props.nodeModel.properties.node_data.stt_model_id_type) {
205+
set(props.nodeModel.properties.node_data, 'stt_model_id_type', 'custom')
206+
}
207+
if (!props.nodeModel.properties.node_data.stt_model_id_reference) {
208+
set(props.nodeModel.properties.node_data, 'stt_model_id_reference', [])
209+
}
179210
return props.nodeModel.properties.node_data
180211
} else {
181212
set(props.nodeModel.properties, 'node_data', form)

0 commit comments

Comments
 (0)