mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-30 16:45:35 +08:00
### What problem does this PR solve? Feat: Upload files in the chat box on the agent page #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -3,11 +3,15 @@ import { useGetFileIcon } from '@/pages/chat/hooks';
|
||||
|
||||
import { useSendAgentMessage } from './use-send-agent-message';
|
||||
|
||||
import MessageInput from '@/components/message-input';
|
||||
import { FileUploadProps } from '@/components/file-upload';
|
||||
import { NextMessageInput } from '@/components/message-input/next';
|
||||
import MessageItem from '@/components/next-message-item';
|
||||
import PdfDrawer from '@/components/pdf-drawer';
|
||||
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
||||
import { useFetchAgent } from '@/hooks/use-agent-request';
|
||||
import {
|
||||
useFetchAgent,
|
||||
useUploadCanvasFileWithProgress,
|
||||
} from '@/hooks/use-agent-request';
|
||||
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
||||
import { Message } from '@/interfaces/database/chat';
|
||||
import { buildMessageUuidWithRole } from '@/utils/chat';
|
||||
@ -20,15 +24,16 @@ import { buildBeginQueryWithObject } from '../utils';
|
||||
|
||||
const AgentChatBox = () => {
|
||||
const {
|
||||
sendLoading,
|
||||
handleInputChange,
|
||||
handlePressEnter,
|
||||
value,
|
||||
ref,
|
||||
sendLoading,
|
||||
derivedMessages,
|
||||
handleInputChange,
|
||||
handlePressEnter,
|
||||
stopOutputMessage,
|
||||
sendFormMessage,
|
||||
findReferenceByMessageId,
|
||||
appendUploadResponseList,
|
||||
} = useSendAgentMessage();
|
||||
|
||||
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
||||
@ -37,6 +42,7 @@ const AgentChatBox = () => {
|
||||
const { data: userInfo } = useFetchUserInfo();
|
||||
const { data: canvasInfo } = useFetchAgent();
|
||||
const { id: canvasId } = useParams();
|
||||
const { uploadCanvasFile, loading } = useUploadCanvasFileWithProgress();
|
||||
|
||||
const getInputs = useCallback((message: Message) => {
|
||||
return get(message, 'data.inputs', {}) as Record<string, BeginQuery>;
|
||||
@ -66,6 +72,15 @@ const AgentChatBox = () => {
|
||||
[canvasId, getInputs, sendFormMessage],
|
||||
);
|
||||
|
||||
const handleUploadFile: NonNullable<FileUploadProps['onUpload']> =
|
||||
useCallback(
|
||||
async (files, options) => {
|
||||
const ret = await uploadCanvasFile({ files, options });
|
||||
appendUploadResponseList(ret.data);
|
||||
},
|
||||
[appendUploadResponseList, uploadCanvasFile],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="flex flex-1 flex-col px-5 h-[90vh]">
|
||||
@ -104,15 +119,17 @@ const AgentChatBox = () => {
|
||||
</div>
|
||||
<div ref={ref} />
|
||||
</div>
|
||||
<MessageInput
|
||||
<NextMessageInput
|
||||
value={value}
|
||||
sendLoading={sendLoading}
|
||||
disabled={false}
|
||||
sendDisabled={sendLoading}
|
||||
conversationId=""
|
||||
isUploading={loading}
|
||||
onPressEnter={handlePressEnter}
|
||||
onInputChange={handleInputChange}
|
||||
stopOutputMessage={stopOutputMessage}
|
||||
onUpload={handleUploadFile}
|
||||
conversationId=""
|
||||
/>
|
||||
</section>
|
||||
<PdfDrawer
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Sheet, SheetContent } from '@/components/ui/sheet';
|
||||
import { Sheet, SheetContent, SheetTitle } from '@/components/ui/sheet';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -12,6 +12,7 @@ export function ChatSheet({ hideModal }: IModalProps<any>) {
|
||||
className={cn('top-20 p-0')}
|
||||
onInteractOutside={(e) => e.preventDefault()}
|
||||
>
|
||||
<SheetTitle className="hidden"></SheetTitle>
|
||||
<div className="pl-5 pt-2">{t('chat.chat')}</div>
|
||||
<AgentChatBox></AgentChatBox>
|
||||
</SheetContent>
|
||||
|
||||
@ -137,6 +137,38 @@ export function useFindMessageReference(answerList: IEventList) {
|
||||
return { findReferenceByMessageId };
|
||||
}
|
||||
|
||||
interface UploadResponseDataType {
|
||||
created_at: number;
|
||||
created_by: string;
|
||||
extension: string;
|
||||
id: string;
|
||||
mime_type: string;
|
||||
name: string;
|
||||
preview_url: null;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export function useSetUploadResponseData() {
|
||||
const [uploadResponseList, setUploadResponseList] = useState<
|
||||
UploadResponseDataType[]
|
||||
>([]);
|
||||
|
||||
const append = useCallback((data: UploadResponseDataType) => {
|
||||
setUploadResponseList((prev) => [...prev, data]);
|
||||
}, []);
|
||||
|
||||
const clear = useCallback(() => {
|
||||
setUploadResponseList([]);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
uploadResponseList,
|
||||
setUploadResponseList,
|
||||
appendUploadResponseList: append,
|
||||
clearUploadResponseList: clear,
|
||||
};
|
||||
}
|
||||
|
||||
export const useSendAgentMessage = (url?: string) => {
|
||||
const { id: agentId } = useParams();
|
||||
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
||||
@ -155,6 +187,11 @@ export const useSendAgentMessage = (url?: string) => {
|
||||
addNewestOneAnswer,
|
||||
} = useSelectDerivedMessages();
|
||||
const { addEventList } = useContext(AgentChatLogContext);
|
||||
const {
|
||||
appendUploadResponseList,
|
||||
clearUploadResponseList,
|
||||
uploadResponseList,
|
||||
} = useSetUploadResponseData();
|
||||
|
||||
const sendMessage = useCallback(
|
||||
async ({ message }: { message: Message; messages?: Message[] }) => {
|
||||
@ -171,9 +208,13 @@ export const useSendAgentMessage = (url?: string) => {
|
||||
params.query = message.content;
|
||||
// params.message_id = message.id;
|
||||
params.inputs = transferInputsArrayToObject(query); // begin operator inputs
|
||||
|
||||
params.files = uploadResponseList;
|
||||
}
|
||||
const res = await send(params);
|
||||
|
||||
clearUploadResponseList();
|
||||
|
||||
if (receiveMessageError(res)) {
|
||||
sonnerMessage.error(res?.data?.message);
|
||||
|
||||
@ -184,7 +225,15 @@ export const useSendAgentMessage = (url?: string) => {
|
||||
// refetch(); // pull the message list after sending the message successfully
|
||||
}
|
||||
},
|
||||
[agentId, send, inputs, setValue, removeLatestMessage],
|
||||
[
|
||||
agentId,
|
||||
send,
|
||||
inputs,
|
||||
uploadResponseList,
|
||||
setValue,
|
||||
removeLatestMessage,
|
||||
clearUploadResponseList,
|
||||
],
|
||||
);
|
||||
|
||||
const sendFormMessage = useCallback(
|
||||
@ -243,16 +292,17 @@ export const useSendAgentMessage = (url?: string) => {
|
||||
}, [addEventList, answerList]);
|
||||
|
||||
return {
|
||||
handlePressEnter,
|
||||
handleInputChange,
|
||||
value,
|
||||
sendLoading: !done,
|
||||
derivedMessages,
|
||||
ref,
|
||||
handlePressEnter,
|
||||
handleInputChange,
|
||||
removeMessageById,
|
||||
stopOutputMessage,
|
||||
send,
|
||||
sendFormMessage,
|
||||
findReferenceByMessageId,
|
||||
appendUploadResponseList,
|
||||
};
|
||||
};
|
||||
|
||||
@ -150,7 +150,8 @@ function AgentForm({ node }: INextOperatorForm) {
|
||||
<FormContainer>
|
||||
<QueryVariable
|
||||
name="visual_files_var"
|
||||
label="Visual files var"
|
||||
label="Visual Input File"
|
||||
type={VariableType.File}
|
||||
></QueryVariable>
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
Reference in New Issue
Block a user