From 755fb96a3348e8350779fba0d36af1dc73d7b6b6 Mon Sep 17 00:00:00 2001 From: zhsama Date: Fri, 10 Oct 2025 10:43:13 +0800 Subject: [PATCH] feat(trigger): add plugin trigger test-run handling to workflow --- .../workflow-app/components/workflow-main.tsx | 3 + .../workflow-app/hooks/use-workflow-run.ts | 80 +++++++++++++++---- .../hooks/use-workflow-start-run.tsx | 42 ++++++++++ .../components/workflow/header/run-mode.tsx | 4 + .../components/workflow/hooks-store/store.ts | 3 + .../workflow/hooks/use-workflow-start-run.tsx | 2 + 6 files changed, 118 insertions(+), 16 deletions(-) diff --git a/web/app/components/workflow-app/components/workflow-main.tsx b/web/app/components/workflow-app/components/workflow-main.tsx index 14a2156d3c..b9399ba986 100644 --- a/web/app/components/workflow-app/components/workflow-main.tsx +++ b/web/app/components/workflow-app/components/workflow-main.tsx @@ -68,6 +68,7 @@ const WorkflowMain = ({ handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, } = useWorkflowStartRun() const availableNodesMetaData = useAvailableNodesMetaData() const { getWorkflowRunAndTraceUrl } = useGetRunAndTraceUrl() @@ -112,6 +113,7 @@ const WorkflowMain = ({ handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, availableNodesMetaData, getWorkflowRunAndTraceUrl, exportCheck, @@ -147,6 +149,7 @@ const WorkflowMain = ({ handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, availableNodesMetaData, getWorkflowRunAndTraceUrl, exportCheck, diff --git a/web/app/components/workflow-app/hooks/use-workflow-run.ts b/web/app/components/workflow-app/hooks/use-workflow-run.ts index d3fde6de1c..1f3798cb68 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-run.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-run.ts @@ -26,12 +26,12 @@ import { useConfigsMap } from './use-configs-map' import { API_PREFIX } from '@/config' import { ContentType, getAccessToken, getBaseOptions } from '@/service/fetch' -type HandleRunMode = 'default' | 'schedule' | 'webhook' - +type HandleRunMode = 'default' | 'schedule' | 'webhook' | 'plugin' type HandleRunOptions = { mode?: HandleRunMode scheduleNodeId?: string webhookNodeId?: string + pluginNodeId?: string } export const useWorkflowRun = () => { @@ -184,6 +184,13 @@ export const useWorkflowRun = () => { } url = `/apps/${appDetail.id}/workflows/draft/trigger/webhook/run` } + else if (runMode === 'plugin') { + if (!appDetail?.id) { + console.error('handleRun: missing app id for trigger plugin run') + return + } + url = `/apps/${appDetail.id}/workflows/draft/trigger/run` + } else if (appDetail?.mode === 'advanced-chat') { url = `/apps/${appDetail.id}/advanced-chat/workflows/draft/run` } @@ -191,11 +198,19 @@ export const useWorkflowRun = () => { url = `/apps/${appDetail.id}/workflows/draft/run` } - const requestBody = runMode === 'schedule' - ? { node_id: options?.scheduleNodeId } - : runMode === 'webhook' - ? { node_id: options?.webhookNodeId } - : resolvedParams + let requestBody = {} + + if (runMode === 'schedule') + requestBody = { node_id: options?.scheduleNodeId } + + else if (runMode === 'webhook') + requestBody = { node_id: options?.webhookNodeId } + + else if (runMode === 'plugin') + requestBody = { node_id: options?.pluginNodeId } + + else + requestBody = resolvedParams if (!url) return @@ -210,6 +225,11 @@ export const useWorkflowRun = () => { return } + if (runMode === 'plugin' && !options?.pluginNodeId) { + console.error('handleRun: plugin trigger run requires node id') + return + } + abortControllerRef.current?.abort() abortControllerRef.current = null @@ -233,6 +253,18 @@ export const useWorkflowRun = () => { resultText: '', }) } + else if (runMode === 'plugin') { + setIsListening(true) + setShowVariableInspectPanel(true) + setWorkflowRunningData({ + result: { + status: WorkflowRunningStatus.Running, + inputs_truncated: false, + process_data_truncated: false, + outputs_truncated: false, + }, + }) + } else { setIsListening(false) setWorkflowRunningData({ @@ -263,6 +295,8 @@ export const useWorkflowRun = () => { const clearAbortController = () => { abortControllerRef.current = null + delete (window as any).__webhookDebugAbortController + delete (window as any).__pluginDebugAbortController } const clearListeningState = () => { @@ -416,7 +450,7 @@ export const useWorkflowRun = () => { }, { once: true }) }) - const runWebhookDebug = async () => { + const runTriggerDebug = async (debugType: 'webhook' | 'plugin') => { const urlWithPrefix = (url.startsWith('http://') || url.startsWith('https://')) ? url : `${API_PREFIX}${url.startsWith('/') ? url : `/${url}`}` @@ -424,8 +458,13 @@ export const useWorkflowRun = () => { const controller = new AbortController() abortControllerRef.current = controller - // Store controller in global variable as fallback - ;(window as any).__webhookDebugAbortController = controller + const controllerKey = debugType === 'webhook' + ? '__webhookDebugAbortController' + : '__pluginDebugAbortController' + + ;(window as any)[controllerKey] = controller + + const debugLabel = debugType === 'webhook' ? 'Webhook' : 'Plugin' const poll = async (): Promise => { try { @@ -447,7 +486,7 @@ export const useWorkflowRun = () => { return if (!response.ok) { - const message = `Webhook debug request failed (${response.status})` + const message = `${debugLabel} debug request failed (${response.status})` Toast.notify({ type: 'error', message }) clearAbortController() return @@ -468,7 +507,7 @@ export const useWorkflowRun = () => { return } - const errorMessage = data.message || 'Webhook debug failed' + const errorMessage = data.message || `${debugLabel} debug failed` Toast.notify({ type: 'error', message: errorMessage }) clearAbortController() setWorkflowRunningData({ @@ -520,13 +559,13 @@ export const useWorkflowRun = () => { catch (error) { if (controller.signal.aborted) return - console.error('handleRun: webhook debug polling error', error) - Toast.notify({ type: 'error', message: 'Webhook debug request failed' }) + console.error(`handleRun: ${debugLabel.toLowerCase()} debug polling error`, error) + Toast.notify({ type: 'error', message: `${debugLabel} debug request failed` }) clearAbortController() setWorkflowRunningData({ result: { status: WorkflowRunningStatus.Failed, - error: 'Webhook debug request failed', + error: `${debugLabel} debug request failed`, inputs_truncated: false, process_data_truncated: false, outputs_truncated: false, @@ -541,7 +580,12 @@ export const useWorkflowRun = () => { } if (runMode === 'webhook') { - await runWebhookDebug() + await runTriggerDebug('webhook') + return + } + + if (runMode === 'plugin') { + await runTriggerDebug('plugin') return } @@ -572,6 +616,10 @@ export const useWorkflowRun = () => { if (webhookController) webhookController.abort() + const pluginController = (window as any).__pluginDebugAbortController + if (pluginController) + pluginController.abort() + // Also try the ref if (abortControllerRef.current) abortControllerRef.current.abort() diff --git a/web/app/components/workflow-app/hooks/use-workflow-start-run.tsx b/web/app/components/workflow-app/hooks/use-workflow-start-run.tsx index 05a67194ff..87812b8de3 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-start-run.tsx +++ b/web/app/components/workflow-app/hooks/use-workflow-start-run.tsx @@ -147,6 +147,47 @@ export const useWorkflowStartRun = () => { ) }, [store, workflowStore, handleRun, doSyncWorkflowDraft]) + const handleWorkflowTriggerPluginRunInWorkflow = useCallback(async (nodeId?: string) => { + if (!nodeId) + return + const { + workflowRunningData, + showDebugAndPreviewPanel, + setShowDebugAndPreviewPanel, + setShowInputsPanel, + setShowEnvPanel, + } = workflowStore.getState() + + if (workflowRunningData?.result.status === WorkflowRunningStatus.Running) + return + + const { getNodes } = store.getState() + const nodes = getNodes() + const pluginNode = nodes.find(node => node.id === nodeId && node.data.type === BlockEnum.TriggerPlugin) + + if (!pluginNode) { + console.warn('handleWorkflowTriggerPluginRunInWorkflow: plugin node not found', nodeId) + return + } + + setShowEnvPanel(false) + + if (!showDebugAndPreviewPanel) + setShowDebugAndPreviewPanel(true) + + setShowInputsPanel(false) + + await doSyncWorkflowDraft() + handleRun( + { node_id: nodeId }, + undefined, + { + mode: 'plugin', + pluginNodeId: nodeId, + }, + ) + }, [store, workflowStore, handleRun, doSyncWorkflowDraft]) + const handleWorkflowStartRunInChatflow = useCallback(async () => { const { showDebugAndPreviewPanel, @@ -180,5 +221,6 @@ export const useWorkflowStartRun = () => { handleWorkflowStartRunInChatflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, } } diff --git a/web/app/components/workflow/header/run-mode.tsx b/web/app/components/workflow/header/run-mode.tsx index 43058f3e1f..c34549e355 100644 --- a/web/app/components/workflow/header/run-mode.tsx +++ b/web/app/components/workflow/header/run-mode.tsx @@ -24,6 +24,7 @@ const RunMode = ({ handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, } = useWorkflowStartRun() const { handleStopRun } = useWorkflowRun() const { validateBeforeRun } = useWorkflowRunValidation() @@ -66,6 +67,9 @@ const RunMode = ({ if (option.nodeId) handleWorkflowTriggerWebhookRunInWorkflow({ nodeId: option.nodeId }) } + else if (option.type === 'plugin') { + handleWorkflowTriggerPluginRunInWorkflow(option.nodeId) + } else { // Placeholder for trigger-specific execution logic for schedule, webhook, plugin types console.log('TODO: Handle trigger execution for type:', option.type, 'nodeId:', option.nodeId) diff --git a/web/app/components/workflow/hooks-store/store.ts b/web/app/components/workflow/hooks-store/store.ts index f863223fd6..df9a44b2be 100644 --- a/web/app/components/workflow/hooks-store/store.ts +++ b/web/app/components/workflow/hooks-store/store.ts @@ -47,6 +47,7 @@ export type CommonHooksFnMap = { handleWorkflowStartRunInChatflow: () => void handleWorkflowTriggerScheduleRunInWorkflow: (nodeId?: string) => void handleWorkflowTriggerWebhookRunInWorkflow: (params: { nodeId: string }) => void + handleWorkflowTriggerPluginRunInWorkflow: (nodeId?: string) => void availableNodesMetaData?: AvailableNodesMetaData getWorkflowRunAndTraceUrl: (runId?: string) => { runUrl: string; traceUrl: string } exportCheck?: () => Promise @@ -91,6 +92,7 @@ export const createHooksStore = ({ handleWorkflowStartRunInChatflow = noop, handleWorkflowTriggerScheduleRunInWorkflow = noop, handleWorkflowTriggerWebhookRunInWorkflow = noop, + handleWorkflowTriggerPluginRunInWorkflow = noop, availableNodesMetaData = { nodes: [], }, @@ -131,6 +133,7 @@ export const createHooksStore = ({ handleWorkflowStartRunInChatflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, availableNodesMetaData, getWorkflowRunAndTraceUrl, exportCheck, diff --git a/web/app/components/workflow/hooks/use-workflow-start-run.tsx b/web/app/components/workflow/hooks/use-workflow-start-run.tsx index 0713786fab..8cb1a45e2a 100644 --- a/web/app/components/workflow/hooks/use-workflow-start-run.tsx +++ b/web/app/components/workflow/hooks/use-workflow-start-run.tsx @@ -6,6 +6,7 @@ export const useWorkflowStartRun = () => { const handleWorkflowStartRunInChatflow = useHooksStore(s => s.handleWorkflowStartRunInChatflow) const handleWorkflowTriggerScheduleRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerScheduleRunInWorkflow) const handleWorkflowTriggerWebhookRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerWebhookRunInWorkflow) + const handleWorkflowTriggerPluginRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerPluginRunInWorkflow) return { handleStartWorkflowRun, @@ -13,5 +14,6 @@ export const useWorkflowStartRun = () => { handleWorkflowStartRunInChatflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, + handleWorkflowTriggerPluginRunInWorkflow, } }