File size: 10,493 Bytes
c0a4e63
0cfca76
 
 
8ed7829
6faec7c
fed5558
 
 
055c98e
 
0cfca76
055c98e
 
 
 
 
5f0b7f9
055c98e
708a26e
 
 
5f0b7f9
6faec7c
055c98e
0cfca76
 
6faec7c
8ed7829
6faec7c
 
0cfca76
 
6faec7c
 
0cfca76
 
6faec7c
8ed7829
708a26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0cfca76
708a26e
 
 
 
 
 
 
 
 
 
6086ed3
 
 
708a26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f0b7f9
0cfca76
5f0b7f9
0cfca76
6faec7c
0cfca76
5f0b7f9
0cfca76
 
6faec7c
0cfca76
 
 
 
6faec7c
 
0cfca76
 
 
5f0b7f9
d40cdca
708a26e
 
 
 
 
 
0cfca76
 
708a26e
 
 
 
 
0cfca76
5f0b7f9
6faec7c
 
 
708a26e
 
0cfca76
 
 
fed5558
 
 
 
 
 
 
 
 
6faec7c
fed5558
708a26e
 
0cfca76
6faec7c
fed5558
5f0b7f9
6faec7c
0cfca76
 
708a26e
 
 
 
 
 
 
 
 
 
0cfca76
6086ed3
0cfca76
 
708a26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import gradio as gr
import pandas as pd
import logging
from typing import Dict, Any, List, Optional

# Import the reconstruction function that now expects a cache dictionary
from services.report_data_handler import fetch_and_reconstruct_data_from_bubble

# UI formatting functions
try:
    from ui.insights_ui_generator import (
        format_report_for_display,
        extract_key_results_for_selection,
        format_single_okr_for_display
    )
    AGENTIC_MODULES_LOADED = True
except ImportError as e:
    logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
    AGENTIC_MODULES_LOADED = False
    def format_report_for_display(report_data): 
        # Ensure this placeholder returns a dictionary matching the expected structure
        return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
    def extract_key_results_for_selection(okrs_dict): return []
    def format_single_okr_for_display(okr_data, **kwargs): return "Agentic modules not loaded."

logger = logging.getLogger(__name__)

