import gradio as gr import logging # Ipotizziamo che tu abbia queste funzioni nel tuo progetto: # - list_databases(), create_database(), modify_database(), delete_database()... # - list_indexed_files(), upload_and_index(), delete_file_from_database(), etc. # - search_documents(), list_indexed_documents()... # # Se hanno nomi o posizioni diverse, adatta gli import di conseguenza from app.document_handling import ( list_databases, create_database, modify_database, delete_database, upload_and_index, list_indexed_files, delete_file_from_database, list_indexed_documents, search_documents, ) from app.llm_handling import answer_question from app.logging_config import configure_logging configure_logging() def update_dropdowns(): """Aggiorna tutti i dropdown con la lista aggiornata dei database.""" databases = list_databases() # Ritorniamo 6 update() perché nel codice ci sono 6 dropdown da sincronizzare return [gr.update(choices=databases) for _ in range(6)] def extract_text_from_files(files): """Estrae e concatena il testo da PDF, DOCX e TXT.""" text = "" for file in files: try: if file.name.endswith('.pdf'): text += extract_text_from_pdf(file.name) # Definita in document_handling elif file.name.endswith('.docx'): text += extract_text_from_docx(file.name) # Definita in document_handling else: with open(file.name, 'r', encoding='utf-8') as f: text += f.read() except Exception as e: logging.error(f"Errore durante la lettura del file {file.name}: {e}") return text with gr.Blocks() as rag_chatbot: gr.Markdown("# Chatbot basato su RAG") databases = list_databases() # Questi State() servono per la gestione dei dropdown. # Se non ti servono come stati separati, puoi anche rimuoverli. db_name_upload = gr.State() db_name_list = gr.State() db_name_chat = gr.State() db_name_new = gr.State() modify_db_old_name = gr.State() delete_db_dropdown = gr.State() # ============================================= # TAB: Chatbot # ============================================= with gr.Tab("Chatbot"): with gr.Row(): with gr.Column(scale=2): # Dropdown per selezionare il DB db_name_chat = gr.Dropdown( choices=databases, label="Seleziona Database", value="default_db" ) # Chatbot component chatbot = gr.Chatbot(label="Conversazione", type="messages") # Input domanda question_input = gr.Textbox( label="Fai una domanda", placeholder="Scrivi qui la tua domanda...", lines=2 ) # Bottoni azione with gr.Row(): ask_button = gr.Button("Invia") clear_button = gr.Button("Pulisci Chat") # File upload con dimensioni ridotte with gr.Row(): file_input = gr.File( label="Carica PDF/Docx/TXT per la conversazione", file_types=[".pdf", ".docx", ".txt"], file_count="multiple", height="100px", # Altezza ridotta scale=3 # Riduce la larghezza relativa ) upload_button = gr.Button("Carica Documenti", scale=1) # Stato chat chat_state = gr.State([]) # ---------------------- # FUNZIONI DI CALLBACK # ---------------------- def chat_upload_and_respond(files, chat_history, db_name): # Se chat_history è None, inizializziamo if chat_history is None: chat_history = [] # Estrai il testo dai file text = extract_text_from_files(files) # Aggiungo un messaggio "assistant" che mostra il testo caricato chat_history.append({ "role": "assistant", "content": f"📄 Contenuto dei documenti caricati:\n{text}" }) return chat_history def respond(message, chat_history, db_name): if chat_history is None: chat_history = [] # `answer_question` restituisce due messaggi (user + assistant) in lista new_messages = answer_question(message, db_name) # Li aggiungiamo in coda alla history chat_history.extend(new_messages) # Ritorniamo l'input svuotato (per pulire il Textbox) e la nuova history return "", chat_history def clear_chat(): # Svuota la chat return [], [] # ------------------ # EVENTI BOTTONE # ------------------ upload_button.click( fn=chat_upload_and_respond, inputs=[file_input, chat_state, db_name_chat], outputs=chatbot ) ask_button.click( fn=respond, inputs=[question_input, chat_state, db_name_chat], outputs=[question_input, chatbot] ) clear_button.click( fn=clear_chat, outputs=[chatbot, chat_state] ) # ============================================= # TAB: Gestione Database # ============================================= with gr.Tab("Gestione Database"): gr.Markdown("## Operazioni sui Database") with gr.Row(): with gr.Column(): gr.Markdown("### Crea Database") db_name_input = gr.Textbox(label="Nome Nuovo Database") create_db_button = gr.Button("Crea Database") create_output = gr.Textbox(label="Stato Creazione") with gr.Column(): gr.Markdown("### Rinomina Database") modify_db_old_name = gr.Dropdown(choices=databases, label="Database da Rinominare") modify_db_new_name = gr.Textbox(label="Nuovo Nome") modify_db_button = gr.Button("Rinomina Database") modify_output = gr.Textbox(label="Stato Modifica") with gr.Column(): gr.Markdown("### Elimina Database") delete_db_dropdown = gr.Dropdown(choices=databases, label="Database da Eliminare") delete_db_button = gr.Button("Elimina Database") delete_output = gr.Textbox(label="Stato Eliminazione") # Eventi per i pulsanti di gestione DB create_db_button.click( create_database, # funzione inputs=db_name_input, # input outputs=create_output # output ).then( update_dropdowns, outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] ) modify_db_button.click( modify_database, inputs=[modify_db_old_name, modify_db_new_name], outputs=modify_output ).then( update_dropdowns, outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] ) delete_db_button.click( delete_database, inputs=delete_db_dropdown, outputs=delete_output ).then( update_dropdowns, outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] ) # ============================================= # TAB: Gestione Documenti # ============================================= with gr.Tab("Gestione Documenti"): with gr.Column(): gr.Markdown("### Carica Documenti") with gr.Row(): file_input = gr.File( label="Carica i tuoi documenti", file_types=[".txt", ".pdf", ".docx"], file_count="multiple" ) db_name_upload = gr.Dropdown( choices=databases, label="Seleziona Database", value="default_db" ) with gr.Row(): title_input = gr.Textbox(label="Titolo del documento") author_input = gr.Textbox(label="Autore") upload_button = gr.Button("Indicizza Documenti") upload_output = gr.Textbox(label="Stato Upload") with gr.Column(): gr.Markdown("### Documenti nel Database") db_name_list = gr.Dropdown( choices=databases, label="Seleziona Database", value="default_db" ) list_button = gr.Button("Visualizza Files") list_output = gr.Textbox(label="Files nel Database") delete_file_input = gr.Textbox(label="Nome file da eliminare") delete_file_button = gr.Button("Elimina File") delete_file_output = gr.Textbox(label="Stato Eliminazione") # Eventi upload_button.click( upload_and_index, inputs=[file_input, title_input, author_input, db_name_upload], outputs=upload_output ).then( list_indexed_files, inputs=db_name_list, outputs=list_output ) list_button.click( list_indexed_files, inputs=db_name_list, outputs=list_output ) delete_file_button.click( delete_file_from_database, inputs=[delete_file_input, db_name_list], outputs=delete_file_output ).then( list_indexed_files, inputs=db_name_list, outputs=list_output ).then( update_dropdowns, outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] ) # ============================================= # TAB: Visualizza Documenti Indicizzati # ============================================= with gr.Tab("Visualizza Documenti Indicizzati"): with gr.Column(): gr.Markdown("### Documenti nel Database") db_name_list = gr.Dropdown( choices=databases, label="Seleziona Database", value="default_db", interactive=True ) list_button = gr.Button("Visualizza Documenti") list_output = gr.Textbox( label="Elenco Documenti", lines=10, interactive=False, value="Clicca 'Visualizza Documenti' per vedere l'elenco" ) list_button.click( fn=list_indexed_documents, inputs=[db_name_list], outputs=[list_output], api_name="list_docs" ) # ============================================= # TAB: Nuove Funzionalità # ============================================= with gr.Tab("Nuove Funzionalità "): gr.Markdown("## Cerca Documenti e Genera Riassunto") db_name_new = gr.Dropdown(choices=databases, label="Seleziona Database", value="default_db") search_input = gr.Textbox(label="Inserisci Termine di Ricerca") search_button = gr.Button("Cerca Documenti") search_output = gr.Textbox(label="Documenti Trovati") summary_button = gr.Button("Genera Riassunto") summary_output = gr.Textbox(label="Riassunto") search_button.click( search_documents, inputs=[search_input, db_name_new], outputs=search_output ) # Esempio di eventuale generazione riassunto # summary_button.click( # generate_summary, # inputs=db_name_new, # outputs=summary_output # ) # Avvio dell'app if __name__ == "__main__": rag_chatbot.launch()