""" Componenti UI riutilizzabili per Streamlit. """ import streamlit as st import pandas as pd from typing import Dict from config import Config def setup_page_config(): """Configura la pagina Streamlit""" st.set_page_config( page_title="Anonimizzatore Documenti", page_icon="🔒", layout="wide" ) def display_sidebar(): """Mostra sidebar con configurazioni""" with st.sidebar: st.header("⚙️ Configurazione") # Status Azure if Config.AZURE_API_KEY and Config.AZURE_ENDPOINT: st.success("✅ Azure OpenAI configurato") st.info(f"Chat Model: {Config.DEPLOYMENT_NAME}") st.info(f"Embedding Model: {Config.AZURE_EMBEDDING_DEPLOYMENT_NAME}") else: st.error("❌ Azure OpenAI non configurato") st.write("Configura le variabili d'ambiente:") st.code(""" AZURE_ENDPOINT=your_endpoint AZURE_API_KEY=your_api_key AZURE_ENDPOINT_EMB=your_embedding_endpoint AZURE_API_KEY_EMB=your_embedding_api_key """) st.markdown("---") # Statistiche documenti if 'uploaded_files' in st.session_state and st.session_state.uploaded_files: st.subheader("📊 Statistiche") uploaded_count = len(st.session_state.uploaded_files) anonymized_count = len(st.session_state.get('anonymized_docs', {})) confirmed_count = sum(1 for doc in st.session_state.get('anonymized_docs', {}).values() if doc.get('confirmed', False)) st.metric("File caricati", uploaded_count) st.metric("Anonimizzati", anonymized_count) st.metric("Confermati", confirmed_count) if confirmed_count > 0: if st.session_state.get('vector_store_built', False): st.success("✅ Knowledge Base pronto") else: st.info("🔄 Knowledge Base da costruire") st.markdown("---") # Reset button if st.button("🔄 Reset sessione"): for key in list(st.session_state.keys()): del st.session_state[key] st.rerun() def display_entity_editor(entities: Dict, doc_key: str): """Editor per entità rilevate""" if not entities: st.info("Nessuna entità sensibile rilevata.") return entities st.subheader("🔍 Entità rilevate") st.write("Verifica e modifica le entità sensibili:") current_entities_list = list(entities.items()) updated_entities_dict = {} deleted_placeholders = set() for i, (placeholder, original_value) in enumerate(current_entities_list): col1, col2, col3 = st.columns([2, 3, 1]) with col1: st.write(f"**{placeholder}**") with col2: new_value = st.text_input( "Valore originale", value=original_value, key=f"{doc_key}_{placeholder}_value_{i}" ) updated_entities_dict[placeholder] = new_value with col3: if st.button("🗑️", key=f"{doc_key}_{placeholder}_delete_{i}", help="Rimuovi"): deleted_placeholders.add(placeholder) # Gestisci cancellazioni if deleted_placeholders: final_entities = {k: v for k, v in updated_entities_dict.items() if k not in deleted_placeholders} st.session_state.anonymized_docs[doc_key]['entities'] = final_entities # Re-anonimizza testo from anonymizer import NERAnonimizer anonymizer = NERAnonimizer() st.session_state.anonymized_docs[doc_key]['anonymized'], _ = anonymizer.anonymize( st.session_state.anonymized_docs[doc_key]['original'] ) st.session_state.vector_store_built = False st.rerun() return updated_entities_dict def display_file_preview(filename: str, content: str, max_chars: int = 500): """Mostra anteprima file""" with st.expander(f"📄 {filename} ({len(content)} caratteri)"): preview_text = content[:max_chars] if len(content) > max_chars: preview_text += "..." st.text_area( "Contenuto", value=preview_text, height=150, disabled=True, key=f"preview_{filename}", label_visibility="collapsed" ) def display_analysis_results(filename: str, result: Dict): """Mostra risultati analisi""" with st.expander(f"📊 Analisi: {filename}"): # Metriche col1, col2, col3 = st.columns(3) col1.metric("Caratteri testo", len(result['anonymized_text'])) col2.metric("Entità trovate", result['entities_count']) col3.metric("Stato", "✅ Completato") # Testo anonimizzato st.subheader("📄 Testo Anonimizzato") st.text_area( "Testo processato", value=result['anonymized_text'], height=150, disabled=True, key=f"analysis_text_{filename}" ) # Analisi AI st.subheader("🤖 Analisi AI") st.markdown(result['analysis']) # Entità if result['entities']: st.subheader("🔍 Entità Anonimizzate") entities_df = pd.DataFrame([ { 'Placeholder': k, 'Valore Originale': v, 'Tipo': k.split('_')[0].replace('[', '') } for k, v in result['entities'].items() ]) st.dataframe(entities_df, use_container_width=True) def display_crewai_result(analysis: Dict, index: int): """Mostra risultato analisi CrewAI""" with st.expander( f"🤖 Analisi {index}: {analysis['analysis_type'].upper()} - {analysis['timestamp']}" ): # Info header col1, col2, col3 = st.columns(3) with col1: st.metric("Tipo Analisi", analysis['analysis_type'].capitalize()) with col2: st.metric("Timestamp", analysis['timestamp']) with col3: agents_used = analysis.get('agents_used', 'auto') if agents_used == 'auto': agent_count = "Automatico" elif isinstance(agents_used, list): agent_count = f"{len(agents_used)} agenti" else: agent_count = str(agents_used) st.metric("Agenti", agent_count) # Query e risultato st.subheader("❓ Query Originale") st.info(analysis['query']) st.subheader("🎯 Risultato Analisi") st.markdown(analysis['result']) def display_progress_metrics(): """Mostra metriche di progresso""" if 'anonymized_docs' in st.session_state: confirmed_count = sum(1 for doc in st.session_state.anonymized_docs.values() if doc.get('confirmed', False)) total_count = len(st.session_state.anonymized_docs) if total_count > 0: st.metric( "Progresso Conferme", f"{confirmed_count}/{total_count}", delta=f"{(confirmed_count/total_count)*100:.1f}%" ) def display_examples_section(): """Mostra esempi di query CrewAI""" with st.expander("💡 Esempi di Query per CrewAI"): st.markdown(""" **Analisi Comprensiva:** - "Fornisci un'analisi completa dei documenti identificando rischi, opportunità e raccomandazioni strategiche" - "Analizza la comunicazione aziendale e suggerisci miglioramenti nella gestione clienti" **Analisi Documentale:** - "Classifica i documenti per tipologia e identifica pattern ricorrenti" - "Analizza la struttura e organizzazione delle informazioni nei documenti" **Sentiment Analysis:** - "Valuta il sentiment generale nelle comunicazioni e identifica aree di miglioramento" - "Analizza le emozioni e i trend nei feedback dei clienti" **Query RAG Avanzata:** - "Trova tutte le menzioni di problemi operativi e le relative soluzioni proposte" - "Estrai informazioni su scadenze, deadline e milestone importanti" **Personalizzata:** - Combina agenti specifici per analisi mirate alle tue esigenze """) def create_download_button(data: str, filename: str, label: str, key: str): """Crea bottone download con dati""" st.download_button( label=label, data=data, file_name=filename, mime="application/json", key=key )