diff --git a/web/src/components/AudioRecorder/index.tsx b/web/src/components/AudioRecorder/index.tsx index f6a030b4..d31746f6 100644 --- a/web/src/components/AudioRecorder/index.tsx +++ b/web/src/components/AudioRecorder/index.tsx @@ -1,16 +1,21 @@ import { type FC, useRef, useState } from 'react' import RecordRTC from 'recordrtc' -import { fileUpload } from '@/api/fileStorage' +import { fileUploadUrlWithoutApiPrefix } from '@/api/fileStorage' +import { request } from '@/utils/request' interface AudioRecorderProps { - onRecordingComplete?: (file: { file_id: string; file_key: string; }, blob: Blob) => void - className?: string + onRecordingComplete?: (file: { file_id: string; file_key: string; url: string; type?: string; }, blob?: Blob) => void + className?: string; + action?: string; + requestConfig?: Record; } const AudioRecorder: FC = ({ onRecordingComplete, className = '', + action = fileUploadUrlWithoutApiPrefix, + requestConfig = {} }) => { const [isRecording, setIsRecording] = useState(false) const recorderRef = useRef(null) @@ -33,11 +38,17 @@ const AudioRecorder: FC = ({ if (recorderRef.current) { recorderRef.current.stopRecording(() => { const blob = recorderRef.current!.getBlob() + const url = recorderRef.current!.toURL() const formData = new FormData() formData.append('file', blob, `recording_${Date.now()}.webm`) - fileUpload(formData) + request + .uploadFile(action, formData, requestConfig) .then(res => { - onRecordingComplete?.(res as { file_id: string; file_key: string; }, blob) + onRecordingComplete?.({ + ...(res as { file_id: string; file_key: string }), + type: blob.type, + url + }, blob) recorderRef.current?.destroy() recorderRef.current = null }) diff --git a/web/src/components/Chat/ChatInput.tsx b/web/src/components/Chat/ChatInput.tsx index c155bb22..49fb65d2 100644 --- a/web/src/components/Chat/ChatInput.tsx +++ b/web/src/components/Chat/ChatInput.tsx @@ -2,10 +2,11 @@ * @Author: ZhaoYing * @Date: 2025-12-10 16:46:14 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-10 12:13:52 + * @Last Modified time: 2026-03-04 18:42:49 */ import { type FC, useEffect, useMemo } from 'react' import { Flex, Input, Form } from 'antd' + import SendIcon from '@/assets/images/conversation/send.svg' import SendDisabledIcon from '@/assets/images/conversation/sendDisabled.svg' import LoadingIcon from '@/assets/images/conversation/loading.svg' @@ -80,9 +81,31 @@ const ChatInput: FC = ({ ) } + if (file.type.includes('video')) { + return ( +
+
+ ) + } + if (file.type.includes('audio')) { + return ( +
+
+ ) + } return (
- {(file.type.includes('word') || file.type.includes('wordprocessingml.document')) &&
} {(file.type.includes('pdf')) &&
= ({ chatList, data, updateChatList, handleSave, sourc content: '', created_at: Date.now(), }; - + if (isCluster) { updateChatList(prev => prev.map(item => ({ ...item, @@ -134,7 +134,7 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc }) } /** Update assistant message when error occurs */ - const updateErrorAssistantMessage = (message_length: number, model_config_id?: string) => { + const updateErrorAssistantMessage = (message_length: number, model_config_id?: string) => { if (message_length > 0 || !model_config_id) return updateChatList(prev => { @@ -245,7 +245,15 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc "stream": true, "timeout": 60, }, handleStreamMessage) - .finally(() => setLoading(false)); + .catch(() => { + setLoading(false) + setCompareLoading(false) + updateClusterErrorAssistantMessage(0) + }) + .finally(() => { + setLoading(false) + setCompareLoading(false) + }) }, 0) }) .catch(() => { @@ -290,7 +298,7 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc }) } /** Update cluster message when error occurs */ - const updateClusterErrorAssistantMessage = (message_length: number) => { + const updateClusterErrorAssistantMessage = (message_length: number) => { if (message_length > 0) return updateChatList(prev => { @@ -333,7 +341,7 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc data.map(item => { const { conversation_id, content, message_length } = item.data as { conversation_id: string, content: string, message_length: number }; - switch(item.event) { + switch (item.event) { case 'start': if (conversation_id && conversationId !== conversation_id) { setConversationId(conversation_id); @@ -356,27 +364,35 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc }; setTimeout(() => { - draftRun( - data.app_id, - { - message, - conversation_id: conversationId, - stream: true, - files: fileList.map(file => { - if (file.url) { - return file - } else { - return { - type: file.type, - transfer_method: 'local_file', - upload_file_id: file.response.data.file_id - } + draftRun( + data.app_id, + { + message, + conversation_id: conversationId, + stream: true, + files: fileList.map(file => { + if (file.url) { + return file + } else { + return { + type: file.type, + transfer_method: 'local_file', + upload_file_id: file.response.data.file_id } - }), - }, - handleStreamMessage - ) - .finally(() => setLoading(false)) + } + }), + }, + handleStreamMessage + ) + .catch(() => { + setLoading(false) + setCompareLoading(false) + updateClusterErrorAssistantMessage(0) + }) + .finally(() => { + setLoading(false) + setCompareLoading(false) + }) }, 0) }) .catch(() => { @@ -395,12 +411,17 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc const fileChange = (file?: any) => { setFileList([...fileList, file]) } - // const handleRecordingComplete = async (file: any) => { - // console.log('file', file) - // } + const handleRecordingComplete = async (file: any) => { + setFileList([...fileList, { + uid: file.file_id, + response: { data: file }, + thumbUrl: file.url, + type: file.type + }]) + } const handleShowUpload: MenuProps['onClick'] = ({ key }) => { - switch(key) { + switch (key) { case 'define': uploadFileListModalRef.current?.handleOpen() break @@ -417,99 +438,98 @@ const Chat: FC = ({ chatList, data, updateChatList, handleSave, sourc return (
{chatList.length === 0 - ? - : <> -
- {chatList.map((chat, index) => ( -
1, - })}> - {chat.label && -
-
-
{chat.label}
-
handleDelete(index)} - >
+ : <> +
+ {chatList.map((chat, index) => ( +
1, + })}> + {chat.label && +
+
+
{chat.label}
+
handleDelete(index)} + >
+
-
- } - } - data={chat.list || []} - streamLoading={compareLoading} - labelPosition="top" - labelFormat={(item) => item.role === 'user' ? t('application.you') : chat.label} - errorDesc={t('application.ReplyException')} - /> -
- ))} -
-
- - - - - ) - }, - ], - onClick: handleShowUpload + } + -
-
+ contentClassNames={{ + 'rb:max-w-[400px]!': chatList.length === 1, + 'rb:max-w-[260px]!': chatList.length === 2, + 'rb:max-w-[150px]!': chatList.length === 3, + 'rb:max-w-[108px]!': chatList.length === 4, + }} + empty={} + data={chat.list || []} + streamLoading={compareLoading} + labelPosition="top" + labelFormat={(item) => item.role === 'user' ? t('application.you') : chat.label} + errorDesc={t('application.ReplyException')} + /> +
+ ))} +
+
+ + + + + ) + }, + ], + onClick: handleShowUpload + }} + > +
+
+
+ + + +
- {/* - - - */} - -
-
- + +
+ } { /** Custom file removal callback */ onRemove?: (file: UploadFile) => boolean | void | Promise; } + +const transform_file_type = { + 'text/plain': 'document/text', + 'text/markdown': 'document/markdown', + 'text/x-markdown': 'document/x-markdown', + + 'application/pdf': 'document/pdf', + + 'application/msword': 'document/doc', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'document/docx', + + 'application/vnd.ms-powerpoint': 'document/ppt', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'document/pptx', +} // Mapping of file extensions to MIME types const ALL_FILE_TYPE: { [key: string]: string; } = { - // txt: 'text/plain', + txt: 'text/plain', + md: 'text/markdown', + xmd: 'text/x-markdown', + pdf: 'application/pdf', doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - - xls: 'application/vnd.ms-excel', - xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - csv: 'text/csv', ppt: 'application/vnd.ms-powerpoint', pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - - // md: 'text/markdown', - // htm: 'text/html', - // html: 'text/html', - // json: 'application/json', + jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', @@ -84,6 +94,23 @@ const ALL_FILE_TYPE: { bmp: 'image/bmp', webp: 'image/webp', svg: 'image/svg+xml', + + mp4: 'video/mp4', + mov: 'video/quicktime', + avi: 'video/x-msvideo', + mkv: 'video/x-matroska', + webm: 'video/webm', + flv: 'video/x-flv', + wmv: 'video/x-ms-wmv', + + mp3: 'audio/mpeg', + wav: 'audio/wav', + ogg: 'audio/ogg', + aac: 'audio/aac', + flac: 'audio/flac', + m4a: 'audio/mp4', + wma: 'audio/x-ms-wma', + xm4a: 'audio/x-m4a', } export interface UploadFilesRef { /** Current file list */ @@ -178,6 +205,10 @@ const UploadFiles = forwardRef(({ * Handles upload state changes */ const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { + newFileList.map(file => { + const type = (file.type && transform_file_type[file.type as keyof typeof transform_file_type]) || file.type + file.type = type + }) setFileList(newFileList); if (onChange) { onChange(maxCount === 1 ? newFileList[newFileList.length - 1] : newFileList); diff --git a/web/src/views/Conversation/components/UploadFileListModal.tsx b/web/src/views/Conversation/components/UploadFileListModal.tsx index c5110701..a43b9dd4 100644 --- a/web/src/views/Conversation/components/UploadFileListModal.tsx +++ b/web/src/views/Conversation/components/UploadFileListModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-06 21:09:47 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-09 10:17:54 + * @Last Modified time: 2026-03-04 17:47:09 */ /** * Upload File List Modal Component @@ -104,7 +104,9 @@ const UploadFileListModal = forwardRef diff --git a/web/src/views/Conversation/index.tsx b/web/src/views/Conversation/index.tsx index 2ad2a5a4..8a67b3ae 100644 --- a/web/src/views/Conversation/index.tsx +++ b/web/src/views/Conversation/index.tsx @@ -14,7 +14,7 @@ import { type FC, useState, useEffect, useRef } from 'react' import { useParams, useLocation } from 'react-router-dom' import { useTranslation } from 'react-i18next' import InfiniteScroll from 'react-infinite-scroll-component'; -import { Flex, Skeleton, Form, Dropdown, type MenuProps, App } from 'antd' +import { Flex, Skeleton, Form, Dropdown, type MenuProps, App, Divider } from 'antd' import { SettingOutlined } from '@ant-design/icons' import clsx from 'clsx' import dayjs from 'dayjs' @@ -35,7 +35,7 @@ import OnlineCheckedIcon from '@/assets/images/conversation/onlineChecked.svg' import MemoryFunctionCheckedIcon from '@/assets/images/conversation/memoryFunctionChecked.svg' import { type SSEMessage } from '@/utils/stream' import UploadFiles from './components/FileUpload' -// import AudioRecorder from '@/components/AudioRecorder' +import AudioRecorder from '@/components/AudioRecorder' import { shareFileUploadUrlWithoutApiPrefix } from '@/api/fileStorage' import UploadFileListModal from './components/UploadFileListModal' import type { VariableConfigModalRef } from '@/views/Workflow/types' @@ -305,17 +305,27 @@ const Conversation: FC = () => { }), variables: params }, handleStreamMessage, shareToken) + .catch(() => { + setLoading(false) + setStreamLoading(false) + }) .finally(() => { setLoading(false) + setStreamLoading(false) }) } const fileChange = (file?: any) => { form.setFieldValue('files', [...(queryValues.files || []), file]) } - // const handleRecordingComplete = async (file: any) => { - // console.log('file', file) - // } + const handleRecordingComplete = async (file: any) => { + form.setFieldValue('files', [...(queryValues.files || []), { + uid: file.file_id, + response: { data: file }, + thumbUrl: file.url, + type: file.type + }]) + } const handleShowUpload: MenuProps['onClick'] = ({ key }) => { switch(key) { @@ -329,6 +339,7 @@ const Conversation: FC = () => { form.setFieldValue('files', [...(queryValues.files || []), ...fileList]) } const updateFileList = (fileList?: any[]) => { + console.log('fileList', fileList) form.setFieldValue('files', [...(fileList || [])]) } @@ -383,7 +394,7 @@ const Conversation: FC = () => {
} - contentClassName="rb:h-[calc(100%-180px)]" + contentClassName={!queryValues?.files?.length ? "rb:h-[calc(100%-144px)]" : "rb:h-[calc(100%-208px)]"} data={chatList} streamLoading={streamLoading} loading={loading} @@ -405,13 +416,12 @@ const Conversation: FC = () => { key: 'upload', label: ( ) }, @@ -455,10 +465,19 @@ const Conversation: FC = () => { )} - {/* - + + - */} + diff --git a/web/src/views/ModelManagement/components/CustomModelModal.tsx b/web/src/views/ModelManagement/components/CustomModelModal.tsx index 112534a5..d47fc996 100644 --- a/web/src/views/ModelManagement/components/CustomModelModal.tsx +++ b/web/src/views/ModelManagement/components/CustomModelModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:49:28 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-28 17:24:05 + * @Last Modified time: 2026-03-04 11:31:43 */ /** * Custom Model Modal @@ -10,8 +10,8 @@ * Supports logo upload, type/provider selection, and tagging */ -import { forwardRef, useImperativeHandle, useState } from 'react'; -import { Form, Input, App } from 'antd'; +import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import { Form, Input, App, Checkbox } from 'antd'; import { useTranslation } from 'react-i18next'; import type { CustomModelForm, ModelListItem, CustomModelModalRef, CustomModelModalProps } from '../types'; @@ -35,6 +35,14 @@ const CustomModelModal = forwardRef( const [isEdit, setIsEdit] = useState(false); const [form] = Form.useForm(); const [loading, setLoading] = useState(false) + const modelType = Form.useWatch(['type'], form); + const isOmni = Form.useWatch(['is_omni'], form); + + useEffect(() => { + if (isOmni) { + form.setFieldsValue({ is_vision: true }) + } + }, [isOmni]) /** Close modal and reset state */ const handleClose = () => { @@ -49,9 +57,12 @@ const CustomModelModal = forwardRef( if (model) { setIsEdit(true); setModel(model); + const { capability, is_omni, ...rest} = model form.setFieldsValue({ - ...model, - logo: model.logo && model.logo.startsWith('http') ? { url: model.logo, uid: model.logo, status: 'done', name: 'logo' } : undefined + ...rest, + logo: model.logo && model.logo.startsWith('http') ? { url: model.logo, uid: model.logo, status: 'done', name: 'logo' } : undefined, + is_omni, + is_vision: capability?.includes('vision') || false, }); } else { setIsEdit(false); @@ -79,9 +90,14 @@ const CustomModelModal = forwardRef( form .validateFields() .then((values) => { - const { logo, ...rest } = values; + const { logo, type, is_vision, is_omni, ...rest } = values; const formData: CustomModelForm = { - ...rest + ...rest, + type, + } + if (!['embedding', 'rerank'].includes(type as string)) { + formData.capability = is_omni ? ["vision", "audio"] : is_vision ? ['vision'] : [] + formData.is_omni = is_omni } if (typeof logo === 'object' && logo?.response?.data.file_id) { @@ -108,7 +124,7 @@ const CustomModelModal = forwardRef( useImperativeHandle(ref, () => ({ handleOpen, })); - + console.log('modelType', modelType) return ( ( - ( > + + {!['embedding', 'rerank'].includes(modelType as string) && + <> + + {t('modelNew.is_omni')} + + + {t('modelNew.is_vision')} + + + } ); diff --git a/web/src/views/ModelManagement/components/ModelImplement/SubModelModal.tsx b/web/src/views/ModelManagement/components/ModelImplement/SubModelModal.tsx index e312b779..b2b44bf3 100644 --- a/web/src/views/ModelManagement/components/ModelImplement/SubModelModal.tsx +++ b/web/src/views/ModelManagement/components/ModelImplement/SubModelModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:49:20 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-03 16:54:54 + * @Last Modified time: 2026-03-04 11:51:01 */ /** * Sub-Model Modal @@ -10,8 +10,8 @@ * Uses cascader for hierarchical selection */ -import { forwardRef, useImperativeHandle, useState, useEffect } from 'react'; -import { Form, Cascader, App, type CascaderProps } from 'antd'; +import { type ReactNode, forwardRef, useImperativeHandle, useState, useEffect } from 'react'; +import { Form, Cascader, App, type CascaderProps, Space } from 'antd'; import { useTranslation } from 'react-i18next'; import type { SubModelModalForm, SubModelModalRef, SubModelModalProps } from './types'; @@ -19,6 +19,7 @@ import RbModal from '@/components/RbModal' import CustomSelect from '@/components/CustomSelect' import { modelProviderUrl, getModelNewList } from '@/api/models' import type { ProviderModelItem } from '../../types' +import Tag from '@/components/Tag'; const { SHOW_CHILD } = Cascader; @@ -27,7 +28,7 @@ const { SHOW_CHILD } = Cascader; */ interface Option { value: string | number; - label: string; + label: string | ReactNode; children?: Option[]; [key: string]: any; } @@ -116,7 +117,11 @@ const SubModelModal = forwardRef(({ })) return { ...vo, - label: vo.name, + label: + {vo.name} + {t(`modelNew.${vo.type}`)} + {vo.capability?.filter(item => item !== 'video').map(vo => {t(`modelNew.${vo}`)})} + , value: vo.id, children: children } diff --git a/web/src/views/ModelManagement/components/ModelListDetail.tsx b/web/src/views/ModelManagement/components/ModelListDetail.tsx index aad7b887..5291d5c4 100644 --- a/web/src/views/ModelManagement/components/ModelListDetail.tsx +++ b/web/src/views/ModelManagement/components/ModelListDetail.tsx @@ -1,8 +1,8 @@ /* * @Author: ZhaoYing * @Date: 2026-02-03 16:49:45 - * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-03 16:49:45 + * @Last Modified by: ZhaoYing + * @Last Modified time: 2026-03-04 11:50:47 */ /** * Model List Detail Drawer @@ -133,9 +133,10 @@ const ModelListDetail = forwardRef(({ + subTitle={ {t(`modelNew.${item.type}`)} {item.api_keys.length}{t('modelNew.apiKeyNum')} + {item.capability?.filter(item => item !=='video').map(vo => {t(`modelNew.${vo}`)})} } avatarUrl={getLogoUrl(item.logo)} avatar={ diff --git a/web/src/views/ModelManagement/components/ModelSquareDetail.tsx b/web/src/views/ModelManagement/components/ModelSquareDetail.tsx index 4fee5a7b..6826e9f5 100644 --- a/web/src/views/ModelManagement/components/ModelSquareDetail.tsx +++ b/web/src/views/ModelManagement/components/ModelSquareDetail.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:49:49 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-03 16:54:26 + * @Last Modified time: 2026-03-04 11:50:31 */ /** * Model Square Detail Drawer @@ -89,9 +89,10 @@ const ModelSquareDetail = forwardRef - {t(`modelNew.${item.type}`)} - {item.is_official && {t(`modelNew.official`)}} + subTitle={ + {t(`modelNew.${item.type}`)} + {item.is_official && {t(`modelNew.official`)}} + {item.capability?.filter(item => item !== 'video').map(vo => {t(`modelNew.${vo}`)})} } avatarUrl={getLogoUrl(item.logo)} avatar={ diff --git a/web/src/views/ModelManagement/types.ts b/web/src/views/ModelManagement/types.ts index e7e1f9ac..3233353b 100644 --- a/web/src/views/ModelManagement/types.ts +++ b/web/src/views/ModelManagement/types.ts @@ -1,8 +1,8 @@ /* * @Author: ZhaoYing * @Date: 2026-02-03 16:50:18 - * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-03 16:50:18 + * @Last Modified by: ZhaoYing + * @Last Modified time: 2026-03-04 11:39:20 */ /** * Type definitions for Model Management @@ -148,7 +148,9 @@ export interface ModelListItem { /** Update timestamp */ updated_at: number; /** Associated API keys */ - api_keys: ModelApiKey[] + api_keys: ModelApiKey[]; + capability?: string[]; + is_omni?: boolean; } /** @@ -261,6 +263,8 @@ export interface ModelPlazaItem { add_count: number; /** Whether user has added this model */ is_added: boolean; + capability?: string[]; + is_omni?: boolean; } /** @@ -291,6 +295,9 @@ export interface CustomModelForm { /** API base URL */ api_base: string; }> + is_vision?: boolean; + is_omni?: boolean; + capability?: string[]; } /** diff --git a/web/src/views/Workflow/components/Chat/Chat.tsx b/web/src/views/Workflow/components/Chat/Chat.tsx index e4c80e3c..eb24a206 100644 --- a/web/src/views/Workflow/components/Chat/Chat.tsx +++ b/web/src/views/Workflow/components/Chat/Chat.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-06 21:10:56 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-04 12:10:17 + * @Last Modified time: 2026-03-04 18:51:48 */ /** * Workflow Chat Component @@ -23,7 +23,7 @@ */ import { forwardRef, useImperativeHandle, useState, useRef } from 'react' import { useTranslation } from 'react-i18next' -import { App, Space, Button, Flex, Dropdown, type MenuProps } from 'antd' +import { App, Space, Button, Flex, Dropdown, type MenuProps, Divider } from 'antd' import ChatIcon from '@/assets/images/application/chat.png' import RbDrawer from '@/components/RbDrawer'; @@ -38,7 +38,7 @@ import { type SSEMessage } from '@/utils/stream' import type { Variable } from '../Properties/VariableList/types' import ChatInput from '@/components/Chat/ChatInput' 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 type { UploadFileListModalRef } from '@/views/Conversation/types' import Runtime from './Runtime'; @@ -359,6 +359,7 @@ const Chat = forwardRef(({ appId setStreamLoading(true) draftRun(appId, data, handleStreamMessage) .catch((error) => { + console.log('draftRun error', error) setChatList(prev => { const newList = [...prev] const lastIndex = newList.length - 1 @@ -390,9 +391,13 @@ const Chat = forwardRef(({ appId const fileChange = (file?: any) => { setFileList([...fileList, file]) } - // const handleRecordingComplete = async (file: any) => { - // console.log('file', file) - // } + const handleRecordingComplete = async (file: any) => { + setFileList([...fileList, { + response: { data: file }, + thumbUrl: file.url, + type: file.type + }]) + } /** * Handles dropdown menu actions for file upload @@ -424,6 +429,8 @@ const Chat = forwardRef(({ appId handleClose })); + console.log('fileList', fileList) + return ( @@ -470,7 +477,6 @@ const Chat = forwardRef(({ appId { key: 'upload', label: ( ) @@ -484,10 +490,10 @@ const Chat = forwardRef(({ appId >
- {/* + - */} +