mirror of https://github.com/langgenius/dify.git
stop & restart
This commit is contained in:
parent
05f97f6e06
commit
552ccb058b
|
|
@ -1,19 +1,26 @@
|
|||
import {
|
||||
forwardRef,
|
||||
memo,
|
||||
useCallback,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import { useWorkflowStore } from '../../store'
|
||||
import { useWorkflowRun } from '../../hooks'
|
||||
import UserInput from './user-input'
|
||||
import { useChat } from './hooks'
|
||||
import type { ChatWrapperRefType } from './index'
|
||||
import Chat from '@/app/components/base/chat/chat'
|
||||
import type { OnSend } from '@/app/components/base/chat/types'
|
||||
import { useFeaturesStore } from '@/app/components/base/features/hooks'
|
||||
import { fetchSuggestedQuestions } from '@/service/debug'
|
||||
import {
|
||||
fetchSuggestedQuestions,
|
||||
stopChatMessageResponding,
|
||||
} from '@/service/debug'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
|
||||
const ChatWrapper = () => {
|
||||
const ChatWrapper = forwardRef<ChatWrapperRefType>((_, ref) => {
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
const workflowStore = useWorkflowStore()
|
||||
const featuresStore = useFeaturesStore()
|
||||
const { handleStopRun } = useWorkflowRun()
|
||||
|
|
@ -38,31 +45,38 @@ const ChatWrapper = () => {
|
|||
isResponding,
|
||||
suggestedQuestions,
|
||||
handleSend,
|
||||
} = useChat(config)
|
||||
handleRestart,
|
||||
} = useChat(
|
||||
config,
|
||||
[],
|
||||
taskId => stopChatMessageResponding(appDetail!.id, taskId),
|
||||
)
|
||||
|
||||
const doSend = useCallback<OnSend>((query, files) => {
|
||||
const appId = useAppStore.getState().appDetail?.id
|
||||
|
||||
if (appId) {
|
||||
handleSend(
|
||||
{
|
||||
query,
|
||||
files,
|
||||
inputs: workflowStore.getState().inputs,
|
||||
conversation_id: conversationId,
|
||||
},
|
||||
{
|
||||
onGetSuggestedQuestions: (messageId, getAbortController) => fetchSuggestedQuestions(appId, messageId, getAbortController),
|
||||
},
|
||||
)
|
||||
}
|
||||
}, [conversationId, handleSend, workflowStore])
|
||||
handleSend(
|
||||
{
|
||||
query,
|
||||
files,
|
||||
inputs: workflowStore.getState().inputs,
|
||||
conversation_id: conversationId,
|
||||
},
|
||||
{
|
||||
onGetSuggestedQuestions: (messageId, getAbortController) => fetchSuggestedQuestions(appDetail!.id, messageId, getAbortController),
|
||||
},
|
||||
)
|
||||
}, [conversationId, handleSend, workflowStore, appDetail])
|
||||
|
||||
const doStop = useCallback(() => {
|
||||
handleStop()
|
||||
handleStopRun()
|
||||
}, [handleStop, handleStopRun])
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
handleRestart,
|
||||
}
|
||||
}, [handleRestart])
|
||||
|
||||
return (
|
||||
<Chat
|
||||
config={config as any}
|
||||
|
|
@ -79,6 +93,8 @@ const ChatWrapper = () => {
|
|||
suggestedQuestions={suggestedQuestions}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
ChatWrapper.displayName = 'ChatWrapper'
|
||||
|
||||
export default memo(ChatWrapper)
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ type SendCallback = {
|
|||
export const useChat = (
|
||||
config: any,
|
||||
prevChatList?: ChatItem[],
|
||||
stopChat?: (taskId: string) => void,
|
||||
) => {
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useToastContext()
|
||||
const { handleRun } = useWorkflowRun()
|
||||
const hasStopResponded = useRef(false)
|
||||
const connversationId = useRef('')
|
||||
const taskIdRef = useRef('')
|
||||
const [chatList, setChatList] = useState<ChatItem[]>(prevChatList || [])
|
||||
const chatListRef = useRef<ChatItem[]>(prevChatList || [])
|
||||
const [isResponding, setIsResponding] = useState(false)
|
||||
|
|
@ -52,10 +54,33 @@ export const useChat = (
|
|||
const handleStop = useCallback(() => {
|
||||
hasStopResponded.current = true
|
||||
handleResponding(false)
|
||||
if (stopChat && taskIdRef.current)
|
||||
stopChat(taskIdRef.current)
|
||||
|
||||
if (suggestedQuestionsAbortControllerRef.current)
|
||||
suggestedQuestionsAbortControllerRef.current.abort()
|
||||
}, [handleResponding])
|
||||
}, [handleResponding, stopChat])
|
||||
|
||||
const handleRestart = useCallback(() => {
|
||||
connversationId.current = ''
|
||||
taskIdRef.current = ''
|
||||
handleStop()
|
||||
const newChatList = config?.opening_statement
|
||||
? [{
|
||||
id: `${Date.now()}`,
|
||||
content: config.opening_statement,
|
||||
isAnswer: true,
|
||||
isOpeningStatement: true,
|
||||
suggestedQuestions: config.suggested_questions,
|
||||
}]
|
||||
: []
|
||||
handleUpdateChatList(newChatList)
|
||||
setSuggestQuestions([])
|
||||
}, [
|
||||
config,
|
||||
handleStop,
|
||||
handleUpdateChatList,
|
||||
])
|
||||
|
||||
const updateCurrentQA = useCallback(({
|
||||
responseItem,
|
||||
|
|
@ -140,7 +165,7 @@ export const useChat = (
|
|||
handleRun(
|
||||
params,
|
||||
{
|
||||
onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId }: any) => {
|
||||
onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId, taskId }: any) => {
|
||||
responseItem.content = responseItem.content + message
|
||||
|
||||
if (messageId && !hasSetResponseId) {
|
||||
|
|
@ -151,6 +176,7 @@ export const useChat = (
|
|||
if (isFirstMessage && newConversationId)
|
||||
connversationId.current = newConversationId
|
||||
|
||||
taskIdRef.current = taskId
|
||||
if (messageId)
|
||||
responseItem.id = messageId
|
||||
|
||||
|
|
@ -207,6 +233,7 @@ export const useChat = (
|
|||
chatList,
|
||||
handleSend,
|
||||
handleStop,
|
||||
handleRestart,
|
||||
isResponding,
|
||||
suggestedQuestions,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,19 @@
|
|||
import { memo } from 'react'
|
||||
import {
|
||||
memo,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useStore } from '../../store'
|
||||
import ChatWrapper from './chat-wrapper'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
|
||||
export type ChatWrapperRefType = {
|
||||
handleRestart: () => void
|
||||
}
|
||||
const DebugAndPreview = () => {
|
||||
const { t } = useTranslation()
|
||||
const chatRef = useRef({ handleRestart: () => {} })
|
||||
const showRunHistory = useStore(s => s.showRunHistory)
|
||||
|
||||
return (
|
||||
|
|
@ -19,10 +28,16 @@ const DebugAndPreview = () => {
|
|||
>
|
||||
<div className='shrink-0 flex items-center justify-between px-4 pt-3 pb-2 font-semibold text-gray-900'>
|
||||
{t('workflow.common.debugAndPreview').toLocaleUpperCase()}
|
||||
<div className='h-8' />
|
||||
<Button
|
||||
className='pl-2.5 pr-[7px] h-8 bg-white border-[0.5px] border-gray-200 shadow-xs rounded-lg text-[13px] text-primary-600 font-semibold'
|
||||
onClick={() => chatRef.current.handleRestart()}
|
||||
>
|
||||
<RefreshCcw01 className='mr-1 w-3.5 h-3.5' />
|
||||
{t('common.operation.refresh')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className='grow rounded-b-2xl'>
|
||||
<ChatWrapper />
|
||||
<div className='grow rounded-b-2xl overflow-y-auto'>
|
||||
<ChatWrapper ref={chatRef} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue