Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -25,9 +25,8 @@ from ui.ui_generators import (
|
|
25 |
create_enhanced_report_tab, # NEW: Import the function to build the enhanced Report tab UI
|
26 |
BOMB_ICON, EXPLORE_ICON, FORMULA_ICON, ACTIVE_ICON
|
27 |
)
|
28 |
-
# NEW: Import the OKR UI
|
29 |
-
from ui.okr_ui_generator import create_enhanced_okr_tab, format_okrs_for_enhanced_display,
|
30 |
-
|
31 |
from ui.analytics_plot_generator import update_analytics_plots_figures, create_placeholder_plot
|
32 |
from formulas import PLOT_FORMULAS
|
33 |
|
@@ -43,17 +42,18 @@ try:
|
|
43 |
from services.report_data_handler import fetch_and_reconstruct_data_from_bubble
|
44 |
# UI formatting functions
|
45 |
from ui.insights_ui_generator import (
|
46 |
-
format_report_for_display # This will now return header HTML and body Markdown
|
|
|
|
|
47 |
)
|
48 |
-
# The functions below are no longer needed due to the new OKR display approach and are removed from insights_ui_generator.py
|
49 |
-
# from ui.insights_ui_generator import extract_key_results_for_selection, format_single_okr_for_display
|
50 |
AGENTIC_MODULES_LOADED = True
|
51 |
except ImportError as e:
|
52 |
logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
|
53 |
AGENTIC_MODULES_LOADED = False
|
54 |
# Placeholder functions to prevent app from crashing if imports fail
|
55 |
def load_and_display_agentic_results(*args, **kwargs):
|
56 |
-
# NOTE: This return signature MUST match agentic_display_outputs
|
|
|
57 |
empty_header_html = """
|
58 |
<div class="report-title">📊 Comprehensive Analysis Report</div>
|
59 |
<div class="report-subtitle">AI-Generated Insights from Your LinkedIn Data</div>
|
@@ -68,22 +68,32 @@ except ImportError as e:
|
|
68 |
</div>
|
69 |
</div>
|
70 |
"""
|
71 |
-
#
|
|
|
|
|
72 |
return (
|
73 |
-
gr.update(value="Modules not loaded."), # 0
|
74 |
-
gr.update(choices=[], value=None),
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
81 |
)
|
82 |
def fetch_and_reconstruct_data_from_bubble(*args, **kwargs):
|
83 |
return None, {}
|
84 |
def format_report_for_display(report_data):
|
85 |
# Placeholder for when modules are not loaded, returns structure matching the new design
|
86 |
return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
|
89 |
# --- ANALYTICS TAB MODULE IMPORT ---
|
@@ -122,11 +132,10 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
122 |
|
123 |
# States for agentic results display
|
124 |
orchestration_raw_results_st = gr.State(None)
|
125 |
-
#
|
126 |
-
|
127 |
-
key_results_for_selection_st = gr.State([])
|
128 |
selected_key_result_ids_st = gr.State([])
|
129 |
-
|
130 |
# --- NEW: Session-specific cache for reconstructed OKR data ---
|
131 |
reconstruction_cache_st = gr.State({})
|
132 |
|
@@ -162,7 +171,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
162 |
fn_get_initial_insight=get_initial_insight_prompt_and_suggestions,
|
163 |
fn_generate_llm_response=generate_llm_response
|
164 |
)
|
165 |
-
|
166 |
def update_report_display(selected_report_id: str, current_token_state: dict):
|
167 |
"""
|
168 |
Updates the report header and body display when a new report is selected.
|
@@ -206,7 +215,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
206 |
if not selected_report_id:
|
207 |
# When no report is selected, update both header and body
|
208 |
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_no_selection)
|
209 |
-
|
210 |
agentic_df = current_token_state.get("bubble_agentic_analysis_data")
|
211 |
if agentic_df is None or agentic_df.empty:
|
212 |
# When no data is available, update both header and body
|
@@ -216,26 +225,18 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
216 |
if selected_report_series_df.empty:
|
217 |
# When report is not found, update both header and body
|
218 |
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_not_found(selected_report_id))
|
219 |
-
|
220 |
selected_report_series = selected_report_series_df.iloc[0]
|
221 |
-
|
222 |
# Call the format_report_for_display, which now returns a dict
|
223 |
formatted_content_parts = format_report_for_display(selected_report_series)
|
224 |
-
|
225 |
# Update the two separate Gradio components
|
226 |
return (
|
227 |
gr.update(value=formatted_content_parts['header_html']),
|
228 |
gr.update(value=formatted_content_parts['body_markdown'])
|
229 |
)
|
230 |
|
231 |
-
# NEW: Function to update the enhanced OKR display
|
232 |
-
def update_okr_tab_display(raw_results: dict):
|
233 |
-
"""
|
234 |
-
Updates the enhanced OKR HTML display based on the raw agentic results.
|
235 |
-
This replaces the old update_okr_display_on_selection which used a checkbox group.
|
236 |
-
"""
|
237 |
-
return gr.update(value=format_okrs_for_enhanced_display(raw_results))
|
238 |
-
|
239 |
|
240 |
with gr.Tabs() as tabs:
|
241 |
# --- NEW HOME TAB ---
|
@@ -263,34 +264,48 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
263 |
|
264 |
|
265 |
with gr.TabItem("4️⃣ Agentic OKRs & Tasks", id="tab_agentic_okrs", visible=AGENTIC_MODULES_LOADED):
|
266 |
-
|
267 |
-
|
268 |
|
269 |
-
|
270 |
-
|
271 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
|
273 |
if AGENTIC_MODULES_LOADED:
|
274 |
report_selector_dd.change(
|
275 |
fn=update_report_display, # This now calls the enhanced function
|
276 |
# MODIFIED: Updated outputs to match the two new display components
|
277 |
inputs=[report_selector_dd, token_state],
|
278 |
-
outputs=[report_header_html_display, report_body_markdown_display],
|
279 |
show_progress="minimal"
|
280 |
)
|
281 |
|
282 |
# Ensure agentic_display_outputs correctly maps to the newly created components
|
283 |
# This list must match the outputs of load_and_display_agentic_results
|
284 |
-
# REMOVED: okr_display_html from this list, as it's updated separately
|
285 |
agentic_display_outputs = [
|
286 |
-
agentic_pipeline_status_md,
|
287 |
-
report_selector_dd,
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
|
|
|
|
|
|
294 |
]
|
295 |
|
296 |
initial_load_event = org_urn_display.change(
|
@@ -309,14 +324,13 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
309 |
).then(
|
310 |
fn=load_and_display_agentic_results,
|
311 |
inputs=[token_state, reconstruction_cache_st],
|
312 |
-
# MODIFIED:
|
313 |
outputs=agentic_display_outputs,
|
314 |
show_progress="minimal"
|
315 |
-
).then(
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
outputs=[okr_display_html],
|
320 |
show_progress="minimal"
|
321 |
)
|
322 |
|
|
|
25 |
create_enhanced_report_tab, # NEW: Import the function to build the enhanced Report tab UI
|
26 |
BOMB_ICON, EXPLORE_ICON, FORMULA_ICON, ACTIVE_ICON
|
27 |
)
|
28 |
+
# NEW: Import the new OKR UI functions
|
29 |
+
from ui.okr_ui_generator import create_enhanced_okr_tab, format_okrs_for_enhanced_display, get_initial_okr_display
|
|
|
30 |
from ui.analytics_plot_generator import update_analytics_plots_figures, create_placeholder_plot
|
31 |
from formulas import PLOT_FORMULAS
|
32 |
|
|
|
42 |
from services.report_data_handler import fetch_and_reconstruct_data_from_bubble
|
43 |
# UI formatting functions
|
44 |
from ui.insights_ui_generator import (
|
45 |
+
format_report_for_display, # This will now return header HTML and body Markdown
|
46 |
+
# REMOVED: extract_key_results_for_selection, - Moved to okr_ui_generator (implicitly)
|
47 |
+
# REMOVED: format_single_okr_for_display - Moved to okr_ui_generator (implicitly)
|
48 |
)
|
|
|
|
|
49 |
AGENTIC_MODULES_LOADED = True
|
50 |
except ImportError as e:
|
51 |
logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
|
52 |
AGENTIC_MODULES_LOADED = False
|
53 |
# Placeholder functions to prevent app from crashing if imports fail
|
54 |
def load_and_display_agentic_results(*args, **kwargs):
|
55 |
+
# NOTE: This return signature MUST match agentic_display_outputs
|
56 |
+
# Adjusted return values for the new split report display components and the new OKR HTML
|
57 |
empty_header_html = """
|
58 |
<div class="report-title">📊 Comprehensive Analysis Report</div>
|
59 |
<div class="report-subtitle">AI-Generated Insights from Your LinkedIn Data</div>
|
|
|
68 |
</div>
|
69 |
</div>
|
70 |
"""
|
71 |
+
# The load_and_display_agentic_results function returns many values.
|
72 |
+
# Ensure the placeholder returns the correct number of gr.update components
|
73 |
+
# matching the `outputs` in the .then() call later.
|
74 |
return (
|
75 |
+
gr.update(value="Modules not loaded."), # agentic_pipeline_status_md (0)
|
76 |
+
gr.update(choices=[], value=None), # report_selector_dd (1)
|
77 |
+
gr.update(choices=[], value=[]), # key_results_cbg (2) - KEPT HIDDEN for compatibility
|
78 |
+
gr.update(value="Modules not loaded."), # okr_detail_display_md (3) - KEPT HIDDEN for compatibility
|
79 |
+
None, # orchestration_raw_results_st (4)
|
80 |
+
[], # selected_key_result_ids_st (5) - KEPT HIDDEN for compatibility
|
81 |
+
[], # key_results_for_selection_st (6) - KEPT HIDDEN for compatibility
|
82 |
+
gr.update(value=empty_header_html), # report_header_html_display (7)
|
83 |
+
gr.update(value=empty_body_markdown), # report_body_markdown_display (8)
|
84 |
+
{}, # reconstruction_cache_st (9)
|
85 |
+
gr.update(value=get_initial_okr_display()) # NEW: enhanced_okr_display_html (10)
|
86 |
)
|
87 |
def fetch_and_reconstruct_data_from_bubble(*args, **kwargs):
|
88 |
return None, {}
|
89 |
def format_report_for_display(report_data):
|
90 |
# Placeholder for when modules are not loaded, returns structure matching the new design
|
91 |
return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
|
92 |
+
# REMOVED from insights_ui_generator.py, so also remove placeholder if not needed by other direct calls
|
93 |
+
# def extract_key_results_for_selection(okr_data):
|
94 |
+
# return []
|
95 |
+
# def format_single_okr_for_display(okr_data, **kwargs):
|
96 |
+
# return "Agentic modules not loaded. OKR display unavailable."
|
97 |
|
98 |
|
99 |
# --- ANALYTICS TAB MODULE IMPORT ---
|
|
|
132 |
|
133 |
# States for agentic results display
|
134 |
orchestration_raw_results_st = gr.State(None)
|
135 |
+
# KEPT for compatibility with load_and_display_agentic_results signature
|
136 |
+
key_results_for_selection_st = gr.State([])
|
|
|
137 |
selected_key_result_ids_st = gr.State([])
|
138 |
+
|
139 |
# --- NEW: Session-specific cache for reconstructed OKR data ---
|
140 |
reconstruction_cache_st = gr.State({})
|
141 |
|
|
|
171 |
fn_get_initial_insight=get_initial_insight_prompt_and_suggestions,
|
172 |
fn_generate_llm_response=generate_llm_response
|
173 |
)
|
174 |
+
|
175 |
def update_report_display(selected_report_id: str, current_token_state: dict):
|
176 |
"""
|
177 |
Updates the report header and body display when a new report is selected.
|
|
|
215 |
if not selected_report_id:
|
216 |
# When no report is selected, update both header and body
|
217 |
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_no_selection)
|
218 |
+
|
219 |
agentic_df = current_token_state.get("bubble_agentic_analysis_data")
|
220 |
if agentic_df is None or agentic_df.empty:
|
221 |
# When no data is available, update both header and body
|
|
|
225 |
if selected_report_series_df.empty:
|
226 |
# When report is not found, update both header and body
|
227 |
return gr.update(value=empty_header_html), gr.update(value=empty_body_markdown_not_found(selected_report_id))
|
228 |
+
|
229 |
selected_report_series = selected_report_series_df.iloc[0]
|
230 |
+
|
231 |
# Call the format_report_for_display, which now returns a dict
|
232 |
formatted_content_parts = format_report_for_display(selected_report_series)
|
233 |
+
|
234 |
# Update the two separate Gradio components
|
235 |
return (
|
236 |
gr.update(value=formatted_content_parts['header_html']),
|
237 |
gr.update(value=formatted_content_parts['body_markdown'])
|
238 |
)
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
|
241 |
with gr.Tabs() as tabs:
|
242 |
# --- NEW HOME TAB ---
|
|
|
264 |
|
265 |
|
266 |
with gr.TabItem("4️⃣ Agentic OKRs & Tasks", id="tab_agentic_okrs", visible=AGENTIC_MODULES_LOADED):
|
267 |
+
gr.Markdown("## 🎯 AI Generated OKRs and Actionable Tasks (from Bubble.io)")
|
268 |
+
gr.Markdown("Basato sull'analisi AI, l'agente ha proposto i seguenti OKR.")
|
269 |
|
270 |
+
if not AGENTIC_MODULES_LOADED:
|
271 |
+
gr.Markdown("🔴 **Error:** Agentic modules could not be loaded.")
|
272 |
|
273 |
+
# Keep the old components but make them invisible to maintain load_and_display_agentic_results signature
|
274 |
+
with gr.Column(visible=False):
|
275 |
+
gr.Markdown("### Suggested Key Results (OLD UI - HIDDEN)")
|
276 |
+
key_results_cbg = gr.CheckboxGroup(label="Select Key Results", choices=[], value=[], interactive=True)
|
277 |
+
gr.Markdown("### Detailed OKRs and Tasks (OLD UI - HIDDEN)")
|
278 |
+
okr_detail_display_md = gr.Markdown("I dettagli OKR appariranno qui.")
|
279 |
+
|
280 |
+
# NEW: Add the enhanced OKR display HTML component
|
281 |
+
enhanced_okr_display_html = create_enhanced_okr_tab()
|
282 |
+
|
283 |
+
# REMOVED: The old update_okr_display_on_selection function and its change event
|
284 |
+
# as the new UI handles display dynamically from raw_results_st
|
285 |
|
286 |
if AGENTIC_MODULES_LOADED:
|
287 |
report_selector_dd.change(
|
288 |
fn=update_report_display, # This now calls the enhanced function
|
289 |
# MODIFIED: Updated outputs to match the two new display components
|
290 |
inputs=[report_selector_dd, token_state],
|
291 |
+
outputs=[report_header_html_display, report_body_markdown_display],
|
292 |
show_progress="minimal"
|
293 |
)
|
294 |
|
295 |
# Ensure agentic_display_outputs correctly maps to the newly created components
|
296 |
# This list must match the outputs of load_and_display_agentic_results
|
|
|
297 |
agentic_display_outputs = [
|
298 |
+
agentic_pipeline_status_md, # 0: Status Markdown (hidden)
|
299 |
+
report_selector_dd, # 1: Dropdown for selecting reports
|
300 |
+
key_results_cbg, # 2: Checkbox group for OKRs (kept hidden)
|
301 |
+
okr_detail_display_md, # 3: Markdown for detailed OKR display (kept hidden)
|
302 |
+
orchestration_raw_results_st, # 4: Raw results state
|
303 |
+
selected_key_result_ids_st, # 5: Selected KR IDs state (kept hidden)
|
304 |
+
key_results_for_selection_st, # 6: All KRs for selection state (kept hidden)
|
305 |
+
report_header_html_display, # 7: New HTML output for header
|
306 |
+
report_body_markdown_display, # 8: New Markdown output for body
|
307 |
+
reconstruction_cache_st, # 9: Reconstruction cache state
|
308 |
+
enhanced_okr_display_html # 10: NEW: The enhanced HTML display for OKRs
|
309 |
]
|
310 |
|
311 |
initial_load_event = org_urn_display.change(
|
|
|
324 |
).then(
|
325 |
fn=load_and_display_agentic_results,
|
326 |
inputs=[token_state, reconstruction_cache_st],
|
327 |
+
# MODIFIED: Updated outputs to match all components returned by load_and_display_agentic_results
|
328 |
outputs=agentic_display_outputs,
|
329 |
show_progress="minimal"
|
330 |
+
).then( # NEW CHAIN: Update the enhanced OKR display after load_and_display_agentic_results runs
|
331 |
+
fn=format_okrs_for_enhanced_display,
|
332 |
+
inputs=[orchestration_raw_results_st], # Take the raw results as input
|
333 |
+
outputs=[enhanced_okr_display_html],
|
|
|
334 |
show_progress="minimal"
|
335 |
)
|
336 |
|