Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -18,14 +18,14 @@ from config import (
|
|
| 18 |
BUBBLE_API_ENDPOINT_ENV_VAR
|
| 19 |
)
|
| 20 |
|
|
|
|
|
|
|
| 21 |
# UPDATED: Using the new data loading function from the refactored state manager
|
| 22 |
from services.state_manager import load_data_from_bubble
|
| 23 |
-
|
| 24 |
-
# Import UI generator functions (these are now passed to build_main_app_ui)
|
| 25 |
from ui.ui_generators import (
|
| 26 |
build_analytics_tab_plot_area,
|
| 27 |
-
build_home_tab_ui,
|
| 28 |
-
create_enhanced_report_tab,
|
| 29 |
BOMB_ICON, EXPLORE_ICON, FORMULA_ICON, ACTIVE_ICON
|
| 30 |
)
|
| 31 |
# NEW: Import the new OKR UI functions
|
|
@@ -33,9 +33,6 @@ from ui.okr_ui_generator import create_enhanced_okr_tab, format_okrs_for_enhance
|
|
| 33 |
from ui.analytics_plot_generator import update_analytics_plots_figures, create_placeholder_plot
|
| 34 |
from formulas import PLOT_FORMULAS
|
| 35 |
|
| 36 |
-
# NEW: Import UI enhancements from the new module
|
| 37 |
-
from ui.ui_main_page_enhancements import build_main_app_ui, update_report_display_enhanced
|
| 38 |
-
|
| 39 |
# --- CHATBOT MODULE IMPORTS ---
|
| 40 |
from features.chatbot.chatbot_prompts import get_initial_insight_prompt_and_suggestions
|
| 41 |
from features.chatbot.chatbot_handler import generate_llm_response
|
|
@@ -49,6 +46,8 @@ try:
|
|
| 49 |
# UI formatting functions
|
| 50 |
from ui.insights_ui_generator import (
|
| 51 |
format_report_for_display, # This will now return header HTML and body Markdown
|
|
|
|
|
|
|
| 52 |
)
|
| 53 |
AGENTIC_MODULES_LOADED = True
|
| 54 |
except ImportError as e:
|
|
@@ -77,15 +76,15 @@ except ImportError as e:
|
|
| 77 |
# matching the `outputs` in the .then() call later.
|
| 78 |
return (
|
| 79 |
gr.update(value="Modules not loaded."), # agentic_pipeline_status_md (0)
|
| 80 |
-
gr.update(choices=[], value=None),
|
| 81 |
-
gr.update(choices=[], value=[]),
|
| 82 |
-
gr.update(value="Modules not loaded."),
|
| 83 |
-
None,
|
| 84 |
-
[],
|
| 85 |
-
[],
|
| 86 |
-
gr.update(value=empty_header_html),
|
| 87 |
-
gr.update(value=empty_body_markdown),
|
| 88 |
-
{},
|
| 89 |
gr.update(value=get_initial_okr_display()), # NEW: enhanced_okr_display_html (10)
|
| 90 |
gr.update(value={}) # NEW: actionable_okrs_data_st (11)
|
| 91 |
)
|
|
@@ -96,97 +95,241 @@ except ImportError as e:
|
|
| 96 |
return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
|
| 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 |
-
# The event handlers are now set up *inside* build_main_app_ui,
|
| 148 |
-
# so these calls are no longer needed here.
|
| 149 |
|
| 150 |
if __name__ == "__main__":
|
| 151 |
-
# Enhanced startup logging
|
| 152 |
-
print("🚀 Starting LinkedIn Organization Dashboard...")
|
| 153 |
-
|
| 154 |
-
# Environment variable checks with better logging
|
| 155 |
-
missing_vars = []
|
| 156 |
-
|
| 157 |
if not os.environ.get(LINKEDIN_CLIENT_ID_ENV_VAR):
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
bubble_vars = [BUBBLE_APP_NAME_ENV_VAR, BUBBLE_API_KEY_PRIVATE_ENV_VAR, BUBBLE_API_ENDPOINT_ENV_VAR]
|
| 162 |
-
if not all(os.environ.get(var) for var in bubble_vars):
|
| 163 |
-
missing_vars.extend([var for var in bubble_vars if not os.environ.get(var)])
|
| 164 |
-
logging.warning("⚠️ WARNING: One or more Bubble environment variables are not set.")
|
| 165 |
-
|
| 166 |
-
if not os.environ.get("GEMINI_API_KEY"):
|
| 167 |
-
missing_vars.append("GEMINI_API_KEY")
|
| 168 |
-
logging.warning("⚠️ WARNING: 'GEMINI_API_KEY' is not set.")
|
| 169 |
-
|
| 170 |
if not AGENTIC_MODULES_LOADED:
|
| 171 |
-
logging.warning("
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
print(f"⚠️ Missing environment variables: {', '.join(missing_vars)}")
|
| 175 |
-
print("🔧 Please set these variables for full functionality.")
|
| 176 |
-
else:
|
| 177 |
-
print("✅ All environment variables are properly configured.")
|
| 178 |
-
|
| 179 |
-
print("🌐 Launching dashboard on http://0.0.0.0:7860")
|
| 180 |
-
print("🎯 Dashboard features:")
|
| 181 |
-
print(" • 📊 Advanced LinkedIn Analytics")
|
| 182 |
-
print(" • 🤖 AI-Powered Insights")
|
| 183 |
-
print(" • 🎯 OKR Generation & Tracking")
|
| 184 |
-
print(" • ☁️ Bubble.io Integration")
|
| 185 |
-
|
| 186 |
-
app.launch(
|
| 187 |
-
server_name="0.0.0.0",
|
| 188 |
-
server_port=int(os.environ.get("PORT", 7860)),
|
| 189 |
-
debug=True,
|
| 190 |
-
show_error=True
|
| 191 |
-
)
|
| 192 |
|
|
|
|
|
|
| 18 |
BUBBLE_API_ENDPOINT_ENV_VAR
|
| 19 |
)
|
| 20 |
|
| 21 |
+
from services.analytics_tab_module import AnalyticsTab
|
| 22 |
+
|
| 23 |
# UPDATED: Using the new data loading function from the refactored state manager
|
| 24 |
from services.state_manager import load_data_from_bubble
|
|
|
|
|
|
|
| 25 |
from ui.ui_generators import (
|
| 26 |
build_analytics_tab_plot_area,
|
| 27 |
+
build_home_tab_ui, # NEW: Import the function to build the Home tab UI
|
| 28 |
+
create_enhanced_report_tab, # NEW: Import the function to build the enhanced Report tab UI
|
| 29 |
BOMB_ICON, EXPLORE_ICON, FORMULA_ICON, ACTIVE_ICON
|
| 30 |
)
|
| 31 |
# NEW: Import the new OKR UI functions
|
|
|
|
| 33 |
from ui.analytics_plot_generator import update_analytics_plots_figures, create_placeholder_plot
|
| 34 |
from formulas import PLOT_FORMULAS
|
| 35 |
|
|
|
|
|
|
|
|
|
|
| 36 |
# --- CHATBOT MODULE IMPORTS ---
|
| 37 |
from features.chatbot.chatbot_prompts import get_initial_insight_prompt_and_suggestions
|
| 38 |
from features.chatbot.chatbot_handler import generate_llm_response
|
|
|
|
| 46 |
# UI formatting functions
|
| 47 |
from ui.insights_ui_generator import (
|
| 48 |
format_report_for_display, # This will now return header HTML and body Markdown
|
| 49 |
+
# REMOVED: extract_key_results_for_selection, - Moved to okr_ui_generator (implicitly)
|
| 50 |
+
# REMOVED: format_single_okr_for_display - Moved to okr_ui_generator (implicitly)
|
| 51 |
)
|
| 52 |
AGENTIC_MODULES_LOADED = True
|
| 53 |
except ImportError as e:
|
|
|
|
| 76 |
# matching the `outputs` in the .then() call later.
|
| 77 |
return (
|
| 78 |
gr.update(value="Modules not loaded."), # agentic_pipeline_status_md (0)
|
| 79 |
+
gr.update(choices=[], value=None), # report_selector_dd (1)
|
| 80 |
+
gr.update(choices=[], value=[]), # key_results_cbg (2) - KEPT HIDDEN for compatibility
|
| 81 |
+
gr.update(value="Modules not loaded."), # okr_detail_display_md (3) - KEPT HIDDEN for compatibility
|
| 82 |
+
None, # orchestration_raw_results_st (4)
|
| 83 |
+
[], # selected_key_result_ids_st (5) - KEPT HIDDEN for compatibility
|
| 84 |
+
[], # key_results_for_selection_st (6) - KEPT HIDDEN for compatibility
|
| 85 |
+
gr.update(value=empty_header_html), # report_header_html_display (7)
|
| 86 |
+
gr.update(value=empty_body_markdown), # report_body_markdown_display (8)
|
| 87 |
+
{}, # reconstruction_cache_st (9)
|
| 88 |
gr.update(value=get_initial_okr_display()), # NEW: enhanced_okr_display_html (10)
|
| 89 |
gr.update(value={}) # NEW: actionable_okrs_data_st (11)
|
| 90 |
)
|
|
|
|
| 95 |
return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
|
| 96 |
|
| 97 |
|
| 98 |
+
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
| 99 |
+
title="LinkedIn Organization Dashboard") as app:
|
| 100 |
+
# --- STATE MANAGEMENT ---
|
| 101 |
+
token_state = gr.State(value={
|
| 102 |
+
"token": None, "client_id": None, "org_urn": None,
|
| 103 |
+
"bubble_posts_df": pd.DataFrame(), "bubble_post_stats_df": pd.DataFrame(),
|
| 104 |
+
"bubble_mentions_df": pd.DataFrame(), "bubble_follower_stats_df": pd.DataFrame(),
|
| 105 |
+
"bubble_agentic_analysis_data": pd.DataFrame(), # To store agentic results from Bubble
|
| 106 |
+
"url_user_token_temp_storage": None,
|
| 107 |
+
"config_date_col_posts": "published_at", "config_date_col_mentions": "date",
|
| 108 |
+
"config_date_col_followers": "date", "config_media_type_col": "media_type",
|
| 109 |
+
"config_eb_labels_col": "li_eb_label"
|
| 110 |
+
})
|
| 111 |
+
|
| 112 |
+
# States for analytics tab chatbot
|
| 113 |
+
chat_histories_st = gr.State({})
|
| 114 |
+
current_chat_plot_id_st = gr.State(None)
|
| 115 |
+
plot_data_for_chatbot_st = gr.State({})
|
| 116 |
+
|
| 117 |
+
# States for agentic results display
|
| 118 |
+
orchestration_raw_results_st = gr.State(None)
|
| 119 |
+
# KEPT for compatibility with load_and_display_agentic_results signature
|
| 120 |
+
key_results_for_selection_st = gr.State([])
|
| 121 |
+
selected_key_result_ids_st = gr.State([])
|
| 122 |
+
|
| 123 |
+
# --- NEW: Session-specific cache for reconstructed OKR data ---
|
| 124 |
+
reconstruction_cache_st = gr.State({})
|
| 125 |
+
# NEW: State to hold the actionable_okrs dictionary explicitly
|
| 126 |
+
actionable_okrs_data_st = gr.State({})
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
# --- UI LAYOUT ---
|
| 130 |
+
gr.Markdown("# 🚀 LinkedIn Organization Dashboard")
|
| 131 |
+
url_user_token_display = gr.Textbox(label="User Token (Hidden)", interactive=False, visible=False)
|
| 132 |
+
org_urn_display = gr.Textbox(label="Org URN (Hidden)", interactive=False, visible=False)
|
| 133 |
+
status_box = gr.Textbox(label="Status", interactive=False, value="Initializing...")
|
| 134 |
+
|
| 135 |
+
app.load(fn=get_url_user_token, inputs=None, outputs=[url_user_token_display, org_urn_display], api_name="get_url_params", show_progress=False)
|
| 136 |
+
|
| 137 |
+
def initial_data_load_sequence(url_token, org_urn_val, current_state):
|
| 138 |
+
"""
|
| 139 |
+
Handles the initial data loading from Bubble.
|
| 140 |
+
No longer generates dashboard HTML as the Home tab is now static.
|
| 141 |
+
"""
|
| 142 |
+
status_msg, new_state = load_data_from_bubble(url_token, org_urn_val, current_state)
|
| 143 |
+
return status_msg, new_state
|
| 144 |
+
|
| 145 |
+
analytics_icons = {'bomb': BOMB_ICON, 'explore': EXPLORE_ICON, 'formula': FORMULA_ICON, 'active': ACTIVE_ICON}
|
| 146 |
+
analytics_tab_instance = AnalyticsTab(
|
| 147 |
+
token_state=token_state,
|
| 148 |
+
chat_histories_st=chat_histories_st,
|
| 149 |
+
current_chat_plot_id_st=current_chat_plot_id_st,
|
| 150 |
+
plot_data_for_chatbot_st=plot_data_for_chatbot_st,
|
| 151 |
+
plot_id_to_formula_map=PLOT_ID_TO_FORMULA_KEY_MAP,
|
| 152 |
+
plot_formulas_data=PLOT_FORMULAS,
|
| 153 |
+
icons=analytics_icons,
|
| 154 |
+
fn_build_plot_area=build_analytics_tab_plot_area,
|
| 155 |
+
fn_update_plot_figures=update_analytics_plots_figures,
|
| 156 |
+
fn_create_placeholder_plot=create_placeholder_plot,
|
| 157 |
+
fn_get_initial_insight=get_initial_insight_prompt_and_suggestions,
|
| 158 |
+
fn_generate_llm_response=generate_llm_response
|
| 159 |
+
)
|
| 160 |
+
|
| 161 |
+
def update_report_display(selected_report_id: str, current_token_state: dict):
|
| 162 |
+
"""
|
| 163 |
+
Updates the report header and body display when a new report is selected.
|
| 164 |
+
This function now expects format_report_for_display to return a dict with
|
| 165 |
+
'header_html' and 'body_markdown'.
|
| 166 |
+
"""
|
| 167 |
+
# Define empty states for header and body
|
| 168 |
+
empty_header_html = """
|
| 169 |
+
<div class="report-title">📊 Comprehensive Analysis Report</div>
|
| 170 |
+
<div class="report-subtitle">AI-Generated Insights from Your LinkedIn Data</div>
|
| 171 |
+
<div class="status-badge">Generated from Bubble.io</div>
|
| 172 |
+
"""
|
| 173 |
+
empty_body_markdown_no_selection = """
|
| 174 |
+
<div class="empty-state">
|
| 175 |
+
<div class="empty-state-icon">📋</div>
|
| 176 |
+
<div class="empty-state-title">Select a Report</div>
|
| 177 |
+
<div class="empty-state-description">
|
| 178 |
+
Choose a report from the dropdown above to view its detailed analysis and insights.
|
| 179 |
+
</div>
|
| 180 |
+
</div>
|
| 181 |
+
"""
|
| 182 |
+
empty_body_markdown_no_data = """
|
| 183 |
+
<div class="empty-state">
|
| 184 |
+
<div class="empty-state-icon">⚠️</div>
|
| 185 |
+
<div class="empty-state-title">Data Not Available</div>
|
| 186 |
+
<div class="empty-state-description">
|
| 187 |
+
Analysis data is not loaded or is empty. Please try refreshing the page.
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
"""
|
| 191 |
+
empty_body_markdown_not_found = lambda _id: f"""
|
| 192 |
+
<div class="empty-state">
|
| 193 |
+
<div class="empty-state-icon">❌</div>
|
| 194 |
+
<div class="empty-state-title">Report Not Found</div>
|
| 195 |
+
<div class="empty-state-description">
|
| 196 |
+
Report with ID '{_id}' was not found in the database.
|
| 197 |
+
</div>
|
| 198 |
+
</div>
|
| 199 |
+
"""
|
| 200 |
+
|
| 201 |
+
if not selected_report_id:
|
| 202 |
+
# When no report is selected, update both header and body
|
| 203 |
+
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_no_selection)
|
| 204 |
+
|
| 205 |
+
agentic_df = current_token_state.get("bubble_agentic_analysis_data")
|
| 206 |
+
if agentic_df is None or agentic_df.empty:
|
| 207 |
+
# When no data is available, update both header and body
|
| 208 |
+
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_no_data)
|
| 209 |
+
|
| 210 |
+
selected_report_series_df = agentic_df[agentic_df['_id'] == selected_report_id]
|
| 211 |
+
if selected_report_series_df.empty:
|
| 212 |
+
# When report is not found, update both header and body
|
| 213 |
+
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_not_found(selected_report_id))
|
| 214 |
+
|
| 215 |
+
selected_report_series = selected_report_series_df.iloc[0]
|
| 216 |
+
|
| 217 |
+
# Call the format_report_for_display, which now returns a dict
|
| 218 |
+
formatted_content_parts = format_report_for_display(selected_report_series)
|
| 219 |
+
|
| 220 |
+
# Update the two separate Gradio components
|
| 221 |
+
return (
|
| 222 |
+
gr.update(value=formatted_content_parts['header_html']),
|
| 223 |
+
gr.update(value=formatted_content_parts['body_markdown'])
|
| 224 |
+
)
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
with gr.Tabs() as tabs:
|
| 228 |
+
# --- NEW HOME TAB ---
|
| 229 |
+
with gr.TabItem("1️⃣ Home", id="tab_home"):
|
| 230 |
+
# Call the new function from ui_generators to build the Home tab content
|
| 231 |
+
btn_graphs, btn_reports, btn_okr, btn_help = build_home_tab_ui()
|
| 232 |
+
|
| 233 |
+
# Link buttons to tab selection
|
| 234 |
+
btn_graphs.click(fn=lambda: gr.update(selected="tab_analytics_module"), outputs=tabs)
|
| 235 |
+
btn_reports.click(fn=lambda: gr.update(selected="tab_agentic_report"), outputs=tabs)
|
| 236 |
+
btn_okr.click(fn=lambda: gr.update(selected="tab_agentic_okrs"), outputs=tabs)
|
| 237 |
+
# btn_help.click(fn=lambda: gr.update(selected="tab_help"), outputs=tabs) # Uncomment if you add a help tab
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
analytics_tab_instance.create_tab_ui() # This is the "Graphs" tab, assuming its ID is "tab_analytics"
|
| 241 |
+
|
| 242 |
+
# --- REPLACED: Agentic Analysis Report Tab with enhanced UI ---
|
| 243 |
+
# The create_enhanced_report_tab function now builds this entire tab's UI.
|
| 244 |
+
# It also returns the relevant Gradio components needed for callbacks.
|
| 245 |
+
with gr.TabItem("3️⃣ Agentic Analysis Report", id="tab_agentic_report", visible=AGENTIC_MODULES_LOADED):
|
| 246 |
+
# The create_enhanced_report_tab function handles the CSS and HTML structure
|
| 247 |
+
# MODIFIED: Unpacked 4 values instead of 3
|
| 248 |
+
agentic_pipeline_status_md, report_selector_dd, report_header_html_display, report_body_markdown_display = \
|
| 249 |
+
create_enhanced_report_tab(AGENTIC_MODULES_LOADED)
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
with gr.TabItem("4️⃣ Agentic OKRs & Tasks", id="tab_agentic_okrs", visible=AGENTIC_MODULES_LOADED):
|
| 253 |
+
gr.Markdown("## 🎯 AI Generated OKRs and Actionable Tasks (from Bubble.io)")
|
| 254 |
+
gr.Markdown("Basato sull'analisi AI, l'agente ha proposto i seguenti OKR.")
|
| 255 |
+
|
| 256 |
+
if not AGENTIC_MODULES_LOADED:
|
| 257 |
+
gr.Markdown("🔴 **Error:** Agentic modules could not be loaded.")
|
| 258 |
+
|
| 259 |
+
# Keep the old components but make them invisible to maintain load_and_display_agentic_results signature
|
| 260 |
+
with gr.Column(visible=False):
|
| 261 |
+
gr.Markdown("### Suggested Key Results (OLD UI - HIDDEN)")
|
| 262 |
+
key_results_cbg = gr.CheckboxGroup(label="Select Key Results", choices=[], value=[], interactive=True)
|
| 263 |
+
gr.Markdown("### Detailed OKRs and Tasks (OLD UI - HIDDEN)")
|
| 264 |
+
okr_detail_display_md = gr.Markdown("I dettagli OKR appariranno qui.")
|
| 265 |
+
|
| 266 |
+
# NEW: Add the enhanced OKR display HTML component
|
| 267 |
+
enhanced_okr_display_html = create_enhanced_okr_tab()
|
| 268 |
+
|
| 269 |
+
# REMOVED: The old update_okr_display_on_selection function and its change event
|
| 270 |
+
# as the new UI handles display dynamically from raw_results_st
|
| 271 |
+
|
| 272 |
+
if AGENTIC_MODULES_LOADED:
|
| 273 |
+
report_selector_dd.change(
|
| 274 |
+
fn=update_report_display, # This now calls the enhanced function
|
| 275 |
+
# MODIFIED: Updated outputs to match the two new display components
|
| 276 |
+
inputs=[report_selector_dd, token_state],
|
| 277 |
+
outputs=[report_header_html_display, report_body_markdown_display],
|
| 278 |
+
show_progress="minimal"
|
| 279 |
+
)
|
| 280 |
+
|
| 281 |
+
# Ensure agentic_display_outputs correctly maps to the newly created components
|
| 282 |
+
# This list must match the outputs of load_and_display_agentic_results
|
| 283 |
+
agentic_display_outputs = [
|
| 284 |
+
agentic_pipeline_status_md, # 0: Status Markdown (hidden)
|
| 285 |
+
report_selector_dd, # 1: Dropdown for selecting reports
|
| 286 |
+
key_results_cbg, # 2: Checkbox group for OKRs (kept hidden)
|
| 287 |
+
okr_detail_display_md, # 3: Markdown for detailed OKR display (kept hidden)
|
| 288 |
+
orchestration_raw_results_st, # 4: Raw results state
|
| 289 |
+
selected_key_result_ids_st, # 5: Selected KR IDs state (kept hidden)
|
| 290 |
+
key_results_for_selection_st, # 6: All KRs for selection state (kept hidden)
|
| 291 |
+
report_header_html_display, # 7: New HTML output for header
|
| 292 |
+
report_body_markdown_display, # 8: New Markdown output for body
|
| 293 |
+
reconstruction_cache_st, # 9: Reconstruction cache state
|
| 294 |
+
enhanced_okr_display_html, # 10: NEW: The enhanced HTML display for OKRs
|
| 295 |
+
actionable_okrs_data_st # 11: NEW: The actionable_okrs dictionary state
|
| 296 |
+
]
|
| 297 |
+
|
| 298 |
+
initial_load_event = org_urn_display.change(
|
| 299 |
+
fn=initial_data_load_sequence,
|
| 300 |
+
inputs=[url_user_token_display, org_urn_display, token_state],
|
| 301 |
+
outputs=[status_box, token_state],
|
| 302 |
+
show_progress="full"
|
| 303 |
+
)
|
| 304 |
+
|
| 305 |
+
initial_load_event.then(
|
| 306 |
+
fn=analytics_tab_instance._refresh_analytics_graphs_ui,
|
| 307 |
+
inputs=[token_state, analytics_tab_instance.date_filter_selector, analytics_tab_instance.custom_start_date_picker,
|
| 308 |
+
analytics_tab_instance.custom_end_date_picker, chat_histories_st],
|
| 309 |
+
outputs=analytics_tab_instance.graph_refresh_outputs_list,
|
| 310 |
+
show_progress="full"
|
| 311 |
+
).then(
|
| 312 |
+
fn=load_and_display_agentic_results,
|
| 313 |
+
inputs=[token_state, reconstruction_cache_st],
|
| 314 |
+
# MODIFIED: Updated outputs to match all components returned by load_and_display_agentic_results (now 12)
|
| 315 |
+
outputs=agentic_display_outputs,
|
| 316 |
+
show_progress="minimal"
|
| 317 |
+
).then( # NEW CHAIN: Update the enhanced OKR display after load_and_display_agentic_results runs
|
| 318 |
+
fn=format_okrs_for_enhanced_display,
|
| 319 |
+
inputs=[reconstruction_cache_st], # Change from actionable_okrs_data_st to reconstruction_cache_st
|
| 320 |
+
outputs=[enhanced_okr_display_html],
|
| 321 |
+
show_progress="minimal"
|
| 322 |
)
|
| 323 |
|
|
|
|
|
|
|
| 324 |
|
| 325 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
if not os.environ.get(LINKEDIN_CLIENT_ID_ENV_VAR):
|
| 327 |
+
logging.warning(f"WARNING: '{LINKEDIN_CLIENT_ID_ENV_VAR}' is not set.")
|
| 328 |
+
if not all(os.environ.get(var) for var in [BUBBLE_APP_NAME_ENV_VAR, BUBBLE_API_KEY_PRIVATE_ENV_VAR, BUBBLE_API_ENDPOINT_ENV_VAR]):
|
| 329 |
+
logging.warning("WARNING: One or more Bubble environment variables are not set.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
if not AGENTIC_MODULES_LOADED:
|
| 331 |
+
logging.warning("CRITICAL: Agentic modules failed to load.")
|
| 332 |
+
if not os.environ.get("GEMINI_API_KEY"):
|
| 333 |
+
logging.warning("WARNING: 'GEMINI_API_KEY' is not set.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
|
| 335 |
+
app.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)), debug=True)
|