From 5ec7bbf3d3a144dcb28a635ee3a2d10d7dd15f26 Mon Sep 17 00:00:00 2001 From: sd0ric4 <1286518974@qq.com> Date: Wed, 26 Mar 2025 00:12:28 +0800 Subject: [PATCH] feat: add optional query parameter to PostWorkflowDebugProps and remove realmode from ModuleDispatchProps --- .../global/core/workflow/runtime/type.d.ts | 1 - .../service/core/workflow/dispatch/index.ts | 3 +- .../dispatch/interactive/formInput.ts | 3 +- .../dispatch/interactive/userSelect.ts | 3 +- .../chat/components/InteractiveComponents.tsx | 414 ++++++++++++++++++ .../chat/components/WholeResponseModal.tsx | 5 +- .../app/src/global/core/workflow/api.d.ts | 1 + .../Flow/nodes/render/NodeCard.tsx | 85 +++- .../WorkflowComponents/context/index.tsx | 74 +++- 9 files changed, 572 insertions(+), 17 deletions(-) create mode 100644 projects/app/src/components/core/chat/components/InteractiveComponents.tsx diff --git a/packages/global/core/workflow/runtime/type.d.ts b/packages/global/core/workflow/runtime/type.d.ts index b2d6068cb..f5db3a89c 100644 --- a/packages/global/core/workflow/runtime/type.d.ts +++ b/packages/global/core/workflow/runtime/type.d.ts @@ -65,7 +65,6 @@ export type ModuleDispatchProps = ChatDispatchProps & { runtimeNodes: RuntimeNodeItemType[]; runtimeEdges: RuntimeEdgeItemType[]; params: T; - realmode?: 'test' | 'chat' | 'debug'; }; export type SystemVariablesType = { diff --git a/packages/service/core/workflow/dispatch/index.ts b/packages/service/core/workflow/dispatch/index.ts index ff3f9d4f4..24b279f5c 100644 --- a/packages/service/core/workflow/dispatch/index.ts +++ b/packages/service/core/workflow/dispatch/index.ts @@ -581,8 +581,7 @@ export async function dispatchWorkFlow(data: Props): Promise(undefined); + const { onChangeNode, onNextNodeDebug, workflowDebugData, setWorkflowDebugData } = + useContextSelector(WorkflowContext, (v) => ({ + onChangeNode: v.onChangeNode, + onNextNodeDebug: v.onNextNodeDebug, + workflowDebugData: v.workflowDebugData, + setWorkflowDebugData: v.setWorkflowDebugData + })); + + const handleSelect = useCallback( + (value: string) => { + if (!nodeId || !workflowDebugData) return; + + // 保存选中的值到本地状态 + setSelectedValue(value); + + // 更新查询以包含用户的选择 + const updatedQuery: UserChatItemValueItemType[] = [ + ...(workflowDebugData.query || []), + { + type: ChatItemValueTypeEnum.text, + text: { + content: value + } + } as UserChatItemValueItemType + ]; + + // 更新工作流调试数据 + setWorkflowDebugData({ + ...workflowDebugData, + query: updatedQuery + }); + }, + [nodeId, onChangeNode, workflowDebugData, setWorkflowDebugData] + ); + + // 处理下一步调试的逻辑 + const handleStartDebug = useCallback(() => { + if (!nodeId || !workflowDebugData) return; + + // 先将当前节点设置为入口节点 + onChangeNode({ + nodeId, + type: 'attr', + key: 'isEntry', + value: true + }); + + // 然后调用onNextNodeDebug函数 + onNextNodeDebug(); + }, [nodeId, workflowDebugData, onNextNodeDebug, onChangeNode]); + + return ( + + {interactive?.params?.description && ( + + + + )} + + {interactive.params.userSelectOptions?.map((option) => { + const selected = + option.value === selectedValue || option.value === interactive?.params?.userSelectedVal; + + return ( + + ); + })} + + + {/* 添加下一步按钮,在选择完成后显示 */} + {(selectedValue !== undefined || interactive?.params?.userSelectedVal !== undefined) && ( + + + + )} + + ); +}); + +export const RenderUserFormInteractive = React.memo(function RenderFormInput({ + interactive, + nodeId +}: { + interactive: UserInputInteractive; + nodeId?: string; +}) { + const { t } = useTranslation(); + const { register, setValue, handleSubmit: handleSubmitChat, control, reset } = useForm(); + const [isSubmitted, setIsSubmitted] = useState(false); + const { onChangeNode, onNextNodeDebug, workflowDebugData, setWorkflowDebugData } = + useContextSelector(WorkflowContext, (v) => ({ + onChangeNode: v.onChangeNode, + onNextNodeDebug: v.onNextNodeDebug, + workflowDebugData: v.workflowDebugData, + setWorkflowDebugData: v.setWorkflowDebugData + })); + + const onSubmit = useCallback( + (data: any) => { + if (!nodeId || !workflowDebugData) return; + + // 标记表单已提交 + setIsSubmitted(true); + + const jsonData = JSON.stringify(data); + + // 更新查询以包含用户的表单数据 + const updatedQuery: UserChatItemValueItemType[] = [ + ...(workflowDebugData.query || []), + { + type: ChatItemValueTypeEnum.text, + text: { + content: jsonData + } + } as UserChatItemValueItemType + ]; + + // 更新工作流调试数据 + setWorkflowDebugData({ + ...workflowDebugData, + query: updatedQuery + }); + }, + [nodeId, onChangeNode, workflowDebugData, setWorkflowDebugData] + ); + + // 处理下一步调试的逻辑 + const handleStartDebug = useCallback(() => { + if (!nodeId || !workflowDebugData) return; + + // 先将当前节点设置为入口节点 + onChangeNode({ + nodeId, + type: 'attr', + key: 'isEntry', + value: true + }); + + // 然后调用onNextNodeDebug函数 + onNextNodeDebug(); + }, [nodeId, workflowDebugData, onNextNodeDebug, onChangeNode]); + + useEffect(() => { + if (interactive.type === 'userInput') { + const defaultValues = interactive.params.inputForm?.reduce( + (acc: Record, item) => { + acc[item.label] = !!item.value ? item.value : item.defaultValue; + return acc; + }, + {} + ); + reset(defaultValues); + } + + // 如果已经有表单结果,标记为已提交 + if (interactive.params.submitted) { + setIsSubmitted(true); + } + }, [interactive, reset, nodeId]); + + return ( + + {interactive.params.description && ( + + + + )} + + + {interactive.params.inputForm?.map((input) => ( + + + + {input.label} + + {input.description && } + + {input.type === FlowNodeInputTypeEnum.input && ( + + )} + {input.type === FlowNodeInputTypeEnum.textarea && ( +