@@ -490,112 +490,126 @@ class ParallelizationAnalysisDemo {
490490 }
491491
492492 generatePerspectiveAnalysis ( perspective , topic , result ) {
493- // Generate mock analysis based on perspective characteristics
494- const analyses = {
495- analytical : ( topic ) => ( {
496- title : 'Data-Driven Analysis' ,
497- keyPoints : [
498- 'Market research indicates significant growth potential' ,
499- 'Statistical trends show 40% year-over-year increases' ,
500- 'Quantitative models predict positive ROI within 18 months' ,
501- 'Benchmark analysis reveals competitive advantages'
502- ] ,
503- insights : 'Evidence-based evaluation shows strong fundamentals with measurable success metrics.' ,
504- recommendations : [
505- 'Implement robust analytics tracking' ,
506- 'Establish KPI baselines and monitoring' ,
507- 'Conduct A/B testing for optimization'
508- ] ,
509- confidence : 0.85
510- } ) ,
511-
512- creative : ( topic ) => ( {
513- title : 'Innovative Exploration' ,
514- keyPoints : [
515- 'Blue ocean opportunities in emerging markets' ,
516- 'Disruptive potential through novel approaches' ,
517- 'Cross-industry inspiration from unexpected sources' ,
518- 'Future-forward thinking beyond current paradigms'
519- ] ,
520- insights : 'Innovative approaches could revolutionize the traditional landscape and create new value propositions.' ,
521- recommendations : [
522- 'Prototype unconventional solutions' ,
523- 'Explore adjacent market opportunities' ,
524- 'Foster innovation through experimentation'
525- ] ,
526- confidence : 0.78
527- } ) ,
528-
529- practical : ( topic ) => ( {
530- title : 'Implementation Focus' ,
531- keyPoints : [
532- 'Clear roadmap with achievable milestones' ,
533- 'Resource requirements are manageable' ,
534- 'Technical feasibility confirmed by experts' ,
535- 'Operational processes can scale effectively'
536- ] ,
537- insights : 'Practical implementation is feasible with proper planning and resource allocation.' ,
538- recommendations : [
539- 'Develop phased rollout strategy' ,
540- 'Allocate adequate resources and timeline' ,
541- 'Establish clear success criteria'
542- ] ,
543- confidence : 0.92
544- } ) ,
545-
546- critical : ( topic ) => ( {
547- title : 'Risk Assessment' ,
548- keyPoints : [
549- 'Market volatility poses significant challenges' ,
550- 'Regulatory compliance requires careful attention' ,
551- 'Competitive responses could erode advantages' ,
552- 'Technical dependencies create vulnerability'
553- ] ,
554- insights : 'Several critical risks must be mitigated before proceeding with full implementation.' ,
555- recommendations : [
556- 'Develop comprehensive risk mitigation plan' ,
557- 'Establish contingency strategies' ,
558- 'Monitor regulatory changes closely'
559- ] ,
560- confidence : 0.88
561- } ) ,
562-
563- strategic : ( topic ) => ( {
564- title : 'Long-term Strategy' ,
565- keyPoints : [
566- 'Aligns with 5-year organizational vision' ,
567- 'Creates sustainable competitive moats' ,
568- 'Positions for future market expansion' ,
569- 'Builds platform for additional opportunities'
570- ] ,
571- insights : 'Strategic positioning provides long-term value creation and competitive advantage.' ,
572- recommendations : [
573- 'Integrate with broader strategic initiatives' ,
574- 'Build capabilities for future expansion' ,
575- 'Establish strategic partnerships'
576- ] ,
577- confidence : 0.89
578- } ) ,
579-
580- user_centered : ( topic ) => ( {
581- title : 'Human Impact Analysis' ,
582- keyPoints : [
583- 'Significant positive impact on user experience' ,
584- 'Accessibility considerations well-addressed' ,
585- 'Stakeholder feedback overwhelmingly positive' ,
586- 'Social impact creates meaningful value'
587- ] ,
588- insights : 'Human-centered approach ensures widespread adoption and positive societal impact.' ,
589- recommendations : [
590- 'Prioritize user feedback in development' ,
591- 'Ensure accessibility across all features' ,
592- 'Measure and optimize user satisfaction'
593- ] ,
594- confidence : 0.91
595- } )
596- } ;
493+ // Extract real LLM content from the API response
494+ const perspectiveId = perspective . id ;
495+
496+ // Find matching task from parallel_tasks array
497+ let taskResult = null ;
498+ if ( result && result . result && Array . isArray ( result . result . parallel_tasks ) ) {
499+ taskResult = result . result . parallel_tasks . find ( t => t . perspective === perspectiveId ) ;
500+ // Fallback: match by index if perspective field doesn't match
501+ if ( ! taskResult ) {
502+ taskResult = result . result . parallel_tasks [ 0 ] ;
503+ }
504+ }
505+
506+ const llmText = taskResult ? taskResult . result : ( result && result . result && result . result . aggregated_result ) || '' ;
507+
508+ if ( ! llmText ) {
509+ // Fallback if no LLM result available
510+ return {
511+ title : `${ perspective . name } Analysis` ,
512+ keyPoints : [ 'No analysis content received from server' ] ,
513+ insights : 'The API call completed but returned no content for this perspective.' ,
514+ recommendations : [ 'Try again or check server logs' ] ,
515+ confidence : 0
516+ } ;
517+ }
597518
598- return ( analyses [ perspective . id ] && analyses [ perspective . id ] ( topic ) ) || analyses . analytical ( topic ) ;
519+ // Parse the LLM markdown into structured analysis
520+ return this . parseLlmResponse ( perspective , llmText ) ;
521+ }
522+
523+ parseLlmResponse ( perspective , text ) {
524+ // Extract sections from LLM markdown response
525+ const lines = text . split ( '\n' ) . filter ( l => l . trim ( ) ) ;
526+
527+ // Extract title from first heading or first bold line
528+ let title = `${ perspective . name } Analysis` ;
529+ for ( const line of lines ) {
530+ const headingMatch = line . match ( / ^ \* \* ( .+ ?) \* \* $ / ) || line . match ( / ^ # + \s + ( .+ ) / ) ;
531+ if ( headingMatch ) {
532+ title = headingMatch [ 1 ] . replace ( / \* \* / g, '' ) ;
533+ break ;
534+ }
535+ }
536+
537+ // Extract bullet points as key points (first 6)
538+ const keyPoints = [ ] ;
539+ for ( const line of lines ) {
540+ const bulletMatch = line . match ( / ^ \s * [ - * ] \s + \* \* ( .+ ?) \* \* [: \s] * ( .* ) / ) ;
541+ if ( bulletMatch ) {
542+ keyPoints . push ( bulletMatch [ 1 ] + ( bulletMatch [ 2 ] ? ': ' + bulletMatch [ 2 ] : '' ) ) ;
543+ } else {
544+ const simpleBullet = line . match ( / ^ \s * [ - * ] \s + ( .+ ) / ) ;
545+ if ( simpleBullet && keyPoints . length < 6 ) {
546+ keyPoints . push ( simpleBullet [ 1 ] . replace ( / \* \* / g, '' ) ) ;
547+ }
548+ }
549+ if ( keyPoints . length >= 6 ) break ;
550+ }
551+
552+ // If no bullet points found, extract first few sentences
553+ if ( keyPoints . length === 0 ) {
554+ const sentences = text . replace ( / \* \* / g, '' ) . replace ( / # + \s + / g, '' ) . split ( / [ . ! ? ] + / ) . filter ( s => s . trim ( ) . length > 20 ) ;
555+ for ( let i = 0 ; i < Math . min ( 4 , sentences . length ) ; i ++ ) {
556+ keyPoints . push ( sentences [ i ] . trim ( ) ) ;
557+ }
558+ }
559+
560+ // Extract insights from conclusion or findings sections
561+ let insights = '' ;
562+ const conclusionMatch = text . match ( / \* \* C o n c l u s i o n \* \* \s * \n + ( [ \s \S ] * ?) (? = \n \* \* | $ ) / i) ;
563+ const findingsMatch = text . match ( / \* \* F i n d i n g s \* \* \s * \n + ( [ \s \S ] * ?) (? = \n \* \* | $ ) / i) ;
564+ if ( conclusionMatch ) {
565+ insights = conclusionMatch [ 1 ] . replace ( / \* \* / g, '' ) . replace ( / \n / g, ' ' ) . trim ( ) . slice ( 0 , 300 ) ;
566+ } else if ( findingsMatch ) {
567+ insights = findingsMatch [ 1 ] . replace ( / \* \* / g, '' ) . replace ( / \n / g, ' ' ) . trim ( ) . slice ( 0 , 300 ) ;
568+ } else {
569+ // Use a middle paragraph as insights
570+ const paragraphs = text . split ( / \n \n + / ) . filter ( p => p . trim ( ) . length > 50 && ! p . startsWith ( '#' ) && ! p . startsWith ( '*' ) ) ;
571+ if ( paragraphs . length > 1 ) {
572+ insights = paragraphs [ Math . floor ( paragraphs . length / 2 ) ] . replace ( / \* \* / g, '' ) . trim ( ) . slice ( 0 , 300 ) ;
573+ } else if ( paragraphs . length === 1 ) {
574+ insights = paragraphs [ 0 ] . replace ( / \* \* / g, '' ) . trim ( ) . slice ( 0 , 300 ) ;
575+ }
576+ }
577+
578+ // Extract recommendations
579+ const recommendations = [ ] ;
580+ const recMatch = text . match ( / \* \* R e c o m m e n d a t i o n [ s ] ? \* \* \s * \n + ( [ \s \S ] * ?) (? = \n \* \* | $ ) / i) ;
581+ if ( recMatch ) {
582+ const recLines = recMatch [ 1 ] . split ( '\n' ) ;
583+ for ( const line of recLines ) {
584+ const bullet = line . match ( / ^ \s * [ - * \d . ] + \s + \* \* ( .+ ?) \* \* [: \s] * ( .* ) / ) ;
585+ if ( bullet ) {
586+ recommendations . push ( bullet [ 1 ] + ( bullet [ 2 ] ? ': ' + bullet [ 2 ] : '' ) ) ;
587+ } else {
588+ const simpleBullet = line . match ( / ^ \s * [ - * \d . ] + \s + ( .+ ) / ) ;
589+ if ( simpleBullet ) {
590+ recommendations . push ( simpleBullet [ 1 ] . replace ( / \* \* / g, '' ) ) ;
591+ }
592+ }
593+ if ( recommendations . length >= 4 ) break ;
594+ }
595+ }
596+
597+ // Fallback recommendations from key points if none found
598+ if ( recommendations . length === 0 && keyPoints . length > 2 ) {
599+ recommendations . push ( ...keyPoints . slice ( - 2 ) ) ;
600+ }
601+
602+ // Estimate confidence based on content richness
603+ const wordCount = text . split ( / \s + / ) . length ;
604+ const confidence = Math . min ( 0.95 , 0.5 + ( wordCount / 2000 ) * 0.45 ) ;
605+
606+ return {
607+ title,
608+ keyPoints : keyPoints . length > 0 ? keyPoints : [ 'Analysis completed' ] ,
609+ insights : insights || 'Analysis completed successfully. See key points for details.' ,
610+ recommendations : recommendations . length > 0 ? recommendations : [ 'Review the full analysis for detailed recommendations' ] ,
611+ confidence
612+ } ;
599613 }
600614
601615 displayPerspectiveResult ( perspectiveId , analysis ) {
@@ -655,28 +669,61 @@ class ParallelizationAnalysisDemo {
655669 }
656670
657671 generateAggregatedInsights ( ) {
658- return [
659- {
660- title : 'Convergent Findings' ,
661- content : 'All perspectives agree on the fundamental viability and positive potential of the analyzed topic.' ,
662- type : 'consensus'
663- } ,
664- {
665- title : 'Divergent Views' ,
666- content : 'Risk assessment varies significantly between perspectives, with critical analysis highlighting more concerns than creative exploration.' ,
672+ // Build aggregated insights from actual analysis results
673+ const results = Array . from ( this . analysisResults . values ( ) ) ;
674+ const analyses = results . map ( r => r . analysis ) . filter ( Boolean ) ;
675+
676+ if ( analyses . length === 0 ) {
677+ return [ { title : 'No Results' , content : 'No perspective analyses were completed.' , type : 'info' } ] ;
678+ }
679+
680+ // Collect all key points across perspectives
681+ const allKeyPoints = analyses . flatMap ( a => a . keyPoints || [ ] ) ;
682+ const allRecommendations = analyses . flatMap ( a => a . recommendations || [ ] ) ;
683+ const perspectiveNames = results . map ( r => {
684+ const p = this . perspectives [ r . perspectiveId ] ;
685+ return p ? p . name : r . perspectiveId ;
686+ } ) ;
687+
688+ const insights = [ ] ;
689+
690+ // Summarize key findings from all perspectives
691+ insights . push ( {
692+ title : 'Key Findings Across Perspectives' ,
693+ content : `${ analyses . length } perspectives analyzed (${ perspectiveNames . join ( ', ' ) } ). ` +
694+ `Identified ${ allKeyPoints . length } key points: ${ allKeyPoints . slice ( 0 , 3 ) . join ( '; ' ) } ${ allKeyPoints . length > 3 ? '...' : '' } .` ,
695+ type : 'consensus'
696+ } ) ;
697+
698+ // Insights summary
699+ const insightTexts = analyses . map ( a => a . insights ) . filter ( Boolean ) ;
700+ if ( insightTexts . length > 0 ) {
701+ insights . push ( {
702+ title : 'Perspective Insights' ,
703+ content : insightTexts . map ( ( t , i ) => `${ perspectiveNames [ i ] } : ${ t . slice ( 0 , 150 ) } ` ) . join ( ' | ' ) ,
667704 type : 'divergence'
668- } ,
669- {
670- title : 'Implementation Priority' ,
671- content : 'Practical and strategic perspectives suggest a phased approach with clear milestones and risk mitigation.' ,
672- type : 'synthesis'
673- } ,
674- {
675- title : 'Success Factors' ,
676- content : 'User-centered design, data-driven decisions, and innovative thinking emerge as key success drivers.' ,
705+ } ) ;
706+ }
707+
708+ // Recommendations synthesis
709+ if ( allRecommendations . length > 0 ) {
710+ insights . push ( {
711+ title : 'Combined Recommendations' ,
712+ content : allRecommendations . slice ( 0 , 5 ) . join ( '. ' ) + '.' ,
677713 type : 'synthesis'
678- }
679- ] ;
714+ } ) ;
715+ }
716+
717+ // Confidence summary
718+ const avgConfidence = analyses . reduce ( ( sum , a ) => sum + ( a . confidence || 0 ) , 0 ) / analyses . length ;
719+ insights . push ( {
720+ title : 'Confidence Assessment' ,
721+ content : `Average confidence across perspectives: ${ Math . round ( avgConfidence * 100 ) } %. ` +
722+ analyses . map ( ( a , i ) => `${ perspectiveNames [ i ] } : ${ Math . round ( ( a . confidence || 0 ) * 100 ) } %` ) . join ( ', ' ) + '.' ,
723+ type : 'synthesis'
724+ } ) ;
725+
726+ return insights ;
680727 }
681728
682729 displayAggregatedInsights ( insights ) {
0 commit comments