Skip to content

Commit 9295499

Browse files
waleedlatif1claude
andauthored
fix(traces): prevent condition blocks from rendering source agent's timeSegments (#3534)
* fix(traces): prevent condition blocks from rendering source agent's timeSegments Condition blocks spread their source block's entire output into their own output. When the source is an agent, this leaked providerTiming/timeSegments into the condition's output, causing buildTraceSpans to create "Initial response" as a child of the condition span instead of the agent span. Two fixes: - Skip timeSegment child creation for condition block types in buildTraceSpans - Filter execution metadata (providerTiming, tokens, toolCalls, model, cost) from condition handler's filterSourceOutput Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(traces): guard condition blocks from leaked metadata on old persisted logs Extend isConditionBlockType guards to also skip setting span.providerTiming, span.cost, span.tokens, and span.model for condition blocks. This ensures old persisted logs (recorded before the filterSourceOutput fix) don't display misleading execution metadata on condition spans. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(traces): guard toolCalls fallback path for condition blocks on old logs The else branch that extracts toolCalls from log.output also needs a condition block guard, otherwise old persisted logs with leaked toolCalls from the source agent would render on the condition span. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(traces): extract isCondition to local variable for readability Cache isConditionBlockType(log.blockType) in a local const at the top of the forEach loop instead of calling it 6 times per iteration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6bcbd15 commit 9295499

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

apps/sim/executor/handlers/condition/condition-handler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ export class ConditionBlockHandler implements BlockHandler {
166166
if (!output || typeof output !== 'object') {
167167
return output
168168
}
169-
const { _pauseMetadata, error, ...rest } = output
169+
const { _pauseMetadata, error, providerTiming, tokens, toolCalls, model, cost, ...rest } =
170+
output
170171
return rest
171172
}
172173

apps/sim/lib/logs/execution/trace-spans/trace-spans.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { createLogger } from '@sim/logger'
22
import type { ToolCall, TraceSpan } from '@/lib/logs/types'
3-
import { isWorkflowBlockType, stripCustomToolPrefix } from '@/executor/constants'
3+
import {
4+
isConditionBlockType,
5+
isWorkflowBlockType,
6+
stripCustomToolPrefix,
7+
} from '@/executor/constants'
48
import type { ExecutionResult } from '@/executor/types'
59
import { stripCloneSuffixes } from '@/executor/utils/subflow-utils'
610

@@ -109,6 +113,7 @@ export function buildTraceSpans(result: ExecutionResult): {
109113
if (!log.blockId || !log.blockType) return
110114

111115
const spanId = `${log.blockId}-${new Date(log.startedAt).getTime()}`
116+
const isCondition = isConditionBlockType(log.blockType)
112117

113118
const duration = log.durationMs || 0
114119

@@ -164,7 +169,7 @@ export function buildTraceSpans(result: ExecutionResult): {
164169
...(log.parentIterations?.length && { parentIterations: log.parentIterations }),
165170
}
166171

167-
if (log.output?.providerTiming) {
172+
if (!isCondition && log.output?.providerTiming) {
168173
const providerTiming = log.output.providerTiming as {
169174
duration: number
170175
startTime: string
@@ -186,15 +191,15 @@ export function buildTraceSpans(result: ExecutionResult): {
186191
}
187192
}
188193

189-
if (log.output?.cost) {
194+
if (!isCondition && log.output?.cost) {
190195
span.cost = log.output.cost as {
191196
input?: number
192197
output?: number
193198
total?: number
194199
}
195200
}
196201

197-
if (log.output?.tokens) {
202+
if (!isCondition && log.output?.tokens) {
198203
const t = log.output.tokens as
199204
| number
200205
| {
@@ -224,12 +229,13 @@ export function buildTraceSpans(result: ExecutionResult): {
224229
}
225230
}
226231

227-
if (log.output?.model) {
232+
if (!isCondition && log.output?.model) {
228233
span.model = log.output.model as string
229234
}
230235

231236
if (
232237
!isWorkflowBlockType(log.blockType) &&
238+
!isCondition &&
233239
log.output?.providerTiming?.timeSegments &&
234240
Array.isArray(log.output.providerTiming.timeSegments)
235241
) {
@@ -317,7 +323,7 @@ export function buildTraceSpans(result: ExecutionResult): {
317323
}
318324
}
319325
)
320-
} else {
326+
} else if (!isCondition) {
321327
let toolCallsList = null
322328

323329
try {

0 commit comments

Comments
 (0)