File size: 3,238 Bytes
a8c9c7b
 
 
 
 
 
 
 
 
c2eb2e5
 
a8c9c7b
c2eb2e5
a8c9c7b
 
 
 
 
 
c2eb2e5
 
a8c9c7b
c2eb2e5
 
 
 
a8c9c7b
 
c2eb2e5
 
 
a8c9c7b
c2eb2e5
a8c9c7b
c2eb2e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import uuid
from fastapi import APIRouter, HTTPException
from qdrant_client import QdrantClient
from app.api.schemas.telemetry import TelemetryPayload
from app.core.engine import DECI_Engine

router = APIRouter()
engine = DECI_Engine()

# Intentamos levantar el cliente de Qdrant. 
# En producción (Hugging Face Spaces), si no lo usas local, puedes usar "deci_vault" o memoria volátil.
try:
    vault = QdrantClient(host="localhost", port=6333, timeout=2.0)
except Exception:
    vault = None

@router.post("/analyze")
async def analyze_session(payload: TelemetryPayload):
    """

    Analiza la sesión de keystrokes y, si es humana, intenta resguardar la firma 

    en el Cognitive DNA Vault sin bloquear el flujo principal si la DB falla.

    """
    if not payload.events:
        raise HTTPException(status_code=400, detail="No telemetry events provided")
    
    # 1. Procesamos la sesión con el motor continuo calibrado
    try:
        result = engine.process_session(payload.events)
    except Exception as engine_err:
        print(f"🚨 [ENGINE_ERROR]: Fallo crítico en el motor matemático: {str(engine_err)}")
        raise HTTPException(status_code=500, detail="Internal processing error in DECI Engine")

    vault_synced = False

    # 2. BLINDAJE VERTEX: Aislamiento total de la persistencia vectorial
    if vault:
        try:
            # Solo intentamos el upsert si el veredicto es estrictamente humano
            if result.get("is_human"):
                # Inicializamos el vector de 128 dimensiones
                vector = [0.0] * 128
                vector[0] = float(result.get("score", 0.0))
                
                # Extraemos el desglose asegurando fallbacks por si las llaves cambian
                breakdown = result.get("breakdown", {})
                vector[1] = float(breakdown.get("entropy", 0.0))
                vector[2] = float(breakdown.get("cv", 0.0))
                vector[3] = float(breakdown.get("burst_ratio", breakdown.get("burst", 0.0)))
                
                vault.upsert(
                    collection_name="cognitive_dna",
                    points=[{
                        "id": str(uuid.uuid4()),
                        "vector": vector,
                        "payload": {
                            "user": "Denis",
                            "session_id": payload.session_id,
                            "verdict": result.get("verdict")
                        }
                    }]
                )
                print("🚀 [VAULT] Firma cognitiva sincronizada en Qdrant con éxito.")
                vault_synced = True
                
        except Exception as qdrant_err:
            # CAPTURAMOS EL ERRNO 111 AQUÍ: El log avisa, pero NO rompe el flujo de la sesión
            print(f"⚠ [VAULT_FALLBACK] Qdrant no disponible o conexión rechazada ({str(qdrant_err)}). Continuando en modo volátil.")
            vault_synced = False

    # 3. Retornamos la respuesta limpia al frontend pase lo que pase con la base de datos
    return {
        "session_id": payload.session_id,
        "analysis": result,
        "vault_synced": vault_synced
    }