GuglielmoTor commited on
Commit
64f7441
·
verified ·
1 Parent(s): 9407175

Update services/agentic_handlers.py

Browse files
Files changed (1) hide show
  1. services/agentic_handlers.py +68 -66
services/agentic_handlers.py CHANGED
@@ -44,51 +44,49 @@ class AgenticHandlers:
44
  This function is intended to be triggered by changes in token_state
45
  (e.g., after initial load or after sync).
46
  It yields updates for the agentic report and OKR tabs.
 
 
47
  """
48
  logging.info(f"Agentic pipeline auto-trigger. Token: {'Set' if current_token_state_val.get('token') else 'Not Set'}")
49
 
50
  # Initial "waiting" status updates
51
  initial_report_status = "Pipeline AI: In attesa dei dati necessari..."
52
- initial_okr_value_for_markdown = "" # Assuming this component is Markdown, value should be string
53
- # initial_okr_interactive = False # Markdown does not take 'interactive' in gr.update
54
  initial_okr_details = "Pipeline AI: In attesa dei dati necessari..."
55
- initial_orchestration_results = self.orchestration_raw_results_st.value # Preserve if re-running
56
  initial_selected_krs = self.selected_key_result_ids_st.value
57
  initial_krs_for_selection = self.key_results_for_selection_st.value
58
 
59
- # Check if components exist (in case tabs were conditionally not fully rendered)
60
  report_status_md_update = gr.update(value=initial_report_status) if self.report_components.get("agentic_pipeline_status_md") else gr.update()
61
- report_display_md_update = gr.update() # No change to report display yet
62
 
63
- # If key_results_cbg is the Markdown component causing the error, its update should not have 'interactive'.
64
- # Its value should be a string.
65
  okrs_cbg_update = gr.update(value=initial_okr_value_for_markdown) if self.okrs_components.get("key_results_cbg") else gr.update()
66
  okrs_detail_md_update = gr.update(value=initial_okr_details) if self.okrs_components.get("okr_detail_display_md") else gr.update()
67
 
68
  if not current_token_state_val or not current_token_state_val.get("token"):
69
  logging.info("Agentic pipeline: Token not available in token_state. Skipping actual run.")
70
  yield (
71
- report_status_md_update, # For agentic_pipeline_status_md
72
- report_display_md_update, # For agentic_report_display_md (no change yet)
73
- okrs_cbg_update, # For key_results_cbg (now updated as if it's Markdown)
74
- okrs_detail_md_update, # For okr_detail_display_md
75
- initial_orchestration_results, # For orchestration_raw_results_st
76
- initial_selected_krs, # For selected_key_result_ids_st
77
- initial_krs_for_selection # For key_results_for_selection_st
78
  )
79
  return
80
 
81
- # Update status to "in progress"
82
  in_progress_status = "Analisi AI (Sempre) in corso..."
83
  if self.report_components.get("agentic_pipeline_status_md"):
84
  report_status_md_update = gr.update(value=in_progress_status)
85
- if self.okrs_components.get("okr_detail_display_md"): # Also update OKR detail placeholder
86
  okrs_detail_md_update = gr.update(value="Dettagli OKR (Sempre) in corso di generazione...")
87
 
88
- # okrs_cbg_update remains as initially defined (waiting state, no choices/interactive)
89
  yield (
90
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
91
- initial_orchestration_results, initial_selected_krs, initial_krs_for_selection
 
 
92
  )
93
 
94
  if not self.agentic_modules_really_loaded:
@@ -97,24 +95,21 @@ class AgenticHandlers:
97
  if self.report_components.get("agentic_pipeline_status_md"):
98
  report_status_md_update = gr.update(value=error_status)
99
  if self.report_components.get("agentic_report_display_md"):
100
- report_display_md_update = gr.update(value=error_status) # Update report display too
101
 
102
- # If key_results_cbg is Markdown, update its value to reflect the error.
103
- # No choices or interactive argument here.
104
  if self.okrs_components.get("key_results_cbg"):
105
- okrs_cbg_update = gr.update(value=error_status) # Value is string
106
 
107
  if self.okrs_components.get("okr_detail_display_md"):
108
- okrs_detail_md_update = gr.update(value=error_status) # Update OKR detail too
109
 
110
  yield (
111
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
112
- None, [], [] # Reset states
113
  )
114
  return
115
 
116
  try:
117
- # Always use "Sempre" filter for the autonomous agentic pipeline
118
  date_filter_val_agentic = "Sempre"
119
  custom_start_val_agentic = None
120
  custom_end_val_agentic = None
@@ -135,7 +130,7 @@ class AgenticHandlers:
135
  krs_for_selection_update_val = []
136
 
137
  if orchestration_output:
138
- orchestration_results_update_val = orchestration_output # Store the raw output
139
 
140
  report_str = orchestration_output.get('comprehensive_analysis_report', "Nessun report testuale fornito.")
141
  if self.report_components.get("agentic_report_display_md"):
@@ -143,15 +138,11 @@ class AgenticHandlers:
143
 
144
  actionable_okrs = orchestration_output.get('actionable_okrs_and_tasks')
145
  krs_for_ui_selection_list = extract_key_results_for_selection(actionable_okrs)
146
- krs_for_selection_update_val = krs_for_ui_selection_list # Store for CBG change handler
147
 
148
  if self.okrs_components.get("key_results_cbg"):
149
- # If this component is Markdown, it cannot take choices or interactive.
150
- # Its value should be a string.
151
  okrs_cbg_update = gr.update(value="Key Results available for selection (display as Markdown)")
152
- # Example string value if it's Markdown.
153
 
154
- # Display all OKRs initially (before any KR selection)
155
  all_okrs_md_parts = []
156
  if actionable_okrs and isinstance(actionable_okrs.get("okrs"), list):
157
  for okr_idx, okr_item in enumerate(actionable_okrs["okrs"]):
@@ -164,15 +155,14 @@ class AgenticHandlers:
164
  if self.okrs_components.get("okr_detail_display_md"):
165
  okrs_detail_md_update = gr.update(value="\n\n---\n\n".join(all_okrs_md_parts))
166
 
167
- selected_krs_update_val = [] # Reset selection
168
- else: # No output from pipeline
169
  final_status_text = "Pipeline AI (Sempre): Nessun risultato prodotto."
170
  if self.report_components.get("agentic_report_display_md"):
171
  report_display_md_update = gr.update(value="Nessun report generato dalla pipeline AI (Sempre).")
172
 
173
- # If key_results_cbg is Markdown
174
  if self.okrs_components.get("key_results_cbg"):
175
- okrs_cbg_update = gr.update(value="Nessun Key Result (Markdown display)") # String value
176
 
177
  if self.okrs_components.get("okr_detail_display_md"):
178
  okrs_detail_md_update = gr.update(value="Nessun OKR generato o errore nella pipeline AI (Sempre).")
@@ -182,7 +172,9 @@ class AgenticHandlers:
182
 
183
  yield (
184
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
185
- orchestration_results_update_val, selected_krs_update_val, krs_for_selection_update_val
 
 
186
  )
187
 
188
  except Exception as e:
@@ -193,16 +185,15 @@ class AgenticHandlers:
193
  if self.report_components.get("agentic_report_display_md"):
194
  report_display_md_update = gr.update(value=f"Errore generazione report AI (Sempre): {str(e)}")
195
 
196
- # If key_results_cbg is Markdown
197
  if self.okrs_components.get("key_results_cbg"):
198
- okrs_cbg_update = gr.update(value=f"Errore Key Results (Markdown): {str(e)}") # String value
199
 
200
  if self.okrs_components.get("okr_detail_display_md"):
201
  okrs_detail_md_update = gr.update(value=f"Errore generazione OKR AI (Sempre): {str(e)}")
202
 
203
  yield (
204
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
205
- None, [], [] # Reset states on error
206
  )
207
 
208
  def update_okr_display_on_kr_selection(self, selected_kr_unique_ids: list,
@@ -211,28 +202,48 @@ class AgenticHandlers:
211
  """
