Skip to content

Commit 9bb18c4

Browse files
committed
feat: Support reference model in ai chat node
1 parent 7fb3fb1 commit 9bb18c4

File tree

3 files changed

+65
-19
lines changed

3 files changed

+65
-19
lines changed

apps/application/flow/step_node/ai_chat_step_node/i_chat_node.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717

1818
class ChatNodeSerializer(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
system = serializers.CharField(required=False, allow_blank=True, allow_null=True,
2124
label=_("Role Setting"))
2225
prompt = serializers.CharField(required=True, label=_("Prompt word"))
@@ -58,7 +61,7 @@ def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
5861
def _run(self):
5962
if [WorkflowMode.KNOWLEDGE, WorkflowMode.KNOWLEDGE_LOOP, WorkflowMode.TOOL,
6063
WorkflowMode.TOOL_LOOP].__contains__(
61-
self.workflow_manage.flow.workflow_mode):
64+
self.workflow_manage.flow.workflow_mode):
6265
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data,
6366
**{'history_chat_record': [], 'stream': True, 'chat_id': None, 'chat_record_id': None})
6467
else:
@@ -67,6 +70,8 @@ def _run(self):
6770
def execute(self, model_id, system, prompt, dialogue_number, history_chat_record, stream, chat_id,
6871
chat_record_id,
6972
model_params_setting=None,
73+
model_id_type=None,
74+
model_id_reference=None,
7075
dialogue_type=None,
7176
model_setting=None,
7277
mcp_servers=None,

apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ def save_context(self, details, workflow_manage):
151151

152152
def execute(self, model_id, system, prompt, dialogue_number, history_chat_record, stream, chat_id, chat_record_id,
153153
model_params_setting=None,
154+
model_id_type=None,
155+
model_id_reference=None,
154156
dialogue_type=None,
155157
model_setting=None,
156158
mcp_servers=None,
@@ -165,8 +167,20 @@ def execute(self, model_id, system, prompt, dialogue_number, history_chat_record
165167
if dialogue_type is None:
166168
dialogue_type = 'WORKFLOW'
167169

168-
if model_params_setting is None:
170+
if model_id_type == 'reference' and model_id_reference:
171+
172+
reference_data = self.workflow_manage.get_reference_field(
173+
model_id_reference[0],
174+
model_id_reference[1:],
175+
)
176+
177+
if reference_data and isinstance(reference_data, dict):
178+
model_id = reference_data.get('model_id', model_id)
179+
model_params_setting = reference_data.get('model_params_setting')
180+
181+
if model_params_setting is None and model_id:
169182
model_params_setting = get_default_model_params_setting(model_id)
183+
170184
if model_setting is None:
171185
model_setting = {'reasoning_content_enable': False, 'reasoning_content_end': '</think>',
172186
'reasoning_content_start': '<think>'}

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

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
>
1414
<el-form-item
1515
:label="$t('views.application.form.aiModel.label')"
16-
prop="model_id"
16+
:prop="chat_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: chat_data.model_id_type === 'reference' ? $t('workflow.variable.placeholder') : $t('views.application.form.aiModel.placeholder'),
2020
trigger: 'change',
2121
}"
2222
>
@@ -28,7 +28,27 @@
2828
}}<span class="color-danger">*</span></span
2929
>
3030
</div>
31-
31+
<el-select v-model="chat_data.model_id_type" :teleported="false" size="small" style="width: 85px" @change="chat_data.model_id_reference = []">
32+
<el-option :label="$t('workflow.variable.Referencing')" value="reference" />
33+
<el-option :label="$t('common.custom')" value="custom" />
34+
</el-select>
35+
</div>
36+
</template>
37+
<div class="flex-between w-full" v-if="chat_data.model_id_type !== 'reference'">
38+
<div>
39+
<ModelSelect
40+
@change="model_change"
41+
@wheel="wheel"
42+
:teleported="false"
43+
v-model="chat_data.model_id"
44+
:placeholder="$t('views.application.form.aiModel.placeholder')"
45+
:options="modelOptions"
46+
@submitModel="getSelectModel"
47+
showFooter
48+
:model-type="'LLM'"
49+
></ModelSelect>
50+
</div>
51+
<div class="ml-8">
3252
<el-button
3353
:disabled="!chat_data.model_id"
3454
type="primary"
@@ -39,18 +59,15 @@
3959
<AppIcon iconName="app-setting"></AppIcon>
4060
</el-button>
4161
</div>
42-
</template>
43-
<ModelSelect
44-
@change="model_change"
45-
@wheel="wheel"
46-
:teleported="false"
47-
v-model="chat_data.model_id"
48-
:placeholder="$t('views.application.form.aiModel.placeholder')"
49-
:options="modelOptions"
50-
@submitModel="getSelectModel"
51-
showFooter
52-
:model-type="'LLM'"
53-
></ModelSelect>
62+
</div>
63+
<NodeCascader
64+
v-else
65+
ref="nodeCascaderRef"
66+
:nodeModel="nodeModel"
67+
class="w-full"
68+
:placeholder="$t('workflow.variable.placeholder')"
69+
v-model="chat_data.model_id_reference"
70+
/>
5471
</el-form-item>
5572

5673
<el-form-item>
@@ -71,7 +88,7 @@
7188
type="primary"
7289
link
7390
@click="openGeneratePromptDialog(chat_data.model_id)"
74-
:disabled="!chat_data.model_id"
91+
:disabled="chat_data.model_id_type === 'reference' || !chat_data.model_id"
7592
>
7693
<AppIcon iconName="app-generate-star"></AppIcon>
7794
</el-button>
@@ -458,6 +475,7 @@
458475
<script setup lang="ts">
459476
import { cloneDeep, set, groupBy } from 'lodash'
460477
import NodeContainer from '@/workflow/common/NodeContainer.vue'
478+
import NodeCascader from '@/workflow/common/NodeCascader.vue'
461479
import type { FormInstance } from 'element-plus'
462480
import { ref, computed, onMounted, inject, reactive } from 'vue'
463481
import { isLastNode } from '@/workflow/common/data'
@@ -532,6 +550,8 @@ const collapseData = reactive({
532550
533551
const form = {
534552
model_id: '',
553+
model_id_type: 'custom',
554+
model_id_reference: [],
535555
system: '',
536556
prompt: defaultPrompt,
537557
dialogue_number: 1,
@@ -556,6 +576,12 @@ const chat_data = computed({
556576
reasoning_content_enable: false,
557577
})
558578
}
579+
if (!props.nodeModel.properties.node_data.model_id_type) {
580+
set(props.nodeModel.properties.node_data, 'model_id_type', 'custom')
581+
}
582+
if (!props.nodeModel.properties.node_data.model_id_reference) {
583+
set(props.nodeModel.properties.node_data, 'model_id_reference', [])
584+
}
559585
return props.nodeModel.properties.node_data
560586
} else {
561587
set(props.nodeModel.properties, 'node_data', form)
@@ -573,6 +599,7 @@ const aiChatNodeFormRef = ref<FormInstance>()
573599
574600
const modelOptions = ref<any>(null)
575601
const AIModeParamSettingDialogRef = ref<InstanceType<typeof AIModeParamSettingDialog>>()
602+
const nodeCascaderRef = ref()
576603
const ReasoningParamSettingDialogRef = ref<InstanceType<typeof ReasoningParamSettingDialog>>()
577604
const validate = () => {
578605
return aiChatNodeFormRef.value?.validate().catch((err) => {

0 commit comments

Comments
 (0)