Spaces:
Sleeping
Sleeping
Update refApp.py
Browse files
refApp.py
CHANGED
|
@@ -4,6 +4,54 @@ import copy
|
|
| 4 |
import json
|
| 5 |
import requests
|
| 6 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
# --- PAGE CONFIGURATION (MUST BE THE FIRST STREAMLIT COMMAND) ---
|
| 9 |
# Fixed deployment issue
|
|
@@ -340,39 +388,58 @@ def save_to_local_file(new_content_json_string):
|
|
| 340 |
st.error(f"Erreur de sauvegarde du fichier local: {e}")
|
| 341 |
return False
|
| 342 |
|
| 343 |
-
|
|
|
|
| 344 |
if 'editable_prompts' in st.session_state:
|
| 345 |
data_to_save = _preprocess_for_saving(st.session_state.editable_prompts)
|
| 346 |
try:
|
| 347 |
json_string = json.dumps(data_to_save, indent=4, ensure_ascii=False)
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
except Exception as e: # pragma: no cover
|
| 353 |
-
st.error(f"Erreur préparation données pour sauvegarde
|
| 354 |
-
|
| 355 |
-
def
|
| 356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
if raw_content:
|
| 358 |
try:
|
| 359 |
loaded_data = json.loads(raw_content)
|
| 360 |
if not loaded_data or not isinstance(loaded_data, dict):
|
| 361 |
-
raise ValueError("Contenu fichier
|
| 362 |
return _postprocess_after_loading(loaded_data)
|
| 363 |
except (json.JSONDecodeError, TypeError, ValueError) as e:
|
| 364 |
-
st.info(f"Erreur chargement fichier
|
| 365 |
else:
|
| 366 |
-
st.info("Fichier
|
| 367 |
initial_data = copy.deepcopy(INITIAL_PROMPT_TEMPLATES)
|
| 368 |
if raw_content is None or raw_content == "{}":
|
| 369 |
data_to_save_init = _preprocess_for_saving(initial_data)
|
| 370 |
try:
|
| 371 |
json_string_init = json.dumps(data_to_save_init, indent=4, ensure_ascii=False)
|
| 372 |
-
|
| 373 |
-
|
|
|
|
|
|
|
| 374 |
except Exception as e: # pragma: no cover
|
| 375 |
-
st.error(f"Erreur sauvegarde initiale
|
| 376 |
return initial_data
|
| 377 |
|
| 378 |
# --- ACCESS CODE VERIFICATION ---
|
|
@@ -444,7 +511,7 @@ if not st.session_state.access_granted:
|
|
| 444 |
|
| 445 |
# --- Session State Initialization ---
|
| 446 |
if 'editable_prompts' not in st.session_state:
|
| 447 |
-
st.session_state.editable_prompts =
|
| 448 |
if 'view_mode' not in st.session_state:
|
| 449 |
st.session_state.view_mode = "accueil" # Nouvelle vue par défaut
|
| 450 |
|
|
@@ -675,7 +742,7 @@ with tab_edition_generation:
|
|
| 675 |
st.error(f"Le métier '{new_family_name.strip()}' existe déjà.")
|
| 676 |
else:
|
| 677 |
st.session_state.editable_prompts[new_family_name.strip()] = {}
|
| 678 |
-
|
| 679 |
st.success(f"Métier '{new_family_name.strip()}' créée.")
|
| 680 |
st.session_state.force_select_family_name = new_family_name.strip()
|
| 681 |
st.session_state.use_case_selector_edition = None
|
|
@@ -698,7 +765,7 @@ with tab_edition_generation:
|
|
| 698 |
st.error(f"Un métier nommé '{renamed_family_name}' existe déjà.")
|
| 699 |
else:
|
| 700 |
st.session_state.editable_prompts[renamed_family_name] = st.session_state.editable_prompts.pop(current_selected_family_for_edit_logic)
|
| 701 |
-
|
| 702 |
st.success(f"Métier '{current_selected_family_for_edit_logic}' renommé en '{renamed_family_name}'.")
|
| 703 |
st.session_state.force_select_family_name = renamed_family_name
|
| 704 |
if st.session_state.library_selected_family_for_display == current_selected_family_for_edit_logic:
|
|
@@ -717,7 +784,7 @@ with tab_edition_generation:
|
|
| 717 |
if st.button(_text_confirm_delete, type="primary", key=f"confirm_del_fam_sb_{current_selected_family_for_edit_logic}", use_container_width=True):
|
| 718 |
deleted_fam_name = current_selected_family_for_edit_logic
|
| 719 |
del st.session_state.editable_prompts[current_selected_family_for_edit_logic]
|
| 720 |
-
|
| 721 |
st.success(f"Métier '{deleted_fam_name}' supprimée.")
|
| 722 |
st.session_state.confirming_delete_family_name = None
|
| 723 |
st.session_state.family_selector_edition = None
|
|
@@ -786,7 +853,7 @@ with tab_edition_generation:
|
|
| 786 |
"variables": [], "tags": [],
|
| 787 |
"usage_count": 0, "created_at": now_iso_create, "updated_at": now_iso_update
|
| 788 |
}
|
| 789 |
-
|
| 790 |
st.success(f"Cas d'usage '{uc_name_val}' créé avec succès dans '{parent_family_val}'.")
|
| 791 |
st.session_state.show_create_new_use_case_form = False
|
| 792 |
st.session_state.force_select_family_name = parent_family_val
|
|
@@ -1078,7 +1145,7 @@ elif st.session_state.view_mode == "library":
|
|
| 1078 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 1079 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 1080 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 1081 |
-
|
| 1082 |
st.success(f"Cas d'usage '{original_uc_name_for_dup}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 1083 |
|
| 1084 |
st.session_state.duplicating_use_case_details = None
|
|
@@ -1105,7 +1172,7 @@ elif st.session_state.view_mode == "library":
|
|
| 1105 |
deleted_uc_name_for_msg = details['use_case']
|
| 1106 |
deleted_uc_fam_for_msg = details['family']
|
| 1107 |
del st.session_state.editable_prompts[details["family"]][details["use_case"]]
|
| 1108 |
-
|
| 1109 |
st.success(f"'{deleted_uc_name_for_msg}' supprimé de '{deleted_uc_fam_for_msg}'.")
|
| 1110 |
st.session_state.confirming_delete_details = None
|
| 1111 |
st.rerun()
|
|
@@ -1258,7 +1325,7 @@ elif st.session_state.view_mode == "edit":
|
|
| 1258 |
st.balloons()
|
| 1259 |
current_prompt_config["usage_count"] = current_prompt_config.get("usage_count", 0) + 1
|
| 1260 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1261 |
-
|
| 1262 |
|
| 1263 |
except Exception as e: # Garder un catch-all pour les erreurs imprévues
|
| 1264 |
st.error(f"Erreur inattendue lors de la génération du prompt : {e}") # pragma: no cover
|
|
@@ -1308,7 +1375,7 @@ elif st.session_state.view_mode == "edit":
|
|
| 1308 |
current_prompt_config['template'] = new_tpl
|
| 1309 |
current_prompt_config['description'] = new_desc
|
| 1310 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1311 |
-
|
| 1312 |
st.success("Template et Description sauvegardés!");
|
| 1313 |
st.rerun()
|
| 1314 |
st.markdown("---"); st.subheader("Variables du Prompt"); current_variables_list = current_prompt_config.get('variables', [])
|
|
@@ -1320,14 +1387,14 @@ elif st.session_state.view_mode == "edit":
|
|
| 1320 |
with col_info: st.markdown(f"**{idx + 1}. {var_data.get('name', 'N/A')}** ({var_data.get('label', 'N/A')})\n*Type: `{var_data.get('type', 'N/A')}`*")
|
| 1321 |
with col_up:
|
| 1322 |
disable_up_button = (idx == 0)
|
| 1323 |
-
if st.button("↑", key=f"{action_key_prefix}_up", help="Monter cette variable", disabled=disable_up_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx-1] = current_variables_list[idx-1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1324 |
with col_down:
|
| 1325 |
disable_down_button = (idx == len(current_variables_list) - 1)
|
| 1326 |
-
if st.button("↓", key=f"{action_key_prefix}_down", help="Descendre cette variable", disabled=disable_down_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx+1] = current_variables_list[idx+1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1327 |
with col_edit:
|
| 1328 |
if st.button("Modifier", key=f"{action_key_prefix}_edit", use_container_width=True): st.session_state.editing_variable_info = { "family": final_selected_family_edition, "use_case": final_selected_use_case_edition, "index": idx, "data": copy.deepcopy(var_data) }; st.session_state.variable_type_to_create = var_data.get('type'); st.rerun()
|
| 1329 |
with col_delete:
|
| 1330 |
-
if st.button("Suppr.", key=f"{action_key_prefix}_delete", type="secondary", use_container_width=True): variable_name_to_delete = current_variables_list.pop(idx).get('name', 'Variable inconnue'); current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1331 |
st.markdown("---"); st.subheader("Ajouter une Variable"); is_editing_var = False; variable_data_for_form = {"name": "", "label": "", "type": "", "options": "", "default": ""}
|
| 1332 |
if st.session_state.editing_variable_info and st.session_state.editing_variable_info.get("family") == final_selected_family_edition and st.session_state.editing_variable_info.get("use_case") == final_selected_use_case_edition:
|
| 1333 |
edit_var_idx = st.session_state.editing_variable_info["index"]
|
|
@@ -1430,7 +1497,7 @@ elif st.session_state.view_mode == "edit":
|
|
| 1430 |
if var_name_val_submit in existing_var_names_in_uc: st.error(f"Une variable avec le nom technique '{var_name_val_submit}' existe déjà pour ce cas d'usage."); can_proceed_with_save = False
|
| 1431 |
else: target_vars_list.append(new_var_data_to_submit); st.success(f"Variable '{var_name_val_submit}' ajoutée avec succès.")
|
| 1432 |
if can_proceed_with_save:
|
| 1433 |
-
current_prompt_config["variables"] = target_vars_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1434 |
if not is_editing_var: st.session_state.variable_type_to_create = None
|
| 1435 |
st.rerun()
|
| 1436 |
|
|
@@ -1444,7 +1511,7 @@ elif st.session_state.view_mode == "edit":
|
|
| 1444 |
st.rerun()
|
| 1445 |
st.markdown("---"); st.subheader("🏷️ Tags"); current_tags_str = ", ".join(current_prompt_config.get("tags", []))
|
| 1446 |
new_tags_str_input = st.text_input("Tags (séparés par des virgules):", value=current_tags_str, key=f"tags_input_{final_selected_family_edition}_{final_selected_use_case_edition}")
|
| 1447 |
-
if st.button("Sauvegarder Tags", key=f"save_tags_btn_{final_selected_family_edition}_{final_selected_use_case_edition}"): current_prompt_config["tags"] = sorted(list(set(t.strip() for t in new_tags_str_input.split(',') if t.strip()))); current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1448 |
|
| 1449 |
st.markdown("---")
|
| 1450 |
st.subheader("Actions sur le Cas d'Usage")
|
|
@@ -1501,7 +1568,7 @@ elif st.session_state.view_mode == "edit":
|
|
| 1501 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 1502 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 1503 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 1504 |
-
|
| 1505 |
st.success(f"Cas d'usage '{original_uc_name_for_dup_form}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 1506 |
|
| 1507 |
st.session_state.duplicating_use_case_details = None
|
|
@@ -1696,7 +1763,7 @@ elif st.session_state.view_mode == "generator":
|
|
| 1696 |
st.balloons()
|
| 1697 |
current_prompt_config["usage_count"] = current_prompt_config.get("usage_count", 0) + 1
|
| 1698 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1699 |
-
|
| 1700 |
|
| 1701 |
except Exception as e:
|
| 1702 |
st.error(f"Erreur inattendue lors de la génération du prompt : {e}")
|
|
@@ -1749,7 +1816,7 @@ elif st.session_state.view_mode == "generator":
|
|
| 1749 |
current_prompt_config['template'] = new_tpl
|
| 1750 |
current_prompt_config['description'] = new_desc
|
| 1751 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1752 |
-
|
| 1753 |
st.success("Template et Description sauvegardés!");
|
| 1754 |
st.rerun()
|
| 1755 |
st.markdown("---"); st.subheader("Variables du Prompt"); current_variables_list = current_prompt_config.get('variables', [])
|
|
@@ -1761,14 +1828,14 @@ elif st.session_state.view_mode == "generator":
|
|
| 1761 |
with col_info: st.markdown(f"**{idx + 1}. {var_data.get('name', 'N/A')}** ({var_data.get('label', 'N/A')})\n*Type: `{var_data.get('type', 'N/A')}`*")
|
| 1762 |
with col_up:
|
| 1763 |
disable_up_button = (idx == 0)
|
| 1764 |
-
if st.button("↑", key=f"{action_key_prefix}_up", help="Monter cette variable", disabled=disable_up_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx-1] = current_variables_list[idx-1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1765 |
with col_down:
|
| 1766 |
disable_down_button = (idx == len(current_variables_list) - 1)
|
| 1767 |
-
if st.button("↓", key=f"{action_key_prefix}_down", help="Descendre cette variable", disabled=disable_down_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx+1] = current_variables_list[idx+1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1768 |
with col_edit:
|
| 1769 |
if st.button("Modifier", key=f"{action_key_prefix}_edit", use_container_width=True): st.session_state.editing_variable_info = { "family": generator_family, "use_case": generator_use_case, "index": idx, "data": copy.deepcopy(var_data) }; st.session_state.variable_type_to_create = var_data.get('type'); st.rerun()
|
| 1770 |
with col_delete:
|
| 1771 |
-
if st.button("Suppr.", key=f"{action_key_prefix}_delete", type="secondary", use_container_width=True): variable_name_to_delete = current_variables_list.pop(idx).get('name', 'Variable inconnue'); current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1772 |
st.markdown("---"); st.subheader("Ajouter une Variable"); is_editing_var = False; variable_data_for_form = {"name": "", "label": "", "type": "", "options": "", "default": ""}
|
| 1773 |
if st.session_state.editing_variable_info and st.session_state.editing_variable_info.get("family") == generator_family and st.session_state.editing_variable_info.get("use_case") == generator_use_case:
|
| 1774 |
edit_var_idx = st.session_state.editing_variable_info["index"]
|
|
@@ -1871,7 +1938,7 @@ elif st.session_state.view_mode == "generator":
|
|
| 1871 |
if var_name_val_submit in existing_var_names_in_uc: st.error(f"Une variable avec le nom technique '{var_name_val_submit}' existe déjà pour ce cas d'usage."); can_proceed_with_save = False
|
| 1872 |
else: target_vars_list.append(new_var_data_to_submit); st.success(f"Variable '{var_name_val_submit}' ajoutée avec succès.")
|
| 1873 |
if can_proceed_with_save:
|
| 1874 |
-
current_prompt_config["variables"] = target_vars_list; current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1875 |
if not is_editing_var: st.session_state.variable_type_to_create = None
|
| 1876 |
st.rerun()
|
| 1877 |
|
|
@@ -1885,7 +1952,7 @@ elif st.session_state.view_mode == "generator":
|
|
| 1885 |
st.rerun()
|
| 1886 |
st.markdown("---"); st.subheader("🏷️ Tags"); current_tags_str = ", ".join(current_prompt_config.get("tags", []))
|
| 1887 |
new_tags_str_input = st.text_input("Tags (séparés par des virgules):", value=current_tags_str, key=f"tags_input_{generator_family}_{generator_use_case}")
|
| 1888 |
-
if st.button("Sauvegarder Tags", key=f"save_tags_btn_{generator_family}_{generator_use_case}"): current_prompt_config["tags"] = sorted(list(set(t.strip() for t in new_tags_str_input.split(',') if t.strip()))); current_prompt_config["updated_at"] = datetime.now().isoformat();
|
| 1889 |
|
| 1890 |
st.markdown("---")
|
| 1891 |
st.subheader("Actions sur le Cas d'Usage")
|
|
@@ -1942,7 +2009,7 @@ elif st.session_state.view_mode == "generator":
|
|
| 1942 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 1943 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 1944 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 1945 |
-
|
| 1946 |
st.success(f"Cas d'usage '{original_uc_name_for_dup_form}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 1947 |
|
| 1948 |
st.session_state.duplicating_use_case_details = None
|
|
@@ -2053,7 +2120,7 @@ elif st.session_state.view_mode == "inject_manual":
|
|
| 2053 |
if first_new_uc_name is None:
|
| 2054 |
first_new_uc_name = uc_name_stripped
|
| 2055 |
if successful_injections:
|
| 2056 |
-
|
| 2057 |
st.success(f"{len(successful_injections)} cas d'usage injectés avec succès dans '{target_family_name}': {', '.join(successful_injections)}")
|
| 2058 |
st.session_state.injection_json_text = ""
|
| 2059 |
if first_new_uc_name:
|
|
|
|
| 4 |
import json
|
| 5 |
import requests
|
| 6 |
import os
|
| 7 |
+
# --- Hugging Face Hub integration ---
|
| 8 |
+
try:
|
| 9 |
+
from huggingface_hub import HfApi, hf_hub_download
|
| 10 |
+
HF_HUB_AVAILABLE = True
|
| 11 |
+
except ImportError:
|
| 12 |
+
HF_HUB_AVAILABLE = False
|
| 13 |
+
|
| 14 |
+
HF_REPO_ID = "AIB-Research/bibliPrompt"
|
| 15 |
+
HF_JSON_FILENAME = "prompt_templates_data_v3.json"
|
| 16 |
+
HF_TOKEN = os.environ.get("HF_TOKEN", None)
|
| 17 |
+
|
| 18 |
+
# --- Save to Hugging Face Space ---
|
| 19 |
+
def save_to_hf_space(json_path, repo_id=HF_REPO_ID, token=HF_TOKEN):
|
| 20 |
+
if not HF_HUB_AVAILABLE:
|
| 21 |
+
st.warning("huggingface_hub n'est pas installé. Sauvegarde sur HF désactivée.")
|
| 22 |
+
return False
|
| 23 |
+
try:
|
| 24 |
+
api = HfApi()
|
| 25 |
+
api.upload_file(
|
| 26 |
+
path_or_fileobj=json_path,
|
| 27 |
+
path_in_repo=HF_JSON_FILENAME,
|
| 28 |
+
repo_id=repo_id,
|
| 29 |
+
repo_type="space",
|
| 30 |
+
token=token
|
| 31 |
+
)
|
| 32 |
+
st.toast("💾 Données sauvegardées sur Hugging Face Space!", icon="🤗")
|
| 33 |
+
return True
|
| 34 |
+
except Exception as e:
|
| 35 |
+
st.warning(f"Erreur lors de la sauvegarde sur Hugging Face: {e}")
|
| 36 |
+
return False
|
| 37 |
+
|
| 38 |
+
# --- Load from Hugging Face Space ---
|
| 39 |
+
def load_from_hf_space(repo_id=HF_REPO_ID, token=HF_TOKEN):
|
| 40 |
+
if not HF_HUB_AVAILABLE:
|
| 41 |
+
st.warning("huggingface_hub n'est pas installé. Chargement depuis HF désactivé.")
|
| 42 |
+
return None
|
| 43 |
+
try:
|
| 44 |
+
local_path = hf_hub_download(
|
| 45 |
+
repo_id=repo_id,
|
| 46 |
+
filename=HF_JSON_FILENAME,
|
| 47 |
+
repo_type="space",
|
| 48 |
+
token=token
|
| 49 |
+
)
|
| 50 |
+
with open(local_path, "r", encoding="utf-8") as f:
|
| 51 |
+
return f.read()
|
| 52 |
+
except Exception as e:
|
| 53 |
+
st.warning(f"Erreur lors du chargement depuis Hugging Face: {e}")
|
| 54 |
+
return None
|
| 55 |
|
| 56 |
# --- PAGE CONFIGURATION (MUST BE THE FIRST STREAMLIT COMMAND) ---
|
| 57 |
# Fixed deployment issue
|
|
|
|
| 388 |
st.error(f"Erreur de sauvegarde du fichier local: {e}")
|
| 389 |
return False
|
| 390 |
|
| 391 |
+
# --- Unified save/load functions ---
|
| 392 |
+
def save_editable_prompts_to_local_and_hf():
|
| 393 |
if 'editable_prompts' in st.session_state:
|
| 394 |
data_to_save = _preprocess_for_saving(st.session_state.editable_prompts)
|
| 395 |
try:
|
| 396 |
json_string = json.dumps(data_to_save, indent=4, ensure_ascii=False)
|
| 397 |
+
local_ok = save_to_local_file(json_string)
|
| 398 |
+
hf_ok = False
|
| 399 |
+
# Save to HF Space if possible
|
| 400 |
+
with open(LOCAL_DATA_FILENAME, 'w', encoding='utf-8') as f:
|
| 401 |
+
f.write(json_string)
|
| 402 |
+
if HF_HUB_AVAILABLE:
|
| 403 |
+
hf_ok = save_to_hf_space(LOCAL_DATA_FILENAME)
|
| 404 |
+
if local_ok and hf_ok:
|
| 405 |
+
st.toast("💾 Données sauvegardées localement et sur Hugging Face!", icon="💾")
|
| 406 |
+
elif local_ok:
|
| 407 |
+
st.toast("💾 Données sauvegardées localement!", icon="💾")
|
| 408 |
+
elif hf_ok:
|
| 409 |
+
st.toast("💾 Données sauvegardées sur Hugging Face!", icon="🤗")
|
| 410 |
+
else:
|
| 411 |
+
st.warning("Sauvegarde échouée.")
|
| 412 |
except Exception as e: # pragma: no cover
|
| 413 |
+
st.error(f"Erreur préparation données pour sauvegarde: {e}")
|
| 414 |
+
|
| 415 |
+
def load_editable_prompts_from_local_or_hf():
|
| 416 |
+
# Try HF first, fallback to local
|
| 417 |
+
raw_content = None
|
| 418 |
+
if HF_HUB_AVAILABLE:
|
| 419 |
+
raw_content = load_from_hf_space()
|
| 420 |
+
if not raw_content:
|
| 421 |
+
raw_content = get_local_file_content()
|
| 422 |
if raw_content:
|
| 423 |
try:
|
| 424 |
loaded_data = json.loads(raw_content)
|
| 425 |
if not loaded_data or not isinstance(loaded_data, dict):
|
| 426 |
+
raise ValueError("Contenu fichier vide ou mal structuré.")
|
| 427 |
return _postprocess_after_loading(loaded_data)
|
| 428 |
except (json.JSONDecodeError, TypeError, ValueError) as e:
|
| 429 |
+
st.info(f"Erreur chargement fichier ('{str(e)[:50]}...'). Initialisation avec modèles par défaut.")
|
| 430 |
else:
|
| 431 |
+
st.info("Fichier vide ou inaccessible. Initialisation avec modèles par défaut.")
|
| 432 |
initial_data = copy.deepcopy(INITIAL_PROMPT_TEMPLATES)
|
| 433 |
if raw_content is None or raw_content == "{}":
|
| 434 |
data_to_save_init = _preprocess_for_saving(initial_data)
|
| 435 |
try:
|
| 436 |
json_string_init = json.dumps(data_to_save_init, indent=4, ensure_ascii=False)
|
| 437 |
+
save_to_local_file(json_string_init)
|
| 438 |
+
if HF_HUB_AVAILABLE:
|
| 439 |
+
save_to_hf_space(LOCAL_DATA_FILENAME)
|
| 440 |
+
st.info("Modèles par défaut sauvegardés pour initialisation.")
|
| 441 |
except Exception as e: # pragma: no cover
|
| 442 |
+
st.error(f"Erreur sauvegarde initiale: {e}")
|
| 443 |
return initial_data
|
| 444 |
|
| 445 |
# --- ACCESS CODE VERIFICATION ---
|
|
|
|
| 511 |
|
| 512 |
# --- Session State Initialization ---
|
| 513 |
if 'editable_prompts' not in st.session_state:
|
| 514 |
+
st.session_state.editable_prompts = load_editable_prompts_from_local_or_hf()
|
| 515 |
if 'view_mode' not in st.session_state:
|
| 516 |
st.session_state.view_mode = "accueil" # Nouvelle vue par défaut
|
| 517 |
|
|
|
|
| 742 |
st.error(f"Le métier '{new_family_name.strip()}' existe déjà.")
|
| 743 |
else:
|
| 744 |
st.session_state.editable_prompts[new_family_name.strip()] = {}
|
| 745 |
+
save_editable_prompts_to_local_and_hf()
|
| 746 |
st.success(f"Métier '{new_family_name.strip()}' créée.")
|
| 747 |
st.session_state.force_select_family_name = new_family_name.strip()
|
| 748 |
st.session_state.use_case_selector_edition = None
|
|
|
|
| 765 |
st.error(f"Un métier nommé '{renamed_family_name}' existe déjà.")
|
| 766 |
else:
|
| 767 |
st.session_state.editable_prompts[renamed_family_name] = st.session_state.editable_prompts.pop(current_selected_family_for_edit_logic)
|
| 768 |
+
save_editable_prompts_to_local_and_hf()
|
| 769 |
st.success(f"Métier '{current_selected_family_for_edit_logic}' renommé en '{renamed_family_name}'.")
|
| 770 |
st.session_state.force_select_family_name = renamed_family_name
|
| 771 |
if st.session_state.library_selected_family_for_display == current_selected_family_for_edit_logic:
|
|
|
|
| 784 |
if st.button(_text_confirm_delete, type="primary", key=f"confirm_del_fam_sb_{current_selected_family_for_edit_logic}", use_container_width=True):
|
| 785 |
deleted_fam_name = current_selected_family_for_edit_logic
|
| 786 |
del st.session_state.editable_prompts[current_selected_family_for_edit_logic]
|
| 787 |
+
save_editable_prompts_to_local_and_hf()
|
| 788 |
st.success(f"Métier '{deleted_fam_name}' supprimée.")
|
| 789 |
st.session_state.confirming_delete_family_name = None
|
| 790 |
st.session_state.family_selector_edition = None
|
|
|
|
| 853 |
"variables": [], "tags": [],
|
| 854 |
"usage_count": 0, "created_at": now_iso_create, "updated_at": now_iso_update
|
| 855 |
}
|
| 856 |
+
save_editable_prompts_to_local_and_hf()
|
| 857 |
st.success(f"Cas d'usage '{uc_name_val}' créé avec succès dans '{parent_family_val}'.")
|
| 858 |
st.session_state.show_create_new_use_case_form = False
|
| 859 |
st.session_state.force_select_family_name = parent_family_val
|
|
|
|
| 1145 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 1146 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 1147 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 1148 |
+
save_editable_prompts_to_local_and_hf()
|
| 1149 |
st.success(f"Cas d'usage '{original_uc_name_for_dup}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 1150 |
|
| 1151 |
st.session_state.duplicating_use_case_details = None
|
|
|
|
| 1172 |
deleted_uc_name_for_msg = details['use_case']
|
| 1173 |
deleted_uc_fam_for_msg = details['family']
|
| 1174 |
del st.session_state.editable_prompts[details["family"]][details["use_case"]]
|
| 1175 |
+
save_editable_prompts_to_local_and_hf()
|
| 1176 |
st.success(f"'{deleted_uc_name_for_msg}' supprimé de '{deleted_uc_fam_for_msg}'.")
|
| 1177 |
st.session_state.confirming_delete_details = None
|
| 1178 |
st.rerun()
|
|
|
|
| 1325 |
st.balloons()
|
| 1326 |
current_prompt_config["usage_count"] = current_prompt_config.get("usage_count", 0) + 1
|
| 1327 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1328 |
+
save_editable_prompts_to_local_and_hf()
|
| 1329 |
|
| 1330 |
except Exception as e: # Garder un catch-all pour les erreurs imprévues
|
| 1331 |
st.error(f"Erreur inattendue lors de la génération du prompt : {e}") # pragma: no cover
|
|
|
|
| 1375 |
current_prompt_config['template'] = new_tpl
|
| 1376 |
current_prompt_config['description'] = new_desc
|
| 1377 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1378 |
+
save_editable_prompts_to_local_and_hf()
|
| 1379 |
st.success("Template et Description sauvegardés!");
|
| 1380 |
st.rerun()
|
| 1381 |
st.markdown("---"); st.subheader("Variables du Prompt"); current_variables_list = current_prompt_config.get('variables', [])
|
|
|
|
| 1387 |
with col_info: st.markdown(f"**{idx + 1}. {var_data.get('name', 'N/A')}** ({var_data.get('label', 'N/A')})\n*Type: `{var_data.get('type', 'N/A')}`*")
|
| 1388 |
with col_up:
|
| 1389 |
disable_up_button = (idx == 0)
|
| 1390 |
+
if st.button("↑", key=f"{action_key_prefix}_up", help="Monter cette variable", disabled=disable_up_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx-1] = current_variables_list[idx-1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1391 |
with col_down:
|
| 1392 |
disable_down_button = (idx == len(current_variables_list) - 1)
|
| 1393 |
+
if st.button("↓", key=f"{action_key_prefix}_down", help="Descendre cette variable", disabled=disable_down_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx+1] = current_variables_list[idx+1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1394 |
with col_edit:
|
| 1395 |
if st.button("Modifier", key=f"{action_key_prefix}_edit", use_container_width=True): st.session_state.editing_variable_info = { "family": final_selected_family_edition, "use_case": final_selected_use_case_edition, "index": idx, "data": copy.deepcopy(var_data) }; st.session_state.variable_type_to_create = var_data.get('type'); st.rerun()
|
| 1396 |
with col_delete:
|
| 1397 |
+
if st.button("Suppr.", key=f"{action_key_prefix}_delete", type="secondary", use_container_width=True): variable_name_to_delete = current_variables_list.pop(idx).get('name', 'Variable inconnue'); current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.success(f"Variable '{variable_name_to_delete}' supprimée."); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1398 |
st.markdown("---"); st.subheader("Ajouter une Variable"); is_editing_var = False; variable_data_for_form = {"name": "", "label": "", "type": "", "options": "", "default": ""}
|
| 1399 |
if st.session_state.editing_variable_info and st.session_state.editing_variable_info.get("family") == final_selected_family_edition and st.session_state.editing_variable_info.get("use_case") == final_selected_use_case_edition:
|
| 1400 |
edit_var_idx = st.session_state.editing_variable_info["index"]
|
|
|
|
| 1497 |
if var_name_val_submit in existing_var_names_in_uc: st.error(f"Une variable avec le nom technique '{var_name_val_submit}' existe déjà pour ce cas d'usage."); can_proceed_with_save = False
|
| 1498 |
else: target_vars_list.append(new_var_data_to_submit); st.success(f"Variable '{var_name_val_submit}' ajoutée avec succès.")
|
| 1499 |
if can_proceed_with_save:
|
| 1500 |
+
current_prompt_config["variables"] = target_vars_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf()
|
| 1501 |
if not is_editing_var: st.session_state.variable_type_to_create = None
|
| 1502 |
st.rerun()
|
| 1503 |
|
|
|
|
| 1511 |
st.rerun()
|
| 1512 |
st.markdown("---"); st.subheader("🏷️ Tags"); current_tags_str = ", ".join(current_prompt_config.get("tags", []))
|
| 1513 |
new_tags_str_input = st.text_input("Tags (séparés par des virgules):", value=current_tags_str, key=f"tags_input_{final_selected_family_edition}_{final_selected_use_case_edition}")
|
| 1514 |
+
if st.button("Sauvegarder Tags", key=f"save_tags_btn_{final_selected_family_edition}_{final_selected_use_case_edition}"): current_prompt_config["tags"] = sorted(list(set(t.strip() for t in new_tags_str_input.split(',') if t.strip()))); current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.success("Tags sauvegardés!"); st.rerun()
|
| 1515 |
|
| 1516 |
st.markdown("---")
|
| 1517 |
st.subheader("Actions sur le Cas d'Usage")
|
|
|
|
| 1568 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 1569 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 1570 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 1571 |
+
save_editable_prompts_to_local_and_hf()
|
| 1572 |
st.success(f"Cas d'usage '{original_uc_name_for_dup_form}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 1573 |
|
| 1574 |
st.session_state.duplicating_use_case_details = None
|
|
|
|
| 1763 |
st.balloons()
|
| 1764 |
current_prompt_config["usage_count"] = current_prompt_config.get("usage_count", 0) + 1
|
| 1765 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1766 |
+
save_editable_prompts_to_local_and_hf()
|
| 1767 |
|
| 1768 |
except Exception as e:
|
| 1769 |
st.error(f"Erreur inattendue lors de la génération du prompt : {e}")
|
|
|
|
| 1816 |
current_prompt_config['template'] = new_tpl
|
| 1817 |
current_prompt_config['description'] = new_desc
|
| 1818 |
current_prompt_config["updated_at"] = datetime.now().isoformat()
|
| 1819 |
+
save_editable_prompts_to_local_and_hf()
|
| 1820 |
st.success("Template et Description sauvegardés!");
|
| 1821 |
st.rerun()
|
| 1822 |
st.markdown("---"); st.subheader("Variables du Prompt"); current_variables_list = current_prompt_config.get('variables', [])
|
|
|
|
| 1828 |
with col_info: st.markdown(f"**{idx + 1}. {var_data.get('name', 'N/A')}** ({var_data.get('label', 'N/A')})\n*Type: `{var_data.get('type', 'N/A')}`*")
|
| 1829 |
with col_up:
|
| 1830 |
disable_up_button = (idx == 0)
|
| 1831 |
+
if st.button("↑", key=f"{action_key_prefix}_up", help="Monter cette variable", disabled=disable_up_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx-1] = current_variables_list[idx-1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1832 |
with col_down:
|
| 1833 |
disable_down_button = (idx == len(current_variables_list) - 1)
|
| 1834 |
+
if st.button("↓", key=f"{action_key_prefix}_down", help="Descendre cette variable", disabled=disable_down_button, use_container_width=True): current_variables_list[idx], current_variables_list[idx+1] = current_variables_list[idx+1], current_variables_list[idx]; current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1835 |
with col_edit:
|
| 1836 |
if st.button("Modifier", key=f"{action_key_prefix}_edit", use_container_width=True): st.session_state.editing_variable_info = { "family": generator_family, "use_case": generator_use_case, "index": idx, "data": copy.deepcopy(var_data) }; st.session_state.variable_type_to_create = var_data.get('type'); st.rerun()
|
| 1837 |
with col_delete:
|
| 1838 |
+
if st.button("Suppr.", key=f"{action_key_prefix}_delete", type="secondary", use_container_width=True): variable_name_to_delete = current_variables_list.pop(idx).get('name', 'Variable inconnue'); current_prompt_config["variables"] = current_variables_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.success(f"Variable '{variable_name_to_delete}' supprimée."); st.session_state.editing_variable_info = None; st.session_state.variable_type_to_create = None; st.rerun()
|
| 1839 |
st.markdown("---"); st.subheader("Ajouter une Variable"); is_editing_var = False; variable_data_for_form = {"name": "", "label": "", "type": "", "options": "", "default": ""}
|
| 1840 |
if st.session_state.editing_variable_info and st.session_state.editing_variable_info.get("family") == generator_family and st.session_state.editing_variable_info.get("use_case") == generator_use_case:
|
| 1841 |
edit_var_idx = st.session_state.editing_variable_info["index"]
|
|
|
|
| 1938 |
if var_name_val_submit in existing_var_names_in_uc: st.error(f"Une variable avec le nom technique '{var_name_val_submit}' existe déjà pour ce cas d'usage."); can_proceed_with_save = False
|
| 1939 |
else: target_vars_list.append(new_var_data_to_submit); st.success(f"Variable '{var_name_val_submit}' ajoutée avec succès.")
|
| 1940 |
if can_proceed_with_save:
|
| 1941 |
+
current_prompt_config["variables"] = target_vars_list; current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf()
|
| 1942 |
if not is_editing_var: st.session_state.variable_type_to_create = None
|
| 1943 |
st.rerun()
|
| 1944 |
|
|
|
|
| 1952 |
st.rerun()
|
| 1953 |
st.markdown("---"); st.subheader("🏷️ Tags"); current_tags_str = ", ".join(current_prompt_config.get("tags", []))
|
| 1954 |
new_tags_str_input = st.text_input("Tags (séparés par des virgules):", value=current_tags_str, key=f"tags_input_{generator_family}_{generator_use_case}")
|
| 1955 |
+
if st.button("Sauvegarder Tags", key=f"save_tags_btn_{generator_family}_{generator_use_case}"): current_prompt_config["tags"] = sorted(list(set(t.strip() for t in new_tags_str_input.split(',') if t.strip()))); current_prompt_config["updated_at"] = datetime.now().isoformat(); save_editable_prompts_to_local_and_hf(); st.success("Tags sauvegardés!"); st.rerun()
|
| 1956 |
|
| 1957 |
st.markdown("---")
|
| 1958 |
st.subheader("Actions sur le Cas d'Usage")
|
|
|
|
| 2009 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["created_at"] = now_iso_dup_create
|
| 2010 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["updated_at"] = now_iso_dup_update
|
| 2011 |
st.session_state.editable_prompts[target_family_on_submit][new_uc_name_val_from_form]["usage_count"] = 0
|
| 2012 |
+
save_editable_prompts_to_local_and_hf()
|
| 2013 |
st.success(f"Cas d'usage '{original_uc_name_for_dup_form}' dupliqué en '{new_uc_name_val_from_form}' dans la famille '{target_family_on_submit}'.")
|
| 2014 |
|
| 2015 |
st.session_state.duplicating_use_case_details = None
|
|
|
|
| 2120 |
if first_new_uc_name is None:
|
| 2121 |
first_new_uc_name = uc_name_stripped
|
| 2122 |
if successful_injections:
|
| 2123 |
+
save_editable_prompts_to_local_and_hf()
|
| 2124 |
st.success(f"{len(successful_injections)} cas d'usage injectés avec succès dans '{target_family_name}': {', '.join(successful_injections)}")
|
| 2125 |
st.session_state.injection_json_text = ""
|
| 2126 |
if first_new_uc_name:
|