212
  Updates the OKR detail display when Key Results are selected in the CheckboxGroup.
213
  """
 
 
 
 
 
214
  if not self.agentic_modules_really_loaded:
215
  return gr.update(value="Moduli AI non caricati. Impossibile visualizzare i dettagli OKR.")
216
- if not raw_orchestration_results:
 
 
 
 
 
 
 
 
 
 
217
  return gr.update(value="Nessun dato dalla pipeline AI o moduli non caricati.")
218
 
219
- actionable_okrs_dict = raw_orchestration_results.get("actionable_okrs_and_tasks")
 
 
 
 
 
220
  if not actionable_okrs_dict or not isinstance(actionable_okrs_dict.get("okrs"), list):
221
- return gr.update(value="Nessun OKR trovato nei risultati della pipeline.")
222
 
223
  okrs_list = actionable_okrs_dict["okrs"]
224
- if not okrs_list: # Should be caught by above, but defensive
225
  return gr.update(value="Nessun OKR generato.")
226
 
227
- # Create a mapping from unique_kr_id to its (okr_index, kr_index_within_okr)
228
  kr_id_to_indices = {}
229
- if all_krs_for_selection_list: # This list comes from extract_key_results_for_selection
 
230
  for kr_info in all_krs_for_selection_list:
231
- kr_id_to_indices[kr_info['unique_kr_id']] = (kr_info['okr_index'], kr_info['kr_index'])
 
232
 
233
- # Group selected KR indices by their parent OKR index
234
  selected_krs_by_okr_idx = defaultdict(list)
235
- if selected_kr_unique_ids: # This is the list of unique_kr_ids from the checkboxgroup
236
  for kr_unique_id in selected_kr_unique_ids:
237
  if kr_unique_id in kr_id_to_indices:
238
  okr_idx, kr_idx_in_okr = kr_id_to_indices[kr_unique_id]
@@ -240,31 +251,27 @@ class AgenticHandlers:
240
 
241
  output_md_parts = []
242
  for okr_idx, okr_data in enumerate(okrs_list):
243
- # If specific KRs are selected, only show OKRs that have at least one selected KR,
244
- # and then format that OKR to only show its selected KRs.
245
- # If no KRs are selected, show all OKRs with all their KRs.
246
-
247
- accepted_indices_for_this_okr = selected_krs_by_okr_idx.get(okr_idx) # This will be a list of KR indices or None
248
 
249
- if selected_kr_unique_ids: # If there's any selection active
250
- if accepted_indices_for_this_okr is not None: # Only format/display if this OKR has selected KRs
251
  formatted_okr_md = format_single_okr_for_display(
252
  okr_data,
253
  accepted_kr_indices=accepted_indices_for_this_okr,
254
  okr_main_index=okr_idx
255
  )
256
  output_md_parts.append(formatted_okr_md)
257
- else: # No KRs selected, display all OKRs fully
258
  formatted_okr_md = format_single_okr_for_display(
259
  okr_data,
260
- accepted_kr_indices=None, # None means show all KRs for this OKR
261
  okr_main_index=okr_idx
262
  )
263
  output_md_parts.append(formatted_okr_md)
264
 
265
  if not output_md_parts and selected_kr_unique_ids:
266
  final_md = "Nessun OKR corrisponde alla selezione corrente o i KR selezionati non hanno task dettagliati."
267
- elif not output_md_parts and not selected_kr_unique_ids: # Should mean okrs_list was empty
268
  final_md = "Nessun OKR generato."
269
  else:
270
  final_md = "\n\n---\n\n".join(output_md_parts)
@@ -278,17 +285,12 @@ class AgenticHandlers:
278
  return
279
 
280
  if self.okrs_components.get("key_results_cbg"):
281
- # The input 'key_results_cbg' provides the selected IDs.
282
- # If it's truly a Markdown component now, this .change handler might not behave as expected
283
- # for selection, as Markdown isn't typically an input component this way.
284
- # However, the function signature of update_okr_display_on_kr_selection expects selected_kr_unique_ids.
285
- # This setup might need further review if key_results_cbg is indeed Markdown and meant to be interactive.
286
  self.okrs_components['key_results_cbg'].change(
287
  fn=self.update_okr_display_on_kr_selection,
288
  inputs=[
289
- self.okrs_components['key_results_cbg'], # Current value of checkbox group (or Markdown if changed)
290
- self.orchestration_raw_results_st, # State
291
- self.key_results_for_selection_st # State
292
  ],
293
  outputs=[self.okrs_components['okr_detail_display_md']],
294
  api_name="update_okr_display_on_kr_selection"
 
44
  This function is intended to be triggered by changes in token_state
45
  (e.g., after initial load or after sync).
46
  It yields updates for the agentic report and OKR tabs.
47
+ The 5th, 6th, and 7th yielded values are stringified to prevent errors
48
+ if misconfigured UI routes them to Markdown components.
49
  """
