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

Update services/agentic_handlers.py

Browse files
Files changed (1) hide show
  1. services/agentic_handlers.py +74 -56
services/agentic_handlers.py CHANGED
@@ -2,6 +2,7 @@
2
  import gradio as gr
3
  import logging
4
  from collections import defaultdict
 
5
 
6
  # Attempt to import agentic pipeline functions and UI formatters
7
  try:
@@ -34,25 +35,28 @@ class AgenticHandlers:
34
  self.token_state = token_state_ref
35
  self.orchestration_raw_results_st = orchestration_raw_results_st_ref
36
  self.key_results_for_selection_st = key_results_for_selection_st_ref
37
- self.selected_key_result_ids_st = selected_key_result_ids_st_ref # Though this is updated by CBG, might be read
38
 
39
- self.agentic_modules_really_loaded = AGENTIC_MODULES_LOADED # Store the flag
40
  logging.info(f"AgenticHandlers initialized. Modules loaded: {self.agentic_modules_really_loaded}")
41
 
42
  async def run_agentic_pipeline_autonomously_on_update(self, current_token_state_val):
43
  """
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
@@ -60,7 +64,7 @@ class AgenticHandlers:
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"):
@@ -70,9 +74,9 @@ class AgenticHandlers:
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
 
@@ -82,11 +86,12 @@ class AgenticHandlers:
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:
@@ -97,15 +102,16 @@ class AgenticHandlers:
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
 
@@ -126,7 +132,7 @@ class AgenticHandlers:
126
  logging.info(f"Autonomous agentic pipeline finished. Output keys: {orchestration_output.keys() if orchestration_output else 'None'}")
127
 
128
  orchestration_results_update_val = None
129
- selected_krs_update_val = []
130
  krs_for_selection_update_val = []
131
 
132
  if orchestration_output:
@@ -138,10 +144,12 @@ class AgenticHandlers:
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):
@@ -155,14 +163,15 @@ class AgenticHandlers:
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,9 +181,9 @@ class AgenticHandlers:
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,48 +194,55 @@ class AgenticHandlers:
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,
200
- raw_orchestration_results: dict,
201
- all_krs_for_selection_list: 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).")
@@ -236,14 +252,16 @@ class AgenticHandlers:
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]
@@ -293,7 +311,7 @@ class AgenticHandlers:
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"
297
  )
298
  logging.info("Agentic OKR selection handler setup complete.")
299
  else:
 
2
  import gradio as gr
3
  import logging
4
  from collections import defaultdict
5
+ import json # Added for JSON serialization/deserialization
6
 
7
  # Attempt to import agentic pipeline functions and UI formatters
8
  try:
 
35
  self.token_state = token_state_ref
36
  self.orchestration_raw_results_st = orchestration_raw_results_st_ref
37
  self.key_results_for_selection_st = key_results_for_selection_st_ref
38
+ self.selected_key_result_ids_st = selected_key_result_ids_st_ref
39
 
40
+ self.agentic_modules_really_loaded = AGENTIC_MODULES_LOADED
41
  logging.info(f"AgenticHandlers initialized. Modules loaded: {self.agentic_modules_really_loaded}")
42
 
43
  async def run_agentic_pipeline_autonomously_on_update(self, current_token_state_val):
44
  """
45
+ This function is intended to be triggered by changes in token_state.
 
46
  It yields updates for the agentic report and OKR tabs.
