From f528f2eafcbe2d79426e9cccdf11faacb3a93c34 Mon Sep 17 00:00:00 2001 From: twwu Date: Fri, 26 Dec 2025 16:39:17 +0800 Subject: [PATCH] refactor: streamline chat operation handling and enhance workflow event management --- .github/workflows/build-push.yml | 1 + .../base/chat/chat/answer/operation.tsx | 24 +- .../workflow-app/hooks/use-workflow-run.ts | 262 +++++++++--------- .../workflow/panel/debug-and-preview/hooks.ts | 12 +- 4 files changed, 152 insertions(+), 147 deletions(-) diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index f7f464a601..da1ee93a37 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -8,6 +8,7 @@ on: - "build/**" - "release/e-*" - "hotfix/**" + - "feature/hitl-frontend" tags: - "*" diff --git a/web/app/components/base/chat/chat/answer/operation.tsx b/web/app/components/base/chat/chat/answer/operation.tsx index 4f51c6348e..ac0fe15b10 100644 --- a/web/app/components/base/chat/chat/answer/operation.tsx +++ b/web/app/components/base/chat/chat/answer/operation.tsx @@ -304,30 +304,28 @@ const Operation: FC = ({ )} - {!isOpeningStatement && ( + {!isOpeningStatement && !humanInputFormData && (
- {(config?.text_to_speech?.enabled) && !humanInputFormData && ( + {(config?.text_to_speech?.enabled) && ( )} - {!humanInputFormData && ( - { - copy(content) - Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') }) - }} - > - - - )} - {!noChatInput && !humanInputFormData && ( + { + copy(content) + Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') }) + }} + > + + + {!noChatInput && ( onRegenerate?.(item)}> )} - {(config?.supportAnnotation && config.annotation_reply?.enabled) && !humanInputFormData && ( + {(config?.supportAnnotation && config.annotation_reply?.enabled) && ( { 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( url, { body: requestBody, }, - { - ...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, - }, + finalCallbacks, ) }, [store, doSyncWorkflowDraft, workflowStore, pathname, handleWorkflowFailed, flowId, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace, handleWorkflowPaused, handleWorkflowNodeHumanInputRequired]) diff --git a/web/app/components/workflow/panel/debug-and-preview/hooks.ts b/web/app/components/workflow/panel/debug-and-preview/hooks.ts index 2dcd5fef8e..3c4518258f 100644 --- a/web/app/components/workflow/panel/debug-and-preview/hooks.ts +++ b/web/app/components/workflow/panel/debug-and-preview/hooks.ts @@ -507,6 +507,10 @@ export const useChat = ( }, onHumanInputRequired: ({ 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({ placeholderQuestionId, questionItem, @@ -514,14 +518,8 @@ export const useChat = ( parentId: params.parent_message_id, }) }, - onWorkflowPaused: ({ data }) => { + onWorkflowPaused: ({ data: _data }) => { 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({ placeholderQuestionId, questionItem,