50
  logging.info(f"Agentic pipeline auto-trigger. Token: {'Set' if current_token_state_val.get('token') else 'Not Set'}")
51
 
52
  # Initial "waiting" status updates
53
  initial_report_status = "Pipeline AI: In attesa dei dati necessari..."
54
+ initial_okr_value_for_markdown = ""
 
55
  initial_okr_details = "Pipeline AI: In attesa dei dati necessari..."
56
+ initial_orchestration_results = self.orchestration_raw_results_st.value
57
  initial_selected_krs = self.selected_key_result_ids_st.value
58
  initial_krs_for_selection = self.key_results_for_selection_st.value
59
 
 
60
  report_status_md_update = gr.update(value=initial_report_status) if self.report_components.get("agentic_pipeline_status_md") else gr.update()
61
+ report_display_md_update = gr.update()
62
 
 
 
63
  okrs_cbg_update = gr.update(value=initial_okr_value_for_markdown) if self.okrs_components.get("key_results_cbg") else gr.update()
64
  okrs_detail_md_update = gr.update(value=initial_okr_details) if self.okrs_components.get("okr_detail_display_md") else gr.update()
65
 
66
  if not current_token_state_val or not current_token_state_val.get("token"):
67
  logging.info("Agentic pipeline: Token not available in token_state. Skipping actual run.")
