@@ -27,6 +27,36 @@ export default function AgentActivityTraceDetailPage() {
2727 ( data && ! data . tracing_enabled ) || ( isError && isTracingUnavailableError ( error ) )
2828 ) ;
2929
30+ const toolCalls = data ?. tool_calls ?? [ ] ;
31+ const modelInvocations = data ?. model_invocations ?? [ ] ;
32+
33+ const fallbackToolCalls =
34+ toolCalls . length > 0
35+ ? toolCalls
36+ : ( data ?. spans ?? [ ] )
37+ . filter ( ( span ) => span . tool_name )
38+ . map ( ( span ) => ( {
39+ span_id : span . span_id ,
40+ tool_name : span . tool_name ?? 'unknown-tool' ,
41+ input : span . tool_input ,
42+ output : span . tool_output ,
43+ status : span . status ,
44+ } ) ) ;
45+
46+ const fallbackModelInvocations =
47+ modelInvocations . length > 0
48+ ? modelInvocations
49+ : ( data ?. spans ?? [ ] )
50+ . filter ( ( span ) => Boolean ( span . model_name ) || Boolean ( span . prompt_excerpt ) || Boolean ( span . completion_excerpt ) )
51+ . map ( ( span ) => ( {
52+ span_id : span . span_id ,
53+ model_name : span . model_name ?? span . service ,
54+ model_tier : span . model_tier ?? 'unknown' ,
55+ prompt_excerpt : span . prompt_excerpt ,
56+ completion_excerpt : span . completion_excerpt ,
57+ latency_ms : span . duration_ms ,
58+ } ) ) ;
59+
3060 return (
3161 < MainLayout >
3262 < div className = "space-y-6" >
@@ -100,6 +130,79 @@ export default function AgentActivityTraceDetailPage() {
100130 < h2 className = "mb-3 text-lg font-semibold text-gray-900 dark:text-white" > Timing waterfall</ h2 >
101131 < TraceWaterfall spans = { data . spans } />
102132 </ Card >
133+
134+ < section className = "grid grid-cols-1 gap-6 xl:grid-cols-2" >
135+ < Card className = "p-4" >
136+ < h2 className = "mb-3 text-lg font-semibold text-gray-900 dark:text-white" > Tool calls</ h2 >
137+ { fallbackToolCalls . length === 0 ? (
138+ < p className = "text-sm text-gray-500 dark:text-gray-400" > No tool call details available.</ p >
139+ ) : (
140+ < ul className = "space-y-3" aria-label = "Tool call list" >
141+ { fallbackToolCalls . map ( ( toolCall ) => (
142+ < li key = { `${ toolCall . span_id } -${ toolCall . tool_name } ` } className = "rounded-md border border-gray-200 p-3 dark:border-gray-700" >
143+ < p className = "text-sm font-semibold text-gray-900 dark:text-white" > { toolCall . tool_name } </ p >
144+ { toolCall . input && (
145+ < p className = "mt-1 text-xs text-gray-600 dark:text-gray-300" >
146+ Input: { toolCall . input . slice ( 0 , 180 ) }
147+ { toolCall . input . length > 180 ? '…' : '' }
148+ </ p >
149+ ) }
150+ { toolCall . output && (
151+ < p className = "mt-1 text-xs text-gray-600 dark:text-gray-300" >
152+ Output: { toolCall . output . slice ( 0 , 180 ) }
153+ { toolCall . output . length > 180 ? '…' : '' }
154+ </ p >
155+ ) }
156+ </ li >
157+ ) ) }
158+ </ ul >
159+ ) }
160+ </ Card >
161+
162+ < Card className = "p-4" >
163+ < h2 className = "mb-3 text-lg font-semibold text-gray-900 dark:text-white" > Model invocations</ h2 >
164+ { fallbackModelInvocations . length === 0 ? (
165+ < p className = "text-sm text-gray-500 dark:text-gray-400" > No model invocation details available.</ p >
166+ ) : (
167+ < ul className = "space-y-3" aria-label = "Model invocation list" >
168+ { fallbackModelInvocations . map ( ( invocation ) => (
169+ < li key = { `${ invocation . span_id } -${ invocation . model_name } ` } className = "rounded-md border border-gray-200 p-3 dark:border-gray-700" >
170+ < p className = "text-sm font-semibold text-gray-900 dark:text-white" >
171+ { invocation . model_name } ({ invocation . model_tier } )
172+ </ p >
173+ { invocation . prompt_excerpt && (
174+ < p className = "mt-1 text-xs text-gray-600 dark:text-gray-300" >
175+ Prompt: { invocation . prompt_excerpt . slice ( 0 , 220 ) }
176+ { invocation . prompt_excerpt . length > 220 ? '…' : '' }
177+ </ p >
178+ ) }
179+ { invocation . completion_excerpt && (
180+ < p className = "mt-1 text-xs text-gray-600 dark:text-gray-300" >
181+ Completion: { invocation . completion_excerpt . slice ( 0 , 220 ) }
182+ { invocation . completion_excerpt . length > 220 ? '…' : '' }
183+ </ p >
184+ ) }
185+ </ li >
186+ ) ) }
187+ </ ul >
188+ ) }
189+ </ Card >
190+ </ section >
191+
192+ < Card className = "p-4" >
193+ < h2 className = "mb-3 text-lg font-semibold text-gray-900 dark:text-white" > Decision outcome</ h2 >
194+ < p className = "text-sm text-gray-700 dark:text-gray-300" >
195+ { data . decision_outcome ?? data . spans . find ( ( span ) => span . decision_outcome ) ?. decision_outcome ?? 'Not captured' }
196+ </ p >
197+ < p className = "mt-1 text-sm text-gray-600 dark:text-gray-400" >
198+ Confidence:{ ' ' }
199+ { typeof data . decision_confidence === 'number'
200+ ? `${ Math . round ( data . decision_confidence * 100 ) } %`
201+ : typeof data . spans . find ( ( span ) => typeof span . confidence_score === 'number' ) ?. confidence_score === 'number'
202+ ? `${ Math . round ( ( data . spans . find ( ( span ) => typeof span . confidence_score === 'number' ) ?. confidence_score ?? 0 ) * 100 ) } %`
203+ : 'N/A' }
204+ </ p >
205+ </ Card >
103206 </ >
104207 ) }
105208 </ div >
0 commit comments