Spaces:
Sleeping
Sleeping
| """ | |
| App principale Streamlit per l'anonimizzazione documenti. | |
| """ | |
| import streamlit as st | |
| import json | |
| import pandas as pd | |
| from ui_components import ( | |
| setup_page_config, display_sidebar, display_entity_editor, | |
| display_file_preview, display_analysis_results, display_crewai_result, | |
| display_progress_metrics, display_examples_section, create_download_button | |
| ) | |
| from utils import ( | |
| init_session_state, process_uploaded_files, run_anonymization, | |
| run_ai_analysis, build_rag_knowledge_base, export_results_json, | |
| get_confirmed_docs_count, reset_document_state, add_chat_message, | |
| add_crewai_result, clear_crewai_history | |
| ) | |
| def main(): | |
| """Funzione principale dell'app""" | |
| # Setup | |
| setup_page_config() | |
| init_session_state() | |
| # Header | |
| st.title("π Anonimizzatore Documenti con NER, RAG e CrewAI") | |
| st.markdown("---") | |
| # Sidebar | |
| display_sidebar() | |
| # Main tabs | |
| tab1, tab2, tab3, tab4, tab5 = st.tabs([ | |
| "π€ Upload", | |
| "π Anonimizzazione", | |
| "π Analisi", | |
| "π¬ Chatbot RAG", | |
| "π€ CrewAI" | |
| ]) | |
| # TAB 1: Upload | |
| with tab1: | |
| upload_tab() | |
| # TAB 2: Anonimizzazione | |
| with tab2: | |
| anonymization_tab() | |
| # TAB 3: Analisi | |
| with tab3: | |
| analysis_tab() | |
| # TAB 4: RAG | |
| with tab4: | |
| rag_tab() | |
| # TAB 5: CrewAI | |
| with tab5: | |
| crewai_tab() | |
| def upload_tab(): | |
| """Tab per upload file""" | |
| st.header("π€ Carica Documenti") | |
| uploaded_files = st.file_uploader( | |
| "Carica uno o piΓΉ file .txt", | |
| type=['txt'], | |
| accept_multiple_files=True, | |
| help="Seleziona i file di testo da anonimizzare" | |
| ) | |
| if uploaded_files: | |
| if process_uploaded_files(uploaded_files): | |
| st.success(f"Caricati {len(uploaded_files)} file") | |
| st.rerun() | |
| else: | |
| st.info("Nessun nuovo file caricato.") | |
| # Mostra anteprima | |
| st.subheader("π File caricati") | |
| for filename, file_data in st.session_state.uploaded_files.items(): | |
| display_file_preview(filename, file_data['content']) | |
| def anonymization_tab(): | |
| """Tab per anonimizzazione""" | |
| st.header("π Anonimizzazione e Revisione") | |
| if not st.session_state.uploaded_files: | |
| st.warning("β οΈ Carica prima alcuni documenti nella tab 'Upload'") | |
| return | |
| # Bottone anonimizzazione | |
| if st.button("π Avvia Anonimizzazione", type="primary"): | |
| run_anonymization() | |
| st.rerun() | |
| # Mostra documenti anonimizzati | |
| if st.session_state.anonymized_docs: | |
| st.subheader("π Revisiona Documenti Anonimizzati") | |
| for filename, doc_data in st.session_state.anonymized_docs.items(): | |
| with st.expander( | |
| f"π {filename} {'β ' if doc_data['confirmed'] else 'β³'}", | |
| expanded=not doc_data['confirmed'] | |
| ): | |
| col1, col2 = st.columns(2) | |
| # Testo originale | |
| with col1: | |
| st.write("**Testo Originale:**") | |
| preview = doc_data['original'][:300] | |
| if len(doc_data['original']) > 300: | |
| preview += "..." | |
| st.text_area( | |
| "Originale", | |
| value=preview, | |
| height=200, | |
| disabled=True, | |
| key=f"orig_{filename}", | |
| label_visibility="collapsed" | |
| ) | |
| # Testo anonimizzato | |
| with col2: | |
| st.write("**Testo Anonimizzato:**") | |
| edited_text = st.text_area( | |
| "Anonimizzato (modificabile)", | |
| value=doc_data['anonymized'], | |
| height=200, | |
| key=f"anon_{filename}", | |
| label_visibility="collapsed" | |
| ) | |
| # Aggiorna se modificato | |
| if edited_text != doc_data['anonymized']: | |
| st.session_state.anonymized_docs[filename]['anonymized'] = edited_text | |
| # Editor entitΓ | |
| updated_entities = display_entity_editor(dict(doc_data['entities']), filename) | |
| # Bottoni azione | |
| col_confirm, col_reset = st.columns(2) | |
| with col_confirm: | |
| if st.button(f"β Conferma {filename}", key=f"confirm_{filename}"): | |
| st.session_state.anonymized_docs[filename]['confirmed'] = True | |
| st.session_state.anonymized_docs[filename]['entities'] = updated_entities | |
| st.success(f"β {filename} confermato!") | |
| st.session_state.vector_store_built = False | |
| st.rerun() | |
| with col_reset: | |
| if st.button(f"π Reset {filename}", key=f"reset_{filename}"): | |
| reset_document_state(filename) | |
| st.rerun() | |
| # Statistiche progresso | |
| display_progress_metrics() | |
| def analysis_tab(): | |
| """Tab per analisi AI""" | |
| st.header("π Analisi AI") | |
| confirmed_docs = {k: v for k, v in st.session_state.anonymized_docs.items() | |
| if v.get('confirmed', False)} | |
| if not confirmed_docs: | |
| st.warning("β οΈ Conferma prima alcuni documenti anonimizzati") | |
| return | |
| st.write(f"Documenti confermati pronti: **{len(confirmed_docs)}**") | |
| if st.button("π€ Avvia Analisi AI", type="primary"): | |
| run_ai_analysis() | |
| # Mostra risultati | |
| if st.session_state.processed_docs: | |
| st.subheader("π Risultati Analisi") | |
| for filename, result in st.session_state.processed_docs.items(): | |
| display_analysis_results(filename, result) | |
| # Download JSON | |
| result_json = export_results_json({ | |
| 'filename': filename, | |
| 'anonymized_text': result['anonymized_text'], | |
| 'analysis': result['analysis'], | |
| 'entities': result['entities'], | |
| 'entities_count': result['entities_count'] | |
| }, f"analisi_{filename}") | |
| create_download_button( | |
| result_json, | |
| f"analisi_{filename}.json", | |
| f"πΎ Scarica {filename}", | |
| f"download_{filename}" | |
| ) | |
| def rag_tab(): | |
| """Tab per RAG chatbot""" | |
| st.header("π¬ Chatta con i Documenti") | |
| confirmed_docs = {k: v for k, v in st.session_state.anonymized_docs.items() | |
| if v.get('confirmed', False)} | |
| if not confirmed_docs: | |
| st.warning("β οΈ Carica e conferma documenti per abilitare il chatbot") | |
| return | |
| # Costruisci knowledge base | |
| if build_rag_knowledge_base(): | |
| st.info(f"Chatbot pronto per {len(confirmed_docs)} documenti") | |
| # Mostra cronologia chat | |
| for message in st.session_state.chat_history: | |
| with st.chat_message(message["role"]): | |
| st.markdown(message["content"]) | |
| # Input utente | |
| if prompt := st.chat_input("Fai una domanda sui documenti..."): | |
| # Aggiungi messaggio utente | |
| add_chat_message("user", prompt) | |
| with st.chat_message("user"): | |
| st.markdown(prompt) | |
| # Genera risposta | |
| with st.chat_message("assistant"): | |
| with st.spinner("Generando risposta..."): | |
| response = st.session_state.rag_chatbot.answer_question(prompt) | |
| st.markdown(response) | |
| # Aggiungi risposta | |
| add_chat_message("assistant", response) | |
| else: | |
| st.error("Impossibile costruire knowledge base. Verifica configurazione Azure.") | |
| def crewai_tab(): | |
| """Tab per CrewAI""" | |
| st.header("π€ Analisi Multi-Agente CrewAI") | |
| confirmed_docs = {k: v for k, v in st.session_state.anonymized_docs.items() | |
| if v.get('confirmed', False)} | |
| if not confirmed_docs: | |
| st.warning("β οΈ Conferma documenti per abilitare CrewAI") | |
| return | |
| if not st.session_state.crewai_manager.agents: | |
| st.error("β CrewAI non configurato. Verifica Azure OpenAI.") | |
| return | |
| # Assicura knowledge base | |
| build_rag_knowledge_base() | |
| st.success(f"π― CrewAI pronto per {len(confirmed_docs)} documenti") | |
| # Configurazione analisi | |
| st.subheader("βοΈ Configurazione Analisi") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| analysis_type = st.selectbox( | |
| "Tipo di Analisi", | |
| options=["comprehensive", "document", "sentiment", "rag", "custom"], | |
| format_func=lambda x: { | |
| "comprehensive": "π Analisi Comprensiva", | |
| "document": "π Analisi Documentale", | |
| "sentiment": "π Sentiment Analysis", | |
| "rag": "π Query RAG Avanzata", | |
| "custom": "βοΈ Personalizzata" | |
| }[x] | |
| ) | |
| with col2: | |
| if analysis_type == "custom": | |
| selected_agents = st.multiselect( | |
| "Agenti da utilizzare", | |
| options=list(st.session_state.crewai_manager.agents.keys()), | |
| default=["strategy_coordinator"], | |
| format_func=lambda x: { | |
| "document_analyst": "π Document Analyst", | |
| "rag_specialist": "π RAG Specialist", | |
| "strategy_coordinator": "π― Strategy Coordinator", | |
| "sentiment_analyst": "π Sentiment Analyst" | |
| }.get(x, x) | |
| ) | |
| else: | |
| selected_agents = [] | |
| # Query input | |
| st.subheader("β Query per l'Analisi") | |
| query_input = st.text_area( | |
| "Inserisci la tua domanda:", | |
| placeholder="Es: Analizza i temi principali e identifica rischi operativi...", | |
| height=100 | |
| ) | |
| # Istruzioni personalizzate | |
| if analysis_type == "custom": | |
| custom_instructions = st.text_area( | |
| "Istruzioni Personalizzate:", | |
| placeholder="Istruzioni specifiche per gli agenti...", | |
| height=80 | |
| ) | |
| else: | |
| custom_instructions = "" | |
| # Bottoni | |
| col_analyze, col_clear = st.columns(2) | |
| with col_analyze: | |
| if st.button("π Avvia Analisi CrewAI", type="primary", disabled=not query_input.strip()): | |
| if analysis_type == "custom" and not selected_agents: | |
| st.error("Seleziona almeno un agente") | |
| else: | |
| # Esegui analisi | |
| if analysis_type == "custom": | |
| result = st.session_state.crewai_manager.create_custom_task( | |
| query_input, selected_agents, custom_instructions | |
| ) | |
| else: | |
| result = st.session_state.crewai_manager.create_analysis_task( | |
| query_input, analysis_type | |
| ) | |
| # Salva risultato | |
| add_crewai_result(query_input, analysis_type, result, selected_agents) | |
| st.success("β Analisi CrewAI completata!") | |
| with col_clear: | |
| if st.button("ποΈ Pulisci Cronologia"): | |
| clear_crewai_history() | |
| st.success("Cronologia pulita!") | |
| st.rerun() | |
| # Mostra risultati | |
| if st.session_state.crewai_history: | |
| st.subheader("π Risultati Analisi CrewAI") | |
| for i, analysis in enumerate(reversed(st.session_state.crewai_history)): | |
| display_crewai_result(analysis, len(st.session_state.crewai_history) - i) | |
| # Download | |
| result_json = export_results_json(analysis, f"crewai_analysis_{i}") | |
| create_download_button( | |
| result_json, | |
| f"crewai_analysis_{analysis['timestamp'].replace(':', '-').replace(' ', '_')}.json", | |
| "πΎ Scarica Risultato", | |
| f"download_crewai_{i}" | |
| ) | |
| # Esempi | |
| display_examples_section() | |
| if __name__ == "__main__": | |
| main() |