refactor(应用): 优化嵌入应用

This commit is contained in:
wxg0103 2024-11-19 17:05:09 +08:00 committed by wxg
parent ec4f844abd
commit 260cdb044e
7 changed files with 111 additions and 13 deletions

View File

@ -12,6 +12,8 @@ class ApplicationNodeSerializer(serializers.Serializer):
question_reference_address = serializers.ListField(required=True, error_messages=ErrMessage.list("用户问题"))
api_input_field_list = serializers.ListField(required=False, error_messages=ErrMessage.list("api输入字段"))
user_input_field_list = serializers.ListField(required=False, error_messages=ErrMessage.uuid("用户输入字段"))
image_list = serializers.ListField(required=False, error_messages=ErrMessage.list("图片"))
document_list = serializers.ListField(required=False, error_messages=ErrMessage.list("文档"))
class IApplicationNode(INode):
@ -31,10 +33,27 @@ class IApplicationNode(INode):
for user_input_field in self.node_params_serializer.data.get('user_input_field_list', []):
kwargs[user_input_field['field']] = self.workflow_manage.get_reference_field(user_input_field['value'][0],
user_input_field['value'][1:])
# 判断是否包含这个属性
app_document_list = self.node_params_serializer.data.get('document_list', [])
if app_document_list and len(app_document_list) > 0:
app_document_list = self.workflow_manage.get_reference_field(
app_document_list[0],
app_document_list[1:])
for document in app_document_list:
if 'file_id' not in document:
raise ValueError("参数值错误: 上传的文档中缺少file_id")
app_image_list = self.node_params_serializer.data.get('image_list', [])
if app_image_list and len(app_image_list) > 0:
app_image_list = self.workflow_manage.get_reference_field(
app_image_list[0],
app_image_list[1:])
for image in app_image_list:
if 'file_id' not in image:
raise ValueError("参数值错误: 上传的图片中缺少file_id")
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data,
app_document_list=app_document_list, app_image_list=app_image_list,
message=str(question), **kwargs)
def execute(self, application_id, message, chat_id, chat_record_id, stream, re_chat, client_id, client_type,
**kwargs) -> NodeResult:
app_document_list=None, app_image_list=None, **kwargs) -> NodeResult:
pass

View File

@ -71,6 +71,7 @@ class BaseApplicationNode(IApplicationNode):
self.answer_text = details.get('answer')
def execute(self, application_id, message, chat_id, chat_record_id, stream, re_chat, client_id, client_type,
app_document_list=None, app_image_list=None,
**kwargs) -> NodeResult:
from application.serializers.chat_message_serializers import ChatMessageSerializer
# 生成嵌入应用的chat_id
@ -79,13 +80,20 @@ class BaseApplicationNode(IApplicationNode):
'application_id': application_id,
'abstract': message
})
if app_document_list is None:
app_document_list = []
if app_image_list is None:
app_image_list = []
response = ChatMessageSerializer(
data={'chat_id': current_chat_id, 'message': message,
're_chat': re_chat,
'stream': stream,
'application_id': application_id,
'client_id': client_id,
'client_type': client_type, 'form_data': kwargs}).chat(base_to_response=OpenaiToResponse())
'client_type': client_type,
'document_list': app_document_list,
'image_list': app_image_list,
'form_data': kwargs}).chat(base_to_response=OpenaiToResponse())
if response.status_code == 200:
if stream:
content_generator = response.streaming_content

View File

