SperanzaMax commited on
Commit
6b990bc
verified
1 Parent(s): 7d14c1f

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +117 -12
app.py CHANGED
@@ -12,6 +12,29 @@ import re
12
  # Configuraci贸n del Sistema Emocional
13
  DB_PATH = "/tmp/cma_memory.db"
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  # Intentar importar los n煤cleos emocionales
16
  try:
17
  sys.path.append(os.path.join(os.path.dirname(__file__), "core"))
@@ -52,6 +75,7 @@ async def dashboard_home():
52
  <title>Cortex-Nexus | Live Dashboard</title>
53
  <meta name="viewport" content="width=device-width, initial-scale=1">
54
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 
55
  <style>
56
  body { font-family: 'Inter', sans-serif; background: #0f172a; color: #f8fafc; margin: 0; padding: 20px; }
57
  .container { max-width: 800px; margin: 0 auto; }
@@ -75,10 +99,11 @@ async def dashboard_home():
75
  </div>
76
  <p style="text-align: center; font-size: 0.8rem; color: #64748b;"><span class="status-dot"></span> SISTEMA ONLINE</p>
77
  <h1>C贸rtex-Nexus Live</h1>
78
- <div class="stats">
79
  <div class="stat-box"><div class="stat-label">EPOCAS</div><div class="stat-value" id="val-epocas">0</div></div>
80
  <div class="stat-box"><div class="stat-label">QUALIA</div><div class="stat-value" id="val-qualia">0.000</div></div>
81
  <div class="stat-box"><div class="stat-label">CONFIANZA</div><div class="stat-value" id="val-confianza">0.000</div></div>
 
82
  </div>
83
  <div class="card">
84
  <canvas id="emotionChart"></canvas>
@@ -108,9 +133,12 @@ async def dashboard_home():
108
  maintainAspectRatio: true,
109
  scales: {
110
  y: { beginAtZero: true, grid: { color: '#334155' }, ticks: { color: '#94a3b8' } },
111
- x: { display: true, grid: { color: 'rgba(51, 65, 85, 0.4)' }, ticks: { color: '#94a3b8', maxTicksLimit: 8 }, title: { display: true, text: 'Hora (Tiempo Real)', color: '#94a3b8' } }
112
  },
113
- plugins: { legend: { position: 'bottom', labels: { color: '#f8fafc', padding: 20 } } }
 
 
 
114
  }
115
  });
116
 
@@ -130,16 +158,33 @@ async def dashboard_home():
130
  document.getElementById('val-epocas').innerText = jsonRes.total_epocas;
131
  document.getElementById('val-qualia').innerText = parseFloat(latest.qualia).toFixed(3);
132
  document.getElementById('val-confianza').innerText = parseFloat(latest.confianza).toFixed(3);
 
133
 
134
- chart.data.labels = data.map(d => {
135
  let t = new Date(d.timestamp);
136
- // Ajustar a Argentina (UTC-3)
137
  t.setHours(t.getHours() - 3);
138
  return t.toLocaleTimeString('es-AR', {hour: '2-digit', minute: '2-digit'});
139
  });
 
140
  chart.data.datasets[0].data = data.map(d => d.qualia);
141
  chart.data.datasets[1].data = data.map(d => d.frustracion);
142
  chart.data.datasets[2].data = data.map(d => d.confianza);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  chart.update('none');
144
  }
145
 
@@ -173,13 +218,34 @@ async def get_history():
173
  cursor.execute("SELECT COUNT(*) FROM snapshots")
174
  total_epocas = cursor.fetchone()[0]
175
 
176
- cursor.execute("SELECT timestamp, qualia, frustracion, autoConfianza AS confianza, fatiga FROM snapshots ORDER BY id DESC LIMIT 40")
 
 
177
  rows = cursor.fetchall()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  conn.close()
179
 
180
  return {
181
  "total_epocas": total_epocas,
182
- "history": [dict(r) for r in rows][::-1]
 
 
183
  }
184
  except Exception as e:
185
  return {"error": str(e), "msg": "Error leyendo historial"}
@@ -471,13 +537,8 @@ async def sleep_consolidation():
471
  if not vector_global or not vector_global.memoria:
472
  return {"error": "Vector no inicializado"}
473
 
474
- # Capturar arquetipo ANTES
475
  antes = vector_global.memoria.cargar_meta_vector()
476
-
477
- # Ejecutar consolidaci贸n EMA
478
  vector_global.consolidar_memoria()
479
-
480
- # Capturar arquetipo DESPU脡S
481
  despues = vector_global.memoria.cargar_meta_vector()
482
 
