This commit is contained in:
Archer
2023-11-09 09:46:57 +08:00
committed by GitHub
parent 661ee79943
commit 8bb5588305
402 changed files with 9899 additions and 5967 deletions

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { ModalBody, Box, useTheme } from '@chakra-ui/react';
import { ChatItemType } from '@/types/chat';
import { ChatItemType } from '@fastgpt/global/core/chat/type';
import MyModal from '../MyModal';
const ContextModal = ({

View File

@@ -16,6 +16,7 @@ import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/ty
import MyTooltip from '../MyTooltip';
import NextLink from 'next/link';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useUserStore } from '@/web/support/user/useUserStore';
const QuoteModal = ({
rawSearch = [],
@@ -28,14 +29,15 @@ const QuoteModal = ({
const { isPc } = useSystemStore();
const theme = useTheme();
const router = useRouter();
const { userInfo } = useUserStore();
const { toast } = useToast();
const { setIsLoading, Loading } = useLoading();
const [editInputData, setEditInputData] = useState<InputDataType>();
const [editInputData, setEditInputData] = useState<InputDataType & { datasetId: string }>();
const isShare = useMemo(() => router.pathname === '/chat/share', [router.pathname]);
/**
* click edit, get new kbDataItem
* click edit, get new DataItem
*/
const onclickEdit = useCallback(
async (item: InputDataType) => {
@@ -181,6 +183,7 @@ const QuoteModal = ({
</MyModal>
{editInputData && editInputData.id && (
<InputDataModal
canWrite={userInfo?.team?.canWrite || false}
onClose={() => setEditInputData(undefined)}
onSuccess={() => {
console.log('更新引用成功');

View File

@@ -1,5 +1,6 @@
import React, { useMemo, useState } from 'react';
import { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/api.d';
import type { ChatItemType } from '@fastgpt/global/core/chat/type';
import { Flex, BoxProps, useDisclosure, Image, useTheme } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { useSystemStore } from '@/web/common/system/useSystemStore';

View File

@@ -6,7 +6,7 @@ import MyIcon from '@/components/Icon';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant';
import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
import dynamic from 'next/dynamic';
import { MarkDataType } from '@/global/core/dataset/type';
import { AdminFbkType } from '@fastgpt/global/core/chat/type.d';
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
@@ -28,7 +28,7 @@ const SelectMarkCollection = ({
adminMarkData: AdminMarkType;
setAdminMarkData: (e: AdminMarkType) => void;
onClose: () => void;
onSuccess: (adminFeedback: MarkDataType) => void;
onSuccess: (adminFeedback: AdminFbkType) => void;
}) => {
const { t } = useTranslation();
const theme = useTheme();
@@ -166,12 +166,12 @@ const SelectMarkCollection = ({
datasetId={adminMarkData.datasetId}
defaultValues={{
id: adminMarkData.dataId,
datasetId: adminMarkData.datasetId,
collectionId: adminMarkData.collectionId,
sourceName: '手动标注',
q: adminMarkData.q,
a: adminMarkData.a
}}
canWrite
onSuccess={(data) => {
if (!data.q || !adminMarkData.datasetId || !adminMarkData.collectionId || !data.id) {
return onClose();

View File

@@ -1,6 +1,6 @@
import React, { useMemo, useState } from 'react';
import { Box, useTheme, Flex, Image } from '@chakra-ui/react';
import type { ChatHistoryItemResType } from '@/types/chat';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/api.d';
import { useTranslation } from 'react-i18next';
import { ModuleTemplatesFlat } from '@/constants/flow/ModuleTemplate';
import Tabs from '../Tabs';
@@ -8,7 +8,7 @@ import Tabs from '../Tabs';
import MyModal from '../MyModal';
import MyTooltip from '../MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { formatPrice } from '@fastgpt/global/common/bill/tools';
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
function Row({ label, value }: { label: string; value?: string | number | React.ReactNode }) {
const theme = useTheme();

View File

@@ -10,12 +10,9 @@ import React, {
} from 'react';
import Script from 'next/script';
import { throttle } from 'lodash';
import {
ChatHistoryItemResType,
ChatItemType,
ChatSiteItemType,
ExportChatType
} from '@/types/chat';
import type { ExportChatType } from '@/types/chat.d';
import type { ChatItemType, ChatSiteItemType } from '@fastgpt/global/core/chat/type.d';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/api.d';
import { useToast } from '@/web/common/hooks/useToast';
import { useAudioPlay } from '@/web/common/utils/voice';
import { getErrText } from '@fastgpt/global/common/error/utils';
@@ -38,12 +35,12 @@ import { useMarkdown } from '@/web/common/hooks/useMarkdown';
import { ModuleItemType } from '@fastgpt/global/core/module/type.d';
import { VariableInputEnum } from '@/constants/app';
import { useForm } from 'react-hook-form';
import type { MessageItemType } from '@/types/core/chat/type';
import type { ChatMessageItemType } from '@fastgpt/global/core/ai/type.d';
import { fileDownload } from '@/web/common/file/utils';
import { htmlTemplate } from '@/constants/common';
import { useRouter } from 'next/router';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { TaskResponseKeyEnum } from '@/constants/chat';
import { TaskResponseKeyEnum } from '@fastgpt/global/core/chat/constants';
import { useTranslation } from 'react-i18next';
import { customAlphabet } from 'nanoid';
import { adminUpdateChatFeedback, userUpdateChatFeedback } from '@/web/core/chat/api';
@@ -64,6 +61,7 @@ const SelectMarkCollection = dynamic(() => import('./SelectMarkCollection'));
import styles from './index.module.scss';
import { postQuestionGuide } from '@/web/core/ai/api';
import { splitGuideModule } from '@/global/core/app/modules/utils';
import { AppTTSConfigType } from '@/types/app';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
@@ -73,7 +71,7 @@ type generatingMessageProps = { text?: string; name?: string; status?: 'running'
export type StartChatFnProps = {
chatList: ChatSiteItemType[];
messages: MessageItemType[];
messages: ChatMessageItemType[];
controller: AbortController;
variables: Record<string, any>;
generatingMessage: (e: generatingMessageProps) => void;
@@ -158,7 +156,7 @@ const ChatBox = (
[chatHistory]
);
const { welcomeText, variableModules, questionGuide } = useMemo(
const { welcomeText, variableModules, questionGuide, ttsConfig } = useMemo(
() => splitGuideModule(userGuideModule),
[userGuideModule]
);
@@ -206,32 +204,28 @@ const ChatBox = (
[]
);
// eslint-disable-next-line react-hooks/exhaustive-deps
const generatingMessage = useCallback(
// concat text to end of message
({ text = '', status, name }: generatingMessageProps) => {
setChatHistory((state) =>
state.map((item, index) => {
if (index !== state.length - 1) return item;
return {
...item,
...(text
? {
value: item.value + text
}
: {}),
...(status && name
? {
status,
moduleName: name
}
: {})
};
})
);
generatingScroll();
},
[generatingScroll, setChatHistory]
);
const generatingMessage = ({ text = '', status, name }: generatingMessageProps) => {
setChatHistory((state) =>
state.map((item, index) => {
if (index !== state.length - 1) return item;
return {
...item,
...(text
? {
value: item.value + text
}
: {}),
...(status && name
? {
status,
moduleName: name
}
: {})
};
})
);
generatingScroll();
};
// 重置输入内容
const resetInputVal = useCallback((val: string) => {
@@ -489,7 +483,7 @@ const ChatBox = (
return {
bg: colorMap[chatContent.status] || colorMap.loading,
name: t(chatContent.moduleName || 'common.Loading')
name: chatContent.moduleName || t('common.Loading')
};
}, [chatHistory, isChatting, t]);
/* style end */
@@ -654,8 +648,10 @@ const ChatBox = (
<ChatController
ml={2}
chat={item}
setChatHistory={setChatHistory}
display={index === chatHistory.length - 1 && isChatting ? 'none' : 'flex'}
showVoiceIcon={showVoiceIcon}
ttsConfig={ttsConfig}
onDelete={
onDelMessage
? () => {
@@ -801,13 +797,20 @@ const ChatBox = (
</Box>
{/* message input */}
{onStartChat && variableIsFinish && active ? (
<Box m={['0 auto', '10px auto']} w={'100%'} maxW={['auto', 'min(750px, 100%)']} px={[0, 5]}>
<Box m={['0 auto', '10px auto']} w={'100%'} maxW={['auto', 'min(800px, 100%)']} px={[0, 5]}>
<Box
py={'18px'}
position={'relative'}
boxShadow={`0 0 10px rgba(0,0,0,0.2)`}
borderTop={['1px solid', 0]}
borderTopColor={'myGray.200'}
{...(isPc
? {
border: '1px solid',
borderColor: 'rgba(0,0,0,0.12)'
}
: {
borderTop: '1px solid',
borderTopColor: 'rgba(0,0,0,0.15)'
})}
borderRadius={['none', 'md']}
backgroundColor={'white'}
>
@@ -836,6 +839,7 @@ const ChatBox = (
const textarea = e.target;
textarea.style.height = textareaMinH;
textarea.style.height = `${textarea.scrollHeight}px`;
setRefresh((state) => !state);
}}
onKeyDown={(e) => {
// enter send.(pc or iframe && enter and unPress shift)
@@ -852,11 +856,14 @@ const ChatBox = (
<Flex
alignItems={'center'}
justifyContent={'center'}
h={'25px'}
w={'25px'}
h={['26px', '32px']}
w={['26px', '32px']}
position={'absolute'}
right={['12px', '20px']}
bottom={'15px'}
right={['12px', '14px']}
bottom={['15px', '13px']}
borderRadius={'md'}
bg={TextareaDom.current?.value ? 'myBlue.600' : ''}
lineHeight={1}
>
{isChatting ? (
<MyIcon
@@ -869,16 +876,18 @@ const ChatBox = (
onClick={() => chatController.current?.abort('stop')}
/>
) : (
<MyIcon
name={'chatSend'}
width={['18px', '20px']}
height={['18px', '20px']}
cursor={'pointer'}
color={'gray.500'}
onClick={() => {
handleSubmit((data) => sendPrompt(data, TextareaDom.current?.value))();
}}
/>
<MyTooltip label={t('core.chat.Send Message')}>
<MyIcon
name={'core/chat/sendFill'}
width={'16px'}
height={'16px'}
cursor={'pointer'}
color={TextareaDom.current?.value ? 'white' : 'myBlue.600'}
onClick={() => {
handleSubmit((data) => sendPrompt(data, TextareaDom.current?.value))();
}}
/>
</MyTooltip>
)}
</Flex>
</Box>
@@ -1106,8 +1115,10 @@ function Empty() {
function ChatController({
chat,
setChatHistory,
display,
showVoiceIcon,
ttsConfig,
onReadFeedback,
onMark,
onRetry,
@@ -1117,7 +1128,9 @@ function ChatController({
mr
}: {
chat: ChatSiteItemType;
setChatHistory?: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>;
showVoiceIcon?: boolean;
ttsConfig?: AppTTSConfigType;
onRetry?: () => void;
onDelete?: () => void;
onMark?: () => void;
@@ -1127,7 +1140,9 @@ function ChatController({
const theme = useTheme();
const { t } = useTranslation();
const { copyData } = useCopyData();
const { audioLoading, audioPlaying, hasAudio, playAudio, cancelAudio } = useAudioPlay({});
const { audioLoading, audioPlaying, hasAudio, playAudio, cancelAudio } = useAudioPlay({
ttsConfig
});
const controlIconStyle = {
w: '14px',
cursor: 'pointer',
@@ -1198,7 +1213,24 @@ function ChatController({
{...controlIconStyle}
name={'voice'}
_hover={{ color: '#E74694' }}
onClick={() => playAudio(chat.value)}
onClick={async () => {
const buffer = await playAudio({
buffer: chat.ttsBuffer,
chatItemId: chat.dataId,
text: chat.value
});
if (!setChatHistory) return;
setChatHistory((state) =>
state.map((item) =>
item.dataId === chat.dataId
? {
...item,
ttsBuffer: buffer
}
: item
)
);
}}
/>
</MyTooltip>
))}