Malaji71 commited on
Commit
614e6d2
·
verified ·
1 Parent(s): f7da536

Update semantic_database.py

Browse files
Files changed (1) hide show
  1. semantic_database.py +175 -13
semantic_database.py CHANGED
@@ -15,9 +15,9 @@ logger = logging.getLogger(__name__)
15
  class SemanticDatabase:
16
  """
17
  💾 SISTEMA DE BASE DE DATOS SEMÁNTICA — ¡AHORA EN USO ACTIVO!
18
-
19
  Gestiona:
20
- - Cache de prompts de alta calidad (¡priorizados por el agente!)
21
  - Memoria episódica de sesiones
22
  - Estadísticas del sistema
23
  - Optimización y limpieza automática
@@ -35,7 +35,7 @@ class SemanticDatabase:
35
  with sqlite3.connect(self.db_path) as conn:
36
  cursor = conn.cursor()
37
 
38
- # Tabla de cache de prompts — ¡AHORA USADA ACTIVAMENTE!
39
  cursor.execute("""
40
  CREATE TABLE IF NOT EXISTS prompt_cache (
41
  prompt_hash TEXT PRIMARY KEY,
@@ -109,7 +109,7 @@ class SemanticDatabase:
109
 
110
  def store_cache_result(self, original_prompt: str, enhanced_prompt: str,
111
  category: str, similarity_score: float, source_field: str) -> bool:
112
- """💾 Almacena resultado en cache — ¡USADO POR EL AGENTE!"""
113
  try:
114
  prompt_hash = self._get_prompt_hash(original_prompt)
115
 
@@ -149,11 +149,11 @@ class SemanticDatabase:
149
  return True
150
 
151
  except Exception as e:
152
- logger.error(f"❌ Error almacenando en cache: {e}")
153
  return False
154
 
155
  def get_cached_result(self, prompt: str) -> Optional[Dict]:
156
- """🔍 Busca resultado en cache"""
157
  try:
158
  prompt_hash = self._get_prompt_hash(prompt)
159
 
@@ -204,7 +204,7 @@ class SemanticDatabase:
204
  return None
205
 
206
  except Exception as e:
207
- logger.error(f"❌ Error buscando en cache: {e}")
208
  return None
209
 
210
  def get_top_cached_prompts(self, prompt: str, category: str, top_k: int = 5) -> List[Dict]:
@@ -365,15 +365,177 @@ class SemanticDatabase:
365
 
366
  stats = {}
367
 
368
- # Estadísticas de cache
369
  cursor.execute("SELECT COUNT(*), AVG(hit_count), AVG(similarity_score) FROM prompt_cache")
370
  cache_stats = cursor.fetchone()
371
- stats['cache'] = {
372
- 'total_entries': cache_stats[0] or 0,
373
- 'avg_hit_count': round(cache_stats[1] or 0, 2),
374
- 'avg_similarity': round(cache_stats[2] or 0, 3)
375
  }
376
 
377
  # Estadísticas de memoria episódica
378
  cursor.execute("""
379
- SELECT COUNT(*), COUNT(DISTINCT session_id),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  class SemanticDatabase:
16
  """
17
  💾 SISTEMA DE BASE DE DATOS SEMÁNTICA — ¡AHORA EN USO ACTIVO!
18
+
19
  Gestiona:
20
+ - Caché de prompts de alta calidad (¡priorizados por el agente!)
21
  - Memoria episódica de sesiones
22
  - Estadísticas del sistema
23
  - Optimización y limpieza automática
 
35
  with sqlite3.connect(self.db_path) as conn:
36
  cursor = conn.cursor()
37
 
38
+ # Tabla de caché de prompts — ¡AHORA USADA ACTIVAMENTE!
39
  cursor.execute("""
40
  CREATE TABLE IF NOT EXISTS prompt_cache (
41
  prompt_hash TEXT PRIMARY KEY,
 
109
 
110
  def store_cache_result(self, original_prompt: str, enhanced_prompt: str,
111
  category: str, similarity_score: float, source_field: str) -> bool:
112
+ """💾 Almacena resultado en caché — ¡USADO POR EL AGENTE!"""
113
  try:
114
  prompt_hash = self._get_prompt_hash(original_prompt)
115
 
 
149
  return True
150
 
151
  except Exception as e:
152
+ logger.error(f"❌ Error almacenando en caché: {e}")
153
  return False
154
 
155
  def get_cached_result(self, prompt: str) -> Optional[Dict]:
156
+ """🔍 Busca resultado en caché"""
157
  try:
158
  prompt_hash = self._get_prompt_hash(prompt)
159
 
 
204
  return None
205
 
206
  except Exception as e:
207
+ logger.error(f"❌ Error buscando en caché: {e}")
208
  return None
209
 
210
  def get_top_cached_prompts(self, prompt: str, category: str, top_k: int = 5) -> List[Dict]:
 
365
 
366
  stats = {}
367
 
368
+ # Estadísticas de caché
369
  cursor.execute("SELECT COUNT(*), AVG(hit_count), AVG(similarity_score) FROM prompt_cache")
370
  cache_stats = cursor.fetchone()
371
+ stats['caché'] = {
372
+ 'total_entradas': cache_stats[0] or 0,
373
+ 'promedio_usos': round(cache_stats[1] or 0, 2),
374
+ 'promedio_similitud': round(cache_stats[2] or 0, 3)
375
  }
376
 
377
  # Estadísticas de memoria episódica
378
  cursor.execute("""
379
+ SELECT COUNT(*), COUNT(DISTINCT session_id),
380
+ AVG(similarity_score), AVG(processing_time),
381
+ SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)
382
+ FROM episodic_memory
383
+ """)
384
+ memory_stats = cursor.fetchone()
385
+ stats['episódica'] = {
386
+ 'búsquedas_totales': memory_stats[0] or 0,
387
+ 'sesiones_únicas': memory_stats[1] or 0,
388
+ 'promedio_similitud': round(memory_stats[2] or 0, 3),
389
+ 'tiempo_promedio': round(memory_stats[3] or 0, 2),
390
+ 'tasa_éxito': round(memory_stats[4] or 0, 1)
391
+ }
392
+
393
+ # Estadísticas de últimos 7 días
394
+ cursor.execute("""
395
+ SELECT SUM(total_searches), SUM(cache_hits), AVG(avg_processing_time)
396
+ FROM daily_stats
397
+ WHERE date >= date('now', '-7 days')
398
+ """)
399
+ weekly_stats = cursor.fetchone()
400
+ stats['semanal'] = {
401
+ 'búsquedas_totales': weekly_stats[0] or 0,
402
+ 'aciertos_caché': weekly_stats[1] or 0,
403
+ 'tiempo_promedio': round(weekly_stats[2] or 0, 2)
404
+ }
405
+
406
+ # Información de la base de datos
407
+ cursor.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table'")
408
+ table_count = cursor.fetchone()[0]
409
+
410
+ stats['base_de_datos'] = {
411
+ 'tablas': table_count,
412
+ 'tamaño_mb': self._get_db_size_mb(),
413
+ 'última_limpieza': self._get_config_value('last_cleanup'),
414
+ 'versión': '2.0'
415
+ }
416
+
417
+ return stats
418
+
419
+ except Exception as e:
420
+ logger.error(f"❌ Error obteniendo estadísticas: {e}")
421
+ return {}
422
+
423
+ def cleanup_cache(self, max_age_days: int = 30, max_entries: int = 1000) -> Tuple[int, int]:
424
+ """🧹 Limpieza de caché antiguo"""
425
+ try:
426
+ with self.lock:
427
+ with sqlite3.connect(self.db_path) as conn:
428
+ cursor = conn.cursor()
429
+
430
+ # Eliminar entradas muy antiguas
431
+ cutoff_date = (datetime.now() - timedelta(days=max_age_days)).isoformat()
432
+ cursor.execute(
433
+ "DELETE FROM prompt_cache WHERE last_accessed < ?",
434
+ (cutoff_date,)
435
+ )
436
+ old_deleted = cursor.rowcount
437
+
438
+ # Eliminar entradas menos usadas si hay demasiadas
439
+ cursor.execute("SELECT COUNT(*) FROM prompt_cache")
440
+ total_count = cursor.fetchone()[0]
441
+
442
+ excess_deleted = 0
443
+ if total_count > max_entries:
444
+ excess_count = total_count - max_entries
445
+ cursor.execute("""
446
+ DELETE FROM prompt_cache
447
+ WHERE prompt_hash IN (
448
+ SELECT prompt_hash FROM prompt_cache
449
+ ORDER BY hit_count ASC, last_accessed ASC
450
+ LIMIT ?
451
+ )
452
+ """, (excess_count,))
453
+ excess_deleted = cursor.rowcount
454
+
455
+ # Limpiar memoria episódica antigua (más de 90 días)
456
+ old_memory_cutoff = (datetime.now() - timedelta(days=90)).isoformat()
457
+ cursor.execute(
458
+ "DELETE FROM episodic_memory WHERE timestamp < ?",
459
+ (old_memory_cutoff,)
460
+ )
461
+
462
+ # Actualizar configuración
463
+ self._set_config_value('last_cleanup', datetime.now().isoformat())
464
+
465
+ conn.commit()
466
+
467
+ total_deleted = old_deleted + excess_deleted
468
+ logger.info(f"🧹 Limpieza completada: {total_deleted} entradas eliminadas")
469
+
470
+ return old_deleted, excess_deleted
471
+
472
+ except Exception as e:
473
+ logger.error(f"❌ Error en limpieza: {e}")
474
+ return 0, 0
475
+
476
+ def optimize_databases(self) -> bool:
477
+ """⚡ Optimiza la base de datos"""
478
+ try:
479
+ with self.lock:
480
+ with sqlite3.connect(self.db_path) as conn:
481
+ cursor = conn.cursor()
482
+
483
+ cursor.execute("VACUUM")
484
+ cursor.execute("ANALYZE")
485
+
486
+ conn.commit()
487
+
488
+ logger.info("⚡ Base de datos optimizada")
489
+ return True
490
+
491
+ except Exception as e:
492
+ logger.error(f"❌ Error optimizando base de datos: {e}")
493
+ return False
494
+
495
+ def _get_db_size_mb(self) -> float:
496
+ """📏 Obtiene tamaño de la base de datos en MB"""
497
+ try:
498
+ import os
499
+ size_bytes = os.path.getsize(self.db_path)
500
+ return round(size_bytes / (1024 * 1024), 2)
501
+ except:
502
+ return 0.0
503
+
504
+ def _get_config_value(self, key: str) -> Optional[str]:
505
+ """⚙️ Obtiene valor de configuración"""
506
+ try:
507
+ with sqlite3.connect(self.db_path) as conn:
508
+ cursor = conn.cursor()
509
+ cursor.execute("SELECT value FROM system_config WHERE key = ?", (key,))
510
+ result = cursor.fetchone()
511
+ return result[0] if result else None
512
+ except:
513
+ return None
514
+
515
+ def _set_config_value(self, key: str, value: str) -> bool:
516
+ """⚙️ Establece valor de configuración"""
517
+ try:
518
+ with sqlite3.connect(self.db_path) as conn:
519
+ cursor = conn.cursor()
520
+ cursor.execute("""
521
+ INSERT OR REPLACE INTO system_config (key, value)
522
+ VALUES (?, ?)
523
+ """, (key, value))
524
+ conn.commit()
525
+ return True
526
+ except:
527
+ return False
528
+
529
+ def get_cache_size(self) -> int:
530
+ """📊 Obtiene número de entradas en caché"""
531
+ try:
532
+ with sqlite3.connect(self.db_path) as conn:
533
+ cursor = conn.cursor()
534
+ cursor.execute("SELECT COUNT(*) FROM prompt_cache")
535
+ return cursor.fetchone()[0]
536
+ except:
537
+ return 0
538
+
539
+ def close(self):
540
+ """🔒 Cierra conexiones (cleanup)"""
541
+ logger.info("📊 Base de datos cerrada correctamente")