Análisis integral del sistema: módulos implementados, mejoras, tareas pendientes, potencial y comparativa con PLAUD Note.
La aplicación arranca correctamente en C:\ECCO con todas las páginas funcionales. El bug crítico SQL (1AND) fue corregido en esta sesión. La BD SQLite está inicializada con 21 concejales y 10 temas predefinidos.
La transcripción (Whisper), el análisis LLM (Ollama) y la búsqueda vectorial (ChromaDB) están implementados en código, pero requieren configuración adicional: token HuggingFace para diarización y resolución del conflicto PyTorch 2.3.1 / pysentimiento.
Cada sesión plenaria atraviesa las siguientes etapas. Verde = completamente implementado · Amarillo = implementado, requiere configuración · Rojo = pendiente de completar.
Captura de audio en vivo desde micrófono o bucle WASAPI (Windows), con control en tiempo real (pausa/reanuda/detiene). Incluye normalización de amplitud y reducción de ruido con DeepFilterNet.
recorder.py — grabación en hilo separadodenoiser.py — filtrado DeepFilterNetnormalizer.py — ajuste de nivel dBimporter.py — importación de archivo existentePipeline orquestado que toma el audio limpio y produce intervenciones estructuradas: Whisper transcribe, pyannote identifica quién habla, el aligner fusiona ambos resultados y el result_builder genera el JSON final.
whisper_engine.py — ASR en GPU int8diarizer.py — identificación de hablantesaligner.py — alineación transcripción+hablantepipeline.py — orquestador asíncrono con progresoInterfaz con Ollama para análisis profundo: genera resúmenes ejecutivos, extrae temas de agenda, detecta votaciones automáticamente, analiza sentimiento de intervenciones y redacta el borrador del acta.
ollama_client.py — HTTP client (chat + embed)summarizer.py — resumen corto y detalladotopic_extractor.py — extracción de temasvoting_detector.py — detección automática de votossentiment_analyzer.py — sentimiento en españolacta_generator.py — borrador formal del actaMotor de búsqueda híbrido que combina SQLite FTS5 (palabras clave exactas) con ChromaDB (búsqueda semántica por embeddings). Re-rankea resultados (40% FTS + 60% vectorial) y soporta RAG para responder preguntas sobre legislación.
hybrid_search.py — búsqueda combinadafts_engine.py — full-text SQLitevector_store.py — ChromaDBrag_engine.py — pregunta → respuesta con contextoembedder.py — indexación vía nomic-embed-textGenera documentos formales del Concejo: actas en Word (con estilos Medellín) y PDF, exportaciones de transcripción en TXT/CSV/JSON, e importación de legislación existente con OCR (pytesseract).
acta_docx.py — Word con estilos institucionalesacta_pdf.py — PDF con reportlabexporter.py — TXT, CSV, JSONocr_importer.py — extracción de texto de PDFs escaneadosCapa de persistencia completa: conexión SQLite thread-safe con WAL mode, 12 tablas relacionales, 2 tablas FTS5 virtuales, triggers automáticos y 11 repositorios (uno por entidad de negocio).
connection.py — singleton thread-safe, 64MB cacheschema.py — DDL completo v1 + seed de temasmigrations.py — versionado del schemarepositories/ — concejales, sesiones, intervenciones, votaciones, actas, temas, legislación, asistencia, fotos, analíticaUtilidades transversales del sistema: detector automático de hardware (GPU/CPU/VRAM), cargador de configuración YAML, logger estructurado rotativo y funciones de tiempo.
hardware_detector.py — detecta GPU, ajusta parámetros automáticamenteconfig_loader.py — acceso seguro a config.yamllogger.py — loguru, rotación diaria, archivo de errorestime_utils.py — helpers de fecha/hora11 páginas Streamlit que cubren todo el ciclo de vida de una sesión plenaria: desde la captura hasta la firma del acta, pasando por búsqueda, estadísticas, gestión de concejales, votaciones y fotos.
unrecognized token: "1AND"En analytics_repo.py línea 44, el f-string {'AND ...} producía WHERE 1=1AND. Corregido a {' AND ...'}. Afectaba el Dashboard principal y la página de Estadísticas. Ambas ahora cargan sin errores.
Nueva página con KPIs (total, aprobadas, rechazadas, empates), listado de votaciones por sesión con badges visuales de resultado, y expander que muestra el voto individual de cada concejal.
Nueva página con explorador de sesiones, grid configurable de 2 a 5 columnas, carga manual de imágenes desde el navegador, timestamps del audio y mensaje amigable cuando no hay fotos.
assets/styles.css creadoCSS global extraído del inline de app.py, ampliado con colores PINGS (#0D2E6E, #1565C0, #42A5F5), 10 badges de estado de sesión, cards de concejal, sidebar con marca y botones primarios personalizados.
CLAUDE.md creado en la raízDocumentación estructurada del codebase para Claude Code: arquitectura, comandos frecuentes, convenciones de código, notas de hardware, estado de todas las páginas.
config.yaml optimizado para GTX 1660batch_size_whisper: 8→6 (reduce picos VRAM), cpu_threads: 8→12 (aprovecha todos los hilos del i7-8700K), context_length: 16384→8192 (previene OOM del LLM), timeout_segundos: 300→600 (para sesiones largas en CPU).
migrations.py — error en BD nueva corregidoAl inicializar por primera vez, el código consultaba schema_version antes de que existiera. Corregido con try/except que asume versión 0 si la tabla no existe.
scripts/03_inicializar_bd.py — tres errores corregidosUTF-8 en Windows (sys.stdout.reconfigure), import alias correcto (get_models as get_modelos_disponibles), nombre de función correcto del hardware detector (detect() → dataclass, no diccionario).
07_Concejales.py: grid de 21 perfiles con Ver/Editar. 10_Base_Legal.py: importación de PDFs legislativos con búsqueda RAG en 3 pestañas.
C:\ECCO ↔ e:\PINGS_DSinf\Antigravity\ECCOLas dos rutas son directorios separados (no junction). Se sincronizan los 7 archivos modificados/creados a C:\ECCO sin tocar el venv ni la base de datos.
| Tarea | Categoría | Prioridad | Estado | Notas |
|---|---|---|---|---|
| Token HuggingFace para pyannote | Configuración | 🔴 Crítica | Pendiente | Sin él la diarización falla. Registrar en huggingface.co, aceptar términos de pyannote/speaker-diarization-3.1 y pegar el token en config.yaml → modelos.pyannote.auth_token. |
| Resolver conflicto PyTorch / pysentimiento | Dependencias | 🔴 Crítica | Bloqueado | pysentimiento requiere torch ≥ 2.4; el proyecto instala torch 2.3.1+cu121 para CUDA 12.1. Solución: instalar pysentimiento sin dependencias (--no-deps) o actualizar a torch 2.4+cu121 si es compatible con faster-whisper. |
| Verificar 2 concejales placeholder | Datos | 🟡 Alta | Pendiente | El seed tiene 19 reales + 2 marcados "Concejal por verificar". Consultar concejomedellin.gov.co y actualizar scripts/02_seed_concejales.py. |
| Fotos de perfil de concejales | Datos | 🟡 Alta | Pendiente | Colocar imágenes en data/fotos/{id_concejal}.jpg. La página 07 ya tiene la lógica de visualización. |
| Escudo de Medellín local | Offline | 🟡 Alta | Pendiente | app.py carga el escudo desde Wikipedia (requiere internet). Para modo 100% offline, descargar el SVG y reemplazar la URL por assets/escudo_medellin.svg. |
| Probar pipeline completo con audio real | Validación | 🟡 Alta | Pendiente | Existe el archivo Sesión Plenaria.MP3 (77 MB) en C:\ECCO. Importarlo como sesión de prueba y ejecutar el pipeline completo. |
| Configurar secretario(a) general en config.yaml | Configuración | 🟠 Media | Pendiente | actas.secretario_general está vacío. Completar con el nombre oficial para que aparezca en las actas generadas. |
| Tests automatizados | Calidad | 🟠 Media | Pendiente | pytest ya está en requirements.txt. Falta crear tests/ con pruebas unitarias para los repositorios y el motor de búsqueda. |
| Backup automático de la BD | Operación | 🟠 Media | Parcial | Config indica backup cada 24h pero el scheduler no está activo. Implementar tarea en background (threading.Timer) o usar Windows Task Scheduler. |
| Cifrado de la base de datos | Seguridad | 🟢 Baja | Pendiente | config.yaml → base_datos.encryption: false. SQLite no cifra nativamente. Evaluar SQLCipher o cifrado a nivel de carpeta (BitLocker en Windows). |
| Captura fotográfica automática | Funcionalidad | 🟢 Baja | Parcial | Config habilitada (captura_auto: true, cada 22 min, resolución 1280×720). Falta integrar cv2.VideoCapture en el pipeline y conectar con fotos_repo. |
| Análisis de coaliciones (alineación de votaciones) | Analítica | 🟢 Baja | Parcial | votaciones_repo.alineacion_votaciones() ya existe. Falta crear la visualización (heatmap de concejales × concejales) en la página de Estadísticas o Votaciones. |
| Exportar a PDF la página de Estadísticas | Funcionalidad | 🟢 Baja | Pendiente | Streamlit no tiene impresión directa de gráficas Plotly. Implementar con plotly.io.write_image + reportlab. |
Necesario para descargar pyannote/speaker-diarization-3.1.
pip install huggingface_hub huggingface-cli login
Luego aceptar los términos de uso del modelo en huggingface.co/pyannote/speaker-diarization-3.1
Para importar legislación desde PDFs escaneados. La librería Python pytesseract ya está en requirements.txt pero el ejecutable Tesseract debe instalarse por separado.
winget install UB-Mannheim.TesseractOCR # O descargar desde: github.com/UB-Mannheim/tesseract/wiki
Requerido por pydub y potencialmente por faster-whisper para conversión de formatos de audio (MP3 → WAV).
winget install Gyan.FFmpeg # Verificar: ffmpeg -version
Dos modelos necesarios: el LLM para análisis y el modelo de embeddings para búsqueda semántica.
ollama pull qwen2.5:7b ollama pull nomic-embed-text # Verificar: ollama list
Debe instalarse con el índice especial de CUDA. Leer el comentario en requirements.txt:
pip install torch==2.3.1+cu121 \ torchaudio==2.3.1+cu121 \ --index-url \ https://download.pytorch.org/whl/cu121
Necesario para convertir páginas PDF a imágenes (usado por pdf2image en el importador de legislación).
winget install oschwartz10612.poppler # Agregar al PATH: C:\Program Files\poppler\Library\bin
ECCO puede escalarse a los 125 municipios de Antioquia y a cualquier concejo municipal de Colombia. Un nodo central (ECCO Hub) podría agregar estadísticas departamentales comparando participación, temas y eficiencia legislativa entre municipios.
Con datos de múltiples períodos, ECCO puede construir series de tiempo sobre temas prioritarios del Concejo. Dashboards públicos que muestren qué tan frecuentemente se debate educación vs. infraestructura vs. seguridad en los últimos 10 años.
Un bot de consulta (RAG sobre toda la legislación + actas) que responda preguntas como "¿Qué acuerdos hay sobre ciclovías en Medellín?" o "¿Quién ha hablado más veces sobre presupuesto participativo en los últimos 3 años?"
Sistema de alertas para periodistas y ciudadanos: notificación automática cuando se aprueba un acuerdo sobre temas de su interés, resumen semanal de sesiones vía email/Telegram, o transcripción en vivo durante las sesiones.
Versión pública de solo lectura (sin acceso a grabaciones), donde cualquier ciudadano pueda buscar en las actas, ver estadísticas de asistencia de su concejal y consultar en qué votó cada representante.
Una app ligera (Flutter o React Native) que consuma la API REST de ECCO: ver sesiones en vivo, recibir notificaciones de votaciones, consultar el perfil y estadísticas del concejal de su preferencia.
A diferencia de soluciones en la nube, ECCO procesa todo localmente: el audio, la transcripción, el análisis LLM y el almacenamiento nunca salen del equipo del Concejo. Esto elimina preocupaciones de confidencialidad sobre deliberaciones no públicas, reservas presupuestales o negociaciones políticas sensibles.
PLAUD Note es un dispositivo hardware de grabación y transcripción con app cloud, lanzado en 2024. Se compara con ECCO en el contexto específico del Concejo de Medellín.
PLAUD es superior en usabilidad inmediata y potencia bruta de transcripción (GPT-4o). Pero ECCO supera a PLAUD en todas las dimensiones que importan para el Concejo de Medellín: privacidad, costo cero operativo, generación de actas legales, gestión de votaciones, analítica institucional, escalabilidad y cumplimiento normativo colombiano. PLAUD es una grabadora inteligente; ECCO es un sistema de gestión legislativa completo.
| Fase | Plazo sugerido | Entregables |
|---|---|---|
| Fase 1 — Puesta en producción | 1–2 semanas | Token HuggingFace configurado · PyTorch resuelto · Pipeline probado con la grabación MP3 disponible · 2 concejales placeholder verificados · Escudo local |
| Fase 2 — Primera sesión real | 1 mes | Procesar una sesión plenaria real completa (audio → transcripción → acta) · Validar con la secretaría del Concejo · Ajustar prompts LLM para actas |
| Fase 3 — Analítica y búsqueda | 2–3 meses | 10+ sesiones procesadas · Dashboards de estadísticas con datos reales · Búsqueda semántica sobre legislación importada · Análisis de coaliciones |
| Fase 4 — Portal ciudadano | 4–6 meses | Versión pública de solo lectura · Búsqueda de actas históricas · Estadísticas de asistencia y votaciones públicas |
| Fase 5 — Expansión | 6–12 meses | Piloto en otros concejos de Antioquia · API REST · App móvil companion · ECCO Hub departamental |