483
  drift = {
@@ -485,6 +546,18 @@ async def sleep_consolidation():
485
  for k in antes
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  return {
489
  "status": "Consolidaci贸n completada",
490
  "arquetipo_antes": antes,
@@ -495,6 +568,38 @@ async def sleep_consolidation():
495
  except Exception as e:
496
  return {"error": str(e)}
497
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  # ============================================================
499
  # ANALYTICS DASHBOARD
500
  # ============================================================
 
12
  # Configuraci贸n del Sistema Emocional
13
  DB_PATH = "/tmp/cma_memory.db"
14
 
15
+ # Crear tabla de eventos de sue帽o si no existe
16
+ def _init_sleep_table():
17
+ try:
18
+ conn = sqlite3.connect(DB_PATH)
19
+ conn.execute("""CREATE TABLE IF NOT EXISTS sleep_events (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ timestamp TEXT DEFAULT (datetime('now')),
22
+ antes TEXT, despues TEXT, drift TEXT
23
+ )""")
24
+ conn.execute("""CREATE TABLE IF NOT EXISTS control_responses (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ timestamp TEXT DEFAULT (datetime('now')),
27
+ pregunta TEXT, respuesta_nexus TEXT, respuesta_control TEXT,
28
+ novedad_nexus REAL, novedad_control REAL,
29
+ complejidad_nexus REAL, complejidad_control REAL
30
+ )""")
31
+ conn.commit()
32
+ conn.close()
33
+ except:
34
+ pass
35
+
36
+ _init_sleep_table()
37
+
38
  # Intentar importar los n煤cleos emocionales
39
  try:
40
  sys.path.append(os.path.join(os.path.dirname(__file__), "core"))
 
75
  <title>Cortex-Nexus | Live Dashboard</title>
76
  <meta name="viewport" content="width=device-width, initial-scale=1">
77
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
78
+ <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3"></script>
79
  <style>
80
  body { font-family: 'Inter', sans-serif; background: #0f172a; color: #f8fafc; margin: 0; padding: 20px; }
81
  .container { max-width: 800px; margin: 0 auto; }
 
99
  </div>
100
  <p style="text-align: center; font-size: 0.8rem; color: #64748b;"><span class="status-dot"></span> SISTEMA ONLINE</p>
101
  <h1>C贸rtex-Nexus Live</h1>
102
+ <div class="stats" style="grid-template-columns: 1fr 1fr 1fr 1fr;">
103
  <div class="stat-box"><div class="stat-label">EPOCAS</div><div class="stat-value" id="val-epocas">0</div></div>
104
  <div class="stat-box"><div class="stat-label">QUALIA</div><div class="stat-value" id="val-qualia">0.000</div></div>
105
  <div class="stat-box"><div class="stat-label">CONFIANZA</div><div class="stat-value" id="val-confianza">0.000</div></div>
106
+ <div class="stat-box"><div class="stat-label">SUE脩OS 馃槾</div><div class="stat-value" id="val-sleeps" style="color:#a78bfa;">0</div></div>
107
  </div>
108
  <div class="card">
109
  <canvas id="emotionChart"></canvas>
 
133
  maintainAspectRatio: true,
134
  scales: {
135
  y: { beginAtZero: true, grid: { color: '#334155' }, ticks: { color: '#94a3b8' } },
136
+ x: { display: true, grid: { color: 'rgba(51, 65, 85, 0.4)' }, ticks: { color: '#94a3b8', maxTicksLimit: 10 }, title: { display: true, text: '脷ltimas 24hs (Tiempo Real)', color: '#94a3b8' } }
137
  },
138
+ plugins: {
139
+ legend: { position: 'bottom', labels: { color: '#f8fafc', padding: 20 } },
140
+ annotation: { annotations: {} }
141
+ }
142
  }
143
  });
144
 
 
158
  document.getElementById('val-epocas').innerText = jsonRes.total_epocas;
159
  document.getElementById('val-qualia').innerText = parseFloat(latest.qualia).toFixed(3);
160
  document.getElementById('val-confianza').innerText = parseFloat(latest.confianza).toFixed(3);
161
+ document.getElementById('val-sleeps').innerText = jsonRes.total_sleeps || 0;
162
 
163
+ const labels = data.map(d => {
164
  let t = new Date(d.timestamp);
 
165
  t.setHours(t.getHours() - 3);
166
  return t.toLocaleTimeString('es-AR', {hour: '2-digit', minute: '2-digit'});
167
  });
168
+ chart.data.labels = labels;
169
  chart.data.datasets[0].data = data.map(d => d.qualia);
170
  chart.data.datasets[1].data = data.map(d => d.frustracion);
171
  chart.data.datasets[2].data = data.map(d => d.confianza);
