refactor(应用): 优化嵌入应用
This commit is contained in:
parent
ec4f844abd
commit
260cdb044e
@ -12,6 +12,8 @@ class ApplicationNodeSerializer(serializers.Serializer):
|
|||||||
question_reference_address = serializers.ListField(required=True, error_messages=ErrMessage.list("用户问题"))
|
question_reference_address = serializers.ListField(required=True, error_messages=ErrMessage.list("用户问题"))
|
||||||
api_input_field_list = serializers.ListField(required=False, error_messages=ErrMessage.list("api输入字段"))
|
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("用户输入字段"))
|
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):
|
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', []):
|
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],
|
kwargs[user_input_field['field']] = self.workflow_manage.get_reference_field(user_input_field['value'][0],
|
||||||
user_input_field['value'][1:])
|
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,
|
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)
|
message=str(question), **kwargs)
|
||||||
|
|
||||||
def execute(self, application_id, message, chat_id, chat_record_id, stream, re_chat, client_id, client_type,
|
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
|
pass
|
||||||
|
|||||||
@ -71,6 +71,7 @@ class BaseApplicationNode(IApplicationNode):
|
|||||||
self.answer_text = details.get('answer')
|
self.answer_text = details.get('answer')
|
||||||
|
|
||||||
def execute(self, application_id, message, chat_id, chat_record_id, stream, re_chat, client_id, client_type,
|
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:
|
**kwargs) -> NodeResult:
|
||||||
from application.serializers.chat_message_serializers import ChatMessageSerializer
|
from application.serializers.chat_message_serializers import ChatMessageSerializer
|
||||||
# 生成嵌入应用的chat_id
|
# 生成嵌入应用的chat_id
|
||||||
@ -79,13 +80,20 @@ class BaseApplicationNode(IApplicationNode):
|
|||||||
'application_id': application_id,
|
'application_id': application_id,
|
||||||
'abstract': message
|
'abstract': message
|
||||||
})
|
})
|
||||||
|
if app_document_list is None:
|
||||||
|
app_document_list = []
|
||||||
|
if app_image_list is None:
|
||||||
|
app_image_list = []
|
||||||
response = ChatMessageSerializer(
|
response = ChatMessageSerializer(
|
||||||
data={'chat_id': current_chat_id, 'message': message,
|
data={'chat_id': current_chat_id, 'message': message,
|
||||||
're_chat': re_chat,
|
're_chat': re_chat,
|
||||||
'stream': stream,
|
'stream': stream,
|
||||||
'application_id': application_id,
|
'application_id': application_id,
|
||||||
'client_id': client_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 response.status_code == 200:
|
||||||
if stream:
|
if stream:
|
||||||
content_generator = response.streaming_content
|
content_generator = response.streaming_content
|
||||||
|
|||||||
@ -149,13 +149,20 @@ function clickNodes(item: any, data?: any, type?: string) {
|
|||||||
}
|
}
|
||||||
if (type == 'application') {
|
if (type == 'application') {
|
||||||
if (isWorkFlow(data.type)) {
|
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'] = {
|
item['properties']['node_data'] = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
icon: data.icon,
|
icon: data.icon,
|
||||||
application_id: data.id,
|
application_id: data.id,
|
||||||
api_input_field_list: data.work_flow.nodes[0].properties.api_input_field_list,
|
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 {
|
} else {
|
||||||
item['properties']['node_data'] = {
|
item['properties']['node_data'] = {
|
||||||
@ -186,12 +193,20 @@ function onmousedown(item: any, data?: any, type?: string) {
|
|||||||
}
|
}
|
||||||
if (type == 'application') {
|
if (type == 'application') {
|
||||||
if (isWorkFlow(data.type)) {
|
if (isWorkFlow(data.type)) {
|
||||||
|
const nodeData = data.work_flow.nodes[0].properties.node_data
|
||||||
|
const fileUploadSetting = nodeData.file_upload_setting
|
||||||
item['properties']['node_data'] = {
|
item['properties']['node_data'] = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
icon: data.icon,
|
icon: data.icon,
|
||||||
application_id: data.id,
|
application_id: data.id,
|
||||||
api_input_field_list: data.work_flow.nodes[0].properties.api_input_field_list,
|
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 {
|
} else {
|
||||||
item['properties']['node_data'] = {
|
item['properties']['node_data'] = {
|
||||||
|
|||||||
@ -3,7 +3,12 @@
|
|||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<h4>{{ $t('views.application.applicationList.title') }}</h4>
|
<h4>{{ $t('views.application.applicationList.title') }}</h4>
|
||||||
<div class="flex-between">
|
<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
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@ -17,6 +22,7 @@
|
|||||||
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
|
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
|
||||||
prefix-icon="Search"
|
prefix-icon="Search"
|
||||||
class="w-240"
|
class="w-240"
|
||||||
|
style="min-width: 240px"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,12 @@
|
|||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<h4>知识库</h4>
|
<h4>知识库</h4>
|
||||||
<div class="flex-between">
|
<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
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@ -17,6 +22,7 @@
|
|||||||
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
|
:placeholder="$t('views.application.applicationList.searchBar.placeholder')"
|
||||||
prefix-icon="Search"
|
prefix-icon="Search"
|
||||||
class="w-240"
|
class="w-240"
|
||||||
|
style="max-width: 240px"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,12 @@
|
|||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<h4>函数库</h4>
|
<h4>函数库</h4>
|
||||||
<div class="flex-between">
|
<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
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@ -17,6 +22,7 @@
|
|||||||
placeholder="按函数名称搜索"
|
placeholder="按函数名称搜索"
|
||||||
prefix-icon="Search"
|
prefix-icon="Search"
|
||||||
class="w-240"
|
class="w-240"
|
||||||
|
style="max-width: 240px"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -27,6 +27,44 @@
|
|||||||
v-model="form_data.question_reference_address"
|
v-model="form_data.question_reference_address"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</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">
|
<div v-for="(field, index) in form_data.api_input_field_list" :key="'api-input-' + index">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="field.variable"
|
:label="field.variable"
|
||||||
@ -45,7 +83,6 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</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">
|
<div v-for="(field, index) in form_data.user_input_field_list" :key="'user-input-' + index">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
@ -94,9 +131,11 @@ import NodeCascader from '@/workflow/common/NodeCascader.vue'
|
|||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
question_reference_address: [],
|
question_reference_address: ['start-node', 'question'],
|
||||||
api_input_field_list: [],
|
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>()
|
const applicationNodeFormRef = ref<FormInstance>()
|
||||||
@ -124,7 +163,6 @@ const validate = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(applicationNodeFormRef.value)
|
|
||||||
set(props.nodeModel, 'validate', validate)
|
set(props.nodeModel, 'validate', validate)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user