68
  yield (
69
+ report_status_md_update,
70
+ report_display_md_update,
71
+ okrs_cbg_update,
72
+ okrs_detail_md_update,
73
+ str(initial_orchestration_results), # Stringify state value
74
+ str(initial_selected_krs), # Stringify state value
75
+ str(initial_krs_for_selection) # Stringify state value
76
  )
77
  return
78
 
 
79
  in_progress_status = "Analisi AI (Sempre) in corso..."
80
  if self.report_components.get("agentic_pipeline_status_md"):
81
  report_status_md_update = gr.update(value=in_progress_status)
82
+ if self.okrs_components.get("okr_detail_display_md"):
83
  okrs_detail_md_update = gr.update(value="Dettagli OKR (Sempre) in corso di generazione...")
84
 
 
85
  yield (
86
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
87
+ str(initial_orchestration_results), # Stringify state value
88
+ str(initial_selected_krs), # Stringify state value
89
+ str(initial_krs_for_selection) # Stringify state value
90
  )
91
 
92
  if not self.agentic_modules_really_loaded:
 
95
  if self.report_components.get("agentic_pipeline_status_md"):
96
  report_status_md_update = gr.update(value=error_status)
97
  if self.report_components.get("agentic_report_display_md"):
98
+ report_display_md_update = gr.update(value=error_status)
99
 
 
 
100
  if self.okrs_components.get("key_results_cbg"):
101
+ okrs_cbg_update = gr.update(value=error_status)
102
 
103
  if self.okrs_components.get("okr_detail_display_md"):
104
+ okrs_detail_md_update = gr.update(value=error_status)
105
 
106
  yield (
107
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
108
+ str(None), str([]), str([]) # Stringify state values
109
  )
