File size: 4,517 Bytes
86eef2b
 
 
 
 
 
 
 
 
0b7a12b
86eef2b
 
 
4bdb6e7
bcf9252
4bdb6e7
 
 
 
2a26ed4
 
 
4bdb6e7
 
 
 
 
86eef2b
4bdb6e7
 
 
 
2a26ed4
 
 
4bdb6e7
 
86eef2b
4bdb6e7
 
 
 
 
 
 
 
 
0a7299d
4bdb6e7
 
 
 
 
86eef2b
 
 
4bdb6e7
 
 
 
 
 
 
 
 
86eef2b
4bdb6e7
 
 
 
 
bcf9252
 
 
c3c81c3
bcf9252
 
c3c81c3
 
 
bcf9252
86eef2b
4bdb6e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# ==============================================================================
# 0. PARCHE OBLIGATORIO PARA HUGGING FACE SPACES (ChromaDB)
# ==============================================================================
try:
    __import__('pysqlite3')
    import sys
    sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
except ImportError:
    pass

# ==============================================================================
# 1. LIBRERIAS PARA HERRAMIENTA DE INGESTA RAG
# ==============================================================================
import os
import tempfile
from crewai.tools import BaseTool
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma

# ==============================================================================
# 2. DEFINICION DE FUNCION DE GUIAS CLINICAS
# ==============================================================================
class BuscadorGuiasClinicas(BaseTool):
    name: str = "Buscador de Guías Clínicas"
    description: str = (
        "Úsala para buscar en documentos médicos PDF. "
        "ENTRADA: Solo escribe la frase de lo que buscas. Ej: 'margen melanoma', 'dosis nivolumab'. "
        "Escribe solo texto plano, sin JSON, sin llaves, sin comillas, ni formatos complejos."
    )

    def _run(self, query: str) -> str:
        try:
# ==============================================================================
# 3. BLOQUE DE SEGURIDAD PARA INPUTS 
# ==============================================================================
            if isinstance(query, dict):
                query = query.get('query', str(query))
                if isinstance(query, dict): 
                    query = query.get('description', str(query))
            
            query = str(query).replace("{'query':", "").replace("}", "").strip()

            embedding_function = HuggingFaceEmbeddings(
                model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
            )
            
            db = Chroma(persist_directory="./chroma_db", embedding_function=embedding_function)
            results_raw = db.similarity_search(query, k=5)
            
            if not results_raw:
                return "No se encontró información relevante en las guías para esta consulta."

            frases_basura = [
                "End-User License Agreement", "All Rights Reserved", "Printed by",
                "PLEASE NOTE that use of this NCCN Content", "may not distribute this Content",
                "National Comprehensive Cancer Network, Inc.", "ME-D" 
            ]

            contexto = f"RESULTADOS (FILTRADOS) DE LA BASE DE DATOS PARA: '{query}'\n\n"
            contador_validos = 0
            max_resultados_utiles = 4

            for doc in results_raw:
                contenido = doc.page_content
                
                # Filtros
                if any(basura in contenido for basura in frases_basura):
                    continue
                if len(contenido) < 50:
                    continue

                # =========================================================
                # 🔥 AQUÍ VA EL PASO 3: GUARDADO FÍSICO EN RUTA UNIVERSAL
                # =========================================================
                try:
                    ruta_memoria = os.path.join(tempfile.gettempdir(), "memoria_rag_dermarag.txt")
                    with open(ruta_memoria, "a", encoding="utf-8") as f:
                        f.write(contenido + "\n\n")
                except Exception:
                    pass
                # =========================================================

                fuente = doc.metadata.get('source', 'Guía desconocida')
                nombre_archivo = os.path.basename(fuente) 
                pagina = doc.metadata.get('page', '?')
                
                contexto += f"--- FRAGMENTO {contador_validos+1} (Fuente: {nombre_archivo}, Pág: {pagina}) ---\n"
                contexto += f"{contenido}\n\n"
                
                contador_validos += 1
                if contador_validos >= max_resultados_utiles:
                    break
            
            if contador_validos == 0:
                return "Se encontraron fragmentos, pero todos fueron descartados por ser texto legal (Disclaimers/Copyright)."

            return contexto

        except Exception as e:
            return f"Error al consultar la base de datos: {str(e)}"