diff --git a/apps/sim/app/api/workflows/[id]/execute/route.ts b/apps/sim/app/api/workflows/[id]/execute/route.ts index cf8431f9dc..b393ae492a 100644 --- a/apps/sim/app/api/workflows/[id]/execute/route.ts +++ b/apps/sim/app/api/workflows/[id]/execute/route.ts @@ -987,7 +987,8 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id: const onChildWorkflowInstanceReady = ( blockId: string, childWorkflowInstanceId: string, - iterationContext?: IterationContext + iterationContext?: IterationContext, + executionOrder?: number ) => { sendEvent({ type: 'block:childWorkflowStarted', @@ -1001,6 +1002,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id: iterationCurrent: iterationContext.iterationCurrent, iterationContainerId: iterationContext.iterationContainerId, }), + ...(executionOrder !== undefined && { executionOrder }), }, }) } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx index 9d9b206b79..204ca166c8 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx @@ -160,12 +160,16 @@ const IterationNodeRow = memo(function IterationNodeRow({ onSelectEntry, isExpanded, onToggle, + expandedNodes, + onToggleNode, }: { node: EntryNode selectedEntryId: string | null onSelectEntry: (entry: ConsoleEntry) => void isExpanded: boolean onToggle: () => void + expandedNodes: Set + onToggleNode: (nodeId: string) => void }) { const { entry, children, iterationInfo } = node const hasError = Boolean(entry.error) || children.some((c) => c.entry.error) @@ -226,11 +230,13 @@ const IterationNodeRow = memo(function IterationNodeRow({ {isExpanded && hasChildren && (
{children.map((child) => ( - ))}
@@ -346,6 +352,8 @@ const SubflowNodeRow = memo(function SubflowNodeRow({ onSelectEntry={onSelectEntry} isExpanded={expandedNodes.has(iterNode.entry.id)} onToggle={() => onToggleNode(iterNode.entry.id)} + expandedNodes={expandedNodes} + onToggleNode={onToggleNode} /> ))} @@ -520,6 +528,8 @@ const EntryNodeRow = memo(function EntryNodeRow({ onSelectEntry={onSelectEntry} isExpanded={expandedNodes.has(node.entry.id)} onToggle={() => onToggleNode(node.entry.id)} + expandedNodes={expandedNodes} + onToggleNode={onToggleNode} /> ) } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts index f1bcca15b7..1af79967c8 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts @@ -554,6 +554,7 @@ export function useWorkflowExecution() { childWorkflowInstanceId: string iterationCurrent?: number iterationContainerId?: string + executionOrder?: number }) => { if (isStaleExecution()) return updateConsole( @@ -564,6 +565,7 @@ export function useWorkflowExecution() { ...(data.iterationContainerId !== undefined && { iterationContainerId: data.iterationContainerId, }), + ...(data.executionOrder !== undefined && { executionOrder: data.executionOrder }), }, executionIdRef.current ) diff --git a/apps/sim/executor/execution/block-executor.ts b/apps/sim/executor/execution/block-executor.ts index 6d7f746d4e..9325aa2861 100644 --- a/apps/sim/executor/execution/block-executor.ts +++ b/apps/sim/executor/execution/block-executor.ts @@ -80,7 +80,10 @@ export class BlockExecutor { const startTime = performance.now() let resolvedInputs: Record = {} - const nodeMetadata = this.buildNodeMetadata(node) + const nodeMetadata = { + ...this.buildNodeMetadata(node), + executionOrder: blockLog?.executionOrder, + } let cleanupSelfReference: (() => void) | undefined if (block.metadata?.id === BlockType.HUMAN_IN_THE_LOOP) { diff --git a/apps/sim/executor/execution/types.ts b/apps/sim/executor/execution/types.ts index d3ac877b89..bea082fe8a 100644 --- a/apps/sim/executor/execution/types.ts +++ b/apps/sim/executor/execution/types.ts @@ -89,7 +89,8 @@ export interface ExecutionCallbacks { onChildWorkflowInstanceReady?: ( blockId: string, childWorkflowInstanceId: string, - iterationContext?: IterationContext + iterationContext?: IterationContext, + executionOrder?: number ) => void } @@ -155,7 +156,8 @@ export interface ContextExtensions { onChildWorkflowInstanceReady?: ( blockId: string, childWorkflowInstanceId: string, - iterationContext?: IterationContext + iterationContext?: IterationContext, + executionOrder?: number ) => void /** diff --git a/apps/sim/executor/handlers/workflow/workflow-handler.ts b/apps/sim/executor/handlers/workflow/workflow-handler.ts index 596e879683..b0123d7844 100644 --- a/apps/sim/executor/handlers/workflow/workflow-handler.ts +++ b/apps/sim/executor/handlers/workflow/workflow-handler.ts @@ -62,6 +62,7 @@ export class WorkflowBlockHandler implements BlockHandler { branchTotal?: number originalBlockId?: string isLoopNode?: boolean + executionOrder?: number } ): Promise { return this._executeCore(ctx, block, inputs, nodeMetadata) @@ -79,6 +80,7 @@ export class WorkflowBlockHandler implements BlockHandler { branchTotal?: number originalBlockId?: string isLoopNode?: boolean + executionOrder?: number } ): Promise { logger.info(`Executing workflow block: ${block.id}`) @@ -169,7 +171,12 @@ export class WorkflowBlockHandler implements BlockHandler { const iterationContext = nodeMetadata ? this.getIterationContext(ctx, nodeMetadata) : undefined - ctx.onChildWorkflowInstanceReady?.(effectiveBlockId, instanceId, iterationContext) + ctx.onChildWorkflowInstanceReady?.( + effectiveBlockId, + instanceId, + iterationContext, + nodeMetadata?.executionOrder + ) } const subExecutor = new Executor({ diff --git a/apps/sim/executor/types.ts b/apps/sim/executor/types.ts index b30dba2e1b..bf672dfd94 100644 --- a/apps/sim/executor/types.ts +++ b/apps/sim/executor/types.ts @@ -264,7 +264,8 @@ export interface ExecutionContext { onChildWorkflowInstanceReady?: ( blockId: string, childWorkflowInstanceId: string, - iterationContext?: IterationContext + iterationContext?: IterationContext, + executionOrder?: number ) => void /** @@ -377,6 +378,7 @@ export interface BlockHandler { branchTotal?: number originalBlockId?: string isLoopNode?: boolean + executionOrder?: number } ) => Promise } diff --git a/apps/sim/lib/workflows/executor/execution-events.ts b/apps/sim/lib/workflows/executor/execution-events.ts index 09044acdc5..a9324d1087 100644 --- a/apps/sim/lib/workflows/executor/execution-events.ts +++ b/apps/sim/lib/workflows/executor/execution-events.ts @@ -155,6 +155,7 @@ export interface BlockChildWorkflowStartedEvent extends BaseExecutionEvent { childWorkflowInstanceId: string iterationCurrent?: number iterationContainerId?: string + executionOrder?: number } } @@ -396,7 +397,8 @@ export function createSSECallbacks(options: SSECallbackOptions) { const onChildWorkflowInstanceReady = ( blockId: string, childWorkflowInstanceId: string, - iterationContext?: IterationContext + iterationContext?: IterationContext, + executionOrder?: number ) => { sendEvent({ type: 'block:childWorkflowStarted', @@ -410,6 +412,7 @@ export function createSSECallbacks(options: SSECallbackOptions) { iterationCurrent: iterationContext.iterationCurrent, iterationContainerId: iterationContext.iterationContainerId, }), + ...(executionOrder !== undefined && { executionOrder }), }, }) } diff --git a/apps/sim/stores/terminal/console/store.ts b/apps/sim/stores/terminal/console/store.ts index e3b7f3ea10..3468e4d212 100644 --- a/apps/sim/stores/terminal/console/store.ts +++ b/apps/sim/stores/terminal/console/store.ts @@ -91,6 +91,13 @@ const matchesEntryForUpdate = ( return false } + if ( + update.childWorkflowBlockId !== undefined && + entry.childWorkflowBlockId !== update.childWorkflowBlockId + ) { + return false + } + return true }