110
  return
111
 
112
  try:
 
113
  date_filter_val_agentic = "Sempre"
114
  custom_start_val_agentic = None
115
  custom_end_val_agentic = None
 
130
  krs_for_selection_update_val = []
131
 
132
  if orchestration_output:
133
+ orchestration_results_update_val = orchestration_output
134
 
135
  report_str = orchestration_output.get('comprehensive_analysis_report', "Nessun report testuale fornito.")
136
  if self.report_components.get("agentic_report_display_md"):
 
138
 
139
  actionable_okrs = orchestration_output.get('actionable_okrs_and_tasks')
140
  krs_for_ui_selection_list = extract_key_results_for_selection(actionable_okrs)
141
+ krs_for_selection_update_val = krs_for_ui_selection_list
142
 
143
  if self.okrs_components.get("key_results_cbg"):
 
 
144
  okrs_cbg_update = gr.update(value="Key Results available for selection (display as Markdown)")
 
145
 
 
146
  all_okrs_md_parts = []
147
  if actionable_okrs and isinstance(actionable_okrs.get("okrs"), list):
148
  for okr_idx, okr_item in enumerate(actionable_okrs["okrs"]):
 
155
  if self.okrs_components.get("okr_detail_display_md"):
156
  okrs_detail_md_update = gr.update(value="\n\n---\n\n".join(all_okrs_md_parts))
157
 
158
+ selected_krs_update_val = []
159
+ else:
160
  final_status_text = "Pipeline AI (Sempre): Nessun risultato prodotto."
161
  if self.report_components.get("agentic_report_display_md"):
162
  report_display_md_update = gr.update(value="Nessun report generato dalla pipeline AI (Sempre).")
163
 
 
164
  if self.okrs_components.get("key_results_cbg"):
165
+ okrs_cbg_update = gr.update(value="Nessun Key Result (Markdown display)")
166
 
167
  if self.okrs_components.get("okr_detail_display_md"):
168
  okrs_detail_md_update = gr.update(value="Nessun OKR generato o errore nella pipeline AI (Sempre).")
 
172
 
173
  yield (
174
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
175
+ str(orchestration_results_update_val), # Stringify state value
176
+ str(selected_krs_update_val), # Stringify state value
177
+ str(krs_for_selection_update_val) # Stringify state value
178
  )
179
 
180
  except Exception as e:
 
185
  if self.report_components.get("agentic_report_display_md"):
186
  report_display_md_update = gr.update(value=f"Errore generazione report AI (Sempre): {str(e)}")
187
 
 
188
  if self.okrs_components.get("key_results_cbg"):
189
+ okrs_cbg_update = gr.update(value=f"Errore Key Results (Markdown): {str(e)}")
190
 
191
  if self.okrs_components.get("okr_detail_display_md"):
192
  okrs_detail_md_update = gr.update(value=f"Errore generazione OKR AI (Sempre): {str(e)}")
193
 
194
  yield (
195
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
196
+ str(None), str([]), str([]) # Stringify state values
197
  )
198
 
