Spaces:
Sleeping
Sleeping
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)
|