v4.6.9-alpha (#918)

Co-authored-by: Mufei <327958099@qq.com>
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
Archer
2024-03-04 00:05:25 +08:00
committed by GitHub
parent f9f0b4bffd
commit 42a8184ea0
153 changed files with 4906 additions and 4307 deletions

View File

@@ -13,6 +13,7 @@ import { IMG_BLOCK_KEY } from '@fastgpt/global/core/chat/constants';
import { addDays } from 'date-fns';
import { useRequest } from '@/web/common/hooks/useRequest';
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
enum FileTypeEnum {
@@ -35,8 +36,12 @@ const MessageInput = ({
isChatting,
TextareaDom,
showFileSelector = false,
resetInputVal
}: {
resetInputVal,
shareId,
outLinkUid,
teamId,
teamToken
}: OutLinkChatAuthProps & {
onChange?: (e: string) => void;
onSendMessage: (e: string) => void;
onStop: () => void;
@@ -47,7 +52,6 @@ const MessageInput = ({
}) => {
const [, startSts] = useTransition();
const { shareId } = useRouter().query as { shareId?: string };
const {
isSpeaking,
isTransCription,
@@ -56,7 +60,7 @@ const MessageInput = ({
speakingTimeString,
renderAudioGraph,
stream
} = useSpeech({ shareId });
} = useSpeech({ shareId, outLinkUid, teamId, teamToken });
const { isPc } = useSystemStore();
const canvasRef = useRef<HTMLCanvasElement>(null);
const { t } = useTranslation();
@@ -82,7 +86,10 @@ const MessageInput = ({
maxSize: 1024 * 1024 * 5,
// 30 day expired.
expiredTime: addDays(new Date(), 7),
shareId
shareId,
outLinkUid,
teamId,
teamToken
});
setFileList((state) =>
state.map((item) =>
@@ -320,7 +327,7 @@ ${images.map((img) => JSON.stringify({ src: img.src })).join('\n')}
rows={1}
height={'22px'}
lineHeight={'22px'}
maxHeight={'150px'}
maxHeight={'50vh'}
maxLength={-1}
overflowY={'auto'}
whiteSpace={'pre-wrap'}

View File

@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { useMemo } from 'react';
import { ModalBody, Box, useTheme } from '@chakra-ui/react';
import MyModal from '../MyModal';
@@ -10,12 +10,12 @@ import RawSourceBox from '../core/dataset/RawSourceBox';
const QuoteModal = ({
rawSearch = [],
onClose,
isShare,
showDetail,
metadata
}: {
rawSearch: SearchDataResponseItemType[];
onClose: () => void;
isShare: boolean;
showDetail: boolean;
metadata?: {
collectionId: string;
sourceId?: string;
@@ -57,7 +57,7 @@ const QuoteModal = ({
}
>
<ModalBody>
<QuoteList rawSearch={filterResults} isShare={isShare} />
<QuoteList rawSearch={filterResults} showDetail={showDetail} />
</ModalBody>
</MyModal>
</>
@@ -68,10 +68,10 @@ export default QuoteModal;
export const QuoteList = React.memo(function QuoteList({
rawSearch = [],
isShare
showDetail
}: {
rawSearch: SearchDataResponseItemType[];
isShare: boolean;
showDetail: boolean;
}) {
const theme = useTheme();
@@ -88,7 +88,7 @@ export const QuoteList = React.memo(function QuoteList({
_hover={{ '& .hover-data': { display: 'flex' } }}
bg={i % 2 === 0 ? 'white' : 'myWhite.500'}
>
<QuoteItem quoteItem={item} canViewSource={!isShare} linkToDataset={!isShare} />
<QuoteItem quoteItem={item} canViewSource={showDetail} linkToDataset={showDetail} />
</Box>
))}
</>

View File

@@ -1,7 +1,7 @@
import React, { useMemo, useState } from 'react';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
import type { ChatItemType } from '@fastgpt/global/core/chat/type';
import { Flex, BoxProps, useDisclosure, Image, useTheme, Box } from '@chakra-ui/react';
import { Flex, BoxProps, useDisclosure, useTheme, Box } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
@@ -20,10 +20,10 @@ const WholeResponseModal = dynamic(() => import('./WholeResponseModal'), { ssr:
const ResponseTags = ({
responseData = [],
isShare
showDetail
}: {
responseData?: ChatHistoryItemResType[];
isShare: boolean;
showDetail: boolean;
}) => {
const theme = useTheme();
const { isPc } = useSystemStore();
@@ -76,13 +76,13 @@ const ResponseTags = ({
sourceName: item.sourceName,
sourceId: item.sourceId,
icon: getSourceNameIcon({ sourceId: item.sourceId, sourceName: item.sourceName }),
canReadQuote: !isShare || strIsLink(item.sourceId),
canReadQuote: showDetail || strIsLink(item.sourceId),
collectionId: item.collectionId
})),
historyPreview: chatData?.historyPreview,
runningTime: +responseData.reduce((sum, item) => sum + (item.runningTime || 0), 0).toFixed(2)
};
}, [isShare, responseData]);
}, [showDetail, responseData]);
const TagStyles: BoxProps = {
mr: 2,
@@ -134,7 +134,7 @@ const ResponseTags = ({
</Flex>
</>
)}
{!isShare && (
{showDetail && (
<Flex alignItems={'center'} mt={3} flexWrap={'wrap'}>
{quoteList.length > 0 && (
<MyTooltip label="查看引用">
@@ -187,7 +187,7 @@ const ResponseTags = ({
{!!quoteModalData && (
<QuoteModal
{...quoteModalData}
isShare={isShare}
showDetail={showDetail}
onClose={() => setQuoteModalData(undefined)}
/>
)}
@@ -195,7 +195,11 @@ const ResponseTags = ({
<ContextModal context={contextModalData} onClose={() => setContextModalData(undefined)} />
)}
{isOpenWholeModal && (
<WholeResponseModal response={responseData} isShare={isShare} onClose={onCloseWholeModal} />
<WholeResponseModal
response={responseData}
showDetail={showDetail}
onClose={onCloseWholeModal}
/>
)}
</>
);

View File

@@ -51,11 +51,11 @@ function Row({
const WholeResponseModal = ({
response,
isShare,
showDetail,
onClose
}: {
response: ChatHistoryItemResType[];
isShare: boolean;
showDetail: boolean;
onClose: () => void;
}) => {
const { t } = useTranslation();
@@ -78,7 +78,7 @@ const WholeResponseModal = ({
}
>
<Flex h={'100%'} flexDirection={'column'}>
<ResponseBox response={response} isShare={isShare} />
<ResponseBox response={response} showDetail={showDetail} />
</Flex>
</MyModal>
);
@@ -88,10 +88,10 @@ export default WholeResponseModal;
const ResponseBox = React.memo(function ResponseBox({
response,
isShare
showDetail
}: {
response: ChatHistoryItemResType[];
isShare: boolean;
showDetail: boolean;
}) {
const theme = useTheme();
const { t } = useTranslation();
@@ -142,10 +142,7 @@ const ResponseBox = React.memo(function ResponseBox({
value={`${activeModule?.runningTime || 0}s`}
/>
<Row label={t('core.chat.response.module model')} value={activeModule?.model} />
<Row
label={t('support.wallet.usage.Chars length')}
value={`${activeModule?.charsLength}`}
/>
<Row label={t('core.chat.response.module tokens')} value={`${activeModule?.tokens}`} />
<Row label={t('core.chat.response.module query')} value={activeModule?.query} />
<Row
label={t('core.chat.response.context total length')}
@@ -188,7 +185,7 @@ const ResponseBox = React.memo(function ResponseBox({
{activeModule.quoteList && activeModule.quoteList.length > 0 && (
<Row
label={t('core.chat.response.module quoteList')}
rawDom={<QuoteList isShare={isShare} rawSearch={activeModule.quoteList} />}
rawDom={<QuoteList showDetail={showDetail} rawSearch={activeModule.quoteList} />}
/>
)}
</>
@@ -280,7 +277,7 @@ const ResponseBox = React.memo(function ResponseBox({
{activeModule?.pluginDetail && activeModule?.pluginDetail.length > 0 && (
<Row
label={t('core.chat.response.Plugin Resonse Detail')}
rawDom={<ResponseBox response={activeModule.pluginDetail} isShare={isShare} />}
rawDom={<ResponseBox response={activeModule.pluginDetail} showDetail={showDetail} />}
/>
)}
</>

View File

@@ -68,6 +68,7 @@ import type { AppTTSConfigType, VariableItemType } from '@fastgpt/global/core/mo
import MessageInput from './MessageInput';
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
import ChatBoxDivider from '../core/chat/Divider';
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
@@ -106,7 +107,7 @@ const MessageCardStyle: BoxProps = {
maxW: ['calc(100% - 25px)', 'calc(100% - 40px)']
};
type Props = {
type Props = OutLinkChatAuthProps & {
feedbackType?: `${FeedbackTypeEnum}`;
showMarkIcon?: boolean; // admin mark dataset
showVoiceIcon?: boolean;
@@ -120,9 +121,6 @@ type Props = {
// not chat test params
appId?: string;
chatId?: string;
shareId?: string;
shareTeamId?: string;
outLinkUid?: string;
onUpdateVariable?: (e: Record<string, any>) => void;
onStartChat?: (e: StartChatFnProps) => Promise<{
@@ -147,8 +145,9 @@ const ChatBox = (
appId,
chatId,
shareId,
shareTeamId,
outLinkUid,
teamId,
teamToken,
onUpdateVariable,
onStartChat,
onDelMessage
@@ -288,7 +287,10 @@ const ChatBox = (
const result = await postQuestionGuide(
{
messages: adaptChat2GptMessages({ messages: history, reserveId: false }).slice(-6),
shareId
shareId,
outLinkUid,
teamId,
teamToken
},
abortSignal
);
@@ -300,7 +302,7 @@ const ChatBox = (
}
} catch (error) {}
},
[questionGuide, shareId]
[questionGuide, shareId, outLinkUid, teamId, teamToken]
);
/**
@@ -398,22 +400,20 @@ const ChatBox = (
};
})
);
if (!shareTeamId) {
setTimeout(() => {
createQuestionGuide({
history: newChatList.map((item, i) =>
i === newChatList.length - 1
? {
...item,
value: responseText
}
: item
)
});
generatingScroll();
isPc && TextareaDom.current?.focus();
}, 100);
}
setTimeout(() => {
createQuestionGuide({
history: newChatList.map((item, i) =>
i === newChatList.length - 1
? {
...item,
value: responseText
}
: item
)
});
generatingScroll();
isPc && TextareaDom.current?.focus();
}, 100);
} catch (err: any) {
toast({
title: t(getErrText(err, 'core.chat.error.Chat error')),
@@ -622,6 +622,7 @@ const ChatBox = (
{/* control icon */}
<Flex w={'100%'} alignItems={'center'} justifyContent={'flex-end'}>
<ChatControllerComponent
isChatting={isChatting}
chat={item}
onDelete={
onDelMessage
@@ -654,12 +655,17 @@ const ChatBox = (
<ChatAvatar src={appAvatar} type={'AI'} />
{/* control icon */}
<ChatControllerComponent
isChatting={isChatting}
ml={2}
chat={item}
setChatHistory={setChatHistory}
display={index === chatHistory.length - 1 && isChatting ? 'none' : 'flex'}
showVoiceIcon={showVoiceIcon}
ttsConfig={ttsConfig}
shareId={shareId}
outLinkUid={outLinkUid}
teamId={teamId}
teamToken={teamToken}
onDelete={
onDelMessage
? () => {
@@ -829,7 +835,10 @@ const ChatBox = (
isChatting={index === chatHistory.length - 1 && isChatting}
/>
<ResponseTags responseData={item.responseData} isShare={!!shareId} />
<ResponseTags
responseData={item.responseData}
showDetail={!shareId && !teamId}
/>
{/* custom feedback */}
{item.customFeedbacks && item.customFeedbacks.length > 0 && (
@@ -909,6 +918,10 @@ const ChatBox = (
TextareaDom={TextareaDom}
resetInputVal={resetInputVal}
showFileSelector={showFileSelector}
shareId={shareId}
outLinkUid={outLinkUid}
teamId={teamId}
teamToken={teamToken}
/>
)}
{/* user feedback modal */}
@@ -1236,6 +1249,7 @@ function Empty() {
}
const ChatControllerComponent = React.memo(function ChatControllerComponent({
isChatting,
chat,
setChatHistory,
display,
@@ -1249,8 +1263,13 @@ const ChatControllerComponent = React.memo(function ChatControllerComponent({
onAddUserDislike,
onAddUserLike,
ml,
mr
}: {
mr,
shareId,
outLinkUid,
teamId,
teamToken
}: OutLinkChatAuthProps & {
isChatting: boolean;
chat: ChatSiteItemType;
setChatHistory?: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>;
showVoiceIcon?: boolean;
@@ -1267,7 +1286,11 @@ const ChatControllerComponent = React.memo(function ChatControllerComponent({
const { t } = useTranslation();
const { copyData } = useCopyData();
const { audioLoading, audioPlaying, hasAudio, playAudio, cancelAudio } = useAudioPlay({
ttsConfig
ttsConfig,
shareId,
outLinkUid,
teamId,
teamToken
});
const controlIconStyle = {
w: '14px',
@@ -1296,7 +1319,7 @@ const ChatControllerComponent = React.memo(function ChatControllerComponent({
onClick={() => copyData(chat.value)}
/>
</MyTooltip>
{!!onDelete && (
{!!onDelete && !isChatting && (
<>
{onRetry && (
<MyTooltip label={t('core.chat.retry')}>