@@ -88,31 +88,55 @@ const calculateAgentCompletion = (analysisItem: any, isRebalanceAnalysis: boolea
8888 let totalAgents = 0 ;
8989 let completedAgents = 0 ;
9090
91- // Primary method: Check workflow_steps structure (similar to GitHub Actions)
92- // This is the most reliable way as it mirrors the workflow visualization
93- if ( analysisItem . full_analysis ?. workflow_steps ) {
94- const workflowSteps = analysisItem . full_analysis . workflow_steps ;
95-
96- // Iterate through all phases and count agents
97- Object . keys ( workflowSteps ) . forEach ( phase => {
98- // Skip portfolio phase for rebalance analyses
99- if ( phase === 'portfolio' && isRebalanceAnalysis ) {
100- return ;
101- }
102-
103- const phaseData = workflowSteps [ phase ] ;
104- if ( phaseData ?. agents && Array . isArray ( phaseData . agents ) ) {
105- phaseData . agents . forEach ( ( agent : any ) => {
106- totalAgents ++ ;
107- // Check if agent is completed (similar to GitHub Actions step status)
108- if ( agent . status === 'completed' || agent . status === 'complete' ) {
109- completedAgents ++ ;
110- }
111- } ) ;
91+ const rawWorkflowSteps = analysisItem . full_analysis ?. workflow_steps || analysisItem . full_analysis ?. workflowSteps ;
92+
93+ const countAgents = ( agents : any ) => {
94+ if ( ! agents ) return ;
95+ const list = Array . isArray ( agents )
96+ ? agents
97+ : typeof agents === 'object'
98+ ? Object . values ( agents )
99+ : [ ] ;
100+
101+ list . forEach ( ( agent : any ) => {
102+ if ( ! agent ) return ;
103+ totalAgents ++ ;
104+ const status = typeof agent === 'object' ? agent . status : undefined ;
105+ const normalizedStatus = typeof status === 'string' ? status . toLowerCase ( ) : '' ;
106+ if ( [ 'completed' , 'complete' , 'success' , 'done' ] . includes ( normalizedStatus ) ) {
107+ completedAgents ++ ;
112108 }
113109 } ) ;
114-
115- // Return percentage if we found agents
110+ } ;
111+
112+ const shouldSkipPhase = ( phaseName : string ) => {
113+ if ( ! phaseName ) return false ;
114+ if ( ! isRebalanceAnalysis ) return false ;
115+ const normalized = phaseName . toString ( ) . toLowerCase ( ) ;
116+ return normalized . includes ( 'portfolio' ) ;
117+ } ;
118+
119+ if ( rawWorkflowSteps ) {
120+ if ( Array . isArray ( rawWorkflowSteps ) ) {
121+ rawWorkflowSteps . forEach ( ( step : any ) => {
122+ const phaseName = step ?. id || step ?. name || '' ;
123+ if ( shouldSkipPhase ( phaseName ) ) {
124+ return ;
125+ }
126+ countAgents ( step ?. agents ) ;
127+ } ) ;
128+ } else if ( typeof rawWorkflowSteps === 'object' ) {
129+ Object . keys ( rawWorkflowSteps ) . forEach ( ( phase ) => {
130+ if ( shouldSkipPhase ( phase ) ) {
131+ return ;
132+ }
133+ const phaseData = rawWorkflowSteps [ phase ] ;
134+ if ( phaseData ?. agents ) {
135+ countAgents ( phaseData . agents ) ;
136+ }
137+ } ) ;
138+ }
139+
116140 if ( totalAgents > 0 ) {
117141 return Math . round ( ( completedAgents / totalAgents ) * 100 ) ;
118142 }
0 commit comments