def load_and_display_agentic_results(token_state: dict, session_cache: dict):
    """
    Loads agentic results from state, populates the report library, and displays
    the LATEST report and its fully reconstructed OKRs by default, using a session-specific cache.

    Args:
        token_state: The main state dictionary with Bubble data.
        session_cache: The session-specific cache for reconstructed data.

    Returns:
        A tuple of Gradio updates, including the updated cache.
    """
    # Define placeholder content for empty or error states to match 10 outputs
    empty_header_html = """
        <div class="report-title">πŸ“Š Comprehensive Analysis Report</div>
        <div class="report-subtitle">AI-Generated Insights from Your LinkedIn Data</div>
        <div class="status-badge">Generated from Bubble.io</div>
        """
    empty_body_markdown_no_selection = """
        <div class="empty-state">
            <div class="empty-state-icon">πŸ“„</div>
            <div class="empty-state-title">No Report Selected</div>
            <div class="empty-state-description">
                Please select a report from the library above to view its detailed analysis and insights.
            </div>
        </div>
        """

    initial_updates = (
        gr.update(value="Status: No agentic analysis data found."), # 0: agentic_pipeline_status_md
        gr.update(choices=[], value=None, interactive=False),       # 1: report_selector_dd
        gr.update(choices=[], value=[], interactive=False),         # 2: key_results_cbg
        gr.update(value="No OKRs to display."),                     # 3: okr_detail_display_md
        gr.update(value=None),                                      # 4: orchestration_raw_results_st
        gr.update(value=[]),                                        # 5: selected_key_result_ids_st
        gr.update(value=[]),                                        # 6: key_results_for_selection_st
        gr.update(value=empty_header_html),                         # 7: report_header_html_display
        gr.update(value=empty_body_markdown_no_selection),         # 8: report_body_markdown_display
        gr.update(value=session_cache)                              # 9: reconstruction_cache_st
    )

    if not AGENTIC_MODULES_LOADED:
        logger.error("Agentic modules not loaded, returning placeholder updates.")
        # Ensure error updates match the 10-item signature
        error_header_html = '<div class="report-title">Error Loading Report</div><div class="report-subtitle">Agentic modules not loaded.</div><div class="status-badge">Error</div>'
        error_body_markdown = '<div class="empty-state"><div class="empty-state-icon">❌</div><div class="empty-state-title">Module Error</div><div class="empty-state-description">Agentic analysis modules could not be loaded. Report display unavailable.</div></div>'
        return (
            gr.update(value="Status: Critical module import error."), # 0
            gr.update(choices=[], value=None, interactive=False), # 1
            gr.update(choices=[], value=[], interactive=False), # 2
            gr.update(value="Agentic modules not loaded. No OKRs to display."), # 3
            gr.update(value=None), # 4
            gr.update(value=[]), # 5
            gr.update(value=[]), # 6
            gr.update(value=error_header_html), # 7
            gr.update(value=error_body_markdown), # 8
            gr.update(value=session_cache) # 9
        )

    agentic_df = token_state.get("bubble_agentic_analysis_data")

    if agentic_df is None or agentic_df.empty:
        logger.warning("Agentic analysis DataFrame is missing or empty.")
        return initial_updates

    try:
        if 'Created Date' not in agentic_df.columns or '_id' not in agentic_df.columns:
            raise KeyError("Required columns ('Created Date', '_id') not found.")
        
        agentic_df['Created Date'] = pd.to_datetime(agentic_df['Created Date'])
        agentic_df = agentic_df.sort_values(by='Created Date', ascending=False).reset_index(drop=True)
        
        report_choices = [(f"{row.get('report_type', 'Report')} - {row['Created Date'].strftime('%Y-%m-%d %H:%M')}", row['_id'])
                          for _, row in agentic_df.iterrows()]
        
        if not report_choices:
            return initial_updates

        quarterly_reports_df = agentic_df[agentic_df['report_type'] == 'Quarter'].copy()
        if quarterly_reports_df.empty:
            logger.warning("No quarterly reports found, falling back to latest available report.")
            latest_report_series = agentic_df.iloc[0] # Use the absolute latest if no quarterly
        else:
            latest_report_series = quarterly_reports_df.iloc[0]

        latest_report_id = latest_report_series['_id']
        
        # Split the formatted report content into header and body
        formatted_report_parts = format_report_for_display(latest_report_series)
        report_header_content = formatted_report_parts['header_html']
        report_body_content = formatted_report_parts['body_markdown']

        report_selector_update = gr.update(choices=report_choices, value=latest_report_id, interactive=True)

        # --- MODIFIED: Use the session cache for data reconstruction ---
        reconstructed_data, updated_cache = fetch_and_reconstruct_data_from_bubble(latest_report_series, session_cache)
        
        raw_results_state = None
        okr_details_md = "No OKRs found in the latest report."
        key_results_cbg_update = gr.update(choices=[], value=[], interactive=False)
        all_krs_state = []
        
        if reconstructed_data:
            raw_results_state = reconstructed_data
            actionable_okrs_dict = raw_results_state.get("actionable_okrs", {})
            if actionable_okrs_dict:
                all_krs_state = extract_key_results_for_selection(actionable_okrs_dict)
                if all_krs_state:
                    kr_choices = [(kr['kr_description'], kr['unique_kr_id']) for kr in all_krs_state]
                    key_results_cbg_update = gr.update(choices=kr_choices, value=[], interactive=True)
                    okrs_list = actionable_okrs_dict.get("okrs", [])
                    output_md_parts = [format_single_okr_for_display(okr, okr_main_index=i) for i, okr in enumerate(okrs_list)]
                    okr_details_md = "\n\n---\n\n".join(output_md_parts) if output_md_parts else okr_details_md
            else:
                logger.info(f"No actionable_okrs found in reconstructed data for report ID {latest_report_id}.")
        else:
            logger.error(f"Failed to reconstruct data for latest report ID {latest_report_id}")
            okr_details_md = "Error: Could not reconstruct OKR data for this report."

        status_update = f"Status: Loaded {len(agentic_df)} reports. Displaying latest from {latest_report_series['Created Date'].strftime('%Y-%m-%d')}."
        
        return (
            gr.update(value=status_update),           # 0: agentic_pipeline_status_md
            report_selector_update,                   # 1: report_selector_dd
            key_results_cbg_update,                   # 2: key_results_cbg
            gr.update(value=okr_details_md),          # 3: okr_detail_display_md
            gr.update(value=raw_results_state),       # 4: orchestration_raw_results_st
            gr.update(value=[]),                      # 5: selected_key_result_ids_st (always start empty for selection)
            gr.update(value=all_krs_state),           # 6: key_results_for_selection_st
            gr.update(value=report_header_content),   # 7: report_header_html_display
            gr.update(value=report_body_content),     # 8: report_body_markdown_display
            gr.update(value=updated_cache)            # 9: reconstruction_cache_st
        )

    except Exception as e:
        logger.error(f"Failed to process and display agentic results: {e}", exc_info=True)
        # Ensure error returns match the 10-item signature
        error_header_html = """
            <div class="report-title">⚠️ Error Loading Report</div>
            <div class="report-subtitle">An error occurred during data processing.</div>
            <div class="status-badge" style="background: #e74c3c;">Error</div>
            """
        error_body_markdown = f"""
            <div class="empty-state">
                <div class="empty-state-icon">🚨</div>
                <div class="empty-state-title">Report Loading Failed</div>
                <div class="empty-state-description">
                    An error occurred while loading or processing the report data: {e}.
                    Please try again or contact support if the issue persists.
                </div>
            </div>
            """
        return (
            gr.update(value=f"Status: An error occurred: {e}"), # 0
            gr.update(choices=[], value=None, interactive=False), # 1
            gr.update(choices=[], value=[], interactive=False), # 2
            gr.update(value="Error: Could not display OKRs due to an error."), # 3
            gr.update(value=None), # 4
            gr.update(value=[]), # 5
            gr.update(value=[]), # 6
            gr.update(value=error_header_html), # 7
            gr.update(value=error_body_markdown), # 8
            gr.update(value=session_cache) # 9
        )