@ -149,13 +149,20 @@ function clickNodes(item: any, data?: any, type?: string) {
}
if (type == 'application') {
if (isWorkFlow(data.type)) {
console.log(data.work_flow.nodes[0].properties.api_input_field_list)
const nodeData = data.work_flow.nodes[0].properties.node_data
const fileUploadSetting = nodeData.file_upload_setting
item['properties']['node_data'] = {
name: data.name,
icon: data.icon,
application_id: data.id,
api_input_field_list: data.work_flow.nodes[0].properties.api_input_field_list,
user_input_field_list: data.work_flow.nodes[0].properties.user_input_field_list
user_input_field_list: data.work_flow.nodes[0].properties.user_input_field_list,
...(!fileUploadSetting
? {}
: {
...(fileUploadSetting.document ? { document_list: [] } : {}),
...(fileUploadSetting.image ? { image_list: [] } : {})
})
}
} else {
item['properties']['node_data'] = {
@ -186,12 +193,20 @@ function onmousedown(item: any, data?: any, type?: string) {
}
if (type == 'application') {
if (isWorkFlow(data.type)) {
const nodeData = data.work_flow.nodes[0].properties.node_data
const fileUploadSetting = nodeData.file_upload_setting
item['properties']['node_data'] = {
name: data.name,
icon: data.icon,
application_id: data.id,
api_input_field_list: data.work_flow.nodes[0].properties.api_input_field_list,
user_input_field_list: data.work_flow.nodes[0].properties.user_input_field_list
user_input_field_list: data.work_flow.nodes[0].properties.user_input_field_list,
...(!fileUploadSetting
? {}
: {
...(fileUploadSetting.document ? { document_list: [] } : {}),
...(fileUploadSetting.image ? { image_list: [] } : {})
})
}
} else {
item['properties']['node_data'] = {

View File

@ -3,7 +3,12 @@
<div class="flex-between mb-16">
<h4>{{ $t('views.application.applicationList.title') }}</h4>
<div class="flex-between">
<el-select v-model="selectUserId" class="mr-12 w-120" @change="searchHandle">
<el-select
v-model="selectUserId"
class="mr-12"
@change="searchHandle"
style="max-width: 240px; width: 150px"
>
<el-option
v-for="item in userOptions"
:key="item.value"
@ -17,6 +22,7 @@
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
prefix-icon="Search"
class="w-240"
style="min-width: 240px"
clearable
/>
</div>

View File

@ -3,7 +3,12 @@
<div class="flex-between mb-16">
<h4>知识库</h4>
<div class="flex-between">
<el-select v-model="selectUserId" class="mr-12 w-120" @change="searchHandle">
<el-select
v-model="selectUserId"
class="mr-12"
@change="searchHandle"
style="max-width: 240px; width: 150px"
>
<el-option
v-for="item in userOptions"
:key="item.value"
@ -17,6 +22,7 @@
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
prefix-icon="Search"
class="w-240"
style="max-width: 240px"
clearable
/>
</div>

View File

@ -3,7 +3,12 @@
<div class="flex-between mb-16">
<h4>函数库</h4>
<div class="flex-between">
<el-select v-model="selectUserId" class="mr-12 w-120" @change="searchHandle">
<el-select
v-model="selectUserId"
class="mr-12"
style="max-width: 240px; width: 150px"
@change="searchHandle"
>
<el-option
v-for="item in userOptions"
:key="item.value"
@ -17,6 +22,7 @@
placeholder="按函数名称搜索"
prefix-icon="Search"
class="w-240"
style="max-width: 240px"
clearable
/>
</div>

View File

@ -27,6 +27,44 @@
v-model="form_data.question_reference_address"
/>
</el-form-item>
<el-form-item
v-if="form_data.hasOwnProperty('document_list') || 'document_list' in form_data"
label="选择文档"
prop="document_list"
:rules="{
message: '请选择检索问题',
trigger: 'blur',
required: false
}"
>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
v-model="form_data.document_list"
/>
</el-form-item>
<el-form-item
v-if="form_data.hasOwnProperty('image_list') || 'image_list' in form_data"
label="选择图片"
prop="image_list"
:rules="{
message: '请选择检索问题',
trigger: 'blur',
required: false
}"
>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
v-model="form_data.image_list"
/>
</el-form-item>
<div v-for="(field, index) in form_data.api_input_field_list" :key="'api-input-' + index">
<el-form-item
:label="field.variable"
@ -45,7 +83,6 @@
</el-form-item>
</div>
<!-- Loop through dynamic fields for user_input_field_list -->
<div v-for="(field, index) in form_data.user_input_field_list" :key="'user-input-' + index">
<el-form-item
:label="field.label"
@ -94,9 +131,11 @@ import NodeCascader from '@/workflow/common/NodeCascader.vue'
import type { FormInstance } from 'element-plus'
const form = {
question_reference_address: [],
question_reference_address: ['start-node', 'question'],
api_input_field_list: [],
user_input_field_list: []
user_input_field_list: [],
document_list: ['start-node', 'document'],
image_list: ['start-node', 'image']
}
const applicationNodeFormRef = ref<FormInstance>()
@ -124,7 +163,6 @@ const validate = () => {
}
onMounted(() => {
console.log(applicationNodeFormRef.value)
set(props.nodeModel, 'validate', validate)
})
</script>