172
+
173
+ // Marcadores de sue帽o
174
+ const sleepAnnotations = {};
175
+ (jsonRes.sleep_events || []).forEach((st, i) => {
176
+ let sleepDate = new Date(st);
177
+ sleepDate.setHours(sleepDate.getHours() - 3);
178
+ let sleepLabel = sleepDate.toLocaleTimeString('es-AR', {hour:'2-digit', minute:'2-digit'});
179
+ let idx = labels.findIndex(l => l === sleepLabel);
180
+ if (idx === -1) idx = labels.length - 1;
181
+ sleepAnnotations['sleep'+i] = {
182
+ type: 'line', xMin: idx, xMax: idx,
183
+ borderColor: '#a78bfa', borderWidth: 2, borderDash: [6, 3],
184
+ label: { display: true, content: '馃槾', position: 'start', font: { size: 14 } }
185
+ };
186
+ });
187
+ chart.options.plugins.annotation.annotations = sleepAnnotations;
188
  chart.update('none');
189
  }
190
 
 
218
  cursor.execute("SELECT COUNT(*) FROM snapshots")
219
  total_epocas = cursor.fetchone()[0]
220
 
221
+ # 脷ltimas 24 horas de datos
222
+ since = (datetime.datetime.utcnow() - datetime.timedelta(hours=24)).isoformat()
223
+ cursor.execute("SELECT timestamp, qualia, frustracion, autoConfianza AS confianza, fatiga FROM snapshots WHERE timestamp > ? ORDER BY id ASC", (since,))
224
  rows = cursor.fetchall()
225
+
226
+ # Eventos de sue帽o
227
+ sleep_events = []
228
+ try:
229
+ cursor.execute("SELECT timestamp FROM sleep_events WHERE timestamp > ? ORDER BY id ASC", (since,))
230
+ sleep_events = [dict(r)["timestamp"] for r in cursor.fetchall()]
231
+ except:
232
+ pass
233
+
234
+ # Total de sue帽os
235
+ total_sleeps = 0
236
+ try:
237
+ cursor.execute("SELECT COUNT(*) FROM sleep_events")
238
+ total_sleeps = cursor.fetchone()[0]
239
+ except:
240
+ pass
241
+
242
  conn.close()
243
 
244
  return {
245
  "total_epocas": total_epocas,
246
+ "total_sleeps": total_sleeps,
247
+ "sleep_events": sleep_events,
248
+ "history": [dict(r) for r in rows]
249
  }
250
  except Exception as e:
251
  return {"error": str(e), "msg": "Error leyendo historial"}
 
537
  if not vector_global or not vector_global.memoria:
538
  return {"error": "Vector no inicializado"}
539
 
 
540
  antes = vector_global.memoria.cargar_meta_vector()
 
 
541
  vector_global.consolidar_memoria()
 
 
542
  despues = vector_global.memoria.cargar_meta_vector()
543
 
544
  drift = {
 
546
  for k in antes
547
  }
548
 
549
+ # Guardar evento de sue帽o en DB
550
+ try:
551
+ conn = sqlite3.connect(DB_PATH)
552
+ conn.execute(
553
+ "INSERT INTO sleep_events (antes, despues, drift) VALUES (?, ?, ?)",
554
+ (json.dumps(antes), json.dumps(despues), json.dumps(drift))
555
+ )
556
+ conn.commit()
557
+ conn.close()
558
+ except:
559
+ pass
560
+
561
  return {
562
  "status": "Consolidaci贸n completada",
563
  "arquetipo_antes": antes,
 
568
  except Exception as e:
569
  return {"error": str(e)}
570
 
571
+ @app.post("/api/control")
572
+ async def save_control_comparison(request: Request):
573
+ """Guarda comparaci贸n grupo de control vs Nexus"""
574
+ try:
575
+ data = await request.json()
576
+ conn = sqlite3.connect(DB_PATH)
577
+ conn.execute(
578
+ "INSERT INTO control_responses (pregunta, respuesta_nexus, respuesta_control, novedad_nexus, novedad_control, complejidad_nexus, complejidad_control) VALUES (?, ?, ?, ?, ?, ?, ?)",
579
+ (data.get("pregunta",""), data.get("respuesta_nexus",""), data.get("respuesta_control",""),
580
+ data.get("novedad_nexus",0), data.get("novedad_control",0),
581
+ data.get("complejidad_nexus",0), data.get("complejidad_control",0))
582
+ )
583
+ conn.commit()
584
+ conn.close()
585
+ return {"status": "ok"}
586
+ except Exception as e:
587
+ return {"error": str(e)}
588
+
589
+ @app.get("/api/control")
590
+ async def get_control_comparisons():
591
+ """Obtiene comparaciones grupo de control"""
592
+ try:
593
+ conn = sqlite3.connect(DB_PATH)
594
+ conn.row_factory = sqlite3.Row
595
+ c = conn.cursor()
596
+ c.execute("SELECT * FROM control_responses ORDER BY id DESC LIMIT 20")
597
+ rows = [dict(r) for r in c.fetchall()]
598
+ conn.close()
599
+ return {"comparisons": rows[::-1], "total": len(rows)}
600
+ except Exception as e:
601
+ return {"error": str(e), "comparisons": []}
602
+
603
  # ============================================================
604
  # ANALYTICS DASHBOARD
605
  # ============================================================