feat: workflow application debug chat (#3245)
This commit is contained in:
parent
c7e30bb098
commit
bf630b9d07
@ -82,7 +82,7 @@ class WorkFlowPostHandler:
|
||||
index=0)
|
||||
|
||||
self.chat_info.append_chat_record(chat_record)
|
||||
self.chat_info.set_cahce()
|
||||
self.chat_info.set_cache()
|
||||
if [ChatUserType.ANONYMOUS_USER.value, ChatUserType.CHAT_USER.value].__contains__(
|
||||
workflow_body.get('chat_user_type')):
|
||||
application_public_access_client = (QuerySet(ApplicationChatUserStats)
|
||||
|
||||
@ -219,12 +219,17 @@ class ChatSerializers(serializers.Serializer):
|
||||
other_list = instance.get('other_list')
|
||||
workspace_id = chat_info.application.workspace_id
|
||||
chat_record_id = instance.get('chat_record_id')
|
||||
debug = self.data.get('debug', False)
|
||||
chat_record = None
|
||||
history_chat_record = chat_info.chat_record_list
|
||||
if chat_record_id is not None:
|
||||
chat_record = self.get_chat_record(chat_info, chat_record_id)
|
||||
history_chat_record = [r for r in chat_info.chat_record_list if str(r.id) != chat_record_id]
|
||||
work_flow_manage = WorkflowManage(Flow.new_instance(chat_info.work_flow_version.work_flow),
|
||||
if not debug:
|
||||
work_flow = chat_info.work_flow_version.work_flow
|
||||
else:
|
||||
work_flow = chat_info.application.work_flow
|
||||
work_flow_manage = WorkflowManage(Flow.new_instance(work_flow),
|
||||
{'history_chat_record': history_chat_record, 'question': message,
|
||||
'chat_id': chat_info.chat_id, 'chat_record_id': str(
|
||||
uuid.uuid1()) if chat_record is None else chat_record.id,
|
||||
@ -233,7 +238,7 @@ class ChatSerializers(serializers.Serializer):
|
||||
'chat_user_id': chat_user_id,
|
||||
'chat_user_type': chat_user_type,
|
||||
'workspace_id': workspace_id,
|
||||
'debug': self.data.get('debug', False)},
|
||||
'debug': debug},
|
||||
WorkFlowPostHandler(chat_info),
|
||||
base_to_response, form_data, image_list, document_list, audio_list,
|
||||
other_list,
|
||||
@ -339,12 +344,14 @@ class OpenChatSerializers(serializers.Serializer):
|
||||
chat_user_type = self.data.get("chat_user_type")
|
||||
debug = self.data.get("debug")
|
||||
chat_id = str(uuid.uuid7())
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application_id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if work_flow_version is None:
|
||||
raise AppApiException(500,
|
||||
gettext(
|
||||
"The application has not been published. Please use it after publishing."))
|
||||
work_flow_version = None
|
||||
if not debug:
|
||||
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application_id).order_by(
|
||||
'-create_time')[0:1].first()
|
||||
if work_flow_version is None:
|
||||
raise AppApiException(500,
|
||||
gettext(
|
||||
"The application has not been published. Please use it after publishing."))
|
||||
ChatInfo(chat_id, chat_user_id, chat_user_type, [],
|
||||
[],
|
||||
application_id,
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/lang-python": "^6.2.1",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@logicflow/core": "^2.0.15",
|
||||
"@logicflow/extension": "^2.0.20",
|
||||
"@logicflow/core": "^1.2.27",
|
||||
"@logicflow/extension": "^1.2.27",
|
||||
"@vavt/cm-extension": "^1.9.1",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"@wecom/jssdk": "^2.3.1",
|
||||
|
||||
@ -22,60 +22,55 @@ const getModel: (
|
||||
return get(`${prefix}/model`, data, loading)
|
||||
}
|
||||
/**
|
||||
* 获取当前用户可使用的模型列表
|
||||
* @param application_id
|
||||
* @param loading
|
||||
* @query { query_text: string, top_number: number, similarity: number }
|
||||
* @returns
|
||||
* 获取工作空间下重排模型列表
|
||||
* @param loading 加载器
|
||||
* @returns 重排模型列表
|
||||
*/
|
||||
const getApplicationRerankerModel: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (application_id, loading) => {
|
||||
const getRerankerModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'RERANKER' }, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户可使用的模型列表
|
||||
* @param application_id
|
||||
* 获取语音转文本模型列表
|
||||
* @param loading
|
||||
* @query { query_text: string, top_number: number, similarity: number }
|
||||
* @returns
|
||||
* @returns 语音转文本模型列表
|
||||
*/
|
||||
const getApplicationSTTModel: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (application_id, loading) => {
|
||||
const getSTTModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'STT' }, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户可使用的模型列表
|
||||
* @param application_id
|
||||
* 获取文本转语音模型列表
|
||||
* @param loading
|
||||
* @query { query_text: string, top_number: number, similarity: number }
|
||||
* @returns
|
||||
*/
|
||||
const getApplicationTTSModel: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (application_id, loading) => {
|
||||
const getTTSModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'TTS' }, loading)
|
||||
}
|
||||
|
||||
const getApplicationImageModel: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (application_id, loading) => {
|
||||
/**
|
||||
* 获取图片理解模型列表
|
||||
* @param loading
|
||||
* @returns 图片理解模型列表
|
||||
*/
|
||||
const getImageModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'IMAGE' }, loading)
|
||||
}
|
||||
|
||||
const getApplicationTTIModel: (
|
||||
application_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<Array<any>>> = (application_id, loading) => {
|
||||
/**
|
||||
* 获取图片生成模型列表
|
||||
* @param loading
|
||||
* @returns 图片生成模型列表
|
||||
*/
|
||||
const getTTIModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'TTI' }, loading)
|
||||
}
|
||||
/**
|
||||
* 获取大语言模型列表
|
||||
* @param loading
|
||||
* @returns 大语言模型列表
|
||||
*/
|
||||
const getLLMModel: (loading?: Ref<boolean>) => Promise<Result<Array<any>>> = (loading) => {
|
||||
return get(`${prefix}/model`, { model_type: 'LLM' }, loading)
|
||||
}
|
||||
/**
|
||||
* 获取模型参数表单
|
||||
* @param model_id 模型id
|
||||
@ -182,9 +177,10 @@ export default {
|
||||
pauseDownload,
|
||||
getModelParamsForm,
|
||||
updateModelParamsForm,
|
||||
getApplicationRerankerModel,
|
||||
getApplicationSTTModel,
|
||||
getApplicationTTSModel,
|
||||
getApplicationImageModel,
|
||||
getApplicationTTIModel,
|
||||
getRerankerModel,
|
||||
getSTTModel,
|
||||
getTTSModel,
|
||||
getImageModel,
|
||||
getTTIModel,
|
||||
getLLMModel,
|
||||
}
|
||||
|
||||
31
ui/src/directives/resize.ts
Normal file
31
ui/src/directives/resize.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { App } from 'vue'
|
||||
export default {
|
||||
install: (app: App) => {
|
||||
app.directive('resize', {
|
||||
created(el: any, binding: any) {
|
||||
// 记录长宽
|
||||
let width = ''
|
||||
let height = ''
|
||||
function getSize() {
|
||||
const style = (document.defaultView as any).getComputedStyle(el)
|
||||
// 如果当前长宽和历史长宽不同
|
||||
if (width !== style.width || height !== style.height) {
|
||||
// binding.value在这里就是下面的resizeChart函数
|
||||
|
||||
binding.value({
|
||||
width: parseFloat(style.width),
|
||||
height: parseFloat(style.height)
|
||||
})
|
||||
}
|
||||
width = style.width
|
||||
height = style.height
|
||||
}
|
||||
|
||||
;(el as any).__vueDomResize__ = setInterval(getSize, 500)
|
||||
},
|
||||
unmounted(el: any, binding: any) {
|
||||
clearInterval((el as any).__vueDomResize__)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -673,7 +673,7 @@ function getKnowledge() {
|
||||
function getModel() {
|
||||
loading.value = true
|
||||
modelAPI
|
||||
.getModel({})
|
||||
.getLLMModel()
|
||||
.then((res: any) => {
|
||||
modelOptions.value = groupBy(res?.data, 'provider')
|
||||
loading.value = false
|
||||
@ -686,7 +686,7 @@ function getModel() {
|
||||
function getSTTModel() {
|
||||
loading.value = true
|
||||
modelAPI
|
||||
.getApplicationSTTModel(id)
|
||||
.getSTTModel()
|
||||
.then((res: any) => {
|
||||
sttModelOptions.value = groupBy(res?.data, 'provider')
|
||||
loading.value = false
|
||||
@ -699,7 +699,7 @@ function getSTTModel() {
|
||||
function getTTSModel() {
|
||||
loading.value = true
|
||||
modelAPI
|
||||
.getApplicationTTSModel(id)
|
||||
.getTTSModel()
|
||||
.then((res: any) => {
|
||||
ttsModelOptions.value = groupBy(res?.data, 'provider')
|
||||
loading.value = false
|
||||
|
||||
@ -144,8 +144,8 @@
|
||||
{
|
||||
required: true,
|
||||
message: $t('common.inputPlaceholder'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-input v-model="form.title" @blur="form.title = form.title.trim()" />
|
||||
@ -176,7 +176,7 @@ import { MsgError, MsgConfirm } from '@/utils/message'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { t } from '@/locales'
|
||||
const {
|
||||
params: { id }
|
||||
params: { id },
|
||||
} = app.config.globalProperties.$route as any
|
||||
|
||||
const height = ref<{
|
||||
@ -186,14 +186,14 @@ const height = ref<{
|
||||
}>({
|
||||
stepContainerHeight: 0,
|
||||
inputContainerHeight: 0,
|
||||
outputContainerHeight: 0
|
||||
outputContainerHeight: 0,
|
||||
})
|
||||
const showAnchor = ref<boolean>(false)
|
||||
const anchorData = ref<any>()
|
||||
const titleFormRef = ref()
|
||||
const nodeNameDialogVisible = ref<boolean>(false)
|
||||
const form = ref<any>({
|
||||
title: ''
|
||||
title: '',
|
||||
})
|
||||
|
||||
const condition = computed({
|
||||
@ -206,7 +206,7 @@ const condition = computed({
|
||||
}
|
||||
set(props.nodeModel.properties, 'condition', 'AND')
|
||||
return true
|
||||
}
|
||||
},
|
||||
})
|
||||
const showNode = computed({
|
||||
set: (v) => {
|
||||
@ -218,7 +218,7 @@ const showNode = computed({
|
||||
}
|
||||
set(props.nodeModel.properties, 'showNode', true)
|
||||
return true
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const handleWheel = (event: any) => {
|
||||
@ -244,7 +244,7 @@ const editName = async (formEl: FormInstance | undefined) => {
|
||||
if (valid) {
|
||||
if (
|
||||
!props.nodeModel.graphModel.nodes?.some(
|
||||
(node: any) => node.properties.stepName === form.value.title
|
||||
(node: any) => node.properties.stepName === form.value.title,
|
||||
)
|
||||
) {
|
||||
set(props.nodeModel.properties, 'stepName', form.value.title)
|
||||
@ -274,7 +274,7 @@ const copyNode = () => {
|
||||
const deleteNode = () => {
|
||||
MsgConfirm(t('common.tip'), t('views.applicationWorkflow.delete.confirmTitle'), {
|
||||
confirmButtonText: t('common.confirm'),
|
||||
confirmButtonClass: 'danger'
|
||||
confirmButtonClass: 'danger',
|
||||
}).then(() => {
|
||||
props.nodeModel.graphModel.deleteNode(props.nodeModel.id)
|
||||
})
|
||||
@ -295,13 +295,13 @@ function clickNodes(item: any) {
|
||||
type: item.type,
|
||||
properties: item.properties,
|
||||
x: anchorData.value?.x + width / 2 + 200,
|
||||
y: anchorData.value?.y - item.height
|
||||
y: anchorData.value?.y - item.height,
|
||||
})
|
||||
props.nodeModel.graphModel.addEdge({
|
||||
type: 'app-edge',
|
||||
sourceNodeId: props.nodeModel.id,
|
||||
sourceAnchorId: anchorData.value?.id,
|
||||
targetNodeId: nodeModel.id
|
||||
targetNodeId: nodeModel.id,
|
||||
})
|
||||
|
||||
closeNodeMenu()
|
||||
@ -317,7 +317,7 @@ const nodeFields = computed(() => {
|
||||
label: field.label,
|
||||
value: field.value,
|
||||
globeLabel: `{{${props.nodeModel.properties.stepName}.${field.value}}}`,
|
||||
globeValue: `{{context['${props.nodeModel.id}'].${field.value}}}`
|
||||
globeValue: `{{context['${props.nodeModel.id}'].${field.value}}}`,
|
||||
}
|
||||
})
|
||||
return fields
|
||||
@ -364,4 +364,9 @@ onMounted(() => {
|
||||
:deep(.el-card) {
|
||||
overflow: visible;
|
||||
}
|
||||
.app-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -11,7 +11,7 @@ import AppEdge from './common/edge'
|
||||
import Control from './common/NodeControl.vue'
|
||||
import { baseNodes } from '@/workflow/common/data'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
import '@logicflow/core/dist/index.css'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
import { initDefaultShortcut } from '@/workflow/common/shortcut'
|
||||
import Dagre from '@/workflow/plugins/dagre'
|
||||
import { getTeleport } from '@/workflow/common/teleport'
|
||||
@ -32,11 +32,11 @@ type ShapeItem = {
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
data: Object || null
|
||||
data: Object || null,
|
||||
})
|
||||
|
||||
const defaultData = {
|
||||
nodes: [...baseNodes]
|
||||
nodes: [...baseNodes],
|
||||
}
|
||||
const graphData = computed({
|
||||
get: () => {
|
||||
@ -48,7 +48,7 @@ const graphData = computed({
|
||||
},
|
||||
set: (value) => {
|
||||
return value
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const lf = ref()
|
||||
@ -67,27 +67,27 @@ const renderGraphData = (data?: any) => {
|
||||
adjustEdge: false,
|
||||
adjustEdgeStartAndEnd: false,
|
||||
background: {
|
||||
backgroundColor: '#f5f6f7'
|
||||
backgroundColor: '#f5f6f7',
|
||||
},
|
||||
grid: {
|
||||
size: 10,
|
||||
type: 'dot',
|
||||
config: {
|
||||
color: '#DEE0E3',
|
||||
thickness: 1
|
||||
}
|
||||
thickness: 1,
|
||||
},
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true
|
||||
enabled: true,
|
||||
},
|
||||
isSilentMode: false,
|
||||
container: container
|
||||
container: container,
|
||||
})
|
||||
lf.value.setTheme({
|
||||
bezier: {
|
||||
stroke: '#afafaf',
|
||||
strokeWidth: 1
|
||||
}
|
||||
strokeWidth: 1,
|
||||
},
|
||||
})
|
||||
lf.value.on('graph:rendered', () => {
|
||||
flowId.value = lf.value.graphModel.flowId
|
||||
@ -124,7 +124,7 @@ const onmousedown = (shapeItem: ShapeItem) => {
|
||||
if (shapeItem.type) {
|
||||
lf.value.dnd.startDrag({
|
||||
type: shapeItem.type,
|
||||
properties: { ...shapeItem.properties }
|
||||
properties: { ...shapeItem.properties },
|
||||
})
|
||||
}
|
||||
if (shapeItem.callback) {
|
||||
@ -139,7 +139,7 @@ const addNode = (shapeItem: ShapeItem) => {
|
||||
type: shapeItem.type,
|
||||
properties: shapeItem.properties,
|
||||
x: virtualRectCenterPositionX,
|
||||
y: virtualRectCenterPositionY - lf.value.graphModel.height / 2
|
||||
y: virtualRectCenterPositionY - lf.value.graphModel.height / 2,
|
||||
})
|
||||
newNode.isSelected = true
|
||||
newNode.isHovered = true
|
||||
@ -157,7 +157,7 @@ defineExpose({
|
||||
addNode,
|
||||
clearGraphData,
|
||||
renderGraphData,
|
||||
render
|
||||
render,
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
:rules="{
|
||||
required: true,
|
||||
message: $t('views.application.form.aiModel.placeholder'),
|
||||
trigger: 'change'
|
||||
trigger: 'change',
|
||||
}"
|
||||
>
|
||||
<template #label>
|
||||
@ -68,7 +68,7 @@
|
||||
:rules="{
|
||||
required: true,
|
||||
message: $t('views.application.form.prompt.requiredMessage'),
|
||||
trigger: 'blur'
|
||||
trigger: 'blur',
|
||||
}"
|
||||
>
|
||||
<template #label>
|
||||
@ -80,9 +80,7 @@
|
||||
>
|
||||
</div>
|
||||
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
|
||||
<template #content
|
||||
>{{ $t('views.application.form.prompt.tooltip') }}
|
||||
</template>
|
||||
<template #content>{{ $t('views.application.form.prompt.tooltip') }} </template>
|
||||
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
@ -127,9 +125,7 @@
|
||||
<template #label>
|
||||
<div class="flex-between w-full">
|
||||
<div>
|
||||
<span>{{
|
||||
$t('views.application.form.reasoningContent.label')
|
||||
}}</span>
|
||||
<span>{{ $t('views.application.form.reasoningContent.label') }}</span>
|
||||
</div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@ -179,6 +175,7 @@ import NodeContainer from '@/workflow/common/NodeContainer.vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import applicationApi from '@/api/application/application'
|
||||
import modelAPI from '@/api/model/model.ts'
|
||||
import useStore from '@/stores'
|
||||
import { isLastNode } from '@/workflow/common/data'
|
||||
import AIModeParamSettingDialog from '@/views/application/component/AIModeParamSettingDialog.vue'
|
||||
@ -213,7 +210,7 @@ const model_change = (model_id?: string) => {
|
||||
}
|
||||
}
|
||||
const {
|
||||
params: { id }
|
||||
params: { id },
|
||||
} = app.config.globalProperties.$route as any
|
||||
|
||||
// @ts-ignore
|
||||
@ -234,8 +231,8 @@ const form = {
|
||||
model_setting: {
|
||||
reasoning_content_start: '<think>',
|
||||
reasoning_content_end: '</think>',
|
||||
reasoning_content_enable: false
|
||||
}
|
||||
reasoning_content_enable: false,
|
||||
},
|
||||
}
|
||||
|
||||
const chat_data = computed({
|
||||
@ -245,7 +242,7 @@ const chat_data = computed({
|
||||
set(props.nodeModel.properties.node_data, 'model_setting', {
|
||||
reasoning_content_start: '<think>',
|
||||
reasoning_content_end: '</think>',
|
||||
reasoning_content_enable: false
|
||||
reasoning_content_enable: false,
|
||||
})
|
||||
}
|
||||
return props.nodeModel.properties.node_data
|
||||
@ -257,7 +254,7 @@ const chat_data = computed({
|
||||
},
|
||||
set: (value) => {
|
||||
set(props.nodeModel.properties, 'node_data', value)
|
||||
}
|
||||
},
|
||||
})
|
||||
const props = defineProps<{ nodeModel: any }>()
|
||||
|
||||
@ -274,7 +271,7 @@ const validate = () => {
|
||||
|
||||
function getModel() {
|
||||
if (id) {
|
||||
applicationApi.getApplicationModel(id).then((res: any) => {
|
||||
modelAPI.getLLMModel().then((res: any) => {
|
||||
modelOptions.value = groupBy(res?.data, 'provider')
|
||||
})
|
||||
} else {
|
||||
@ -302,7 +299,7 @@ function submitReasoningDialog(val: any) {
|
||||
let model_setting = cloneDeep(props.nodeModel.properties.node_data.model_setting)
|
||||
model_setting = {
|
||||
...model_setting,
|
||||
...val
|
||||
...val,
|
||||
}
|
||||
|
||||
set(props.nodeModel.properties.node_data, 'model_setting', model_setting)
|
||||
@ -312,7 +309,7 @@ const mcpServersDialogRef = ref()
|
||||
function openMcpServersDialog() {
|
||||
const config = {
|
||||
mcp_servers: chat_data.value.mcp_servers,
|
||||
mcp_enable: chat_data.value.mcp_enable
|
||||
mcp_enable: chat_data.value.mcp_enable,
|
||||
}
|
||||
mcpServersDialogRef.value.open(config)
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
:rules="{
|
||||
message: t('views.application.form.appName.requiredMessage'),
|
||||
trigger: 'blur',
|
||||
required: true
|
||||
required: true,
|
||||
}"
|
||||
>
|
||||
<el-input
|
||||
@ -86,9 +86,7 @@
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<div class="flex-between">
|
||||
<span class="mr-4">{{
|
||||
$t('views.application.form.voiceInput.label')
|
||||
}}</span>
|
||||
<span class="mr-4">{{ $t('views.application.form.voiceInput.label') }}</span>
|
||||
<div class="flex">
|
||||
<el-checkbox v-if="form_data.stt_model_enable" v-model="form_data.stt_autosend">{{
|
||||
$t('views.application.form.voiceInput.autoSend')
|
||||
@ -115,9 +113,7 @@
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<div class="flex-between">
|
||||
<span class="mr-4">{{
|
||||
$t('views.application.form.voicePlay.label')
|
||||
}}</span>
|
||||
<span class="mr-4">{{ $t('views.application.form.voicePlay.label') }}</span>
|
||||
<div class="flex">
|
||||
<el-checkbox v-if="form_data.tts_model_enable" v-model="form_data.tts_autoplay">{{
|
||||
$t('views.application.form.voicePlay.autoPlay')
|
||||
@ -133,14 +129,8 @@
|
||||
</template>
|
||||
<div class="w-full">
|
||||
<el-radio-group v-model="form_data.tts_type" v-show="form_data.tts_model_enable">
|
||||
<el-radio
|
||||
:label="$t('views.application.form.voicePlay.browser')"
|
||||
value="BROWSER"
|
||||
/>
|
||||
<el-radio
|
||||
:label="$t('views.application.form.voicePlay.tts')"
|
||||
value="TTS"
|
||||
/>
|
||||
<el-radio :label="$t('views.application.form.voicePlay.browser')" value="BROWSER" />
|
||||
<el-radio :label="$t('views.application.form.voicePlay.tts')" value="TTS" />
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="flex-between w-full">
|
||||
@ -183,6 +173,7 @@ import NodeContainer from '@/workflow/common/NodeContainer.vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import applicationApi from '@/api/application/application'
|
||||
import modelAPI from '@/api/model/model.ts'
|
||||
import { MsgError, MsgSuccess, MsgWarning } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
import TTSModeParamSettingDialog from '@/views/application/component/TTSModeParamSettingDialog.vue'
|
||||
@ -191,7 +182,7 @@ import UserInputFieldTable from './component/UserInputFieldTable.vue'
|
||||
import FileUploadSettingDialog from '@/workflow/nodes/base-node/component/FileUploadSettingDialog.vue'
|
||||
|
||||
const {
|
||||
params: { id }
|
||||
params: { id },
|
||||
} = app.config.globalProperties.$route as any
|
||||
|
||||
const props = defineProps<{ nodeModel: any }>()
|
||||
@ -206,7 +197,7 @@ const FileUploadSettingDialogRef = ref<InstanceType<typeof FileUploadSettingDial
|
||||
const form = {
|
||||
name: '',
|
||||
desc: '',
|
||||
prologue: t('views.application.form.defaultPrologue')
|
||||
prologue: t('views.application.form.defaultPrologue'),
|
||||
}
|
||||
|
||||
const wheel = (e: any) => {
|
||||
@ -234,7 +225,7 @@ const form_data = computed({
|
||||
},
|
||||
set: (value) => {
|
||||
set(props.nodeModel.properties, 'node_data', value)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const baseNodeFormRef = ref<FormInstance>()
|
||||
@ -247,13 +238,13 @@ const validate = () => {
|
||||
) {
|
||||
return Promise.reject({
|
||||
node: props.nodeModel,
|
||||
errMessage: t('views.application.form.voicePlay.requiredMessage')
|
||||
errMessage: t('views.application.form.voicePlay.requiredMessage'),
|
||||
})
|
||||
}
|
||||
if (form_data.value.stt_model_enable && !form_data.value.stt_model_id) {
|
||||
return Promise.reject({
|
||||
node: props.nodeModel,
|
||||
errMessage: t('views.application.form.voiceInput.requiredMessage')
|
||||
errMessage: t('views.application.form.voiceInput.requiredMessage'),
|
||||
})
|
||||
}
|
||||
return baseNodeFormRef.value?.validate().catch((err) => {
|
||||
@ -262,13 +253,13 @@ const validate = () => {
|
||||
}
|
||||
|
||||
function getSTTModel() {
|
||||
applicationApi.getApplicationSTTModel(id).then((res: any) => {
|
||||
modelAPI.getSTTModel().then((res: any) => {
|
||||
sttModelOptions.value = groupBy(res?.data, 'provider')
|
||||
})
|
||||
}
|
||||
|
||||
function getTTSModel() {
|
||||
applicationApi.getApplicationTTSModel(id).then((res: any) => {
|
||||
modelAPI.getTTSModel().then((res: any) => {
|
||||
ttsModelOptions.value = groupBy(res?.data, 'provider')
|
||||
})
|
||||
}
|
||||
@ -316,7 +307,7 @@ const switchFileUpload = () => {
|
||||
audio: false,
|
||||
video: false,
|
||||
other: false,
|
||||
otherExtensions: ['ppt', 'doc']
|
||||
otherExtensions: ['ppt', 'doc'],
|
||||
}
|
||||
|
||||
if (form_data.value.file_upload_enable) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user