Merge pull request #440 from SuanmoSuanyangTechnology/feature/workflow_import_zy
Feature/workflow import zy
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 13:59:45
|
* @Date: 2026-02-03 13:59:45
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-28 16:34:15
|
* @Last Modified time: 2026-03-03 12:08:42
|
||||||
*/
|
*/
|
||||||
import { request } from '@/utils/request'
|
import { request } from '@/utils/request'
|
||||||
import type { ApplicationModalData } from '@/views/ApplicationManagement/types'
|
import type { ApplicationModalData } from '@/views/ApplicationManagement/types'
|
||||||
@@ -120,15 +120,19 @@ export const copyApplication = (app_id: string, new_name: string) => {
|
|||||||
export const getAppStatistics = (app_id: string, data: { start_date: number; end_date: number; }) => {
|
export const getAppStatistics = (app_id: string, data: { start_date: number; end_date: number; }) => {
|
||||||
return request.get(`/apps/${app_id}/statistics`, data)
|
return request.get(`/apps/${app_id}/statistics`, data)
|
||||||
}
|
}
|
||||||
// 导出工作流
|
// Upload workflow and analyze compatibility
|
||||||
export const exportWorkflow = (app_id: string, fileName: string) => {
|
|
||||||
return request.downloadFile(`/apps/${app_id}/workflow/export`, fileName, undefined, undefined, 'GET')
|
|
||||||
}
|
|
||||||
// 工作流上传+兼容性分析
|
|
||||||
export const importWorkflow = (formData: FormData) => {
|
export const importWorkflow = (formData: FormData) => {
|
||||||
return request.uploadFile(`/apps/workflow/import`, formData)
|
return request.uploadFile(`/apps/workflow/import`, formData)
|
||||||
}
|
}
|
||||||
// 完成工作流导入
|
// Complete workflow import
|
||||||
export const completeImportWorkflow = (data: { temp_id: string; name?: string; description?: string }) => {
|
export const completeImportWorkflow = (data: { temp_id: string; name?: string; description?: string }) => {
|
||||||
return request.post(`/apps/workflow/import/save`, data)
|
return request.post(`/apps/workflow/import/save`, data)
|
||||||
}
|
}
|
||||||
|
// Get experience config
|
||||||
|
export const getExperienceConfig = (share_token: string) => {
|
||||||
|
return request.get(`/public/share/config`, {}, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${localStorage.getItem(`shareToken_${share_token}`)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1685,7 +1685,8 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
|||||||
fileType: 'File Type',
|
fileType: 'File Type',
|
||||||
image: 'Image',
|
image: 'Image',
|
||||||
fileUrl: 'File URL',
|
fileUrl: 'File URL',
|
||||||
addRemoteFile: 'Add Remote File'
|
addRemoteFile: 'Add Remote File',
|
||||||
|
variableConfig: 'Variable Configuration',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
title: 'Red Bear Memory Science',
|
title: 'Red Bear Memory Science',
|
||||||
@@ -2193,7 +2194,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
|||||||
save: 'Save',
|
save: 'Save',
|
||||||
export: 'Export',
|
export: 'Export',
|
||||||
variableConfig: 'Variable Configuration',
|
variableConfig: 'Variable Configuration',
|
||||||
variableRequired: 'Required',
|
variableRequired: 'Required, please configure variable values',
|
||||||
addMessage: 'Add Message',
|
addMessage: 'Add Message',
|
||||||
answerDesc: 'Reply',
|
answerDesc: 'Reply',
|
||||||
addNode: 'Add Node',
|
addNode: 'Add Node',
|
||||||
|
|||||||
@@ -1682,7 +1682,8 @@ export const zh = {
|
|||||||
fileType: '文件类型',
|
fileType: '文件类型',
|
||||||
image: '图片',
|
image: '图片',
|
||||||
fileUrl: '文件链接',
|
fileUrl: '文件链接',
|
||||||
addRemoteFile: '添加远程文件'
|
addRemoteFile: '添加远程文件',
|
||||||
|
variableConfig: '变量配置',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
title: '红熊记忆科学',
|
title: '红熊记忆科学',
|
||||||
@@ -2193,7 +2194,7 @@ export const zh = {
|
|||||||
save: '保存',
|
save: '保存',
|
||||||
export: '导出',
|
export: '导出',
|
||||||
variableConfig: '变量配置',
|
variableConfig: '变量配置',
|
||||||
variableRequired: '必填',
|
variableRequired: '必填,请配置变量值',
|
||||||
addMessage: '添加消息',
|
addMessage: '添加消息',
|
||||||
answerDesc: '回复',
|
answerDesc: '回复',
|
||||||
addNode: '添加节点',
|
addNode: '添加节点',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:29:21
|
* @Date: 2026-02-03 16:29:21
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-03-03 11:14:30
|
* @Last Modified time: 2026-03-03 14:24:34
|
||||||
*/
|
*/
|
||||||
import { type FC, type ReactNode, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
|
import { type FC, type ReactNode, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
@@ -403,6 +403,9 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
const handleSaveChatVariable = (values: Variable[]) => {
|
const handleSaveChatVariable = (values: Variable[]) => {
|
||||||
setChatVariables(values)
|
setChatVariables(values)
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
setChatVariables(values?.variables || [])
|
||||||
|
}, [values?.variables])
|
||||||
console.log('values', values)
|
console.log('values', values)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -507,6 +510,7 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
chatList={chatList}
|
chatList={chatList}
|
||||||
updateChatList={setChatList}
|
updateChatList={setChatList}
|
||||||
handleSave={handleSave}
|
handleSave={handleSave}
|
||||||
|
chatVariables={chatVariables}
|
||||||
/>
|
/>
|
||||||
</RbCard>
|
</RbCard>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:27:39
|
* @Date: 2026-02-03 16:27:39
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-10 17:40:15
|
* @Last Modified time: 2026-03-03 14:21:54
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Chat debugging component for application testing
|
* Chat debugging component for application testing
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
import { type FC, useEffect, useState, useRef } from 'react';
|
import { type FC, useEffect, useState, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { Flex, Dropdown, type MenuProps } from 'antd'
|
import { Flex, Dropdown, type MenuProps, App } from 'antd'
|
||||||
|
|
||||||
import ChatIcon from '@/assets/images/application/chat.png'
|
import ChatIcon from '@/assets/images/application/chat.png'
|
||||||
import DebuggingEmpty from '@/assets/images/application/debuggingEmpty.png'
|
import DebuggingEmpty from '@/assets/images/application/debuggingEmpty.png'
|
||||||
@@ -28,6 +28,7 @@ import UploadFiles from '@/views/Conversation/components/FileUpload'
|
|||||||
// import AudioRecorder from '@/components/AudioRecorder'
|
// import AudioRecorder from '@/components/AudioRecorder'
|
||||||
import UploadFileListModal from '@/views/Conversation/components/UploadFileListModal'
|
import UploadFileListModal from '@/views/Conversation/components/UploadFileListModal'
|
||||||
import type { UploadFileListModalRef } from '@/views/Conversation/types'
|
import type { UploadFileListModalRef } from '@/views/Conversation/types'
|
||||||
|
import type { Variable } from './VariableList/types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component props
|
* Component props
|
||||||
@@ -43,14 +44,16 @@ interface ChatProps {
|
|||||||
handleSave: (flag?: boolean) => Promise<unknown>;
|
handleSave: (flag?: boolean) => Promise<unknown>;
|
||||||
/** Source type: multi-agent cluster or single agent */
|
/** Source type: multi-agent cluster or single agent */
|
||||||
source?: 'multi_agent' | 'agent';
|
source?: 'multi_agent' | 'agent';
|
||||||
|
chatVariables?: Variable[]; // Add chatVariables prop
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chat debugging component
|
* Chat debugging component
|
||||||
* Allows testing application with different model configurations side-by-side
|
* Allows testing application with different model configurations side-by-side
|
||||||
*/
|
*/
|
||||||
const Chat: FC<ChatProps> = ({ chatList, data, updateChatList, handleSave, source = 'agent' }) => {
|
const Chat: FC<ChatProps> = ({ chatList, data, updateChatList, handleSave, source = 'agent', chatVariables }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { message: messageApi } = App.useApp()
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [isCluster, setIsCluster] = useState(source === 'multi_agent')
|
const [isCluster, setIsCluster] = useState(source === 'multi_agent')
|
||||||
const [conversationId, setConversationId] = useState<string | null>(null)
|
const [conversationId, setConversationId] = useState<string | null>(null)
|
||||||
@@ -195,6 +198,27 @@ const Chat: FC<ChatProps> = ({ chatList, data, updateChatList, handleSave, sourc
|
|||||||
};
|
};
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
// Validate required variables before sending
|
||||||
|
let isCanSend = true
|
||||||
|
const params: Record<string, any> = {}
|
||||||
|
if (chatVariables && chatVariables.length > 0) {
|
||||||
|
const needRequired: string[] = []
|
||||||
|
chatVariables.forEach(vo => {
|
||||||
|
params[vo.name] = vo.value
|
||||||
|
|
||||||
|
if (vo.required && (params[vo.name] === null || params[vo.name] === undefined || params[vo.name] === '')) {
|
||||||
|
isCanSend = false
|
||||||
|
needRequired.push(vo.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (needRequired.length) {
|
||||||
|
messageApi.error(`${needRequired.join(',')} ${t('workflow.variableRequired')}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCanSend) {
|
||||||
|
return
|
||||||
|
}
|
||||||
runCompare(data.app_id, {
|
runCompare(data.app_id, {
|
||||||
message,
|
message,
|
||||||
files: fileList.map(file => {
|
files: fileList.map(file => {
|
||||||
@@ -214,7 +238,7 @@ const Chat: FC<ChatProps> = ({ chatList, data, updateChatList, handleSave, sourc
|
|||||||
model_parameters: item.model_parameters,
|
model_parameters: item.model_parameters,
|
||||||
conversation_id: item.conversation_id
|
conversation_id: item.conversation_id
|
||||||
})),
|
})),
|
||||||
variables: {},
|
variables: params,
|
||||||
"parallel": true,
|
"parallel": true,
|
||||||
"stream": true,
|
"stream": true,
|
||||||
"timeout": 60,
|
"timeout": 60,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:28:46
|
* @Date: 2026-02-03 16:28:46
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-03 16:28:46
|
* @Last Modified time: 2026-03-03 14:03:44
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Release Share Modal
|
* Release Share Modal
|
||||||
@@ -79,7 +79,7 @@ const ReleaseShareModal = forwardRef<ReleaseShareModalRef, ReleaseShareModalProp
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RbModal
|
<RbModal
|
||||||
title={<>{t('application.shareVersion')} {version?.version}</>}
|
title={<>{t('application.shareVersion')} ({version?.version_name && version.version_name[0].toLocaleLowerCase() === 'v' ? version.version_name : version?.version_name ? `v${version.version_name}` : `v${version?.version}`})</>}
|
||||||
open={visible}
|
open={visible}
|
||||||
onCancel={handleClose}
|
onCancel={handleClose}
|
||||||
footer={false}
|
footer={false}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:58:03
|
* @Date: 2026-02-03 16:58:03
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-10 17:41:05
|
* @Last Modified time: 2026-03-03 13:46:22
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Conversation Page
|
* Conversation Page
|
||||||
@@ -14,11 +14,12 @@ import { type FC, useState, useEffect, useRef } from 'react'
|
|||||||
import { useParams, useLocation } from 'react-router-dom'
|
import { useParams, useLocation } from 'react-router-dom'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import InfiniteScroll from 'react-infinite-scroll-component';
|
import InfiniteScroll from 'react-infinite-scroll-component';
|
||||||
import { Flex, Skeleton, Form, Dropdown, type MenuProps } from 'antd'
|
import { Flex, Skeleton, Form, Dropdown, type MenuProps, App } from 'antd'
|
||||||
|
import { SettingOutlined } from '@ant-design/icons'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
import { getConversationHistory, sendConversation, getConversationDetail, getShareToken } from '@/api/application'
|
import { getConversationHistory, sendConversation, getConversationDetail, getShareToken, getExperienceConfig } from '@/api/application'
|
||||||
import type { HistoryItem, QueryParams, UploadFileListModalRef } from './types'
|
import type { HistoryItem, QueryParams, UploadFileListModalRef } from './types'
|
||||||
import Empty from '@/components/Empty'
|
import Empty from '@/components/Empty'
|
||||||
import { formatDateTime } from '@/utils/format';
|
import { formatDateTime } from '@/utils/format';
|
||||||
@@ -37,12 +38,16 @@ import UploadFiles from './components/FileUpload'
|
|||||||
// import AudioRecorder from '@/components/AudioRecorder'
|
// import AudioRecorder from '@/components/AudioRecorder'
|
||||||
import { shareFileUploadUrlWithoutApiPrefix } from '@/api/fileStorage'
|
import { shareFileUploadUrlWithoutApiPrefix } from '@/api/fileStorage'
|
||||||
import UploadFileListModal from './components/UploadFileListModal'
|
import UploadFileListModal from './components/UploadFileListModal'
|
||||||
|
import type { VariableConfigModalRef } from '@/views/Workflow/types'
|
||||||
|
import type { Variable } from '@/views/Workflow/components/Properties/VariableList/types'
|
||||||
|
import VariableConfigModal from '@/views/Workflow/components/Chat/VariableConfigModal';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversation component for shared applications
|
* Conversation component for shared applications
|
||||||
*/
|
*/
|
||||||
const Conversation: FC = () => {
|
const Conversation: FC = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const { message: messageApi } = App.useApp()
|
||||||
const { token } = useParams()
|
const { token } = useParams()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const searchParams = new URLSearchParams(location.search)
|
const searchParams = new URLSearchParams(location.search)
|
||||||
@@ -64,6 +69,22 @@ const Conversation: FC = () => {
|
|||||||
const queryValues = Form.useWatch<QueryParams>([], form)
|
const queryValues = Form.useWatch<QueryParams>([], form)
|
||||||
|
|
||||||
const uploadFileListModalRef = useRef<UploadFileListModalRef>(null)
|
const uploadFileListModalRef = useRef<UploadFileListModalRef>(null)
|
||||||
|
|
||||||
|
const variableConfigModalRef = useRef<VariableConfigModalRef>(null)
|
||||||
|
const [variables, setVariables] = useState<Variable[]>([]) // Workflow input variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the variable configuration modal
|
||||||
|
*/
|
||||||
|
const handleEditVariables = () => {
|
||||||
|
variableConfigModalRef.current?.handleOpen(variables)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Saves updated variable values from the modal
|
||||||
|
*/
|
||||||
|
const handleSave = (values: Variable[]) => {
|
||||||
|
setVariables([...values])
|
||||||
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const shareToken = localStorage.getItem(`shareToken_${token}`)
|
const shareToken = localStorage.getItem(`shareToken_${token}`)
|
||||||
setShareToken(shareToken)
|
setShareToken(shareToken)
|
||||||
@@ -81,6 +102,17 @@ const Conversation: FC = () => {
|
|||||||
getHistory()
|
getHistory()
|
||||||
}
|
}
|
||||||
}, [token, shareToken, page, hasMore, historyList])
|
}, [token, shareToken, page, hasMore, historyList])
|
||||||
|
useEffect(() => {
|
||||||
|
if (shareToken && token) {
|
||||||
|
getExperienceConfig(token)
|
||||||
|
.then(res => {
|
||||||
|
const response = res as { variables: Variable[] }
|
||||||
|
setVariables(response.variables || [])
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setChatList([])
|
||||||
|
}
|
||||||
|
}, [shareToken, token])
|
||||||
|
|
||||||
/** Group conversation history by date */
|
/** Group conversation history by date */
|
||||||
const groupHistoryByDate = (items: HistoryItem[]): Record<string, HistoryItem[]> => {
|
const groupHistoryByDate = (items: HistoryItem[]): Record<string, HistoryItem[]> => {
|
||||||
@@ -191,12 +223,35 @@ const Conversation: FC = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isNeedVariableConfig = variables.some(vo => vo.required && (vo.value === null || vo.value === undefined || vo.value === ''))
|
||||||
|
|
||||||
/** Send message and handle streaming response */
|
/** Send message and handle streaming response */
|
||||||
const handleSend = () => {
|
const handleSend = () => {
|
||||||
if (!token || !shareToken) {
|
if (!token || !shareToken) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { files = [], ...rest } = queryValues || {}
|
const { files = [], ...rest } = queryValues || {}
|
||||||
|
// Validate required variables before sending
|
||||||
|
let isCanSend = true
|
||||||
|
const params: Record<string, any> = {}
|
||||||
|
if (variables.length > 0) {
|
||||||
|
const needRequired: string[] = []
|
||||||
|
variables.forEach(vo => {
|
||||||
|
params[vo.name] = vo.value ?? vo.defaultValue
|
||||||
|
|
||||||
|
if (vo.required && (params[vo.name] === null || params[vo.name] === undefined || params[vo.name] === '')) {
|
||||||
|
isCanSend = false
|
||||||
|
needRequired.push(vo.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (needRequired.length) {
|
||||||
|
messageApi.error(`${needRequired.join(',')} ${t('workflow.variableRequired')}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCanSend) {
|
||||||
|
return
|
||||||
|
}
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setStreamLoading(true)
|
setStreamLoading(true)
|
||||||
addUserMessage(message, files)
|
addUserMessage(message, files)
|
||||||
@@ -247,7 +302,8 @@ const Conversation: FC = () => {
|
|||||||
upload_file_id: file.response.data.file_id
|
upload_file_id: file.response.data.file_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
variables: params
|
||||||
}, handleStreamMessage, shareToken)
|
}, handleStreamMessage, shareToken)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
@@ -384,6 +440,20 @@ const Conversation: FC = () => {
|
|||||||
{t(`memoryConversation.memory`)}
|
{t(`memoryConversation.memory`)}
|
||||||
</ButtonCheckbox>
|
</ButtonCheckbox>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{variables.length > 0 && (
|
||||||
|
<Form.Item name="variables" className="rb:mb-0!">
|
||||||
|
<div
|
||||||
|
className={clsx("rb:flex rb:items-center rb:border rb:rounded-lg rb:px-2 rb:text-[12px] rb:h-6 rb:cursor-pointer rb:hover:bg-[#F0F3F8] rb:text-[#212332]", {
|
||||||
|
'rb:border-[#FF5D34] rb:text-[#FF5D34]': isNeedVariableConfig,
|
||||||
|
'rb:border-[#DFE4ED]': !isNeedVariableConfig,
|
||||||
|
})}
|
||||||
|
onClick={handleEditVariables}
|
||||||
|
>
|
||||||
|
<SettingOutlined className="rb:mr-1" />
|
||||||
|
{t(`memoryConversation.variableConfig`)}
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
{/* <Flex align="center">
|
{/* <Flex align="center">
|
||||||
<AudioRecorder onRecordingComplete={handleRecordingComplete} />
|
<AudioRecorder onRecordingComplete={handleRecordingComplete} />
|
||||||
@@ -399,6 +469,11 @@ const Conversation: FC = () => {
|
|||||||
ref={uploadFileListModalRef}
|
ref={uploadFileListModalRef}
|
||||||
refresh={addFileList}
|
refresh={addFileList}
|
||||||
/>
|
/>
|
||||||
|
<VariableConfigModal
|
||||||
|
ref={variableConfigModalRef}
|
||||||
|
refresh={handleSave}
|
||||||
|
variables={variables}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:57:46
|
* @Date: 2026-02-03 16:57:46
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-06 21:11:19
|
* @Last Modified time: 2026-03-03 13:46:55
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Type definitions for Conversation
|
* Type definitions for Conversation
|
||||||
@@ -51,6 +51,7 @@ export interface QueryParams {
|
|||||||
/** Current conversation ID */
|
/** Current conversation ID */
|
||||||
conversation_id?: string | null;
|
conversation_id?: string | null;
|
||||||
files?: any[];
|
files?: any[];
|
||||||
|
variables?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UploadFileListModalRef {
|
export interface UploadFileListModalRef {
|
||||||
|
|||||||
@@ -71,20 +71,20 @@ const VariableConfigModal = forwardRef<VariableConfigModalRef, VariableEditModal
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
key={name}
|
key={name}
|
||||||
name={[name, 'value']}
|
name={[name, 'value']}
|
||||||
label={field.type === 'boolean' ? undefined : `${field.name}·${field.description}`}
|
label={field.type === 'boolean' ? undefined : `${field.name}·${field.display_name || field.description}`}
|
||||||
valuePropName={field.type === 'boolean' ? 'checked' : 'value'}
|
valuePropName={field.type === 'boolean' ? 'checked' : 'value'}
|
||||||
rules={[
|
rules={[
|
||||||
{ required: field.required, message: field.type === 'boolean' ? t('common.pleaseSelect') : t('common.pleaseEnter') },
|
{ required: field.required, message: field.type === 'boolean' ? t('common.pleaseSelect') : t('common.pleaseEnter') },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
field.type === 'string' && <Input placeholder={t('common.pleaseEnter')} />
|
(field.type === 'string' || field.type === 'text') && <Input placeholder={t('common.pleaseEnter')} />
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
field.type === 'number' && <InputNumber placeholder={t('common.pleaseEnter')} style={{ width: '100%' }} onChange={(value) => form.setFieldValue(['variables', name, 'value'], value)} />
|
field.type === 'number' && <InputNumber placeholder={t('common.pleaseEnter')} style={{ width: '100%' }} onChange={(value) => form.setFieldValue(['variables', name, 'value'], value)} />
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
field.type === 'boolean' && <Checkbox>{`${field.name}·${field.description}`}</Checkbox>
|
field.type === 'boolean' && <Checkbox>{`${field.name}·${field.display_name || field.description}`}</Checkbox>
|
||||||
}
|
}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const EditableTable: FC<EditableTableProps> = ({
|
|||||||
render: (_: any, __: TableRow, index: number) => (
|
render: (_: any, __: TableRow, index: number) => (
|
||||||
<Form.Item name={[index, 'name']} noStyle>
|
<Form.Item name={[index, 'name']} noStyle>
|
||||||
<Editor
|
<Editor
|
||||||
options={booleanFilterOptions}
|
options={booleanFilterOptions.filter(option => !option.dataType.includes('file'))}
|
||||||
type="input"
|
type="input"
|
||||||
className={contentClassName}
|
className={contentClassName}
|
||||||
size={size}
|
size={size}
|
||||||
@@ -109,7 +109,7 @@ const EditableTable: FC<EditableTableProps> = ({
|
|||||||
const currentType = form.getFieldValue([...Array.isArray(parentName) ? parentName : [parentName], index, 'type']);
|
const currentType = form.getFieldValue([...Array.isArray(parentName) ? parentName : [parentName], index, 'type']);
|
||||||
const filteredOptions = currentType === 'file'
|
const filteredOptions = currentType === 'file'
|
||||||
? booleanFilterOptions.filter(option => option.dataType.includes('file'))
|
? booleanFilterOptions.filter(option => option.dataType.includes('file'))
|
||||||
: booleanFilterOptions;
|
: booleanFilterOptions.filter(option => !option.dataType.includes('file'));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item name={[index, 'value']} noStyle>
|
<Form.Item name={[index, 'value']} noStyle>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export interface Variable {
|
export interface Variable {
|
||||||
name: string;
|
name: string;
|
||||||
|
display_name?: string;
|
||||||
type: string;
|
type: string;
|
||||||
required: boolean;
|
required: boolean;
|
||||||
description: string;
|
description: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user