@@ -16,10 +16,56 @@ const logger = createLogger('WorkflowExecutionStatusAPI')
1616
1717type LogStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'
1818
19+ interface TraceSpanShape {
20+ blockId ?: string
21+ output ?: Record < string , unknown >
22+ children ?: TraceSpanShape [ ]
23+ }
24+
1925interface ExecutionDataShape {
2026 finalOutput ?: { error ?: string } & Record < string , unknown >
2127 error ?: { message ?: string } | string
2228 completionFailure ?: string
29+ traceSpans ?: TraceSpanShape [ ]
30+ }
31+
32+ function collectBlockOutputs ( spans : TraceSpanShape [ ] | undefined ) : Map < string , unknown > {
33+ const map = new Map < string , unknown > ( )
34+ const visit = ( list ?: TraceSpanShape [ ] ) : void => {
35+ if ( ! list ) return
36+ for ( const span of list ) {
37+ if ( span . blockId && span . output !== undefined && ! map . has ( span . blockId ) ) {
38+ map . set ( span . blockId , span . output )
39+ }
40+ if ( span . children ) visit ( span . children )
41+ }
42+ }
43+ visit ( spans )
44+ return map
45+ }
46+
47+ function resolvePath ( value : unknown , path : string [ ] ) : unknown {
48+ let current : unknown = value
49+ for ( const segment of path ) {
50+ if ( current == null || typeof current !== 'object' ) return undefined
51+ current = ( current as Record < string , unknown > ) [ segment ]
52+ }
53+ return current
54+ }
55+
56+ function pickSelectedOutputs (
57+ selectedOutputs : string [ ] ,
58+ blockOutputs : Map < string , unknown >
59+ ) : Record < string , unknown > {
60+ const out : Record < string , unknown > = { }
61+ for ( const selector of selectedOutputs ) {
62+ const [ head , ...rest ] = selector . split ( '.' )
63+ if ( ! head ) continue
64+ if ( ! blockOutputs . has ( head ) ) continue
65+ const blockValue = blockOutputs . get ( head )
66+ out [ selector ] = rest . length === 0 ? blockValue : resolvePath ( blockValue , rest )
67+ }
68+ return out
2369}
2470
2571function pickEarliestPausePoint ( points : PausePoint [ ] ) : PausePoint | null {
@@ -60,7 +106,7 @@ export const GET = withRouteHandler(
60106 const parsed = await parseRequest ( getWorkflowExecutionContract , request , context )
61107 if ( ! parsed . success ) return parsed . response
62108 const { id : workflowId , executionId } = parsed . data . params
63- const { includeOutput } = parsed . data . query
109+ const { includeOutput, selectedOutputs } = parsed . data . query
64110
65111 const access = await validateWorkflowAccess ( request , workflowId , false )
66112 if ( access . error ) {
@@ -137,9 +183,16 @@ export const GET = withRouteHandler(
137183
138184 const error = status === 'failed' ? extractError ( logRow . executionData ) : null
139185
186+ const executionData = logRow . executionData as ExecutionDataShape | undefined
187+
140188 const finalOutput =
141- includeOutput && status === 'completed' && logRow . executionData
142- ? ( ( logRow . executionData as ExecutionDataShape ) . finalOutput ?? null )
189+ includeOutput && status === 'completed' && executionData
190+ ? ( executionData . finalOutput ?? null )
191+ : null
192+
193+ const blockOutputs =
194+ selectedOutputs . length > 0
195+ ? pickSelectedOutputs ( selectedOutputs , collectBlockOutputs ( executionData ?. traceSpans ) )
143196 : null
144197
145198 const response : WorkflowExecutionStatusResponse = {
@@ -155,6 +208,7 @@ export const GET = withRouteHandler(
155208 cost,
156209 error,
157210 finalOutput,
211+ blockOutputs,
158212 }
159213
160214 logger . debug ( 'Fetched execution status' , {
0 commit comments