@@ -57,40 +57,6 @@ function useSetToggle() {
5757 )
5858}
5959
60- /**
61- * Generates a unique key for a trace span
62- */
63- function getSpanKey ( span : TraceSpan ) : string {
64- if ( span . id ) {
65- return span . id
66- }
67- const name = span . name || 'span'
68- const start = span . startTime || 'unknown-start'
69- const end = span . endTime || 'unknown-end'
70- return `${ name } |${ start } |${ end } `
71- }
72-
73- /**
74- * Merges multiple arrays of trace span children, deduplicating by span key
75- */
76- function mergeTraceSpanChildren ( ...groups : TraceSpan [ ] [ ] ) : TraceSpan [ ] {
77- const merged : TraceSpan [ ] = [ ]
78- const seen = new Set < string > ( )
79-
80- groups . forEach ( ( group ) => {
81- group . forEach ( ( child ) => {
82- const key = getSpanKey ( child )
83- if ( seen . has ( key ) ) {
84- return
85- }
86- seen . add ( key )
87- merged . push ( child )
88- } )
89- } )
90-
91- return merged
92- }
93-
9460/**
9561 * Parses a time value to milliseconds
9662 */
@@ -116,34 +82,16 @@ function hasErrorInTree(span: TraceSpan): boolean {
11682
11783/**
11884 * Normalizes and sorts trace spans recursively.
119- * Merges children from both span.children and span.output.childTraceSpans,
120- * deduplicates them, and sorts by start time.
85+ * Deduplicates children and sorts by start time.
12186 */
12287function normalizeAndSortSpans ( spans : TraceSpan [ ] ) : TraceSpan [ ] {
12388 return spans
12489 . map ( ( span ) => {
12590 const enrichedSpan : TraceSpan = { ...span }
12691
127- // Clean output by removing childTraceSpans after extracting
128- if ( enrichedSpan . output && typeof enrichedSpan . output === 'object' ) {
129- enrichedSpan . output = { ...enrichedSpan . output }
130- if ( 'childTraceSpans' in enrichedSpan . output ) {
131- const { childTraceSpans, ...cleanOutput } = enrichedSpan . output as {
132- childTraceSpans ?: TraceSpan [ ]
133- } & Record < string , unknown >
134- enrichedSpan . output = cleanOutput
135- }
136- }
137-
138- // Merge and deduplicate children from both sources
139- const directChildren = Array . isArray ( span . children ) ? span . children : [ ]
140- const outputChildren = Array . isArray ( span . output ?. childTraceSpans )
141- ? ( span . output ! . childTraceSpans as TraceSpan [ ] )
142- : [ ]
143-
144- const mergedChildren = mergeTraceSpanChildren ( directChildren , outputChildren )
145- enrichedSpan . children =
146- mergedChildren . length > 0 ? normalizeAndSortSpans ( mergedChildren ) : undefined
92+ // Process and deduplicate children
93+ const children = Array . isArray ( span . children ) ? span . children : [ ]
94+ enrichedSpan . children = children . length > 0 ? normalizeAndSortSpans ( children ) : undefined
14795
14896 return enrichedSpan
14997 } )
@@ -573,7 +521,19 @@ const TraceSpanNode = memo(function TraceSpanNode({
573521 return children . sort ( ( a , b ) => parseTime ( a . startTime ) - parseTime ( b . startTime ) )
574522 } , [ span , spanId , spanStartTime ] )
575523
576- const hasChildren = allChildren . length > 0
524+ // Hide empty model timing segments for agents without tool calls
525+ const filteredChildren = useMemo ( ( ) => {
526+ const isAgent = span . type ?. toLowerCase ( ) === 'agent'
527+ const hasToolCalls =
528+ ( span . toolCalls ?. length ?? 0 ) > 0 || allChildren . some ( ( c ) => c . type ?. toLowerCase ( ) === 'tool' )
529+
530+ if ( isAgent && ! hasToolCalls ) {
531+ return allChildren . filter ( ( c ) => c . type ?. toLowerCase ( ) !== 'model' )
532+ }
533+ return allChildren
534+ } , [ allChildren , span . type , span . toolCalls ] )
535+
536+ const hasChildren = filteredChildren . length > 0
577537 const isExpanded = isRootWorkflow || expandedNodes . has ( spanId )
578538 const isToggleable = ! isRootWorkflow
579539
@@ -685,7 +645,7 @@ const TraceSpanNode = memo(function TraceSpanNode({
685645 { /* Nested Children */ }
686646 { hasChildren && (
687647 < div className = 'flex min-w-0 flex-col gap-[2px] border-[var(--border)] border-l pl-[10px]' >
688- { allChildren . map ( ( child , index ) => (
648+ { filteredChildren . map ( ( child , index ) => (
689649 < div key = { child . id || `${ spanId } -child-${ index } ` } className = 'pl-[6px]' >
690650 < TraceSpanNode
691651 span = { child }
0 commit comments