+
{flatTagList.length === 0 ? (
No matching tags found
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/hooks/use-terminal-filters.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/hooks/use-terminal-filters.ts
index 1807828f4..c712864cf 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/hooks/use-terminal-filters.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/hooks/use-terminal-filters.ts
@@ -105,11 +105,9 @@ export function useTerminalFilters() {
})
}
- // Apply sorting by timestamp
+ // Sort by executionOrder (monotonically increasing integer from server)
result = [...result].sort((a, b) => {
- const timeA = new Date(a.timestamp).getTime()
- const timeB = new Date(b.timestamp).getTime()
- const comparison = timeA - timeB
+ const comparison = a.executionOrder - b.executionOrder
return sortConfig.direction === 'asc' ? comparison : -comparison
})
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts
index 18b8cfef6..d54ccbfdf 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/utils.ts
@@ -184,13 +184,9 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
group.blocks.push(entry)
}
- // Sort blocks within each iteration by start time ascending (oldest first, top-down)
+ // Sort blocks within each iteration by executionOrder ascending (oldest first, top-down)
for (const group of iterationGroupsMap.values()) {
- group.blocks.sort((a, b) => {
- const aStart = new Date(a.startedAt || a.timestamp).getTime()
- const bStart = new Date(b.startedAt || b.timestamp).getTime()
- return aStart - bStart
- })
+ group.blocks.sort((a, b) => a.executionOrder - b.executionOrder)
}
// Group iterations by iterationType to create subflow parents
@@ -225,6 +221,8 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
const totalDuration = allBlocks.reduce((sum, b) => sum + (b.durationMs || 0), 0)
// Create synthetic subflow parent entry
+ // Use the minimum executionOrder from all child blocks for proper ordering
+ const subflowExecutionOrder = Math.min(...allBlocks.map((b) => b.executionOrder))
const syntheticSubflow: ConsoleEntry = {
id: `subflow-${iterationType}-${firstIteration.blocks[0]?.executionId || 'unknown'}`,
timestamp: new Date(subflowStartMs).toISOString(),
@@ -234,6 +232,7 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
blockType: iterationType,
executionId: firstIteration.blocks[0]?.executionId,
startedAt: new Date(subflowStartMs).toISOString(),
+ executionOrder: subflowExecutionOrder,
endedAt: new Date(subflowEndMs).toISOString(),
durationMs: totalDuration,
success: !allBlocks.some((b) => b.error),
@@ -251,6 +250,8 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
)
const iterDuration = iterBlocks.reduce((sum, b) => sum + (b.durationMs || 0), 0)
+ // Use the minimum executionOrder from blocks in this iteration
+ const iterExecutionOrder = Math.min(...iterBlocks.map((b) => b.executionOrder))
const syntheticIteration: ConsoleEntry = {
id: `iteration-${iterationType}-${iterGroup.iterationCurrent}-${iterBlocks[0]?.executionId || 'unknown'}`,
timestamp: new Date(iterStartMs).toISOString(),
@@ -260,6 +261,7 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
blockType: iterationType,
executionId: iterBlocks[0]?.executionId,
startedAt: new Date(iterStartMs).toISOString(),
+ executionOrder: iterExecutionOrder,
endedAt: new Date(iterEndMs).toISOString(),
durationMs: iterDuration,
success: !iterBlocks.some((b) => b.error),
@@ -300,14 +302,9 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
nodeType: 'block' as const,
}))
- // Combine all nodes and sort by start time ascending (oldest first, top-down)
+ // Combine all nodes and sort by executionOrder ascending (oldest first, top-down)
const allNodes = [...subflowNodes, ...regularNodes]
- allNodes.sort((a, b) => {
- const aStart = new Date(a.entry.startedAt || a.entry.timestamp).getTime()
- const bStart = new Date(b.entry.startedAt || b.entry.timestamp).getTime()
- return aStart - bStart
- })
-
+ allNodes.sort((a, b) => a.entry.executionOrder - b.entry.executionOrder)
return allNodes
}
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 6dcad6c17..2b021b3c5 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
@@ -926,6 +926,7 @@ export function useWorkflowExecution() {
})
// Add entry to terminal immediately with isRunning=true
+ // Use server-provided executionOrder to ensure correct sort order
const startedAt = new Date().toISOString()
addConsole({
input: {},
@@ -933,6 +934,7 @@ export function useWorkflowExecution() {
success: undefined,
durationMs: undefined,
startedAt,
+ executionOrder: data.executionOrder,
endedAt: undefined,
workflowId: activeWorkflowId,
blockId: data.blockId,
@@ -948,8 +950,6 @@ export function useWorkflowExecution() {
},
onBlockCompleted: (data) => {
- logger.info('onBlockCompleted received:', { data })
-
activeBlocksSet.delete(data.blockId)
setActiveBlocks(new Set(activeBlocksSet))
setBlockRunStatus(data.blockId, 'success')
@@ -976,6 +976,7 @@ export function useWorkflowExecution() {
success: true,
durationMs: data.durationMs,
startedAt,
+ executionOrder: data.executionOrder,
endedAt,
})
@@ -987,6 +988,7 @@ export function useWorkflowExecution() {
replaceOutput: data.output,
success: true,
durationMs: data.durationMs,
+ startedAt,
endedAt,
isRunning: false,
// Pass through iteration context for subflow grouping
@@ -1027,6 +1029,7 @@ export function useWorkflowExecution() {
error: data.error,
durationMs: data.durationMs,
startedAt,
+ executionOrder: data.executionOrder,
endedAt,
})
@@ -1039,6 +1042,7 @@ export function useWorkflowExecution() {
success: false,
error: data.error,
durationMs: data.durationMs,
+ startedAt,
endedAt,
isRunning: false,
// Pass through iteration context for subflow grouping
@@ -1163,6 +1167,7 @@ export function useWorkflowExecution() {
if (existingLogs.length === 0) {
// No blocks executed yet - this is a pre-execution error
+ // Use 0 for executionOrder so validation errors appear first
addConsole({
input: {},
output: {},
@@ -1170,6 +1175,7 @@ export function useWorkflowExecution() {
error: data.error,
durationMs: data.duration || 0,
startedAt: new Date(Date.now() - (data.duration || 0)).toISOString(),
+ executionOrder: 0,
endedAt: new Date().toISOString(),
workflowId: activeWorkflowId,
blockId: 'validation',
@@ -1237,6 +1243,7 @@ export function useWorkflowExecution() {
blockType = error.blockType || blockType
}
+ // Use MAX_SAFE_INTEGER so execution errors appear at the end of the log
useTerminalConsoleStore.getState().addConsole({
input: {},
output: {},
@@ -1244,6 +1251,7 @@ export function useWorkflowExecution() {
error: normalizedMessage,
durationMs: 0,
startedAt: new Date().toISOString(),
+ executionOrder: Number.MAX_SAFE_INTEGER,
endedAt: new Date().toISOString(),
workflowId: activeWorkflowId || '',
blockId,
@@ -1615,6 +1623,7 @@ export function useWorkflowExecution() {
success: true,
durationMs: data.durationMs,
startedAt,
+ executionOrder: data.executionOrder,
endedAt,
})
@@ -1624,6 +1633,7 @@ export function useWorkflowExecution() {
success: true,
durationMs: data.durationMs,
startedAt,
+ executionOrder: data.executionOrder,
endedAt,
workflowId,
blockId: data.blockId,
@@ -1653,6 +1663,7 @@ export function useWorkflowExecution() {
output: {},
success: false,
error: data.error,
+ executionOrder: data.executionOrder,
durationMs: data.durationMs,
startedAt,
endedAt,
@@ -1665,6 +1676,7 @@ export function useWorkflowExecution() {
error: data.error,
durationMs: data.durationMs,
startedAt,
+ executionOrder: data.executionOrder,
endedAt,
workflowId,
blockId: data.blockId,
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts
index c69670f8d..0d0597f9a 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts
@@ -111,6 +111,7 @@ export async function executeWorkflowWithFullLogging(
success: true,
durationMs: event.data.durationMs,
startedAt: new Date(Date.now() - event.data.durationMs).toISOString(),
+ executionOrder: event.data.executionOrder,
endedAt: new Date().toISOString(),
workflowId: activeWorkflowId,
blockId: event.data.blockId,
@@ -140,6 +141,7 @@ export async function executeWorkflowWithFullLogging(
error: event.data.error,
durationMs: event.data.durationMs,
startedAt: new Date(Date.now() - event.data.durationMs).toISOString(),
+ executionOrder: event.data.executionOrder,
endedAt: new Date().toISOString(),
workflowId: activeWorkflowId,
blockId: event.data.blockId,
diff --git a/apps/sim/executor/execution/block-executor.ts b/apps/sim/executor/execution/block-executor.ts
index 59b08e4a9..6c97dd1a1 100644
--- a/apps/sim/executor/execution/block-executor.ts
+++ b/apps/sim/executor/execution/block-executor.ts
@@ -21,12 +21,13 @@ import {
generatePauseContextId,
mapNodeMetadataToPauseScopes,
} from '@/executor/human-in-the-loop/utils.ts'
-import type {
- BlockHandler,
- BlockLog,
- BlockState,
- ExecutionContext,
- NormalizedBlockOutput,
+import {
+ type BlockHandler,
+ type BlockLog,
+ type BlockState,
+ type ExecutionContext,
+ getNextExecutionOrder,
+ type NormalizedBlockOutput,
} from '@/executor/types'
import { streamingResponseFormatProcessor } from '@/executor/utils'
import { buildBlockExecutionError, normalizeError } from '@/executor/utils/errors'
@@ -68,7 +69,7 @@ export class BlockExecutor {
if (!isSentinel) {
blockLog = this.createBlockLog(ctx, node.id, block, node)
ctx.blockLogs.push(blockLog)
- this.callOnBlockStart(ctx, node, block)
+ this.callOnBlockStart(ctx, node, block, blockLog.executionOrder)
}
const startTime = performance.now()
@@ -159,7 +160,7 @@ export class BlockExecutor {
this.state.setBlockOutput(node.id, normalizedOutput, duration)
- if (!isSentinel) {
+ if (!isSentinel && blockLog) {
const displayOutput = filterOutputForLog(block.metadata?.id || '', normalizedOutput, {
block,
})
@@ -170,8 +171,9 @@ export class BlockExecutor {
this.sanitizeInputsForLog(resolvedInputs),
displayOutput,
duration,
- blockLog!.startedAt,
- blockLog!.endedAt
+ blockLog.startedAt,
+ blockLog.executionOrder,
+ blockLog.endedAt
)
}
@@ -268,7 +270,7 @@ export class BlockExecutor {
}
)
- if (!isSentinel) {
+ if (!isSentinel && blockLog) {
const displayOutput = filterOutputForLog(block.metadata?.id || '', errorOutput, { block })
this.callOnBlockComplete(
ctx,
@@ -277,8 +279,9 @@ export class BlockExecutor {
this.sanitizeInputsForLog(input),
displayOutput,
duration,
- blockLog!.startedAt,
- blockLog!.endedAt
+ blockLog.startedAt,
+ blockLog.executionOrder,
+ blockLog.endedAt
)
}
@@ -346,6 +349,7 @@ export class BlockExecutor {
blockName,
blockType: block.metadata?.id ?? DEFAULTS.BLOCK_TYPE,
startedAt: new Date().toISOString(),
+ executionOrder: getNextExecutionOrder(ctx),
endedAt: '',
durationMs: 0,
success: false,
@@ -409,7 +413,12 @@ export class BlockExecutor {
return result
}
- private callOnBlockStart(ctx: ExecutionContext, node: DAGNode, block: SerializedBlock): void {
+ private callOnBlockStart(
+ ctx: ExecutionContext,
+ node: DAGNode,
+ block: SerializedBlock,
+ executionOrder: number
+ ): void {
const blockId = node.id
const blockName = block.metadata?.name ?? blockId
const blockType = block.metadata?.id ?? DEFAULTS.BLOCK_TYPE
@@ -417,7 +426,13 @@ export class BlockExecutor {
const iterationContext = this.getIterationContext(ctx, node)
if (this.contextExtensions.onBlockStart) {
- this.contextExtensions.onBlockStart(blockId, blockName, blockType, iterationContext)
+ this.contextExtensions.onBlockStart(
+ blockId,
+ blockName,
+ blockType,
+ executionOrder,
+ iterationContext
+ )
}
}
@@ -429,6 +444,7 @@ export class BlockExecutor {
output: NormalizedBlockOutput,
duration: number,
startedAt: string,
+ executionOrder: number,
endedAt: string
): void {
const blockId = node.id
@@ -447,6 +463,7 @@ export class BlockExecutor {
output,
executionTime: duration,
startedAt,
+ executionOrder,
endedAt,
},
iterationContext
diff --git a/apps/sim/executor/execution/types.ts b/apps/sim/executor/execution/types.ts
index e770989b6..91dfe2c6a 100644
--- a/apps/sim/executor/execution/types.ts
+++ b/apps/sim/executor/execution/types.ts
@@ -55,7 +55,13 @@ export interface IterationContext {
export interface ExecutionCallbacks {
onStream?: (streamingExec: any) => Promise
- onBlockStart?: (blockId: string, blockName: string, blockType: string) => Promise
+ onBlockStart?: (
+ blockId: string,
+ blockName: string,
+ blockType: string,
+ executionOrder: number,
+ iterationContext?: IterationContext
+ ) => Promise
onBlockComplete?: (
blockId: string,
blockName: string,
@@ -97,6 +103,7 @@ export interface ContextExtensions {
blockId: string,
blockName: string,
blockType: string,
+ executionOrder: number,
iterationContext?: IterationContext
) => Promise
onBlockComplete?: (
@@ -108,6 +115,7 @@ export interface ContextExtensions {
output: NormalizedBlockOutput
executionTime: number
startedAt: string
+ executionOrder: number
endedAt: string
},
iterationContext?: IterationContext
diff --git a/apps/sim/executor/orchestrators/loop.ts b/apps/sim/executor/orchestrators/loop.ts
index bd72b8498..8bdf8edd2 100644
--- a/apps/sim/executor/orchestrators/loop.ts
+++ b/apps/sim/executor/orchestrators/loop.ts
@@ -7,7 +7,11 @@ import type { DAG } from '@/executor/dag/builder'
import type { EdgeManager } from '@/executor/execution/edge-manager'
import type { LoopScope } from '@/executor/execution/state'
import type { BlockStateController, ContextExtensions } from '@/executor/execution/types'
-import type { ExecutionContext, NormalizedBlockOutput } from '@/executor/types'
+import {
+ type ExecutionContext,
+ getNextExecutionOrder,
+ type NormalizedBlockOutput,
+} from '@/executor/types'
import type { LoopConfigWithNodes } from '@/executor/types/loop'
import { replaceValidReferences } from '@/executor/utils/reference-validation'
import {
@@ -286,6 +290,7 @@ export class LoopOrchestrator {
output,
executionTime: DEFAULTS.EXECUTION_TIME,
startedAt: now,
+ executionOrder: getNextExecutionOrder(ctx),
endedAt: now,
})
}
diff --git a/apps/sim/executor/orchestrators/parallel.ts b/apps/sim/executor/orchestrators/parallel.ts
index 88942b8cb..6d7ea2dfe 100644
--- a/apps/sim/executor/orchestrators/parallel.ts
+++ b/apps/sim/executor/orchestrators/parallel.ts
@@ -3,7 +3,11 @@ import { DEFAULTS } from '@/executor/constants'
import type { DAG } from '@/executor/dag/builder'
import type { ParallelScope } from '@/executor/execution/state'
import type { BlockStateWriter, ContextExtensions } from '@/executor/execution/types'
-import type { ExecutionContext, NormalizedBlockOutput } from '@/executor/types'
+import {
+ type ExecutionContext,
+ getNextExecutionOrder,
+ type NormalizedBlockOutput,
+} from '@/executor/types'
import type { ParallelConfigWithNodes } from '@/executor/types/parallel'
import { ParallelExpander } from '@/executor/utils/parallel-expansion'
import {
@@ -270,6 +274,7 @@ export class ParallelOrchestrator {
output,
executionTime: 0,
startedAt: now,
+ executionOrder: getNextExecutionOrder(ctx),
endedAt: now,
})
}
diff --git a/apps/sim/executor/types.ts b/apps/sim/executor/types.ts
index 6c87eed25..10c1996b3 100644
--- a/apps/sim/executor/types.ts
+++ b/apps/sim/executor/types.ts
@@ -114,6 +114,11 @@ export interface BlockLog {
loopId?: string
parallelId?: string
iterationIndex?: number
+ /**
+ * Monotonically increasing integer (1, 2, 3, ...) for accurate block ordering.
+ * Generated via getNextExecutionOrder() to ensure deterministic sorting.
+ */
+ executionOrder: number
/**
* Child workflow trace spans for nested workflow execution.
* Stored separately from output to keep output clean for display
@@ -227,7 +232,12 @@ export interface ExecutionContext {
edges?: Array<{ source: string; target: string }>
onStream?: (streamingExecution: StreamingExecution) => Promise
- onBlockStart?: (blockId: string, blockName: string, blockType: string) => Promise
+ onBlockStart?: (
+ blockId: string,
+ blockName: string,
+ blockType: string,
+ executionOrder: number
+ ) => Promise
onBlockComplete?: (
blockId: string,
blockName: string,
@@ -268,6 +278,23 @@ export interface ExecutionContext {
* Stop execution after this block completes. Used for "run until block" feature.
*/
stopAfterBlockId?: string
+
+ /**
+ * Counter for generating monotonically increasing execution order values.
+ * Starts at 0 and increments for each block. Use getNextExecutionOrder() to access.
+ */
+ executionOrderCounter?: { value: number }
+}
+
+/**
+ * Gets the next execution order value for a block.
+ * Returns a simple incrementing integer (1, 2, 3, ...) for clear ordering.
+ */
+export function getNextExecutionOrder(ctx: ExecutionContext): number {
+ if (!ctx.executionOrderCounter) {
+ ctx.executionOrderCounter = { value: 0 }
+ }
+ return ++ctx.executionOrderCounter.value
}
export interface ExecutionResult {
diff --git a/apps/sim/executor/utils/subflow-utils.ts b/apps/sim/executor/utils/subflow-utils.ts
index 5ef3a51b5..c4eb23f38 100644
--- a/apps/sim/executor/utils/subflow-utils.ts
+++ b/apps/sim/executor/utils/subflow-utils.ts
@@ -1,7 +1,7 @@
import { createLogger } from '@sim/logger'
import { LOOP, PARALLEL, PARSING, REFERENCE } from '@/executor/constants'
import type { ContextExtensions } from '@/executor/execution/types'
-import type { BlockLog, ExecutionContext } from '@/executor/types'
+import { type BlockLog, type ExecutionContext, getNextExecutionOrder } from '@/executor/types'
import type { VariableResolver } from '@/executor/variables/resolver'
const logger = createLogger('SubflowUtils')
@@ -208,6 +208,7 @@ export function addSubflowErrorLog(
contextExtensions: ContextExtensions | null
): void {
const now = new Date().toISOString()
+ const execOrder = getNextExecutionOrder(ctx)
const block = ctx.workflow?.blocks?.find((b) => b.id === blockId)
const blockName = block?.metadata?.name || (blockType === 'loop' ? 'Loop' : 'Parallel')
@@ -217,6 +218,7 @@ export function addSubflowErrorLog(
blockName,
blockType,
startedAt: now,
+ executionOrder: execOrder,
endedAt: now,
durationMs: 0,
success: false,
@@ -233,6 +235,7 @@ export function addSubflowErrorLog(
output: { error: errorMessage },
executionTime: 0,
startedAt: now,
+ executionOrder: execOrder,
endedAt: now,
})
}
diff --git a/apps/sim/lib/workflows/executor/execution-events.ts b/apps/sim/lib/workflows/executor/execution-events.ts
index 6c3998e23..ba36f9787 100644
--- a/apps/sim/lib/workflows/executor/execution-events.ts
+++ b/apps/sim/lib/workflows/executor/execution-events.ts
@@ -1,7 +1,3 @@
-/**
- * SSE Event types for workflow execution
- */
-
import type { SubflowType } from '@/stores/workflows/workflow/types'
export type ExecutionEventType =
@@ -83,7 +79,7 @@ export interface BlockStartedEvent extends BaseExecutionEvent {
blockId: string
blockName: string
blockType: string
- // Iteration context for loops and parallels
+ executionOrder: number
iterationCurrent?: number
iterationTotal?: number
iterationType?: SubflowType
@@ -104,8 +100,8 @@ export interface BlockCompletedEvent extends BaseExecutionEvent {
output: any
durationMs: number
startedAt: string
+ executionOrder: number
endedAt: string
- // Iteration context for loops and parallels
iterationCurrent?: number
iterationTotal?: number
iterationType?: SubflowType
@@ -126,8 +122,8 @@ export interface BlockErrorEvent extends BaseExecutionEvent {
error: string
durationMs: number
startedAt: string
+ executionOrder: number
endedAt: string
- // Iteration context for loops and parallels
iterationCurrent?: number
iterationTotal?: number
iterationType?: SubflowType
@@ -228,6 +224,7 @@ export function createSSECallbacks(options: SSECallbackOptions) {
blockId: string,
blockName: string,
blockType: string,
+ executionOrder: number,
iterationContext?: { iterationCurrent: number; iterationTotal: number; iterationType: string }
) => {
sendEvent({
@@ -239,6 +236,7 @@ export function createSSECallbacks(options: SSECallbackOptions) {
blockId,
blockName,
blockType,
+ executionOrder,
...(iterationContext && {
iterationCurrent: iterationContext.iterationCurrent,
iterationTotal: iterationContext.iterationTotal,
@@ -257,6 +255,7 @@ export function createSSECallbacks(options: SSECallbackOptions) {
output: any
executionTime: number
startedAt: string
+ executionOrder: number
endedAt: string
},
iterationContext?: { iterationCurrent: number; iterationTotal: number; iterationType: string }
@@ -284,6 +283,7 @@ export function createSSECallbacks(options: SSECallbackOptions) {
error: callbackData.output.error,
durationMs: callbackData.executionTime || 0,
startedAt: callbackData.startedAt,
+ executionOrder: callbackData.executionOrder,
endedAt: callbackData.endedAt,
...iterationData,
},
@@ -302,6 +302,7 @@ export function createSSECallbacks(options: SSECallbackOptions) {
output: callbackData.output,
durationMs: callbackData.executionTime || 0,
startedAt: callbackData.startedAt,
+ executionOrder: callbackData.executionOrder,
endedAt: callbackData.endedAt,
...iterationData,
},
diff --git a/apps/sim/stores/terminal/console/store.ts b/apps/sim/stores/terminal/console/store.ts
index 15298c625..9b1386da1 100644
--- a/apps/sim/stores/terminal/console/store.ts
+++ b/apps/sim/stores/terminal/console/store.ts
@@ -287,6 +287,14 @@ export const useTerminalConsoleStore = create()(
return entry
}
+ if (
+ typeof update === 'object' &&
+ update.iterationCurrent !== undefined &&
+ entry.iterationCurrent !== update.iterationCurrent
+ ) {
+ return entry
+ }
+
if (typeof update === 'string') {
const newOutput = updateBlockOutput(entry.output, update)
return { ...entry, output: newOutput }
@@ -324,6 +332,10 @@ export const useTerminalConsoleStore = create()(
updatedEntry.success = update.success
}
+ if (update.startedAt !== undefined) {
+ updatedEntry.startedAt = update.startedAt
+ }
+
if (update.endedAt !== undefined) {
updatedEntry.endedAt = update.endedAt
}
@@ -397,9 +409,15 @@ export const useTerminalConsoleStore = create()(
},
merge: (persistedState, currentState) => {
const persisted = persistedState as Partial | undefined
+ const entries = (persisted?.entries ?? currentState.entries).map((entry, index) => {
+ if (entry.executionOrder === undefined) {
+ return { ...entry, executionOrder: index + 1 }
+ }
+ return entry
+ })
return {
...currentState,
- entries: persisted?.entries ?? currentState.entries,
+ entries,
isOpen: persisted?.isOpen ?? currentState.isOpen,
}
},
diff --git a/apps/sim/stores/terminal/console/types.ts b/apps/sim/stores/terminal/console/types.ts
index ca31112eb..3ddb4b424 100644
--- a/apps/sim/stores/terminal/console/types.ts
+++ b/apps/sim/stores/terminal/console/types.ts
@@ -10,6 +10,7 @@ export interface ConsoleEntry {
blockType: string
executionId?: string
startedAt?: string
+ executionOrder: number
endedAt?: string
durationMs?: number
success?: boolean
@@ -20,9 +21,7 @@ export interface ConsoleEntry {
iterationCurrent?: number
iterationTotal?: number
iterationType?: SubflowType
- /** Whether this block is currently running */
isRunning?: boolean
- /** Whether this block execution was canceled */
isCanceled?: boolean
}
@@ -33,14 +32,12 @@ export interface ConsoleUpdate {
error?: string | Error | null
warning?: string
success?: boolean
+ startedAt?: string
endedAt?: string
durationMs?: number
input?: any
- /** Whether this block is currently running */
isRunning?: boolean
- /** Whether this block execution was canceled */
isCanceled?: boolean
- /** Iteration context for subflow blocks */
iterationCurrent?: number
iterationTotal?: number
iterationType?: SubflowType