Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization of Chat component, other bug fixes. Resolves #11848 #11849 #11850

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ADD_EXTERNAL_DATA_TOOL } from '@/app/components/app/configuration/confi
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
import { PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER } from '@/app/components/base/prompt-editor/plugins/update-block'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useFeaturesStore } from '@/app/components/base/features/hooks'

export type ISimplePromptInput = {
mode: AppType
Expand Down Expand Up @@ -54,6 +55,11 @@ const Prompt: FC<ISimplePromptInput> = ({
const { t } = useTranslation()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const featuresStore = useFeaturesStore()
const {
features,
setFeatures,
} = featuresStore!.getState()

const { eventEmitter } = useEventEmitterContextContext()
const {
Expand Down Expand Up @@ -137,8 +143,18 @@ const Prompt: FC<ISimplePromptInput> = ({
})
setModelConfig(newModelConfig)
setPrevPromptConfig(modelConfig.configs)
if (mode !== AppType.completion)

if (mode !== AppType.completion) {
setIntroduction(res.opening_statement)
const newFeatures = produce(features, (draft) => {
draft.opening = {
...draft.opening,
enabled: !!res.opening_statement,
opening_statement: res.opening_statement,
}
})
setFeatures(newFeatures)
}
showAutomaticFalse()
}
const minHeight = initEditorHeight || 228
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const WeightedScore = ({

return (
<div>
<div className='px-3 pt-5 h-[52px] space-x-3 rounded-lg border border-components-panel-border'>
<div className='px-3 pt-5 pb-2 space-x-3 rounded-lg border border-components-panel-border'>
<Slider
className={cn('grow h-0.5 !bg-util-colors-teal-teal-500 rounded-full')}
max={1.0}
Expand All @@ -39,7 +39,7 @@ const WeightedScore = ({
onChange={v => onChange({ value: [v, (10 - v * 10) / 10] })}
trackClassName='weightedScoreSliderTrack'
/>
<div className='flex justify-between mt-1'>
<div className='flex justify-between mt-3'>
<div className='shrink-0 flex items-center w-[90px] system-xs-semibold-uppercase text-util-colors-blue-light-blue-light-500'>
<div className='mr-1 truncate uppercase' title={t('dataset.weightedScore.semantic') || ''}>
{t('dataset.weightedScore.semantic')}
Expand Down
11 changes: 10 additions & 1 deletion web/app/components/base/chat/chat-with-history/chat-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const ChatWrapper = () => {
currentChatInstanceRef,
appData,
themeBuilder,
setChatListSize,
hasMore,
} = useChatWithHistoryContext()
const appConfig = useMemo(() => {
const config = appParams || {}
Expand Down Expand Up @@ -69,7 +71,7 @@ const ChatWrapper = () => {
useEffect(() => {
if (currentChatInstanceRef.current)
currentChatInstanceRef.current.handleStop = handleStop
// eslint-disable-next-line react-hooks/exhaustive-deps
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

const doSend: OnSend = useCallback((message, files, last_answer) => {
Expand Down Expand Up @@ -163,6 +165,11 @@ const ChatWrapper = () => {
/>
: null

const onScrollToTop = useCallback(() => {
if (hasMore)
setChatListSize(size => size + 1)
}, [setChatListSize, hasMore])

return (
<div
className='h-full bg-chatbot-bg overflow-hidden'
Expand All @@ -187,6 +194,8 @@ const ChatWrapper = () => {
answerIcon={answerIcon}
hideProcessDetail
themeBuilder={themeBuilder}
onScrollToTop={onScrollToTop}
hasMoreMessages={hasMore}
/>
</div>
)
Expand Down
26 changes: 15 additions & 11 deletions web/app/components/base/chat/chat-with-history/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export type ChatWithHistoryContextValue = {
handleFeedback: (messageId: string, feedback: Feedback) => void
currentChatInstanceRef: RefObject<{ handleStop: () => void }>
themeBuilder?: ThemeBuilder
hasMore: boolean
setChatListSize: (size: number | ((_size: number) => number)) => void
}

export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({
Expand All @@ -59,21 +61,23 @@ export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>
showConfigPanelBeforeChat: false,
newConversationInputs: {},
newConversationInputsRef: { current: {} },
handleNewConversationInputsChange: () => {},
handleNewConversationInputsChange: () => { },
inputsForms: [],
handleNewConversation: () => {},
handleStartChat: () => {},
handleChangeConversation: () => {},
handlePinConversation: () => {},
handleUnpinConversation: () => {},
handleDeleteConversation: () => {},
handleNewConversation: () => { },
handleStartChat: () => { },
handleChangeConversation: () => { },
handlePinConversation: () => { },
handleUnpinConversation: () => { },
handleDeleteConversation: () => { },
conversationRenaming: false,
handleRenameConversation: () => {},
handleNewConversationCompleted: () => {},
handleRenameConversation: () => { },
handleNewConversationCompleted: () => { },
chatShouldReloadKey: '',
isMobile: false,
isInstalledApp: false,
handleFeedback: () => {},
currentChatInstanceRef: { current: { handleStop: () => {} } },
handleFeedback: () => { },
currentChatInstanceRef: { current: { handleStop: () => { } } },
hasMore: false,
setChatListSize: (_: number | ((_size: number) => number)) => { },
})
export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext)
74 changes: 62 additions & 12 deletions web/app/components/base/chat/chat-with-history/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from 'react'
import { useTranslation } from 'react-i18next'
import useSWR from 'swr'
import useSWRInfinite from 'swr/infinite'
import { useLocalStorageState } from 'ahooks'
import produce from 'immer'
import type {
Expand All @@ -16,6 +17,7 @@ import type {
} from '../types'
import { CONVERSATION_ID_INFO } from '../constants'
import { getPrevChatList } from '../utils'
import type { IChatItem } from '../chat/type'
import {
delConversation,
fetchAppInfo,
Expand All @@ -40,6 +42,8 @@ import { useAppFavicon } from '@/hooks/use-app-favicon'
import { InputVarType } from '@/app/components/workflow/types'
import { TransferMethod } from '@/types/app'

type IChatWithHistory = { data: Array<IChatItem>; limit: number; has_more: boolean }

export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo])
const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
Expand Down Expand Up @@ -107,15 +111,50 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const { data: appMeta } = useSWR(['appMeta', isInstalledApp, appId], () => fetchAppMeta(isInstalledApp, appId))
const { data: appPinnedConversationData, mutate: mutateAppPinnedConversationData } = useSWR(['appConversationData', isInstalledApp, appId, true], () => fetchConversations(isInstalledApp, appId, undefined, true, 100))
const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(['appConversationData', isInstalledApp, appId, false], () => fetchConversations(isInstalledApp, appId, undefined, false, 100))
const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, isInstalledApp, appId] : null, () => fetchChatList(chatShouldReloadKey, isInstalledApp, appId))
const {
data: appChatListData,
isLoading: appChatListDataLoading,
setSize: setChatListSize,
mutate: mutateAppChatListData,
} = useSWRInfinite<IChatWithHistory | null>(
(pageIndex: number, previousPageData) => {
if (pageIndex === 0) {
return [fetchChatList, {
conversationId: chatShouldReloadKey,
installedAppId: appId,
isInstalledApp,
}]
}

if (previousPageData && previousPageData.has_more) {
return [fetchChatList, {
conversationId: chatShouldReloadKey,
installedAppId: appId,
isInstalledApp,
firstId: previousPageData.data.at(-1)?.id,
}]
}

const appPrevChatList = useMemo(
() => (currentConversationId && appChatListData?.data.length)
? getPrevChatList(appChatListData.data)
: [],
[appChatListData, currentConversationId],
return null
},
([_, params]: [unknown, { conversationId: string; installedAppId: string; isInstalledApp: boolean; firstId: string }]) => {
if (params)
return fetchChatList(params.conversationId, params.isInstalledApp, params.installedAppId, params.firstId)
return null
},
{ revalidateFirstPage: false },
)

const hasMore = useMemo(() => {
return !!(appChatListData && appChatListData[appChatListData?.length - 1]?.has_more)
}, [appChatListData])

const appPrevChatList = useMemo(() => {
const items = appChatListData?.flatMap((value: any) => value?.data || []) || []
const res = getPrevChatList(items)
return res
}, [appChatListData])

const [showNewConversationItemInList, setShowNewConversationItemInList] = useState(false)

const pinnedConversationList = useMemo(() => {
Expand Down Expand Up @@ -169,6 +208,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
}
})
}, [appParams])

useEffect(() => {
const conversationInputs: Record<string, any> = {}

Expand Down Expand Up @@ -264,8 +304,9 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
setShowNewConversationItemInList(true)
}
}, [setShowConfigPanelBeforeChat, setShowNewConversationItemInList, checkInputsRequired])

const currentChatInstanceRef = useRef<{ handleStop: () => void }>({ handleStop: () => { } })
const handleChangeConversation = useCallback((conversationId: string) => {
const handleChangeConversation = useCallback((conversationId: string, reloadCurrent = true) => {
currentChatInstanceRef.current.handleStop()
setNewConversationId('')
handleConversationIdInfoChange(conversationId)
Expand All @@ -274,21 +315,28 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
setShowConfigPanelBeforeChat(true)
else
setShowConfigPanelBeforeChat(false)
}, [handleConversationIdInfoChange, setShowConfigPanelBeforeChat, checkInputsRequired])
const handleNewConversation = useCallback(() => {

if (reloadCurrent)
mutateAppChatListData()
}, [handleConversationIdInfoChange, setShowConfigPanelBeforeChat, checkInputsRequired, mutateAppChatListData])

const handleNewConversation = useCallback((reloadCurrent = true) => {
currentChatInstanceRef.current.handleStop()
setNewConversationId('')

if (showNewConversationItemInList) {
handleChangeConversation('')
handleChangeConversation('', reloadCurrent)
}
else if (currentConversationId) {
if (reloadCurrent)
mutateAppChatListData()

handleConversationIdInfoChange('')
setShowConfigPanelBeforeChat(true)
setShowNewConversationItemInList(true)
handleNewConversationInputsChange({})
}
}, [handleChangeConversation, currentConversationId, handleConversationIdInfoChange, setShowConfigPanelBeforeChat, setShowNewConversationItemInList, showNewConversationItemInList, handleNewConversationInputsChange])
}, [handleChangeConversation, currentConversationId, handleConversationIdInfoChange, setShowConfigPanelBeforeChat, setShowNewConversationItemInList, showNewConversationItemInList, handleNewConversationInputsChange, mutateAppChatListData])
const handleUpdateConversationList = useCallback(() => {
mutateAppConversationData()
mutateAppPinnedConversationData()
Expand Down Expand Up @@ -327,7 +375,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
}

if (conversationId === currentConversationId)
handleNewConversation()
handleNewConversation(false)

handleUpdateConversationList()
}, [isInstalledApp, appId, notify, t, handleUpdateConversationList, handleNewConversation, currentConversationId, conversationDeleting])
Expand Down Expand Up @@ -427,5 +475,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
chatShouldReloadKey,
handleFeedback,
currentChatInstanceRef,
hasMore,
setChatListSize,
}
}
4 changes: 4 additions & 0 deletions web/app/components/base/chat/chat-with-history/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
appId,
handleFeedback,
currentChatInstanceRef,
hasMore,
setChatListSize,
} = useChatWithHistory(installedAppInfo)

return (
Expand Down Expand Up @@ -178,6 +180,8 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
handleFeedback,
currentChatInstanceRef,
themeBuilder,
hasMore,
setChatListSize,
}}>
<ChatWithHistory className={className} />
</ChatWithHistoryContext.Provider>
Expand Down
9 changes: 8 additions & 1 deletion web/app/components/base/chat/chat/chat-input-area/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type ChatInputAreaProps = {
inputs?: Record<string, any>
inputsForm?: InputForm[]
theme?: Theme | null
isResponding?: boolean
}
const ChatInputArea = ({
showFeatureBar,
Expand All @@ -51,6 +52,7 @@ const ChatInputArea = ({
inputs = {},
inputsForm = [],
theme,
isResponding,
}: ChatInputAreaProps) => {
const { t } = useTranslation()
const { notify } = useToastContext()
Expand All @@ -77,6 +79,11 @@ const ChatInputArea = ({
const historyRef = useRef([''])
const [currentIndex, setCurrentIndex] = useState(-1)
const handleSend = () => {
if (isResponding) {
notify({ type: 'info', message: t('appDebug.errorMessage.waitForResponse') })
return
}

if (onSend) {
const { files, setFiles } = filesStore.getState()
if (files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)) {
Expand Down Expand Up @@ -116,7 +123,7 @@ const ChatInputArea = ({
setQuery(historyRef.current[currentIndex + 1])
}
else if (currentIndex === historyRef.current.length - 1) {
// If it is the last element, clear the input box
// If it is the last element, clear the input box
setCurrentIndex(historyRef.current.length)
setQuery('')
}
Expand Down
10 changes: 9 additions & 1 deletion web/app/components/base/chat/chat/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ export const useChat = (
setChatList(newChatList)
chatListRef.current = newChatList
}, [])

useEffect(() => {
if (prevChatList && prevChatList.length > 0) {
setChatList(prevChatList)
chatListRef.current = prevChatList
}
}, [prevChatList])

const handleResponding = useCallback((isResponding: boolean) => {
setIsResponding(isResponding)
isRespondingRef.current = isResponding
Expand Down Expand Up @@ -249,7 +257,7 @@ export const useChat = (
else
ttsUrl = `/apps/${params.appId}/text-to-audio`
}
const player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', (_: any): any => {})
const player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', (_: any): any => { })
ssePost(
url,
{
Expand Down
Loading