mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +08:00
refactor: streamline chat operation handling and enhance workflow event management
This commit is contained in:
1
.github/workflows/build-push.yml
vendored
1
.github/workflows/build-push.yml
vendored
@ -8,6 +8,7 @@ on:
|
|||||||
- "build/**"
|
- "build/**"
|
||||||
- "release/e-*"
|
- "release/e-*"
|
||||||
- "hotfix/**"
|
- "hotfix/**"
|
||||||
|
- "feature/hitl-frontend"
|
||||||
tags:
|
tags:
|
||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
|
|||||||
@ -304,30 +304,28 @@ const Operation: FC<OperationProps> = ({
|
|||||||
<Log logItem={item} />
|
<Log logItem={item} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!isOpeningStatement && (
|
{!isOpeningStatement && !humanInputFormData && (
|
||||||
<div className="ml-1 hidden items-center gap-0.5 rounded-[10px] border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 shadow-md backdrop-blur-sm group-hover:flex">
|
<div className="ml-1 hidden items-center gap-0.5 rounded-[10px] border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 shadow-md backdrop-blur-sm group-hover:flex">
|
||||||
{(config?.text_to_speech?.enabled) && !humanInputFormData && (
|
{(config?.text_to_speech?.enabled) && (
|
||||||
<NewAudioButton
|
<NewAudioButton
|
||||||
id={id}
|
id={id}
|
||||||
value={content}
|
value={content}
|
||||||
voice={config?.text_to_speech?.voice}
|
voice={config?.text_to_speech?.voice}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!humanInputFormData && (
|
<ActionButton onClick={() => {
|
||||||
<ActionButton onClick={() => {
|
copy(content)
|
||||||
copy(content)
|
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
||||||
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<RiClipboardLine className="h-4 w-4" />
|
||||||
<RiClipboardLine className="h-4 w-4" />
|
</ActionButton>
|
||||||
</ActionButton>
|
{!noChatInput && (
|
||||||
)}
|
|
||||||
{!noChatInput && !humanInputFormData && (
|
|
||||||
<ActionButton onClick={() => onRegenerate?.(item)}>
|
<ActionButton onClick={() => onRegenerate?.(item)}>
|
||||||
<RiResetLeftLine className="h-4 w-4" />
|
<RiResetLeftLine className="h-4 w-4" />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
)}
|
)}
|
||||||
{(config?.supportAnnotation && config.annotation_reply?.enabled) && !humanInputFormData && (
|
{(config?.supportAnnotation && config.annotation_reply?.enabled) && (
|
||||||
<AnnotationCtrlButton
|
<AnnotationCtrlButton
|
||||||
appId={config?.appId || ''}
|
appId={config?.appId || ''}
|
||||||
messageId={id}
|
messageId={id}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { useWorkflowUpdate } from '@/app/components/workflow/hooks/use-workflow-
|
|||||||
import { useWorkflowRunEvent } from '@/app/components/workflow/hooks/use-workflow-run-event/use-workflow-run-event'
|
import { useWorkflowRunEvent } from '@/app/components/workflow/hooks/use-workflow-run-event/use-workflow-run-event'
|
||||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
import { WorkflowRunningStatus } from '@/app/components/workflow/types'
|
import { WorkflowRunningStatus } from '@/app/components/workflow/types'
|
||||||
import { handleStream, post, ssePost } from '@/service/base'
|
import { handleStream, post, sseGet, ssePost } from '@/service/base'
|
||||||
import { ContentType } from '@/service/fetch'
|
import { ContentType } from '@/service/fetch'
|
||||||
import { useInvalidAllLastRun } from '@/service/use-workflow'
|
import { useInvalidAllLastRun } from '@/service/use-workflow'
|
||||||
import { stopWorkflowRun } from '@/service/workflow'
|
import { stopWorkflowRun } from '@/service/workflow'
|
||||||
@ -661,137 +661,145 @@ export const useWorkflowRun = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const finalCallbacks: IOtherOptions = {
|
||||||
|
...baseSseOptions,
|
||||||
|
getAbortController: (controller: AbortController) => {
|
||||||
|
abortControllerRef.current = controller
|
||||||
|
},
|
||||||
|
onWorkflowFinished: (params) => {
|
||||||
|
handleWorkflowFinished(params)
|
||||||
|
|
||||||
|
if (onWorkflowFinished)
|
||||||
|
onWorkflowFinished(params)
|
||||||
|
if (isInWorkflowDebug) {
|
||||||
|
fetchInspectVars({})
|
||||||
|
invalidAllLastRun()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (params) => {
|
||||||
|
handleWorkflowFailed()
|
||||||
|
|
||||||
|
if (onError)
|
||||||
|
onError(params)
|
||||||
|
},
|
||||||
|
onNodeStarted: (params) => {
|
||||||
|
handleWorkflowNodeStarted(
|
||||||
|
params,
|
||||||
|
{
|
||||||
|
clientWidth,
|
||||||
|
clientHeight,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (onNodeStarted)
|
||||||
|
onNodeStarted(params)
|
||||||
|
},
|
||||||
|
onNodeFinished: (params) => {
|
||||||
|
handleWorkflowNodeFinished(params)
|
||||||
|
|
||||||
|
if (onNodeFinished)
|
||||||
|
onNodeFinished(params)
|
||||||
|
},
|
||||||
|
onIterationStart: (params) => {
|
||||||
|
handleWorkflowNodeIterationStarted(
|
||||||
|
params,
|
||||||
|
{
|
||||||
|
clientWidth,
|
||||||
|
clientHeight,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (onIterationStart)
|
||||||
|
onIterationStart(params)
|
||||||
|
},
|
||||||
|
onIterationNext: (params) => {
|
||||||
|
handleWorkflowNodeIterationNext(params)
|
||||||
|
|
||||||
|
if (onIterationNext)
|
||||||
|
onIterationNext(params)
|
||||||
|
},
|
||||||
|
onIterationFinish: (params) => {
|
||||||
|
handleWorkflowNodeIterationFinished(params)
|
||||||
|
|
||||||
|
if (onIterationFinish)
|
||||||
|
onIterationFinish(params)
|
||||||
|
},
|
||||||
|
onLoopStart: (params) => {
|
||||||
|
handleWorkflowNodeLoopStarted(
|
||||||
|
params,
|
||||||
|
{
|
||||||
|
clientWidth,
|
||||||
|
clientHeight,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (onLoopStart)
|
||||||
|
onLoopStart(params)
|
||||||
|
},
|
||||||
|
onLoopNext: (params) => {
|
||||||
|
handleWorkflowNodeLoopNext(params)
|
||||||
|
|
||||||
|
if (onLoopNext)
|
||||||
|
onLoopNext(params)
|
||||||
|
},
|
||||||
|
onLoopFinish: (params) => {
|
||||||
|
handleWorkflowNodeLoopFinished(params)
|
||||||
|
|
||||||
|
if (onLoopFinish)
|
||||||
|
onLoopFinish(params)
|
||||||
|
},
|
||||||
|
onNodeRetry: (params) => {
|
||||||
|
handleWorkflowNodeRetry(params)
|
||||||
|
|
||||||
|
if (onNodeRetry)
|
||||||
|
onNodeRetry(params)
|
||||||
|
},
|
||||||
|
onAgentLog: (params) => {
|
||||||
|
handleWorkflowAgentLog(params)
|
||||||
|
|
||||||
|
if (onAgentLog)
|
||||||
|
onAgentLog(params)
|
||||||
|
},
|
||||||
|
onTextChunk: (params) => {
|
||||||
|
handleWorkflowTextChunk(params)
|
||||||
|
},
|
||||||
|
onTextReplace: (params) => {
|
||||||
|
handleWorkflowTextReplace(params)
|
||||||
|
},
|
||||||
|
onTTSChunk: (messageId: string, audio: string) => {
|
||||||
|
if (!audio || audio === '')
|
||||||
|
return
|
||||||
|
player?.playAudioWithAudio(audio, true)
|
||||||
|
AudioPlayerManager.getInstance().resetMsgId(messageId)
|
||||||
|
},
|
||||||
|
onTTSEnd: (messageId: string, audio: string) => {
|
||||||
|
player?.playAudioWithAudio(audio, false)
|
||||||
|
},
|
||||||
|
onWorkflowPaused: (params) => {
|
||||||
|
handleWorkflowPaused()
|
||||||
|
if (onWorkflowPaused)
|
||||||
|
onWorkflowPaused(params)
|
||||||
|
const url = `/workflow/${params.workflow_run_id}/events`
|
||||||
|
sseGet(
|
||||||
|
url,
|
||||||
|
{},
|
||||||
|
finalCallbacks,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onHumanInputRequired: (params) => {
|
||||||
|
handleWorkflowNodeHumanInputRequired(params)
|
||||||
|
if (onHumanInputRequired)
|
||||||
|
onHumanInputRequired(params)
|
||||||
|
},
|
||||||
|
...restCallback,
|
||||||
|
}
|
||||||
|
|
||||||
ssePost(
|
ssePost(
|
||||||
url,
|
url,
|
||||||
{
|
{
|
||||||
body: requestBody,
|
body: requestBody,
|
||||||
},
|
},
|
||||||
{
|
finalCallbacks,
|
||||||
...baseSseOptions,
|
|
||||||
getAbortController: (controller: AbortController) => {
|
|
||||||
abortControllerRef.current = controller
|
|
||||||
},
|
|
||||||
onWorkflowFinished: (params) => {
|
|
||||||
handleWorkflowFinished(params)
|
|
||||||
|
|
||||||
if (onWorkflowFinished)
|
|
||||||
onWorkflowFinished(params)
|
|
||||||
if (isInWorkflowDebug) {
|
|
||||||
fetchInspectVars({})
|
|
||||||
invalidAllLastRun()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError: (params) => {
|
|
||||||
handleWorkflowFailed()
|
|
||||||
|
|
||||||
if (onError)
|
|
||||||
onError(params)
|
|
||||||
},
|
|
||||||
onNodeStarted: (params) => {
|
|
||||||
handleWorkflowNodeStarted(
|
|
||||||
params,
|
|
||||||
{
|
|
||||||
clientWidth,
|
|
||||||
clientHeight,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if (onNodeStarted)
|
|
||||||
onNodeStarted(params)
|
|
||||||
},
|
|
||||||
onNodeFinished: (params) => {
|
|
||||||
handleWorkflowNodeFinished(params)
|
|
||||||
|
|
||||||
if (onNodeFinished)
|
|
||||||
onNodeFinished(params)
|
|
||||||
},
|
|
||||||
onIterationStart: (params) => {
|
|
||||||
handleWorkflowNodeIterationStarted(
|
|
||||||
params,
|
|
||||||
{
|
|
||||||
clientWidth,
|
|
||||||
clientHeight,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if (onIterationStart)
|
|
||||||
onIterationStart(params)
|
|
||||||
},
|
|
||||||
onIterationNext: (params) => {
|
|
||||||
handleWorkflowNodeIterationNext(params)
|
|
||||||
|
|
||||||
if (onIterationNext)
|
|
||||||
onIterationNext(params)
|
|
||||||
},
|
|
||||||
onIterationFinish: (params) => {
|
|
||||||
handleWorkflowNodeIterationFinished(params)
|
|
||||||
|
|
||||||
if (onIterationFinish)
|
|
||||||
onIterationFinish(params)
|
|
||||||
},
|
|
||||||
onLoopStart: (params) => {
|
|
||||||
handleWorkflowNodeLoopStarted(
|
|
||||||
params,
|
|
||||||
{
|
|
||||||
clientWidth,
|
|
||||||
clientHeight,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if (onLoopStart)
|
|
||||||
onLoopStart(params)
|
|
||||||
},
|
|
||||||
onLoopNext: (params) => {
|
|
||||||
handleWorkflowNodeLoopNext(params)
|
|
||||||
|
|
||||||
if (onLoopNext)
|
|
||||||
onLoopNext(params)
|
|
||||||
},
|
|
||||||
onLoopFinish: (params) => {
|
|
||||||
handleWorkflowNodeLoopFinished(params)
|
|
||||||
|
|
||||||
if (onLoopFinish)
|
|
||||||
onLoopFinish(params)
|
|
||||||
},
|
|
||||||
onNodeRetry: (params) => {
|
|
||||||
handleWorkflowNodeRetry(params)
|
|
||||||
|
|
||||||
if (onNodeRetry)
|
|
||||||
onNodeRetry(params)
|
|
||||||
},
|
|
||||||
onAgentLog: (params) => {
|
|
||||||
handleWorkflowAgentLog(params)
|
|
||||||
|
|
||||||
if (onAgentLog)
|
|
||||||
onAgentLog(params)
|
|
||||||
},
|
|
||||||
onTextChunk: (params) => {
|
|
||||||
handleWorkflowTextChunk(params)
|
|
||||||
},
|
|
||||||
onTextReplace: (params) => {
|
|
||||||
handleWorkflowTextReplace(params)
|
|
||||||
},
|
|
||||||
onTTSChunk: (messageId: string, audio: string) => {
|
|
||||||
if (!audio || audio === '')
|
|
||||||
return
|
|
||||||
player?.playAudioWithAudio(audio, true)
|
|
||||||
AudioPlayerManager.getInstance().resetMsgId(messageId)
|
|
||||||
},
|
|
||||||
onTTSEnd: (messageId: string, audio: string) => {
|
|
||||||
player?.playAudioWithAudio(audio, false)
|
|
||||||
},
|
|
||||||
onWorkflowPaused: (params) => {
|
|
||||||
handleWorkflowPaused()
|
|
||||||
if (onWorkflowPaused)
|
|
||||||
onWorkflowPaused(params)
|
|
||||||
},
|
|
||||||
onHumanInputRequired: (params) => {
|
|
||||||
handleWorkflowNodeHumanInputRequired(params)
|
|
||||||
if (onHumanInputRequired)
|
|
||||||
onHumanInputRequired(params)
|
|
||||||
},
|
|
||||||
...restCallback,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}, [store, doSyncWorkflowDraft, workflowStore, pathname, handleWorkflowFailed, flowId, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace, handleWorkflowPaused, handleWorkflowNodeHumanInputRequired])
|
}, [store, doSyncWorkflowDraft, workflowStore, pathname, handleWorkflowFailed, flowId, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace, handleWorkflowPaused, handleWorkflowNodeHumanInputRequired])
|
||||||
|
|
||||||
|
|||||||
@ -507,6 +507,10 @@ export const useChat = (
|
|||||||
},
|
},
|
||||||
onHumanInputRequired: ({ data }) => {
|
onHumanInputRequired: ({ data }) => {
|
||||||
responseItem.humanInputFormData = data
|
responseItem.humanInputFormData = data
|
||||||
|
const currentTracingIndex = responseItem.workflowProcess!.tracing!.findIndex(item => item.node_id === data.node_id)
|
||||||
|
if (currentTracingIndex > -1) {
|
||||||
|
responseItem.workflowProcess!.tracing[currentTracingIndex].status = NodeRunningStatus.Paused
|
||||||
|
}
|
||||||
updateCurrentQAOnTree({
|
updateCurrentQAOnTree({
|
||||||
placeholderQuestionId,
|
placeholderQuestionId,
|
||||||
questionItem,
|
questionItem,
|
||||||
@ -514,14 +518,8 @@ export const useChat = (
|
|||||||
parentId: params.parent_message_id,
|
parentId: params.parent_message_id,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onWorkflowPaused: ({ data }) => {
|
onWorkflowPaused: ({ data: _data }) => {
|
||||||
responseItem.workflowProcess!.status = WorkflowRunningStatus.Paused
|
responseItem.workflowProcess!.status = WorkflowRunningStatus.Paused
|
||||||
data.paused_nodes.forEach((nodeId) => {
|
|
||||||
const currentTracingIndex = responseItem.workflowProcess!.tracing!.findIndex(item => item.node_id === nodeId)
|
|
||||||
if (currentTracingIndex > -1) {
|
|
||||||
responseItem.workflowProcess!.tracing[currentTracingIndex].status = NodeRunningStatus.Paused
|
|
||||||
}
|
|
||||||
})
|
|
||||||
updateCurrentQAOnTree({
|
updateCurrentQAOnTree({
|
||||||
placeholderQuestionId,
|
placeholderQuestionId,
|
||||||
questionItem,
|
questionItem,
|
||||||
|
|||||||
Reference in New Issue
Block a user