From d60cb423a4722829fe5c9bbe2cbfb0152c69f26b Mon Sep 17 00:00:00 2001 From: zhaoying Date: Thu, 2 Apr 2026 19:32:47 +0800 Subject: [PATCH] feat(web): workflow add opening_statement --- .../ApplicationConfig/TestChat/index.tsx | 39 +++++++++------ .../FeaturesConfig/FeaturesConfigModal.tsx | 50 +++++++++---------- .../views/Workflow/components/Chat/Chat.tsx | 28 +++++++++-- 3 files changed, 73 insertions(+), 44 deletions(-) diff --git a/web/src/views/ApplicationConfig/TestChat/index.tsx b/web/src/views/ApplicationConfig/TestChat/index.tsx index b3fca33f..70296e4e 100644 --- a/web/src/views/ApplicationConfig/TestChat/index.tsx +++ b/web/src/views/ApplicationConfig/TestChat/index.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-03-13 17:27:52 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-31 16:04:15 + * @Last Modified time: 2026-04-02 17:58:07 */ import { type FC, useState, useRef, useEffect } from 'react' import { useTranslation } from 'react-i18next' @@ -63,6 +63,12 @@ interface NodeData { state: Record; status?: 'completed' | 'failed'; audio_url?: string; + citations?: { + document_id: string; + file_name: string; + knowledge_id: string; + score: string; + }[] } const TestChat: FC = ({ @@ -111,8 +117,7 @@ const TestChat: FC = ({ } }]) } - - + let initVariables: Variable[] = [] switch (application.type) { @@ -162,7 +167,7 @@ const TestChat: FC = ({ }]) } - const updateAssistantMessage = (content: string, audio_url?: string, audio_status?: string, citations?: any[]) => { + const updateAssistantMessage = (content: string, audio_url?: string, audio_status?: string, citations?: NodeData['citations']) => { setChatList(prev => { const newList = [...prev] const lastMsg = newList[newList.length - 1] @@ -281,12 +286,7 @@ const TestChat: FC = ({ data.map(item => { const { conversation_id, content, message_length, audio_url, citations } = item.data as { conversation_id: string, content: string, message_length: number; audio_url?: string; - citations?: { - document_id: string; - file_name: string; - knowledge_id: string; - score: string; - }[] + citations?: NodeData['citations'] }; switch (item.event) { case 'start': @@ -344,15 +344,15 @@ const TestChat: FC = ({ }) } - const handleWorkflowSend = () => { - if (loading || !application || !message || !message?.trim()) return + const handleWorkflowSend = (msg?: string) => { + if (loading || !application || !((message && message?.trim() !== '') || (msg && msg?.trim() !== ''))) return const files = (toolbarRef.current?.getFiles() || []).filter(item => !['uploading', 'error'].includes(item.status)) const variables = toolbarRef.current?.getVariables() || [] const { isCanSend, params } = buildVariableParams(variables) if (!isCanSend) return setLoading(true) - addUserMessage(message, files) + addUserMessage((msg || message) as string, files) addAssistantMessage() toolbarRef.current?.setFiles([]) setFileList([]) @@ -361,7 +361,7 @@ const TestChat: FC = ({ draftRun( application.id, - formatParams(message, conversationId, files, params), + formatParams((msg || message) as string, conversationId, files, params), handleWorkflowStreamMessage ) .catch((error) => { @@ -383,7 +383,7 @@ const TestChat: FC = ({ const handleWorkflowStreamMessage = (data: SSEMessage[]) => { data.forEach(item => { - const { content, conversation_id } = item.data as NodeData; + const { content, conversation_id, citations } = item.data as NodeData; switch (item.event) { // Append streaming text chunks to assistant message case 'message': @@ -412,6 +412,9 @@ const TestChat: FC = ({ // Mark workflow as complete case 'workflow_end': updateWorkflowEndMessage(item.data as NodeData) + if (citations && citations.length > 0) { + updateWorkflowEndMessage(item.data as NodeData, citations) + } setStreamLoading(false) setLoading(false) break @@ -536,7 +539,7 @@ const TestChat: FC = ({ }) } - const updateWorkflowEndMessage = (data: NodeData) => { + const updateWorkflowEndMessage = (data: NodeData, citations?: NodeData['citations']) => { const { error, status } = data; setChatList(prev => { const newList = [...prev] @@ -547,6 +550,10 @@ const TestChat: FC = ({ status, error, content: newList[lastIndex].content === '' ? null : newList[lastIndex].content, + meta_data: { + ...newList[lastIndex].meta_data || {}, + citations + } } } return newList diff --git a/web/src/views/ApplicationConfig/components/FeaturesConfig/FeaturesConfigModal.tsx b/web/src/views/ApplicationConfig/components/FeaturesConfig/FeaturesConfigModal.tsx index 15a8b4e0..3e1e726a 100644 --- a/web/src/views/ApplicationConfig/components/FeaturesConfig/FeaturesConfigModal.tsx +++ b/web/src/views/ApplicationConfig/components/FeaturesConfig/FeaturesConfigModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:27:56 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-27 17:32:10 + * @Last Modified time: 2026-04-02 17:49:51 */ /** * Copy Application Modal @@ -116,24 +116,24 @@ const FeaturesConfigModal = forwardRef +
+ + {values?.opening_statement?.enabled && (() => { + const statement = values.opening_statement?.statement + return statement && statement.trim() !== '' ? <> +
+ {statement} +
+ + : + })()} +
{source !== 'workflow' && <> -
- - {values?.opening_statement?.enabled && (() => { - const statement = values.opening_statement?.statement - return statement && statement.trim() !== '' ? <> -
- {statement} -
- - : - })()} -
-
- -
} +
+ +
{ setOpen(true) + + if (features?.opening_statement?.statement && features?.opening_statement?.statement.trim() !== '') { + setChatList(prev => [...prev, { + role: 'assistant', + created_at: Date.now(), + content: features?.opening_statement?.statement, + meta_data: { + suggested_questions: features?.opening_statement?.suggested_questions || [] + } + }]) + } } useEffect(() => { @@ -164,7 +175,7 @@ const Chat = forwardRef { data.forEach(item => { - const { content, conversation_id, node_id, cycle_id, cycle_idx, input, output, error, elapsed_time, status } = item.data as { + const { content, conversation_id, node_id, cycle_id, cycle_idx, input, output, error, elapsed_time, status, citations } = item.data as { content: string; conversation_id: string | null; cycle_id: string; @@ -177,7 +188,13 @@ const Chat = forwardRef; - status?: 'completed' | 'failed' + status?: 'completed' | 'failed', + citations?: { + document_id: string; + file_name: string; + knowledge_id: string; + score: string; + }[] }; const node = graphRef.current?.getNodes().find(n => n.id === node_id); @@ -312,6 +329,10 @@ const Chat = forwardRef { return }} + onSend={handleSend} />