deci-core-api / app /api /endpoints /session.py
Denisijcu's picture
update
c2eb2e5 verified
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
}