@@ -209,7 +271,7 @@ function PinnedLogs({ executionData, onClose }: { executionData: any; onClose: (
)}
- {formatted.tokens && (
+ {formatted.tokens && formatted.tokens.total > 0 && (
Token Usage
@@ -242,12 +304,7 @@ interface FrozenCanvasData {
startedAt: string
endedAt?: string
totalDurationMs?: number
- blockStats: {
- total: number
- success: number
- error: number
- skipped: number
- }
+
cost: {
total: number | null
input: number | null
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
index 78371d6e7f..373c4ae63e 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/sidebar/sidebar.tsx
@@ -494,42 +494,7 @@ export function Sidebar({
)}
- {/* Enhanced Stats - only show for enhanced logs */}
- {log.metadata?.enhanced && log.metadata?.blockStats && (
-
-
- Block Execution Stats
-
-
-
- Total Blocks:
- {log.metadata.blockStats.total}
-
-
- Successful:
-
- {log.metadata.blockStats.success}
-
-
- {log.metadata.blockStats.error > 0 && (
-
- Failed:
-
- {log.metadata.blockStats.error}
-
-
- )}
- {log.metadata.blockStats.skipped > 0 && (
-
- Skipped:
-
- {log.metadata.blockStats.skipped}
-
-
- )}
-
-
- )}
+
{/* Enhanced Cost - only show for enhanced logs with actual cost data */}
{log.metadata?.enhanced && hasCostInfo && (
@@ -583,7 +548,7 @@ export function Sidebar({
className='w-full justify-start gap-2'
>
- View Frozen Canvas
+ View Snapshot
See the exact workflow state and block inputs/outputs at execution time
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx
index 056372083a..5d6aea8e75 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/trace-spans/trace-spans-display.tsx
@@ -1,11 +1,9 @@
'use client'
-import { useMemo, useState } from 'react'
+import { useState } from 'react'
import {
ChevronDown,
- ChevronDownSquare,
ChevronRight,
- ChevronUpSquare,
Code,
Cpu,
ExternalLink,
@@ -203,39 +201,16 @@ export function TraceSpansDisplay({
// Keep track of expanded spans
const [expandedSpans, setExpandedSpans] = useState>(new Set())
- // Function to collect all span IDs recursively (for expand all functionality)
- const collectAllSpanIds = (spans: TraceSpan[]): string[] => {
- const ids: string[] = []
- const collectIds = (span: TraceSpan) => {
- const spanId = span.id || `span-${span.name}-${span.startTime}`
- ids.push(spanId)
- // Process children
- if (span.children && span.children.length > 0) {
- span.children.forEach(collectIds)
- }
- }
- spans.forEach(collectIds)
- return ids
- }
-
- const allSpanIds = useMemo(() => {
- if (!traceSpans || traceSpans.length === 0) return []
- return collectAllSpanIds(traceSpans)
- }, [traceSpans])
// Early return after all hooks
if (!traceSpans || traceSpans.length === 0) {
return No trace data available
}
- // Format total duration for better readability
- const _formatTotalDuration = (ms: number) => {
- if (ms < 1000) return `${ms}ms`
- return `${(ms / 1000).toFixed(2)}s (${ms}ms)`
- }
+
// Find the earliest start time among all spans to be the workflow start time
const workflowStartTime = traceSpans.reduce((earliest, span) => {
@@ -269,48 +244,12 @@ export function TraceSpansDisplay({
}
}
- // Handle expand all / collapse all
- const handleExpandAll = () => {
- const newExpandedSpans = new Set(allSpanIds)
- setExpandedSpans(newExpandedSpans)
- if (onExpansionChange) {
- onExpansionChange(true)
- }
- }
-
- const handleCollapseAll = () => {
- setExpandedSpans(new Set())
-
- if (onExpansionChange) {
- onExpansionChange(false)
- }
- }
-
- // Determine if all spans are currently expanded
- const allExpanded = allSpanIds.length > 0 && allSpanIds.every((id) => expandedSpans.has(id))
return (
-
Trace Spans
-
+
Workflow Execution
{traceSpans.map((span, index) => {
@@ -369,7 +308,8 @@ function TraceSpanItem({
const expanded = expandedSpans.has(spanId)
const hasChildren = span.children && span.children.length > 0
const hasToolCalls = span.toolCalls && span.toolCalls.length > 0
- const hasNestedItems = hasChildren || hasToolCalls
+ const hasInputOutput = Boolean(span.input || span.output)
+ const hasNestedItems = hasChildren || hasToolCalls || hasInputOutput
// Calculate timing information
const spanStartTime = new Date(span.startTime).getTime()
@@ -389,8 +329,7 @@ function TraceSpanItem({
const safeStartPercent = Math.min(100, Math.max(0, relativeStartPercent))
const safeWidthPercent = Math.max(2, Math.min(100 - safeStartPercent, actualDurationPercent))
- // For parent-relative timing display
- const _startOffsetPercentage = totalDuration > 0 ? (startOffset / totalDuration) * 100 : 0
+
// Handle click to expand/collapse this span
const handleSpanClick = () => {
@@ -605,17 +544,17 @@ function TraceSpanItem({
- {/* Children and tool calls */}
+ {/* Expanded content */}
{expanded && (
{/* Block Input/Output Data */}
{(span.input || span.output) && (
-
+
{/* Input Data */}
{span.input && (
Input
-
@@ -627,7 +566,7 @@ function TraceSpanItem({
{span.status === 'error' ? 'Error Details' : 'Output'}
-
+
)}
-
- )}
- {/* Children and tool calls */}
- {expanded && (
-
+ {/* Children and tool calls */}
{/* Render child spans */}
{hasChildren && (
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx b/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
index 87c32eb3e3..45d628f559 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
@@ -308,14 +308,16 @@ export default function Logs() {
{/* Table with fixed layout */}
{/* Header */}
-
-
-
Time
-
Status
-
Workflow
-
Trigger
-
Cost
-
Duration
+
+
+
+
Time
+
Status
+
Workflow
+
Trigger
+
Cost
+
Duration
+
@@ -344,7 +346,7 @@ export default function Logs() {
) : (
-
+
{logs.map((log) => {
const formattedDate = formatDate(log.createdAt)
const isSelected = selectedLog?.id === log.id
@@ -360,7 +362,7 @@ export default function Logs() {
}`}
onClick={() => handleLogClick(log)}
>
-
+
{/* Time */}
{formattedDate.formatted}
@@ -403,13 +405,13 @@ export default function Logs() {
{/* Cost */}
-
+
{log.metadata?.enhanced && log.metadata?.cost?.total ? (
-
+
${log.metadata.cost.total.toFixed(4)}
) : (
- —
+ —
)}
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts b/apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts
index 0108ada3dc..54d8b632df 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts
+++ b/apps/sim/app/workspace/[workspaceId]/logs/stores/types.ts
@@ -84,12 +84,7 @@ export interface WorkflowLog {
cost?: CostMetadata
blockInput?: Record
enhanced?: boolean
- blockStats?: {
- total: number
- success: number
- error: number
- skipped: number
- }
+
blockExecutions?: Array<{
id: string
blockId: string
diff --git a/apps/sim/lib/logs/enhanced-execution-logger.ts b/apps/sim/lib/logs/enhanced-execution-logger.ts
index 561e6570fa..e72350047b 100644
--- a/apps/sim/lib/logs/enhanced-execution-logger.ts
+++ b/apps/sim/lib/logs/enhanced-execution-logger.ts
@@ -194,12 +194,6 @@ export class EnhancedExecutionLogger implements IExecutionLoggerService {
executionId: string
endedAt: string
totalDurationMs: number
- blockStats: {
- total: number
- success: number
- error: number
- skipped: number
- }
costSummary: {
totalCost: number
totalInputCost: number
@@ -224,7 +218,6 @@ export class EnhancedExecutionLogger implements IExecutionLoggerService {
executionId,
endedAt,
totalDurationMs,
- blockStats,
costSummary,
finalOutput,
traceSpans,
@@ -232,11 +225,8 @@ export class EnhancedExecutionLogger implements IExecutionLoggerService {
logger.debug(`Completing workflow execution ${executionId}`)
- const level = blockStats.error > 0 ? 'error' : 'info'
- const message =
- blockStats.error > 0
- ? `Workflow execution failed: ${blockStats.error} error(s), ${blockStats.success} success(es)`
- : `Workflow execution completed: ${blockStats.success} block(s) executed successfully`
+ const level = 'info'
+ const message = `Workflow execution completed`
const [updatedLog] = await db
.update(workflowExecutionLogs)
@@ -245,10 +235,10 @@ export class EnhancedExecutionLogger implements IExecutionLoggerService {
message,
endedAt: new Date(endedAt),
totalDurationMs,
- blockCount: blockStats.total,
- successCount: blockStats.success,
- errorCount: blockStats.error,
- skippedCount: blockStats.skipped,
+ blockCount: 0,
+ successCount: 0,
+ errorCount: 0,
+ skippedCount: 0,
totalCost: costSummary.totalCost.toString(),
totalInputCost: costSummary.totalInputCost.toString(),
totalOutputCost: costSummary.totalOutputCost.toString(),
diff --git a/apps/sim/lib/logs/enhanced-logging-factory.ts b/apps/sim/lib/logs/enhanced-logging-factory.ts
index 72cde27efd..cd9d9bffb4 100644
--- a/apps/sim/lib/logs/enhanced-logging-factory.ts
+++ b/apps/sim/lib/logs/enhanced-logging-factory.ts
@@ -46,50 +46,7 @@ export async function loadWorkflowStateForExecution(workflowId: string): Promise
}
}
-export function calculateBlockStats(traceSpans: any[]): {
- total: number
- success: number
- error: number
- skipped: number
-} {
- if (!traceSpans || traceSpans.length === 0) {
- return { total: 0, success: 0, error: 0, skipped: 0 }
- }
- // Recursively collect all block spans from the trace span tree
- const collectBlockSpans = (spans: any[]): any[] => {
- const blocks: any[] = []
-
- for (const span of spans) {
- // Check if this span is an actual workflow block
- if (
- span.type &&
- span.type !== 'workflow' &&
- span.type !== 'provider' &&
- span.type !== 'model' &&
- span.blockId
- ) {
- blocks.push(span)
- }
-
- // Recursively check children
- if (span.children && Array.isArray(span.children)) {
- blocks.push(...collectBlockSpans(span.children))
- }
- }
-
- return blocks
- }
-
- const blockSpans = collectBlockSpans(traceSpans)
-
- const total = blockSpans.length
- const success = blockSpans.filter((span) => span.status === 'success').length
- const error = blockSpans.filter((span) => span.status === 'error').length
- const skipped = blockSpans.filter((span) => span.status === 'skipped').length
-
- return { total, success, error, skipped }
-}
export function calculateCostSummary(traceSpans: any[]): {
totalCost: number
diff --git a/apps/sim/lib/logs/enhanced-logging-session.ts b/apps/sim/lib/logs/enhanced-logging-session.ts
index 7d0bc174eb..e3eed5dad9 100644
--- a/apps/sim/lib/logs/enhanced-logging-session.ts
+++ b/apps/sim/lib/logs/enhanced-logging-session.ts
@@ -1,7 +1,6 @@
import { createLogger } from '@/lib/logs/console-logger'
import { enhancedExecutionLogger } from './enhanced-execution-logger'
import {
- calculateBlockStats,
calculateCostSummary,
createEnvironmentObject,
createTriggerObject,
@@ -99,14 +98,12 @@ export class EnhancedLoggingSession {
const { endedAt, totalDurationMs, finalOutput, traceSpans } = params
try {
- const blockStats = calculateBlockStats(traceSpans || [])
const costSummary = calculateCostSummary(traceSpans || [])
await enhancedExecutionLogger.completeWorkflowExecution({
executionId: this.executionId,
endedAt: endedAt || new Date().toISOString(),
totalDurationMs: totalDurationMs || 0,
- blockStats,
costSummary,
finalOutput: finalOutput || {},
traceSpans: traceSpans || [],
@@ -126,7 +123,6 @@ export class EnhancedLoggingSession {
async completeWithError(error?: any): Promise {
try {
- const blockStats = { total: 0, success: 0, error: 1, skipped: 0 }
const costSummary = {
totalCost: 0,
totalInputCost: 0,
@@ -141,7 +137,6 @@ export class EnhancedLoggingSession {
executionId: this.executionId,
endedAt: new Date().toISOString(),
totalDurationMs: 0,
- blockStats,
costSummary,
finalOutput: null,
traceSpans: [],
diff --git a/apps/sim/lib/logs/types.ts b/apps/sim/lib/logs/types.ts
index bf1c76f22a..1bb8700130 100644
--- a/apps/sim/lib/logs/types.ts
+++ b/apps/sim/lib/logs/types.ts
@@ -169,12 +169,7 @@ export interface WorkflowExecutionSummary {
startedAt: string
endedAt: string
durationMs: number
- blockStats: {
- total: number
- success: number
- error: number
- skipped: number
- }
+
costSummary: {
total: number
inputCost: number
@@ -360,12 +355,7 @@ export interface ExecutionLoggerService {
executionId: string
endedAt: string
totalDurationMs: number
- blockStats: {
- total: number
- success: number
- error: number
- skipped: number
- }
+
costSummary: {
totalCost: number
totalInputCost: number