Spaces:
Running
Running
Update run_agentic_pipeline.py
Browse files- run_agentic_pipeline.py +129 -77
run_agentic_pipeline.py
CHANGED
|
@@ -1,106 +1,158 @@
|
|
| 1 |
-
# run_agentic_pipeline.py
|
| 2 |
-
"""
|
| 3 |
-
This module is responsible for loading and displaying pre-computed AI analysis
|
| 4 |
-
results (reports and OKRs) that have been fetched from Bubble.io. It does not
|
| 5 |
-
perform any new analysis.
|
| 6 |
-
"""
|
| 7 |
-
import logging
|
| 8 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
-
#
|
|
|
|
| 11 |
try:
|
| 12 |
from ui.insights_ui_generator import (
|
| 13 |
-
|
| 14 |
extract_key_results_for_selection,
|
| 15 |
format_single_okr_for_display
|
| 16 |
)
|
| 17 |
-
from services.report_data_handler import fetch_and_reconstruct_data_from_bubble
|
| 18 |
AGENTIC_MODULES_LOADED = True
|
| 19 |
except ImportError as e:
|
| 20 |
logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
|
| 21 |
AGENTIC_MODULES_LOADED = False
|
| 22 |
-
|
| 23 |
-
def format_report_to_markdown(report_string): return "Agentic modules not loaded. Report unavailable."
|
| 24 |
def extract_key_results_for_selection(okrs_dict): return []
|
| 25 |
def format_single_okr_for_display(okr_data, **kwargs): return "Agentic modules not loaded. OKR display unavailable."
|
| 26 |
-
def fetch_and_reconstruct_data_from_bubble(df): return None
|
| 27 |
|
| 28 |
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
"""
|
| 31 |
-
Loads pre-computed agentic
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
"""
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
#
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
)
|
| 46 |
|
| 47 |
if not AGENTIC_MODULES_LOADED:
|
| 48 |
-
|
| 49 |
-
error_updates =
|
| 50 |
-
error_updates[-1] = "Errore: Moduli AI non caricati."
|
| 51 |
return tuple(error_updates)
|
| 52 |
|
| 53 |
-
|
| 54 |
-
agentic_data_df = current_token_state.get('bubble_agentic_analysis_data')
|
| 55 |
-
|
| 56 |
-
if agentic_data_df is None or agentic_data_df.empty:
|
| 57 |
-
logging.warning("No agentic analysis data found in the application state.")
|
| 58 |
-
return initial_yield_updates
|
| 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 |
-
return (
|
| 98 |
-
agentic_report_md_update,
|
| 99 |
-
key_results_cbg_update,
|
| 100 |
-
okr_detail_display_md_update,
|
| 101 |
-
reconstructed_data, # Store the full reconstructed data dict in the state
|
| 102 |
-
[], # Reset the selected KR IDs state
|
| 103 |
-
krs_for_selection_state_update, # Update the state with all available KRs
|
| 104 |
-
"Stato: Dati di analisi caricati correttamente da Bubble" # Final status message
|
| 105 |
-
)
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import json
|
| 4 |
+
import logging
|
| 5 |
+
from typing import Dict, Any, List, Optional
|
| 6 |
|
| 7 |
+
# Assuming these functions are in ui.insights_ui_generator
|
| 8 |
+
# Make sure to have this file updated with the new `format_report_for_display` function
|
| 9 |
try:
|
| 10 |
from ui.insights_ui_generator import (
|
| 11 |
+
format_report_for_display,
|
| 12 |
extract_key_results_for_selection,
|
| 13 |
format_single_okr_for_display
|
| 14 |
)
|
|
|
|
| 15 |
AGENTIC_MODULES_LOADED = True
|
| 16 |
except ImportError as e:
|
| 17 |
logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
|
| 18 |
AGENTIC_MODULES_LOADED = False
|
| 19 |
+
def format_report_for_display(report_data): return "Agentic modules not loaded. Report unavailable."
|
|
|
|
| 20 |
def extract_key_results_for_selection(okrs_dict): return []
|
| 21 |
def format_single_okr_for_display(okr_data, **kwargs): return "Agentic modules not loaded. OKR display unavailable."
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
+
logger = logging.getLogger(__name__)
|
| 25 |
+
|
| 26 |
+
def load_and_display_agentic_results(
|
| 27 |
+
token_state: dict,
|
| 28 |
+
orchestration_raw_results_st: Optional[dict],
|
| 29 |
+
selected_key_result_ids_st: List[str],
|
| 30 |
+
key_results_for_selection_st: List[dict]
|
| 31 |
+
):
|
| 32 |
"""
|
| 33 |
+
Loads pre-computed agentic results from the state, populates the report library dropdown,
|
| 34 |
+
and displays the latest report and its associated OKRs by default.
|
| 35 |
+
|
| 36 |
+
This function is designed to work with the UI defined in app.py and expects a specific
|
| 37 |
+
order of outputs.
|
| 38 |
+
|
| 39 |
+
Args:
|
| 40 |
+
token_state: The main state dictionary containing the bubble_agentic_analysis_data DataFrame.
|
| 41 |
+
orchestration_raw_results_st: The state holding the raw JSON/dict of the currently displayed report.
|
| 42 |
+
selected_key_result_ids_st: The state for the IDs of selected Key Results.
|
| 43 |
+
key_results_for_selection_st: The state holding the list of all available Key Results for selection.
|
| 44 |
+
|
| 45 |
+
Returns:
|
| 46 |
+
A tuple of Gradio updates matching the `agentic_display_outputs` list in `app.py`.
|
| 47 |
"""
|
| 48 |
+
# Default empty/initial return values that match the output components list
|
| 49 |
+
# The order is critical:
|
| 50 |
+
# 1. agentic_report_display_md
|
| 51 |
+
# 2. report_selector_dd
|
| 52 |
+
# 3. key_results_cbg
|
| 53 |
+
# 4. okr_detail_display_md
|
| 54 |
+
# 5. orchestration_raw_results_st
|
| 55 |
+
# 6. selected_key_result_ids_st
|
| 56 |
+
# 7. key_results_for_selection_st
|
| 57 |
+
# 8. agentic_pipeline_status_md
|
| 58 |
+
initial_updates = (
|
| 59 |
+
"No agentic analysis data found in Bubble.",
|
| 60 |
+
gr.update(choices=[], value=None, interactive=False),
|
| 61 |
+
gr.update(choices=[], value=[], interactive=False),
|
| 62 |
+
"No OKRs to display.",
|
| 63 |
+
None,
|
| 64 |
+
[],
|
| 65 |
+
[],
|
| 66 |
+
"Status: No agentic analysis data found."
|
| 67 |
)
|
| 68 |
|
| 69 |
if not AGENTIC_MODULES_LOADED:
|
| 70 |
+
error_updates = list(initial_updates)
|
| 71 |
+
error_updates[7] = "Status: Critical module import error."
|
|
|
|
| 72 |
return tuple(error_updates)
|
| 73 |
|
| 74 |
+
agentic_df = token_state.get("bubble_agentic_analysis_data")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
+
if agentic_df is None or agentic_df.empty:
|
| 77 |
+
logger.warning("Agentic analysis DataFrame is missing or empty in the state.")
|
| 78 |
+
return initial_updates
|
| 79 |
|
| 80 |
+
try:
|
| 81 |
+
# --- 1. Prepare Report Library ---
|
| 82 |
+
if 'Created Date' not in agentic_df.columns or '_id' not in agentic_df.columns:
|
| 83 |
+
raise KeyError("Required columns ('Created Date', '_id') not found in agentic data.")
|
| 84 |
+
|
| 85 |
+
# Ensure 'Created Date' is datetime, then sort to get the latest report first
|
| 86 |
+
agentic_df['Created Date'] = pd.to_datetime(agentic_df['Created Date'])
|
| 87 |
+
agentic_df = agentic_df.sort_values(by='Created Date', ascending=False).reset_index(drop=True)
|
| 88 |
+
|
| 89 |
+
# Create choices for the dropdown: (Display Name, Unique ID)
|
| 90 |
+
report_choices = [
|
| 91 |
+
(f"{row.get('report_type', 'Report')} - {row['Created Date'].strftime('%Y-%m-%d %H:%M')}", row['_id'])
|
| 92 |
+
for _, row in agentic_df.iterrows()
|
| 93 |
+
]
|
| 94 |
+
|
| 95 |
+
if not report_choices:
|
| 96 |
+
return initial_updates
|
| 97 |
|
| 98 |
+
# --- 2. Load and Display the Latest Report by Default ---
|
| 99 |
+
latest_report_series = agentic_df.iloc[0]
|
| 100 |
+
latest_report_id = latest_report_series['_id']
|
| 101 |
+
|
| 102 |
+
# Format the latest report's content for the Markdown display
|
| 103 |
+
report_display_md = format_report_for_display(latest_report_series)
|
| 104 |
+
|
| 105 |
+
# Create the update for the report library dropdown
|
| 106 |
+
report_selector_update = gr.update(choices=report_choices, value=latest_report_id, interactive=True)
|
| 107 |
|
| 108 |
+
# --- 3. Load and Prepare OKRs from the Latest Report ---
|
| 109 |
+
raw_results_state = None
|
| 110 |
+
okr_details_md = "No OKRs found in the latest report."
|
| 111 |
+
key_results_cbg_update = gr.update(choices=[], value=[], interactive=False)
|
| 112 |
+
all_krs_state = []
|
| 113 |
+
|
| 114 |
+
# Assumption: The full JSON from the agent is stored in 'orchestration_results'.
|
| 115 |
+
if 'orchestration_results' in latest_report_series and pd.notna(latest_report_series['orchestration_results']):
|
| 116 |
+
try:
|
| 117 |
+
raw_results_state = json.loads(latest_report_series['orchestration_results'])
|
| 118 |
+
except json.JSONDecodeError:
|
| 119 |
+
logger.error(f"Failed to parse 'orchestration_results' JSON for report ID {latest_report_id}")
|
| 120 |
+
raw_results_state = {} # Avoid crashing, proceed with empty data
|
| 121 |
+
else:
|
| 122 |
+
raw_results_state = {}
|
| 123 |
|
| 124 |
+
actionable_okrs_dict = raw_results_state.get("actionable_okrs", {})
|
| 125 |
+
|
| 126 |
+
if actionable_okrs_dict:
|
| 127 |
+
all_krs_state = extract_key_results_for_selection(actionable_okrs_dict)
|
| 128 |
+
if all_krs_state:
|
| 129 |
+
kr_choices = [(kr['kr_description'], kr['unique_kr_id']) for kr in all_krs_state]
|
| 130 |
+
key_results_cbg_update = gr.update(choices=kr_choices, value=[], interactive=True)
|
| 131 |
+
|
| 132 |
+
# Format all OKRs for initial display
|
| 133 |
+
okrs_list = actionable_okrs_dict.get("okrs", [])
|
| 134 |
+
output_md_parts = [
|
| 135 |
+
format_single_okr_for_display(okr_data, okr_main_index=okr_idx)
|
| 136 |
+
for okr_idx, okr_data in enumerate(okrs_list)
|
| 137 |
+
]
|
| 138 |
+
okr_details_md = "\n\n---\n\n".join(output_md_parts) if output_md_parts else okr_details_md
|
| 139 |
|
| 140 |
+
status_update = f"Status: Loaded {len(agentic_df)} reports. Displaying the latest from {latest_report_series['Created Date'].strftime('%Y-%m-%d')}."
|
| 141 |
+
|
| 142 |
+
return (
|
| 143 |
+
report_display_md,
|
| 144 |
+
report_selector_update,
|
| 145 |
+
key_results_cbg_update,
|
| 146 |
+
okr_details_md,
|
| 147 |
+
raw_results_state,
|
| 148 |
+
[], # Reset selected KRs
|
| 149 |
+
all_krs_state,
|
| 150 |
+
status_update
|
| 151 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
|
| 153 |
+
except Exception as e:
|
| 154 |
+
logger.error(f"Failed to process and display agentic results: {e}", exc_info=True)
|
| 155 |
+
error_updates = list(initial_updates)
|
| 156 |
+
error_updates[0] = f"An error occurred while loading reports: {e}"
|
| 157 |
+
error_updates[7] = f"Status: Error - {e}"
|
| 158 |
+
return tuple(error_updates)
|