47
+ State values (5th, 6th, 7th) are serialized to JSON strings.
48
+ Updates for key_results_cbg are now for a CheckboxGroup.
49
  """
50
  logging.info(f"Agentic pipeline auto-trigger. Token: {'Set' if current_token_state_val.get('token') else 'Not Set'}")
51
 
 
52
  initial_report_status = "Pipeline AI: In attesa dei dati necessari..."
 
53
  initial_okr_details = "Pipeline AI: In attesa dei dati necessari..."
54
+
55
+ # Initial state for key_results_cbg (CheckboxGroup)
56
+ initial_okr_cbg_choices = []
57
+ initial_okr_cbg_value = []
58
+ initial_okr_cbg_interactive = False
59
+
60
  initial_orchestration_results = self.orchestration_raw_results_st.value
61
  initial_selected_krs = self.selected_key_result_ids_st.value
62
  initial_krs_for_selection = self.key_results_for_selection_st.value
 
64
  report_status_md_update = gr.update(value=initial_report_status) if self.report_components.get("agentic_pipeline_status_md") else gr.update()
65
  report_display_md_update = gr.update()
66
 
67
+ okrs_cbg_update = gr.update(choices=initial_okr_cbg_choices, value=initial_okr_cbg_value, interactive=initial_okr_cbg_interactive) if self.okrs_components.get("key_results_cbg") else gr.update()
68
  okrs_detail_md_update = gr.update(value=initial_okr_details) if self.okrs_components.get("okr_detail_display_md") else gr.update()
69
 
70
  if not current_token_state_val or not current_token_state_val.get("token"):
 
74
  report_display_md_update,
75
  okrs_cbg_update,
76
  okrs_detail_md_update,
77
+ json.dumps(initial_orchestration_results), # Serialize to JSON
78
+ json.dumps(initial_selected_krs), # Serialize to JSON
79
+ json.dumps(initial_krs_for_selection) # Serialize to JSON
80
  )
81
  return
82
 
 
86
  if self.okrs_components.get("okr_detail_display_md"):
87
  okrs_detail_md_update = gr.update(value="Dettagli OKR (Sempre) in corso di generazione...")
88
 
89
+ # okrs_cbg_update is already set to initial waiting state for CheckboxGroup
90
  yield (
91
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
92
+ json.dumps(initial_orchestration_results), # Serialize to JSON
93
+ json.dumps(initial_selected_krs), # Serialize to JSON
94
+ json.dumps(initial_krs_for_selection) # Serialize to JSON
95
  )
96
 
97
  if not self.agentic_modules_really_loaded:
 
102
  if self.report_components.get("agentic_report_display_md"):
103
  report_display_md_update = gr.update(value=error_status)
104
 
105
+ # Update for key_results_cbg (CheckboxGroup) in error case
106
  if self.okrs_components.get("key_results_cbg"):
107
+ okrs_cbg_update = gr.update(choices=[], value=[], interactive=False)
108
 
109
  if self.okrs_components.get("okr_detail_display_md"):
110
  okrs_detail_md_update = gr.update(value=error_status)
111
 
112
  yield (
113
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
114
+ json.dumps(None), json.dumps([]), json.dumps([]) # Serialize to JSON
115
  )
116
  return
117
 
 
132
  logging.info(f"Autonomous agentic pipeline finished. Output keys: {orchestration_output.keys() if orchestration_output else 'None'}")
133
 
134
  orchestration_results_update_val = None
135
+ selected_krs_update_val = [] # This will be the value for the CheckboxGroup, initially empty
136
  krs_for_selection_update_val = []
137
 
138
  if orchestration_output:
 
144
 
145
  actionable_okrs = orchestration_output.get('actionable_okrs_and_tasks')
146
  krs_for_ui_selection_list = extract_key_results_for_selection(actionable_okrs)
147
+ krs_for_selection_update_val = krs_for_ui_selection_list # This is the list of dicts
148
 
149
+ # Prepare choices for key_results_cbg (CheckboxGroup)
150
+ kr_choices_for_cbg = [(kr['kr_description'], kr['unique_kr_id']) for kr in krs_for_ui_selection_list]
151
  if self.okrs_components.get("key_results_cbg"):
152
+ okrs_cbg_update = gr.update(choices=kr_choices_for_cbg, value=[], interactive=True)
153
 
154
  all_okrs_md_parts = []
155
  if actionable_okrs and isinstance(actionable_okrs.get("okrs"), list):
 
163
  if self.okrs_components.get("okr_detail_display_md"):
164
  okrs_detail_md_update = gr.update(value="\n\n---\n\n".join(all_okrs_md_parts))
165
 
166
+ selected_krs_update_val = [] # Reset CheckboxGroup selection
167
  else:
168
  final_status_text = "Pipeline AI (Sempre): Nessun risultato prodotto."
169
  if self.report_components.get("agentic_report_display_md"):
170
  report_display_md_update = gr.update(value="Nessun report generato dalla pipeline AI (Sempre).")
171
 
172
+ # Update for key_results_cbg (CheckboxGroup) if no output
173
  if self.okrs_components.get("key_results_cbg"):
174
+ okrs_cbg_update = gr.update(choices=[], value=[], interactive=False)
175
 
176
  if self.okrs_components.get("okr_detail_display_md"):
177
  okrs_detail_md_update = gr.update(value="Nessun OKR generato o errore nella pipeline AI (Sempre).")
 
181
 
182
  yield (
183
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
184
+ json.dumps(orchestration_results_update_val), # Serialize to JSON
185
+ json.dumps(selected_krs_update_val), # Serialize to JSON (value for selected_key_result_ids_st)
186
+ json.dumps(krs_for_selection_update_val) # Serialize to JSON (value for key_results_for_selection_st)
187
  )
188
 
189
  except Exception as e:
 
194
  if self.report_components.get("agentic_report_display_md"):
195
  report_display_md_update = gr.update(value=f"Errore generazione report AI (Sempre): {str(e)}")
196
 
197
+ # Update for key_results_cbg (CheckboxGroup) in case of exception
198
  if self.okrs_components.get("key_results_cbg"):
199
+ okrs_cbg_update = gr.update(choices=[], value=[], interactive=False)
200
 
201
  if self.okrs_components.get("okr_detail_display_md"):
202
  okrs_detail_md_update = gr.update(value=f"Errore generazione OKR AI (Sempre): {str(e)}")
203
 
204
  yield (
205
  report_status_md_update, report_display_md_update, okrs_cbg_update, okrs_detail_md_update,
206
+ json.dumps(None), json.dumps([]), json.dumps([]) # Serialize to JSON
207
  )
208
 
209
  def update_okr_display_on_kr_selection(self, selected_kr_unique_ids: list,
210
+ raw_orchestration_results_json: str,
211
+ all_krs_for_selection_list_json: str):
212
  """
