feat(trigger): add plugin trigger test-run handling to workflow

This commit is contained in:
zhsama 2025-10-10 10:43:13 +08:00
parent b8ca480b07
commit 755fb96a33
6 changed files with 118 additions and 16 deletions

View File

@ -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,

View File

@ -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<void> => {
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()

View File

@ -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,
}
}

View File

@ -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)

View File

@ -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<void>
@ -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,

View File

@ -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,
}
}