199
  def update_okr_display_on_kr_selection(self, selected_kr_unique_ids: list,
 
202
  """
203
  Updates the OKR detail display when Key Results are selected in the CheckboxGroup.
204
  """
205
+ # raw_orchestration_results, all_krs_for_selection_list now might be strings
206
+ # if they come from state that was stringified. This needs careful handling
207
+ # if this function is called with outputs from the stringified state.
208
+ # For now, assuming they are passed correctly as dict/list if not from stringified state.
209
+
210
  if not self.agentic_modules_really_loaded:
211
  return gr.update(value="Moduli AI non caricati. Impossibile visualizzare i dettagli OKR.")
212
+
213
+ # Attempt to parse if stringified, this is a significant assumption about how state is used.
214
+ # This part is complex because we don't know if these inputs are direct from UI or from stringified state.
215
+ # A robust solution would involve type checking and conditional parsing (e.g. import json; json.loads if string)
216
+ # For this focused fix, we'll assume they are passed as dict/list for now.
217
+ # If they come from the stringified state, this function will likely fail or misbehave.
218
+ # The problem is, the `inputs` to this handler in `setup_event_handlers` are `gr.State` objects.
219
+ # If those `gr.State` objects now store strings like "'[]'", then `raw_orchestration_results` here
220
+ # will be the string "'[]'", not the list [].
221
+
222
+ if not raw_orchestration_results: # This check might be problematic if "None" (string) is passed
223
  return gr.update(value="Nessun dato dalla pipeline AI o moduli non caricati.")
224
 
225
+ # This is a critical point: if raw_orchestration_results is a string representation
226
+ # of a dict (e.g., "{'key': 'value'}"), .get will fail.
227
+ # We would need to json.loads() it.
228
+ # For now, we proceed assuming it's a dict. This might be the next error point.
229
+ actionable_okrs_dict = raw_orchestration_results.get("actionable_okrs_and_tasks") if isinstance(raw_orchestration_results, dict) else None
230
+
231
  if not actionable_okrs_dict or not isinstance(actionable_okrs_dict.get("okrs"), list):
232
+ return gr.update(value="Nessun OKR trovato nei risultati della pipeline (o dati in formato imprevisto).")
233
 
234
  okrs_list = actionable_okrs_dict["okrs"]
235
+ if not okrs_list:
236
  return gr.update(value="Nessun OKR generato.")
237
 
 
238
  kr_id_to_indices = {}
239
+ # Similar issue here: all_krs_for_selection_list could be a string representation of a list.
240
+ if isinstance(all_krs_for_selection_list, list):
241
  for kr_info in all_krs_for_selection_list:
242
+ if isinstance(kr_info, dict): # defensive check
243
+ kr_id_to_indices[kr_info['unique_kr_id']] = (kr_info['okr_index'], kr_info['kr_index'])
244
 
 
245
  selected_krs_by_okr_idx = defaultdict(list)
246
+ if selected_kr_unique_ids:
247
  for kr_unique_id in selected_kr_unique_ids:
248
  if kr_unique_id in kr_id_to_indices:
249
  okr_idx, kr_idx_in_okr = kr_id_to_indices[kr_unique_id]
 
251
 
252
  output_md_parts = []
253
  for okr_idx, okr_data in enumerate(okrs_list):
254
+ accepted_indices_for_this_okr = selected_krs_by_okr_idx.get(okr_idx)
 
 
 
 
255
 
256
+ if selected_kr_unique_ids:
257
+ if accepted_indices_for_this_okr is not None:
258
  formatted_okr_md = format_single_okr_for_display(
259
  okr_data,
260
  accepted_kr_indices=accepted_indices_for_this_okr,
261
  okr_main_index=okr_idx
262
  )
263
  output_md_parts.append(formatted_okr_md)
264
+ else:
265
  formatted_okr_md = format_single_okr_for_display(
266
  okr_data,
267
+ accepted_kr_indices=None,
268
  okr_main_index=okr_idx
269
  )
270
  output_md_parts.append(formatted_okr_md)
271
 
272
  if not output_md_parts and selected_kr_unique_ids:
273
  final_md = "Nessun OKR corrisponde alla selezione corrente o i KR selezionati non hanno task dettagliati."
274
+ elif not output_md_parts and not selected_kr_unique_ids:
275
  final_md = "Nessun OKR generato."
276
  else:
277
  final_md = "\n\n---\n\n".join(output_md_parts)
 
285
  return
286
 
287
  if self.okrs_components.get("key_results_cbg"):
 
 
 
 
 
288
  self.okrs_components['key_results_cbg'].change(
289
  fn=self.update_okr_display_on_kr_selection,
290
  inputs=[
291
+ self.okrs_components['key_results_cbg'],
292
+ self.orchestration_raw_results_st,
293
+ self.key_results_for_selection_st
294
  ],
295
  outputs=[self.okrs_components['okr_detail_display_md']],
296
  api_name="update_okr_display_on_kr_selection"