213
  Updates the OKR detail display when Key Results are selected in the CheckboxGroup.
214
+ raw_orchestration_results_json and all_krs_for_selection_list_json are expected
215
+ to be JSON strings from state.
216
  """
 
 
 
 
 
217
  if not self.agentic_modules_really_loaded:
218
  return gr.update(value="Moduli AI non caricati. Impossibile visualizzare i dettagli OKR.")
219
 
220
+ parsed_orchestration_results = None
221
+ try:
222
+ if raw_orchestration_results_json: # Check if the string is not empty
223
+ parsed_orchestration_results = json.loads(raw_orchestration_results_json)
224
+ except json.JSONDecodeError as e:
225
+ logging.error(f"Failed to parse raw_orchestration_results_json: {raw_orchestration_results_json}. Error: {e}")
226
+ return gr.update(value="Errore: Dati interni corrotti (orchestration results).")
 
227
 
228
+ if not parsed_orchestration_results: # This covers None or empty after parsing
229
+ return gr.update(value="Nessun dato dalla pipeline AI (orchestration results).")
230
 
231
+ parsed_krs_for_selection_list = []
232
+ try:
233
+ if all_krs_for_selection_list_json: # Check if the string is not empty
234
+ parsed_krs_for_selection_list = json.loads(all_krs_for_selection_list_json)
235
+ except json.JSONDecodeError as e:
236
+ logging.error(f"Failed to parse all_krs_for_selection_list_json: {all_krs_for_selection_list_json}. Error: {e}")
237
+ return gr.update(value="Errore: Dati interni corrotti (krs for selection).")
238
+
239
+ # Ensure parsed_krs_for_selection_list is a list, even if JSON was 'null' or other non-list type
240
+ if not isinstance(parsed_krs_for_selection_list, list):
241
+ logging.warning(f"Parsed all_krs_for_selection_list is not a list: {type(parsed_krs_for_selection_list)}. Defaulting to empty list.")
242
+ parsed_krs_for_selection_list = []
243
+
244
+
245
+ actionable_okrs_dict = parsed_orchestration_results.get("actionable_okrs_and_tasks") if isinstance(parsed_orchestration_results, dict) else None
246
 
247
  if not actionable_okrs_dict or not isinstance(actionable_okrs_dict.get("okrs"), list):
248
  return gr.update(value="Nessun OKR trovato nei risultati della pipeline (o dati in formato imprevisto).")
 
252
  return gr.update(value="Nessun OKR generato.")
253
 
254
  kr_id_to_indices = {}
255
+ if isinstance(parsed_krs_for_selection_list, list): # Ensure it's a list before iterating
256
+ for kr_info in parsed_krs_for_selection_list:
257
+ if isinstance(kr_info, dict) and 'unique_kr_id' in kr_info and 'okr_index' in kr_info and 'kr_index' in kr_info:
 
258
  kr_id_to_indices[kr_info['unique_kr_id']] = (kr_info['okr_index'], kr_info['kr_index'])
259
+ else:
260
+ logging.warning(f"Skipping invalid kr_info item: {kr_info}")
261
+
262
  selected_krs_by_okr_idx = defaultdict(list)
263
+ # selected_kr_unique_ids comes directly from CheckboxGroup, should be a list of strings/values
264
+ if isinstance(selected_kr_unique_ids, list):
265
  for kr_unique_id in selected_kr_unique_ids:
266
  if kr_unique_id in kr_id_to_indices:
267
  okr_idx, kr_idx_in_okr = kr_id_to_indices[kr_unique_id]
 
311
  self.key_results_for_selection_st
312
  ],
313
  outputs=[self.okrs_components['okr_detail_display_md']],
314
+ api_name="update_okr_display_on_kr_selection" # Keep api_name for Gradio
315
  )
316
  logging.info("Agentic OKR selection handler setup complete.")
317
  else: