11import { createLogger } from '@sim/logger'
2+ import { isRecordLike } from '@sim/utils/object'
23import type { ProviderTiming , TraceSpan } from '@/lib/logs/types'
34import {
45 isConditionBlockType ,
@@ -17,6 +18,12 @@ const logger = createLogger('SpanFactory')
1718/** A BlockLog that has already passed the id/type validity check. */
1819type ValidBlockLog = BlockLog & { blockType : string }
1920
21+ /** Converts arbitrary tool results to the object shape expected by trace spans. */
22+ function normalizeTraceOutput ( value : unknown ) : Record < string , unknown > | undefined {
23+ if ( value === undefined ) return undefined
24+ return isRecordLike ( value ) ? value : { value }
25+ }
26+
2027/**
2128 * Creates a TraceSpan from a BlockLog. Returns null for invalid logs.
2229 *
@@ -190,6 +197,7 @@ function buildChildrenFromTimeSegments(
190197 const currentIndex = toolCallIndices . get ( normalizedName ) ?? 0
191198 const match = callsForName [ currentIndex ]
192199 toolCallIndices . set ( normalizedName , currentIndex + 1 )
200+ const output = normalizeTraceOutput ( match ?. result ?? match ?. output )
193201
194202 const toolChild : TraceSpan = {
195203 id : `${ span . id } -segment-${ index } ` ,
@@ -200,9 +208,7 @@ function buildChildrenFromTimeSegments(
200208 endTime : segmentEndTime ,
201209 status : match ?. error || segment . errorMessage ? 'error' : 'success' ,
202210 input : match ?. arguments ?? match ?. input ,
203- output : match ?. error
204- ? { error : match . error , ...( match . result ?? match . output ?? { } ) }
205- : ( match ?. result ?? match ?. output ) ,
211+ output : match ?. error ? { error : match . error , ...output } : output ,
206212 }
207213 if ( segment . toolCallId ) toolChild . toolCallId = segment . toolCallId
208214 if ( segment . errorType ) toolChild . errorType = segment . errorType
@@ -269,6 +275,7 @@ function buildChildrenFromToolCalls(span: TraceSpan, log: ValidBlockLog): TraceS
269275 return toolCalls . map ( ( tc , index ) => {
270276 const startTime = tc . startTime ?? log . startedAt
271277 const endTime = tc . endTime ?? log . endedAt
278+ const output = normalizeTraceOutput ( tc . result ?? tc . output )
272279 return {
273280 id : `${ span . id } -tool-${ index } ` ,
274281 name : stripCustomToolPrefix ( tc . name ?? 'unnamed-tool' ) ,
@@ -278,9 +285,7 @@ function buildChildrenFromToolCalls(span: TraceSpan, log: ValidBlockLog): TraceS
278285 endTime,
279286 status : tc . error ? 'error' : 'success' ,
280287 input : tc . arguments ?? tc . input ,
281- output : tc . error
282- ? { error : tc . error , ...( tc . result ?? tc . output ?? { } ) }
283- : ( tc . result ?? tc . output ) ,
288+ output : tc . error ? { error : tc . error , ...output } : output ,
284289 }
285290 } )
286291}
0 commit comments