From da13fd4d853e16d02a388dc1018f85700e0daecd Mon Sep 17 00:00:00 2001 From: DFFM-maker Date: Fri, 26 Dec 2025 20:38:43 +0100 Subject: [PATCH] feat: PDF support with RAG integration - Added PyMuPDF (fitz) for PDF text extraction - Implemented chunking system for large documents - RAG search now works with PDF documents - Added Qdrant vector store for semantic search - Chainlit UI updated with PDF processing indicators --- app.py | 171 +++++++++++++++++++++++++++++++---------- debugchainlit-app.txt | 173 ++++++++++++++++++++++++++++++++++++++++++ debugchanlit-app.txt | 173 ++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 480 insertions(+), 38 deletions(-) create mode 100644 debugchainlit-app.txt create mode 100644 debugchanlit-app.txt diff --git a/app.py b/app.py index 9b61fc69..aa5ecf81 100644 --- a/app.py +++ b/app.py @@ -7,17 +7,19 @@ from typing import Optional import chainlit as cl import ollama +import fitz # PyMuPDF from qdrant_client import AsyncQdrantClient from qdrant_client.models import PointStruct, Distance, VectorParams from chainlit.data.sql_alchemy import SQLAlchemyDataLayer + # === CONFIGURAZIONE === DATABASE_URL = os.getenv("DATABASE_URL", "postgresql+asyncpg://ai_user:secure_password_here@postgres:5432/ai_station") OLLAMA_URL = os.getenv("OLLAMA_URL", "http://192.168.1.243:11434") QDRANT_URL = os.getenv("QDRANT_URL", "http://qdrant:6333") + # === INIZIALIZZAZIONE DATA LAYER === -# IMPORTANTE: Deve essere inizializzato PRIMA di definire gli handlers try: data_layer = SQLAlchemyDataLayer(conninfo=DATABASE_URL) cl.data_layer = data_layer @@ -26,9 +28,11 @@ except Exception as e: print(f"❌ Failed to initialize data layer: {e}") cl.data_layer = None + WORKSPACES_DIR = "./workspaces" USER_ROLE = "admin" + # === UTILITY FUNCTIONS === def create_workspace(user_role: str): """Crea directory workspace se non esiste""" @@ -36,6 +40,7 @@ def create_workspace(user_role: str): os.makedirs(workspace_path, exist_ok=True) return workspace_path + def save_code_to_file(code: str, user_role: str) -> str: """Salva blocco codice come file .py""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") @@ -47,6 +52,26 @@ def save_code_to_file(code: str, user_role: str) -> str: return file_path + +def extract_text_from_pdf(pdf_path: str) -> str: + """Estrae testo da PDF usando PyMuPDF""" + try: + doc = fitz.open(pdf_path) + text_parts = [] + + for page_num in range(len(doc)): + page = doc[page_num] + text = page.get_text() + text_parts.append(f"--- Pagina {page_num + 1} ---\n{text}\n") + + doc.close() + return "\n".join(text_parts) + + except Exception as e: + print(f"❌ Errore estrazione PDF: {e}") + return "" + + # === QDRANT FUNCTIONS === async def get_qdrant_client() -> AsyncQdrantClient: """Connessione a Qdrant""" @@ -62,6 +87,7 @@ async def get_qdrant_client() -> AsyncQdrantClient: return client + async def get_embeddings(text: str) -> list: """Genera embeddings con Ollama""" client = ollama.Client(host=OLLAMA_URL) @@ -82,34 +108,73 @@ async def get_embeddings(text: str) -> list: print(f"❌ Errore Embedding: {e}") return [] + async def index_document(file_name: str, content: str) -> bool: """Indicizza documento su Qdrant""" try: - embeddings = await get_embeddings(content) - if not embeddings: - return False + # Suddividi documento lungo in chunks + chunks = chunk_text(content, max_length=1500) qdrant_client = await get_qdrant_client() - point_id = str(uuid.uuid4()) + points = [] - point = PointStruct( - id=point_id, - vector=embeddings, - payload={ - "file_name": file_name, - "content": content, - "indexed_at": datetime.now().isoformat() - } - ) + for i, chunk in enumerate(chunks): + embeddings = await get_embeddings(chunk) + if not embeddings: + continue + + point_id = str(uuid.uuid4()) + point = PointStruct( + id=point_id, + vector=embeddings, + payload={ + "file_name": file_name, + "content": chunk, + "chunk_index": i, + "total_chunks": len(chunks), + "indexed_at": datetime.now().isoformat() + } + ) + points.append(point) - await qdrant_client.upsert(collection_name="documents", points=[point]) - return True + if points: + await qdrant_client.upsert(collection_name="documents", points=points) + return True + + return False except Exception as e: print(f"❌ Errore indicizzazione: {e}") return False -async def search_qdrant(query_text: str, limit: int = 3) -> str: + +def chunk_text(text: str, max_length: int = 1500, overlap: int = 200) -> list: + """Divide testo in chunks con overlap""" + if len(text) <= max_length: + return [text] + + chunks = [] + start = 0 + + while start < len(text): + end = start + max_length + + # Cerca l'ultimo punto/newline prima del limite + if end < len(text): + last_period = text.rfind('.', start, end) + last_newline = text.rfind('\n', start, end) + split_point = max(last_period, last_newline) + + if split_point > start: + end = split_point + 1 + + chunks.append(text[start:end].strip()) + start = end - overlap # Overlap per continuità + + return chunks + + +async def search_qdrant(query_text: str, limit: int = 5) -> str: """Ricerca documenti rilevanti""" try: qdrant_client = await get_qdrant_client() @@ -125,16 +190,23 @@ async def search_qdrant(query_text: str, limit: int = 3) -> str: ) contexts = [] + seen_files = set() + for hit in search_result.points: if hit.payload: file_name = hit.payload.get('file_name', 'Unknown') content = hit.payload.get('content', '') + chunk_idx = hit.payload.get('chunk_index', 0) score = hit.score if hasattr(hit, 'score') else 0 - contexts.append( - f"📄 **{file_name}** (relevance: {score:.2f})\n" - f"``````" - ) + # Evita duplicati dello stesso file + file_key = f"{file_name}_{chunk_idx}" + if file_key not in seen_files: + seen_files.add(file_key) + contexts.append( + f"📄 **{file_name}** (chunk {chunk_idx+1}, score: {score:.2f})\n" + f"```\n{content[:600]}...\n```" + ) return "\n\n".join(contexts) if contexts else "" @@ -142,6 +214,7 @@ async def search_qdrant(query_text: str, limit: int = 3) -> str: print(f"❌ Errore ricerca Qdrant: {e}") return "" + # === CHAINLIT HANDLERS === @cl.on_chat_start async def on_chat_start(): @@ -156,11 +229,13 @@ async def on_chat_start(): await cl.Message( content=f"🚀 **AI Station Ready** - Workspace: `{USER_ROLE}`\n\n" - f"📤 Upload `.txt` files per indicizzarli nel RAG\n" + f"📤 Upload **PDF** o **.txt** per indicizzarli nel RAG\n" f"💾 Persistenza conversazioni: {persistence_status}\n" - f"🤖 Modello: `qwen2.5-coder:7b` @ {OLLAMA_URL}" + f"🤖 Modello: `qwen2.5-coder:7b` @ {OLLAMA_URL}\n\n" + f"💡 **Supporto PDF attivo**: Carica fatture, F24, dichiarazioni fiscali!" ).send() + @cl.on_message async def on_message(message: cl.Message): """Gestione messaggi utente""" @@ -172,15 +247,16 @@ async def on_message(message: cl.Message): await handle_file_uploads(message.elements, user_role) # === STEP 2: RAG Search === - context_text = await search_qdrant(message.content, limit=3) + context_text = await search_qdrant(message.content, limit=5) # === STEP 3: Preparazione Prompt === messages = [] if context_text: system_prompt = ( - "Sei un assistente AI esperto. Usa ESCLUSIVAMENTE il seguente contesto " - "per rispondere. Se la risposta non è nel contesto, dillo chiaramente.\n\n" + "Sei un assistente AI esperto in analisi documentale e fiscale. " + "Usa ESCLUSIVAMENTE il seguente contesto per rispondere. " + "Se la risposta non è nel contesto, dillo chiaramente.\n\n" f"**CONTESTO:**\n{context_text}" ) messages.append({"role": "system", "content": system_prompt}) @@ -208,7 +284,7 @@ async def on_message(message: cl.Message): await msg.update() # === STEP 5: Estrai e Salva Codice === - code_blocks = re.findall(r"``````", full_response, re.DOTALL) + code_blocks = re.findall(r"```python\n(.*?)```", full_response, re.DOTALL) if code_blocks: elements = [] @@ -230,35 +306,54 @@ async def on_message(message: cl.Message): except Exception as e: await cl.Message(content=f"❌ **Errore:** {str(e)}").send() + async def handle_file_uploads(elements, user_role: str): - """Gestisce upload e indicizzazione file""" + """Gestisce upload e indicizzazione file (TXT e PDF)""" for element in elements: try: # Salva file dest_path = os.path.join(WORKSPACES_DIR, user_role, element.name) shutil.copy(element.path, dest_path) - # Indicizza solo .txt - if element.name.endswith('.txt'): + content = None + + # Estrai testo in base al tipo di file + if element.name.lower().endswith('.pdf'): + await cl.Message(content=f"📄 Elaborazione PDF **{element.name}**...").send() + content = extract_text_from_pdf(dest_path) + + if not content: + await cl.Message( + content=f"⚠️ **{element.name}**: PDF vuoto o non leggibile" + ).send() + continue + + elif element.name.lower().endswith('.txt'): with open(dest_path, 'r', encoding='utf-8') as f: content = f.read() - + + else: + await cl.Message( + content=f"📁 **{element.name}** salvato (supportati: .pdf, .txt)" + ).send() + continue + + # Indicizza su Qdrant + if content: success = await index_document(element.name, content) if success: + word_count = len(content.split()) await cl.Message( - content=f"✅ **{element.name}** indicizzato in Qdrant" + content=f"✅ **{element.name}** indicizzato in Qdrant\n" + f"📊 Parole estratte: {word_count:,}" ).send() else: await cl.Message( - content=f"⚠️ Errore indicizzazione {element.name}" + content=f"⚠️ Errore indicizzazione **{element.name}**" ).send() - else: - await cl.Message( - content=f"📁 **{element.name}** salvato (solo .txt vengono indicizzati)" - ).send() except Exception as e: await cl.Message( - content=f"❌ Errore con {element.name}: {str(e)}" + content=f"❌ Errore con **{element.name}**: {str(e)}" ).send() diff --git a/debugchainlit-app.txt b/debugchainlit-app.txt new file mode 100644 index 00000000..c93da530 --- /dev/null +++ b/debugchainlit-app.txt @@ -0,0 +1,173 @@ +ai-station-app | 2025-12-26 17:11:49 - WARNING - chainlit - SQLAlchemyDataLayer storage client is not initialized and elements will not be persisted! +ai-station-app | ✅ SQLAlchemyDataLayer initialized successfully +ai-station-app | 2025-12-26 17:11:49 - INFO - chainlit - Created default chainlit markdown file at /app/chainlit.md +ai-station-app | 2025-12-26 17:11:49 - INFO - chainlit - Your app is available at http://0.0.0.0:8000 +ai-station-app | 2025-12-26 17:11:53 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:11:53 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:17:32 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:17:32 - WARNING - chainlit - Translation file for it-IT not found. Using parent translation it. diff --git a/debugchanlit-app.txt b/debugchanlit-app.txt new file mode 100644 index 00000000..c93da530 --- /dev/null +++ b/debugchanlit-app.txt @@ -0,0 +1,173 @@ +ai-station-app | 2025-12-26 17:11:49 - WARNING - chainlit - SQLAlchemyDataLayer storage client is not initialized and elements will not be persisted! +ai-station-app | ✅ SQLAlchemyDataLayer initialized successfully +ai-station-app | 2025-12-26 17:11:49 - INFO - chainlit - Created default chainlit markdown file at /app/chainlit.md +ai-station-app | 2025-12-26 17:11:49 - INFO - chainlit - Your app is available at http://0.0.0.0:8000 +ai-station-app | 2025-12-26 17:11:53 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:11:53 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:17:32 - ERROR - engineio.server - message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | message async handler error +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 557, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^ +ai-station-app | TypeError: connect() missing 1 required positional argument: 'auth' +ai-station-app | +ai-station-app | During handling of the above exception, another exception occurred: +ai-station-app | +ai-station-app | Traceback (most recent call last): +ai-station-app | File "/usr/local/lib/python3.11/site-packages/engineio/async_server.py", line 510, in run_async_handler +ai-station-app | return await self.handlers[event](*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 692, in _handle_eio_message +ai-station-app | await self._handle_connect(eio_sid, pkt.namespace, pkt.data) +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 560, in _handle_connect +ai-station-app | success = await self._trigger_event( +ai-station-app | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/socketio/async_server.py", line 644, in _trigger_event +ai-station-app | ret = await handler(*args) +ai-station-app | ^^^^^^^^^^^^^^^^^^^^ +ai-station-app | File "/usr/local/lib/python3.11/site-packages/chainlit/socket.py", line 125, in connect +ai-station-app | thread_id = auth.get("threadId", None) +ai-station-app | ^^^^^^^^ +ai-station-app | AttributeError: 'NoneType' object has no attribute 'get' +ai-station-app | 2025-12-26 17:17:32 - WARNING - chainlit - Translation file for it-IT not found. Using parent translation it. diff --git a/requirements.txt b/requirements.txt index 830cd045..4616fa05 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ greenlet>=3.0.0 sniffio aiohttp alembic +pymupdf