LinkedinMonitor / run_agentic_pipeline.py
GuglielmoTor's picture
Update run_agentic_pipeline.py
708a26e verified
raw
history blame
10.5 kB
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
)