Spaces:
Build error
Build error
| # app.py - Aplicación Principal | |
| import gradio as gr | |
| import numpy as np | |
| import pandas as pd | |
| import sqlite3 | |
| import json | |
| import cv2 | |
| import io | |
| import base64 | |
| from datetime import datetime, timedelta | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification | |
| import torch | |
| import networkx as nx | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| import random | |
| import hashlib | |
| import threading | |
| import time | |
| from collections import deque | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| from scipy import signal | |
| import warnings | |
| warnings.filterwarnings("ignore") | |
| # Configuración global | |
| DEVICE = "cuda" if torch.cuda.is_available() else "cpu" | |
| MAX_USERS = 1000 # Límite para Spaces gratuito | |
| class SynapseCore: | |
| def __init__(self): | |
| self.db_path = "synapse_data.db" | |
| self.init_database() | |
| self.load_models() | |
| self.active_sessions = {} | |
| self.community_graph = nx.Graph() | |
| def init_database(self): | |
| """Inicializa la base de datos SQLite local""" | |
| conn = sqlite3.connect(self.db_path) | |
| cursor = conn.cursor() | |
| # Tabla de usuarios | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id TEXT PRIMARY KEY, | |
| created_at TIMESTAMP, | |
| emotional_profile TEXT, | |
| purpose_data TEXT, | |
| preferences TEXT | |
| ) | |
| ''') | |
| # Tabla de sesiones emocionales | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS emotional_sessions ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id TEXT, | |
| timestamp TIMESTAMP, | |
| emotion_data TEXT, | |
| context TEXT, | |
| FOREIGN KEY (user_id) REFERENCES users (id) | |
| ) | |
| ''') | |
| # Tabla de interacciones del chatbot | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS chat_interactions ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id TEXT, | |
| timestamp TIMESTAMP, | |
| user_message TEXT, | |
| bot_response TEXT, | |
| therapy_technique TEXT, | |
| FOREIGN KEY (user_id) REFERENCES users (id) | |
| ) | |
| ''') | |
| # Tabla de sesiones de neurofeedback | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS neurofeedback_sessions ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id TEXT, | |
| timestamp TIMESTAMP, | |
| session_data TEXT, | |
| performance_metrics TEXT, | |
| FOREIGN KEY (user_id) REFERENCES users (id) | |
| ) | |
| ''') | |
| # Tabla de comunidad | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS community_posts ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id TEXT, | |
| timestamp TIMESTAMP, | |
| content TEXT, | |
| topic TEXT, | |
| sentiment_score REAL, | |
| anonymous_id TEXT | |
| ) | |
| ''') | |
| conn.commit() | |
| conn.close() | |
| def load_models(self): | |
| """Carga los modelos de IA optimizados""" | |
| try: | |
| # Modelo de análisis de sentimientos (lightweight) | |
| self.sentiment_analyzer = pipeline( | |
| "sentiment-analysis", | |
| model="cardiffnlp/twitter-roberta-base-sentiment-latest", | |
| device=0 if DEVICE == "cuda" else -1 | |
| ) | |
| # Modelo de clasificación de emociones | |
| self.emotion_classifier = pipeline( | |
| "text-classification", | |
| model="j-hartmann/emotion-english-distilroberta-base", | |
| device=0 if DEVICE == "cuda" else -1 | |
| ) | |
| # Modelo para reconocimiento facial de emociones (simulado para demo) | |
| self.face_emotion_model = None # Implementación simulada | |
| except Exception as e: | |
| print(f"Error cargando modelos: {e}") | |
| # Fallback a modelos simulados | |
| self.sentiment_analyzer = None | |
| self.emotion_classifier = None | |
| self.face_emotion_model = None | |
| class EmotionalAnalyzer: | |
| def __init__(self, core): | |
| self.core = core | |
| def analyze_text_emotion(self, text): | |
| """Analiza emociones en texto""" | |
| if not text or len(text.strip()) < 3: | |
| return {"error": "Texto muy corto para análisis"} | |
| try: | |
| # Análisis de sentimiento | |
| sentiment = self.core.sentiment_analyzer(text)[0] if self.core.sentiment_analyzer else { | |
| "label": random.choice(["POSITIVE", "NEGATIVE", "NEUTRAL"]), | |
| "score": random.uniform(0.6, 0.9) | |
| } | |
| # Análisis de emociones específicas | |
| emotions = self.core.emotion_classifier(text)[0] if self.core.emotion_classifier else { | |
| "label": random.choice(["joy", "sadness", "anger", "fear", "surprise", "love"]), | |
| "score": random.uniform(0.5, 0.9) | |
| } | |
| # Análisis adicional simulado | |
| emotional_metrics = { | |
| "arousal": random.uniform(0.2, 0.8), | |
| "valence": random.uniform(0.3, 0.7), | |
| "dominance": random.uniform(0.4, 0.8), | |
| "intensity": emotions["score"] | |
| } | |
| return { | |
| "sentiment": sentiment, | |
| "primary_emotion": emotions, | |
| "metrics": emotional_metrics, | |
| "timestamp": datetime.now().isoformat(), | |
| "text_length": len(text), | |
| "word_count": len(text.split()) | |
| } | |
| except Exception as e: | |
| return {"error": f"Error en análisis: {str(e)}"} | |
| def analyze_facial_emotion(self, image): | |
| """Analiza emociones faciales (simulado para demo)""" | |
| if image is None: | |
| return {"error": "No se proporcionó imagen"} | |
| # Simulación de análisis facial | |
| emotions = ["happiness", "sadness", "anger", "fear", "surprise", "disgust", "neutral"] | |
| detected_emotions = {} | |
| for emotion in emotions: | |
| detected_emotions[emotion] = random.uniform(0.1, 0.9) | |
| # Normalizar para que sumen 1 | |
| total = sum(detected_emotions.values()) | |
| for emotion in detected_emotions: | |
| detected_emotions[emotion] /= total | |
| dominant_emotion = max(detected_emotions, key=detected_emotions.get) | |
| return { | |
| "dominant_emotion": dominant_emotion, | |
| "all_emotions": detected_emotions, | |
| "confidence": detected_emotions[dominant_emotion], | |
| "face_detected": True, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| def generate_emotional_report(self, user_id, days=7): | |
| """Genera reporte emocional del usuario""" | |
| conn = sqlite3.connect(self.core.db_path) | |
| # Obtener datos de los últimos días | |
| query = ''' | |
| SELECT emotion_data, timestamp FROM emotional_sessions | |
| WHERE user_id = ? AND timestamp > ? | |
| ORDER BY timestamp | |
| ''' | |
| start_date = datetime.now() - timedelta(days=days) | |
| cursor = conn.execute(query, (user_id, start_date.isoformat())) | |
| sessions = cursor.fetchall() | |
| conn.close() | |
| if not sessions: | |
| return {"message": "No hay datos suficientes para generar reporte"} | |
| # Procesar datos emocionales | |
| emotions_timeline = [] | |
| sentiment_scores = [] | |
| for session_data, timestamp in sessions: | |
| try: | |
| data = json.loads(session_data) | |
| emotions_timeline.append({ | |
| "timestamp": timestamp, | |
| "primary_emotion": data.get("primary_emotion", {}).get("label", "neutral"), | |
| "sentiment": data.get("sentiment", {}).get("label", "NEUTRAL"), | |
| "intensity": data.get("metrics", {}).get("intensity", 0.5) | |
| }) | |
| # Convertir sentimiento a score numérico | |
| sentiment_label = data.get("sentiment", {}).get("label", "NEUTRAL") | |
| if sentiment_label == "POSITIVE": | |
| sentiment_scores.append(1) | |
| elif sentiment_label == "NEGATIVE": | |
| sentiment_scores.append(-1) | |
| else: | |
| sentiment_scores.append(0) | |
| except json.JSONDecodeError: | |
| continue | |
| # Calcular métricas | |
| avg_sentiment = np.mean(sentiment_scores) if sentiment_scores else 0 | |
| sentiment_trend = "Mejorando" if len(sentiment_scores) > 1 and sentiment_scores[-1] > sentiment_scores[0] else "Estable" | |
| # Emociones más frecuentes | |
| emotion_counts = {} | |
| for entry in emotions_timeline: | |
| emotion = entry["primary_emotion"] | |
| emotion_counts[emotion] = emotion_counts.get(emotion, 0) + 1 | |
| most_frequent_emotion = max(emotion_counts, key=emotion_counts.get) if emotion_counts else "neutral" | |
| return { | |
| "period_days": days, | |
| "total_sessions": len(sessions), | |
| "average_sentiment": avg_sentiment, | |
| "sentiment_trend": sentiment_trend, | |
| "most_frequent_emotion": most_frequent_emotion, | |
| "emotion_distribution": emotion_counts, | |
| "timeline": emotions_timeline[-10:] # Últimas 10 sesiones | |
| } | |
| class TherapyBot: | |
| def __init__(self, core): | |
| self.core = core | |
| self.conversation_memory = {} | |
| self.therapy_techniques = { | |
| "cbt": "Terapia Cognitivo-Conductual", | |
| "dbt": "Terapia Dialéctica Conductual", | |
| "mindfulness": "Mindfulness y Atención Plena", | |
| "acceptance": "Terapia de Aceptación", | |
| "behavioral": "Modificación Conductual" | |
| } | |
| def generate_response(self, user_message, user_id, emotional_context=None): | |
| """Genera respuesta terapéutica personalizada""" | |
| if not user_message or len(user_message.strip()) < 2: | |
| return "Te escucho... ¿Podrías contarme un poco más?" | |
| # Analizar el estado emocional del mensaje | |
| if not emotional_context: | |
| analyzer = EmotionalAnalyzer(self.core) | |
| emotional_context = analyzer.analyze_text_emotion(user_message) | |
| # Seleccionar técnica terapéutica basada en el contexto emocional | |
| technique = self._select_therapy_technique(emotional_context) | |
| # Generar respuesta basada en la técnica seleccionada | |
| response = self._generate_therapeutic_response(user_message, emotional_context, technique) | |
| # Guardar interacción en la base de datos | |
| self._save_interaction(user_id, user_message, response, technique) | |
| return response | |
| def _select_therapy_technique(self, emotional_context): | |
| """Selecciona la técnica terapéutica más apropiada""" | |
| if "error" in emotional_context: | |
| return "cbt" | |
| primary_emotion = emotional_context.get("primary_emotion", {}).get("label", "neutral") | |
| sentiment = emotional_context.get("sentiment", {}).get("label", "NEUTRAL") | |
| # Mapeo de emociones a técnicas terapéuticas | |
| technique_mapping = { | |
| "sadness": "cbt", | |
| "anger": "dbt", | |
| "fear": "mindfulness", | |
| "anxiety": "mindfulness", | |
| "joy": "acceptance", | |
| "love": "acceptance" | |
| } | |
| return technique_mapping.get(primary_emotion, "cbt") | |
| def _generate_therapeutic_response(self, message, emotional_context, technique): | |
| """Genera respuesta terapéutica específica""" | |
| responses_bank = { | |
| "cbt": [ | |
| "Entiendo que te sientes así. ¿Qué pensamientos específicos están contribuyendo a esta emoción?", | |
| "Es importante reconocer estos sentimientos. ¿Podemos explorar qué evidencias tenés para estos pensamientos?", | |
| "Notaste algún patrón en estos pensamientos? A veces nuestras interpretaciones pueden intensificar nuestras emociones.", | |
| "¿Qué le dirías a un amigo cercano que estuviera pasando por algo similar?" | |
| ], | |
| "dbt": [ | |
| "Validemos primero lo que estás sintiendo: estos sentimientos son reales y comprensibles.", | |
| "¿Qué técnicas de tolerancia al malestar podrían ayudarte en este momento?", | |
| "Practiquemos un momento de mindfulness. ¿Podés notar qué sensaciones físicas acompañan a esta emoción?", | |
| "Es sabio buscar el equilibrio. ¿Qué sería lo más efectivo para vos en esta situación?" | |
| ], | |
| "mindfulness": [ | |
| "Tomemos un momento para conectar con el presente. ¿Qué estás notando en tu cuerpo ahora mismo?", | |
| "La respiración puede ser un ancla. ¿Querés que practiquemos juntos una técnica de respiración consciente?", | |
| "Observá estos pensamientos como nubes que pasan. No necesitás aferrarte a ellos ni rechazarlos.", | |
| "¿Podés notar estos sentimientos sin juzgarlos como buenos o malos?" | |
| ], | |
| "acceptance": [ | |
| "Es parte de la experiencia humana sentir esto. No estás solo/a en este sentimiento.", | |
| "¿Qué pasaría si pudieras aceptar esta emoción sin tratar de cambiarla inmediatamente?", | |
| "Tu capacidad de sentir profundamente también es una fortaleza. ¿Cómo podrías honrar esta parte de vos?", | |
| "¿Qué valores son importantes para vos, independientemente de cómo te sientas ahora?" | |
| ] | |
| } | |
| # Seleccionar respuesta apropiada | |
| possible_responses = responses_bank.get(technique, responses_bank["cbt"]) | |
| base_response = random.choice(possible_responses) | |
| # Personalizar basado en el contexto emocional | |
| if emotional_context.get("metrics", {}).get("intensity", 0.5) > 0.7: | |
| base_response = f"Noto que la intensidad de lo que estás sintiendo es alta. {base_response}" | |
| return base_response | |
| def _save_interaction(self, user_id, user_message, bot_response, technique): | |
| """Guarda la interacción en la base de datos""" | |
| conn = sqlite3.connect(self.core.db_path) | |
| cursor = conn.cursor() | |
| cursor.execute(''' | |
| INSERT INTO chat_interactions (user_id, timestamp, user_message, bot_response, therapy_technique) | |
| VALUES (?, ?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), user_message, bot_response, technique)) | |
| conn.commit() | |
| conn.close() | |
| class NeurofeedbackSimulator: | |
| def __init__(self, core): | |
| self.core = core | |
| self.session_duration = 300 # 5 minutos por defecto | |
| def generate_brainwave_data(self, session_type="relaxation", duration_seconds=60): | |
| """Genera datos simulados de ondas cerebrales""" | |
| # Frecuencias de las ondas cerebrales | |
| frequencies = { | |
| "delta": (0.5, 4), # Sueño profundo | |
| "theta": (4, 8), # Meditación profunda | |
| "alpha": (8, 13), # Relajación, atención | |
| "beta": (13, 30), # Concentración, alerta | |
| "gamma": (30, 100) # Procesamiento cognitivo | |
| } | |
| # Parámetros según el tipo de sesión | |
| session_params = { | |
| "relaxation": {"alpha": 0.4, "theta": 0.3, "beta": 0.2, "delta": 0.1, "gamma": 0.0}, | |
| "focus": {"beta": 0.5, "alpha": 0.3, "gamma": 0.1, "theta": 0.1, "delta": 0.0}, | |
| "meditation": {"theta": 0.5, "alpha": 0.3, "delta": 0.2, "beta": 0.0, "gamma": 0.0}, | |
| "creativity": {"alpha": 0.4, "theta": 0.3, "gamma": 0.2, "beta": 0.1, "delta": 0.0} | |
| } | |
| params = session_params.get(session_type, session_params["relaxation"]) | |
| # Generar timeline | |
| sample_rate = 256 # Hz | |
| total_samples = duration_seconds * sample_rate | |
| time_axis = np.linspace(0, duration_seconds, total_samples) | |
| # Generar señales para cada banda de frecuencia | |
| brainwave_data = {} | |
| composite_signal = np.zeros(total_samples) | |
| for wave_type, (freq_min, freq_max) in frequencies.items(): | |
| if params.get(wave_type, 0) > 0: | |
| # Frecuencia central de la banda | |
| center_freq = (freq_min + freq_max) / 2 | |
| # Generar señal sinusoidal con ruido | |
| amplitude = params[wave_type] | |
| noise_factor = 0.1 | |
| signal_clean = amplitude * np.sin(2 * np.pi * center_freq * time_axis) | |
| noise = noise_factor * np.random.normal(0, 1, total_samples) | |
| signal_with_noise = signal_clean + noise | |
| brainwave_data[wave_type] = { | |
| "signal": signal_with_noise, | |
| "amplitude": amplitude, | |
| "frequency": center_freq, | |
| "power": np.mean(signal_with_noise ** 2) | |
| } | |
| composite_signal += signal_with_noise | |
| # Calcular métricas de rendimiento | |
| performance_metrics = self._calculate_performance_metrics(brainwave_data, session_type) | |
| return { | |
| "time_axis": time_axis.tolist(), | |
| "composite_signal": composite_signal.tolist(), | |
| "brainwave_data": {k: {"signal": v["signal"].tolist(), | |
| "amplitude": v["amplitude"], | |
| "frequency": v["frequency"], | |
| "power": v["power"]} for k, v in brainwave_data.items()}, | |
| "performance_metrics": performance_metrics, | |
| "session_type": session_type, | |
| "duration": duration_seconds | |
| } | |
| def _calculate_performance_metrics(self, brainwave_data, session_type): | |
| """Calcula métricas de rendimiento de la sesión""" | |
| # Métricas específicas por tipo de sesión | |
| if session_type == "relaxation": | |
| alpha_power = brainwave_data.get("alpha", {}).get("power", 0) | |
| theta_power = brainwave_data.get("theta", {}).get("power", 0) | |
| relaxation_index = (alpha_power + theta_power) / 2 | |
| return { | |
| "relaxation_index": min(relaxation_index * 100, 100), | |
| "alpha_strength": min(alpha_power * 200, 100), | |
| "overall_score": min((relaxation_index * 80 + alpha_power * 20) * 100, 100) | |
| } | |
| elif session_type == "focus": | |
| beta_power = brainwave_data.get("beta", {}).get("power", 0) | |
| alpha_power = brainwave_data.get("alpha", {}).get("power", 0) | |
| focus_index = beta_power / (alpha_power + 0.01) # Evitar división por cero | |
| return { | |
| "focus_index": min(focus_index * 50, 100), | |
| "beta_strength": min(beta_power * 200, 100), | |
| "overall_score": min((focus_index * 60 + beta_power * 40) * 50, 100) | |
| } | |
| else: # meditation, creativity, etc. | |
| theta_power = brainwave_data.get("theta", {}).get("power", 0) | |
| alpha_power = brainwave_data.get("alpha", {}).get("power", 0) | |
| meditation_index = theta_power * 1.5 + alpha_power | |
| return { | |
| "meditation_index": min(meditation_index * 100, 100), | |
| "theta_strength": min(theta_power * 200, 100), | |
| "overall_score": min(meditation_index * 100, 100) | |
| } | |
| def create_session_visualization(self, session_data): | |
| """Crea visualización de la sesión de neurofeedback""" | |
| try: | |
| # Gráfico de ondas cerebrales en tiempo real | |
| fig = go.Figure() | |
| time_axis = session_data["time_axis"][:1000] # Mostrar solo primeros 1000 puntos para rendimiento | |
| # Agregar cada tipo de onda cerebral | |
| colors = { | |
| "delta": "#FF6B6B", | |
| "theta": "#4ECDC4", | |
| "alpha": "#45B7D1", | |
| "beta": "#96CEB4", | |
| "gamma": "#FFEAA7" | |
| } | |
| for wave_type, wave_data in session_data["brainwave_data"].items(): | |
| signal_data = wave_data["signal"][:1000] | |
| fig.add_trace(go.Scatter( | |
| x=time_axis, | |
| y=signal_data, | |
| mode='lines', | |
| name=f'{wave_type.capitalize()} ({wave_data["frequency"]:.1f} Hz)', | |
| line=dict(color=colors.get(wave_type, "#74B9FF"), width=2) | |
| )) | |
| fig.update_layout( | |
| title=f'Simulación de Ondas Cerebrales - Sesión de {session_data["session_type"].title()}', | |
| xaxis_title='Tiempo (segundos)', | |
| yaxis_title='Amplitud', | |
| template="plotly_dark", | |
| height=400, | |
| showlegend=True | |
| ) | |
| return fig | |
| except Exception as e: | |
| print(f"Error creando visualización: {e}") | |
| return None | |
| class PurposeDiscovery: | |
| def __init__(self, core): | |
| self.core = core | |
| self.purpose_questions = [ | |
| { | |
| "id": 1, | |
| "category": "values", | |
| "question": "¿Qué valores son más importantes para vos en la vida?", | |
| "options": [ | |
| "Familia y relaciones cercanas", | |
| "Crecimiento personal y aprendizaje", | |
| "Contribución social y ayudar a otros", | |
| "Creatividad y expresión artística", | |
| "Éxito profesional y logros", | |
| "Libertad e independencia", | |
| "Estabilidad y seguridad", | |
| "Aventura y experiencias nuevas" | |
| ] | |
| }, | |
| { | |
| "id": 2, | |
| "category": "motivations", | |
| "question": "¿Qué te motiva a levantarte cada mañana?", | |
| "options": [ | |
| "La posibilidad de impactar positivamente en otros", | |
| "Desafíos intelectuales y resolver problemas", | |
| "Crear algo nuevo y original", | |
| "Construir y mantener relaciones significativas", | |
| "Alcanzar metas y objetivos personales", | |
| "Explorar y descubrir cosas nuevas", | |
| "Cuidar y proteger a las personas que amo", | |
| "Expresar mi autenticidad y ser quien realmente soy" | |
| ] | |
| }, | |
| { | |
| "id": 3, | |
| "category": "strengths", | |
| "question": "¿En qué te dicen que sos naturalmente bueno/a?", | |
| "options": [ | |
| "Escuchar y aconsejar a otros", | |
| "Analizar situaciones complejas", | |
| "Liderar equipos y proyectos", | |
| "Crear y diseñar cosas hermosas", | |
| "Enseñar y explicar conceptos", | |
| "Organizar y planificar", | |
| "Conectar con personas diferentes", | |
| "Innovar y pensar fuera de lo convencional" | |
| ] | |
| }, | |
| { | |
| "id": 4, | |
| "category": "impact", | |
| "question": "¿Cómo te gustaría ser recordado/a?", | |
| "options": [ | |
| "Como alguien que hizo una diferencia en la vida de otros", | |
| "Como un/a pionero/a que abrió nuevos caminos", | |
| "Como alguien que inspiró a otros a ser mejores", | |
| "Como un/a creador/a que dejó algo hermoso en el mundo", | |
| "Como alguien que fue auténtico/a y fiel a sí mismo/a", | |
| "Como un/a mentor/a que ayudó a otros a crecer", | |
| "Como alguien que construyó algo duradero e importante", | |
| "Como una persona que vivió intensamente y sin miedo" | |
| ] | |
| }, | |
| { | |
| "id": 5, | |
| "category": "legacy", | |
| "question": "Si tuvieras recursos ilimitados, ¿a qué dedicarías tu tiempo?", | |
| "options": [ | |
| "Resolver problemas sociales importantes", | |
| "Crear arte o contenido que inspire", | |
| "Explorar los misterios del universo", | |
| "Construir comunidades y conectar personas", | |
| "Desarrollar tecnologías que mejoren la vida", | |
| "Preservar conocimiento y cultura para futuras generaciones", | |
| "Aventurarme en experiencias transformadoras", | |
| "Cultivar sabiduría y compartir enseñanzas" | |
| ] | |
| } | |
| ] | |
| self.purpose_archetypes = { | |
| "healer": { | |
| "name": "El/La Sanador/a", | |
| "description": "Tu propósito se centra en ayudar a otros a sanar, crecer y encontrar bienestar.", | |
| "keywords": ["ayudar", "sanar", "cuidar", "apoyar", "guiar"], | |
| "strengths": ["Empatía", "Escucha activa", "Compasión", "Intuición"], | |
| "paths": ["Terapia y counseling", "Medicina y salud", "Trabajo social", "Coaching personal"] | |
| }, | |
| "creator": { | |
| "name": "El/La Creador/a", | |
| "description": "Tu propósito está en crear, innovar y traer algo nuevo al mundo.", | |
| "keywords": ["crear", "innovar", "diseñar", "expresar", "construir"], | |
| "strengths": ["Creatividad", "Visión", "Originalidad", "Expresión"], | |
| "paths": ["Arte y diseño", "Emprendimiento", "Tecnología", "Escritura y medios"] | |
| }, | |
| "teacher": { | |
| "name": "El/La Maestro/a", | |
| "description": "Tu propósito es compartir conocimiento y ayudar a otros a aprender y crecer.", | |
| "keywords": ["enseñar", "educar", "compartir", "guiar", "inspirar"], | |
| "strengths": ["Comunicación", "Paciencia", "Conocimiento", "Inspiración"], | |
| "paths": ["Educación formal", "Mentoring", "Escritura educativa", "Divulgación"] | |
| }, | |
| "explorer": { | |
| "name": "El/La Explorador/a", | |
| "description": "Tu propósito está en descubrir, aventurarte y expandir fronteras.", | |
| "keywords": ["explorar", "descubrir", "aventurar", "investigar", "expandir"], | |
| "strengths": ["Curiosidad", "Valentía", "Adaptabilidad", "Investigación"], | |
| "paths": ["Investigación científica", "Viajes y turismo", "Periodismo", "Deportes extremos"] | |
| }, | |
| "builder": { | |
| "name": "El/La Constructor/a", | |
| "description": "Tu propósito es construir sistemas, organizaciones y estructuras duraderas.", | |
| "keywords": ["construir", "organizar", "sistematizar", "liderar", "estructurar"], | |
| "strengths": ["Liderazgo", "Organización", "Visión estratégica", "Perseverancia"], | |
| "paths": ["Negocios y emprendimiento", "Gestión de proyectos", "Política", "Ingeniería"] | |
| }, | |
| "connector": { | |
| "name": "El/La Conector/a", | |
| "description": "Tu propósito es unir personas, ideas y comunidades.", | |
| "keywords": ["conectar", "unir", "comunicar", "facilitar", "mediar"], | |
| "strengths": ["Comunicación", "Networking", "Diplomacia", "Facilitación"], | |
| "paths": ["Relaciones públicas", "Mediación", "Eventos y comunidades", "Ventas consultivas"] | |
| } | |
| } | |
| def analyze_purpose_responses(self, responses): | |
| """Analiza las respuestas para determinar el arquetipo de propósito""" | |
| if not responses or len(responses) < len(self.purpose_questions): | |
| return {"error": "Respuestas incompletas"} | |
| # Mapeo de respuestas a arquetipos | |
| response_mapping = { | |
| # Pregunta 1 - Valores | |
| 0: ["connector", "healer"], # Familia y relaciones | |
| 1: ["explorer", "teacher"], # Crecimiento y aprendizaje | |
| 2: ["healer", "teacher"], # Contribución social | |
| 3: ["creator", "explorer"], # Creatividad | |
| 4: ["builder", "creator"], # Éxito profesional | |
| 5: ["explorer", "creator"], # Libertad | |
| 6: ["builder", "healer"], # Estabilidad | |
| 7: ["explorer", "creator"], # Aventura | |
| } | |
| # Contar puntos por arquetipo | |
| archetype_scores = {archetype: 0 for archetype in self.purpose_archetypes.keys()} | |
| for i, response_index in enumerate(responses): | |
| if i < len(self.purpose_questions) and response_index < len(self.purpose_questions[i]["options"]): | |
| # Obtener arquetipos asociados a esta respuesta | |
| associated_archetypes = response_mapping.get(response_index, []) | |
| for archetype in associated_archetypes: | |
| if archetype in archetype_scores: | |
| archetype_scores[archetype] += 1 | |
| # Determinar arquetipo dominante | |
| dominant_archetype = max(archetype_scores, key=archetype_scores.get) | |
| secondary_archetype = sorted(archetype_scores.items(), key=lambda x: x[1], reverse=True)[1][0] | |
| # Generar perfil de propósito | |
| primary_profile = self.purpose_archetypes[dominant_archetype] | |
| secondary_profile = self.purpose_archetypes[secondary_archetype] | |
| # Crear roadmap personalizado | |
| roadmap = self._generate_purpose_roadmap(dominant_archetype, responses) | |
| return { | |
| "primary_archetype": { | |
| "type": dominant_archetype, | |
| "profile": primary_profile, | |
| "score": archetype_scores[dominant_archetype] | |
| }, | |
| "secondary_archetype": { | |
| "type": secondary_archetype, | |
| "profile": secondary_profile, | |
| "score": archetype_scores[secondary_archetype] | |
| }, | |
| "all_scores": archetype_scores, | |
| "roadmap": roadmap, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| def _generate_purpose_roadmap(self, dominant_archetype, responses): | |
| """Genera un roadmap personalizado hacia el propósito""" | |
| roadmaps = { | |
| "healer": { | |
| "short_term": [ | |
| "Desarrollar habilidades de escucha activa y empatía", | |
| "Explorar técnicas de ayuda (counseling, coaching)", | |
| "Practicar el autocuidado para poder cuidar a otros", | |
| "Buscar oportunidades de voluntariado en tu área" | |
| ], | |
| "medium_term": [ | |
| "Considerar formación en terapia, coaching o trabajo social", | |
| "Construir una red de personas en profesiones de ayuda", | |
| "Especialízate en un área específica de sanación", | |
| "Crear espacios seguros para que otros se expresen" | |
| ], | |
| "long_term": [ | |
| "Establecer tu propia práctica de ayuda", | |
| "Desarrollar programas innovadores de bienestar", | |
| "Formar a otros en técnicas de sanación", | |
| "Impactar comunidades enteras con tu trabajo" | |
| ] | |
| }, | |
| "creator": { | |
| "short_term": [ | |
| "Dedicate tiempo diario a la práctica creativa", | |
| "Experimenta con diferentes medios y técnicas", | |
| "Documentá y compartí tu proceso creativo", | |
| "Conectá con otros creadores en tu área" | |
| ], | |
| "medium_term": [ | |
| "Desarrollá tu estilo único y distintivo", | |
| "Construí un portafolio sólido de tu trabajo", | |
| "Participá en exhibiciones, concursos o publicaciones", | |
| "Aprendé sobre el lado comercial de tu creatividad" | |
| ], | |
| "long_term": [ | |
| "Establecé tu marca personal como creador/a", | |
| "Creá obras que trasciendan y marquen diferencia", | |
| "Inspirá a la próxima generación de creadores", | |
| "Dejá un legado creativo duradero" | |
| ] | |
| }, | |
| "teacher": { | |
| "short_term": [ | |
| "Identificá qué conocimientos podés compartir", | |
| "Practicá explicar conceptos complejos de forma simple", | |
| "Buscá oportunidades de mentoreo informal", | |
| "Desarrollá tu habilidad de comunicación" | |
| ], | |
| "medium_term": [ | |
| "Creá contenido educativo (blogs, videos, cursos)", | |
| "Formalizá tu educación en pedagogía si es necesario", | |
| "Construí una audiencia interesada en tu expertise", | |
| "Desarrollá métodos de enseñanza innovadores" | |
| ], | |
| "long_term": [ | |
| "Establecé tu autoridad en tu área de conocimiento", | |
| "Creá programas educativos que transformen vidas", | |
| "Formá a otros educadores y multiplicá tu impacto", | |
| "Contribuí al avance del conocimiento en tu campo" | |
| ] | |
| }, | |
| "explorer": { | |
| "short_term": [ | |
| "Cultivá tu curiosidad y hacé preguntas profundas", | |
| "Exponete a nuevas experiencias regularmente", | |
| "Desarrollá habilidades de investigación", | |
| "Documentá tus descubrimientos y aprendizajes" | |
| ], | |
| "medium_term": [ | |
| "Especializáte en un área de exploración específica", | |
| "Construí redes con otros exploradores e investigadores", | |
| "Buscá financiamiento para proyectos de exploración", | |
| "Compartí tus descubrimientos con el mundo" | |
| ], | |
| "long_term": [ | |
| "Lidera expediciones o investigaciones importantes", | |
| "Hace descubrimientos que expandan el conocimiento humano", | |
| "Inspirá a otros a explorar y descubrir", | |
| "Dejá un legado de nuevos conocimientos" | |
| ] | |
| }, | |
| "builder": { | |
| "short_term": [ | |
| "Desarrollá habilidades de liderazgo y gestión", | |
| "Aprendé sobre creación y gestión de sistemas", | |
| "Practicá la planificación estratégica", | |
| "Construí proyectos pequeños para ganar experiencia" | |
| ], | |
| "medium_term": [ | |
| "Lidera equipos en proyectos significativos", | |
| "Desarrollá expertise en tu industria específica", | |
| "Construí una red sólida de colaboradores", | |
| "Crea sistemas que generen valor duradero" | |
| ], | |
| "long_term": [ | |
| "Fundá organizaciones o empresas importantes", | |
| "Crea sistemas que transformen industrias", | |
| "Desarrollá a la próxima generación de líderes", | |
| "Dejá estructuras que perduren en el tiempo" | |
| ] | |
| }, | |
| "connector": { | |
| "short_term": [ | |
| "Desarrollá habilidades de comunicación excepcionales", | |
| "Practicá la construcción de puentes entre personas", | |
| "Aprendé sobre facilitación y mediación", | |
| "Expandí tu red de contactos conscientemente" | |
| ], | |
| "medium_term": [ | |
| "Creá comunidades alrededor de intereses comunes", | |
| "Desarrollá plataformas para conectar a otros", | |
| "Especializáte en resolución de conflictos", | |
| "Construí reputación como facilitador/a confiable" | |
| ], | |
| "long_term": [ | |
| "Lidera iniciativas que unan comunidades globales", | |
| "Creá movimientos que generen cambio positivo", | |
| "Desarrollá tecnologías o sistemas de conexión", | |
| "Dejá un mundo más conectado y colaborativo" | |
| ] | |
| } | |
| } | |
| return roadmaps.get(dominant_archetype, roadmaps["healer"]) | |
| class CommunityHub: | |
| def __init__(self, core): | |
| self.core = core | |
| self.topics = [ | |
| "Ansiedad y Estrés", | |
| "Depresión y Tristeza", | |
| "Relaciones y Familia", | |
| "Autoestima y Confianza", | |
| "Propósito y Significado", | |
| "Trabajo y Carrera", | |
| "Creatividad y Expresión", | |
| "Mindfulness y Meditación", | |
| "Traumas y Sanación", | |
| "Crecimiento Personal" | |
| ] | |
| def create_anonymous_id(self, user_id): | |
| """Crea ID anónimo para la comunidad""" | |
| hash_object = hashlib.sha256(f"{user_id}_{datetime.now().date()}".encode()) | |
| return f"Usuario_{hash_object.hexdigest()[:8]}" | |
| def post_to_community(self, user_id, content, topic): | |
| """Publica contenido anónimo en la comunidad""" | |
| if not content or len(content.strip()) < 10: | |
| return {"error": "El contenido debe tener al menos 10 caracteres"} | |
| # Crear ID anónimo | |
| anonymous_id = self.create_anonymous_id(user_id) | |
| # Analizar sentimiento del post | |
| analyzer = EmotionalAnalyzer(self.core) | |
| emotional_analysis = analyzer.analyze_text_emotion(content) | |
| sentiment_score = emotional_analysis.get("metrics", {}).get("valence", 0.5) | |
| # Guardar post en la base de datos | |
| conn = sqlite3.connect(self.core.db_path) | |
| cursor = conn.cursor() | |
| cursor.execute(''' | |
| INSERT INTO community_posts (user_id, timestamp, content, topic, sentiment_score, anonymous_id) | |
| VALUES (?, ?, ?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), content, topic, sentiment_score, anonymous_id)) | |
| conn.commit() | |
| conn.close() | |
| return { | |
| "message": "Tu mensaje fue compartido anónimamente en la comunidad", | |
| "anonymous_id": anonymous_id, | |
| "topic": topic, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| def get_community_feed(self, topic=None, limit=20): | |
| """Obtiene feed de la comunidad""" | |
| conn = sqlite3.connect(self.core.db_path) | |
| if topic: | |
| query = ''' | |
| SELECT anonymous_id, content, topic, timestamp, sentiment_score | |
| FROM community_posts | |
| WHERE topic = ? | |
| ORDER BY timestamp DESC | |
| LIMIT ? | |
| ''' | |
| cursor = conn.execute(query, (topic, limit)) | |
| else: | |
| query = ''' | |
| SELECT anonymous_id, content, topic, timestamp, sentiment_score | |
| FROM community_posts | |
| ORDER BY timestamp DESC | |
| LIMIT ? | |
| ''' | |
| cursor = conn.execute(query, (limit,)) | |
| posts = cursor.fetchall() | |
| conn.close() | |
| feed = [] | |
| for post in posts: | |
| anonymous_id, content, post_topic, timestamp, sentiment_score = post | |
| # Formatear timestamp | |
| try: | |
| dt = datetime.fromisoformat(timestamp) | |
| time_ago = self._time_ago(dt) | |
| except: | |
| time_ago = "Hace un momento" | |
| # Determinar emoji basado en sentimiento | |
| sentiment_emoji = "😊" if sentiment_score > 0.6 else "😔" if sentiment_score < 0.4 else "😐" | |
| feed.append({ | |
| "id": anonymous_id, | |
| "content": content[:200] + "..." if len(content) > 200 else content, | |
| "topic": post_topic, | |
| "time_ago": time_ago, | |
| "sentiment_emoji": sentiment_emoji | |
| }) | |
| return feed | |
| def _time_ago(self, dt): | |
| """Calcula tiempo transcurrido desde un datetime""" | |
| now = datetime.now() | |
| diff = now - dt | |
| if diff.days > 0: | |
| return f"Hace {diff.days} día{'s' if diff.days > 1 else ''}" | |
| elif diff.seconds > 3600: | |
| hours = diff.seconds // 3600 | |
| return f"Hace {hours} hora{'s' if hours > 1 else ''}" | |
| elif diff.seconds > 60: | |
| minutes = diff.seconds // 60 | |
| return f"Hace {minutes} minuto{'s' if minutes > 1 else ''}" | |
| else: | |
| return "Hace un momento" | |
| def get_community_stats(self): | |
| """Obtiene estadísticas de la comunidad""" | |
| conn = sqlite3.connect(self.core.db_path) | |
| # Total de posts | |
| cursor = conn.execute("SELECT COUNT(*) FROM community_posts") | |
| total_posts = cursor.fetchone()[0] | |
| # Posts por tópico | |
| cursor = conn.execute(''' | |
| SELECT topic, COUNT(*) | |
| FROM community_posts | |
| GROUP BY topic | |
| ORDER BY COUNT(*) DESC | |
| ''') | |
| posts_by_topic = dict(cursor.fetchall()) | |
| # Sentimiento promedio | |
| cursor = conn.execute("SELECT AVG(sentiment_score) FROM community_posts") | |
| avg_sentiment = cursor.fetchone()[0] or 0.5 | |
| # Posts recientes (últimas 24 horas) | |
| yesterday = datetime.now() - timedelta(days=1) | |
| cursor = conn.execute(''' | |
| SELECT COUNT(*) FROM community_posts | |
| WHERE timestamp > ? | |
| ''', (yesterday.isoformat(),)) | |
| recent_posts = cursor.fetchone()[0] | |
| conn.close() | |
| return { | |
| "total_posts": total_posts, | |
| "posts_by_topic": posts_by_topic, | |
| "average_sentiment": avg_sentiment, | |
| "recent_posts": recent_posts, | |
| "community_mood": "Positiva" if avg_sentiment > 0.6 else "Neutral" if avg_sentiment > 0.4 else "Necesita apoyo" | |
| } | |
| # Inicializar el sistema | |
| synapse_core = SynapseCore() | |
| emotional_analyzer = EmotionalAnalyzer(synapse_core) | |
| therapy_bot = TherapyBot(synapse_core) | |
| neurofeedback_sim = NeurofeedbackSimulator(synapse_core) | |
| purpose_discovery = PurposeDiscovery(synapse_core) | |
| community_hub = CommunityHub(synapse_core) | |
| # Funciones de la interfaz Gradio | |
| def generate_user_id(): | |
| """Genera ID único para el usuario""" | |
| return f"user_{hashlib.sha256(str(time.time()).encode()).hexdigest()[:10]}" | |
| def analyze_text_emotions(text, user_id): | |
| """Analiza emociones en texto para la interfaz""" | |
| if not text: | |
| return "Por favor, ingresá algún texto para analizar.", None, None | |
| # Analizar emociones | |
| result = emotional_analyzer.analyze_text_emotion(text) | |
| if "error" in result: | |
| return f"Error: {result['error']}", None, None | |
| # Guardar sesión emocional | |
| conn = sqlite3.connect(synapse_core.db_path) | |
| cursor = conn.cursor() | |
| cursor.execute(''' | |
| INSERT OR IGNORE INTO users (id, created_at, emotional_profile, purpose_data, preferences) | |
| VALUES (?, ?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), "", "", "")) | |
| cursor.execute(''' | |
| INSERT INTO emotional_sessions (user_id, timestamp, emotion_data, context) | |
| VALUES (?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), json.dumps(result), "text_analysis")) | |
| conn.commit() | |
| conn.close() | |
| # Formatear resultado | |
| sentiment = result.get("sentiment", {}) | |
| emotion = result.get("primary_emotion", {}) | |
| metrics = result.get("metrics", {}) | |
| analysis_text = f""" | |
| ## Análisis Emocional Completado ✨ | |
| **Sentimiento Principal:** {sentiment.get('label', 'N/A')} (Confianza: {sentiment.get('score', 0):.2%}) | |
| **Emoción Dominante:** {emotion.get('label', 'N/A').title()} (Intensidad: {emotion.get('score', 0):.2%}) | |
| **Métricas Neuroemocionales:** | |
| - Arousal (Activación): {metrics.get('arousal', 0):.2%} | |
| - Valencia (Positividad): {metrics.get('valence', 0):.2%} | |
| - Dominancia (Control): {metrics.get('dominance', 0):.2%} | |
| --- | |
| *Tu estado emocional fue registrado de forma privada para generar insights personalizados.* | |
| """ | |
| # Crear visualización | |
| emotions_chart = create_emotion_radar_chart(metrics) | |
| sentiment_gauge = create_sentiment_gauge(sentiment.get('score', 0.5), sentiment.get('label', 'NEUTRAL')) | |
| return analysis_text, emotions_chart, sentiment_gauge | |
| def create_emotion_radar_chart(metrics): | |
| """Crea gráfico radar de métricas emocionales""" | |
| try: | |
| categories = ['Arousal<br>(Activación)', 'Valence<br>(Positividad)', 'Dominance<br>(Control)'] | |
| values = [ | |
| metrics.get('arousal', 0.5) * 100, | |
| metrics.get('valence', 0.5) * 100, | |
| metrics.get('dominance', 0.5) * 100 | |
| ] | |
| fig = go.Figure() | |
| fig.add_trace(go.Scatterpolar( | |
| r=values + [values[0]], # Cerrar el círculo | |
| theta=categories + [categories[0]], | |
| fill='toself', | |
| name='Estado Emocional', | |
| fillcolor='rgba(74, 185, 241, 0.3)', | |
| line=dict(color='rgb(74, 185, 241)', width=3) | |
| )) | |
| fig.update_layout( | |
| polar=dict( | |
| radialaxis=dict( | |
| visible=True, | |
| range=[0, 100], | |
| tickfont=dict(color='white', size=10), | |
| gridcolor='rgba(255, 255, 255, 0.2)' | |
| ), | |
| angularaxis=dict( | |
| tickfont=dict(color='white', size=12), | |
| linecolor='rgba(255, 255, 255, 0.2)' | |
| ), | |
| bgcolor='rgba(0, 0, 0, 0)' | |
| ), | |
| showlegend=False, | |
| title=dict( | |
| text="Perfil Neuroemocional", | |
| x=0.5, | |
| font=dict(color='white', size=16) | |
| ), | |
| paper_bgcolor='rgba(0, 0, 0, 0)', | |
| plot_bgcolor='rgba(0, 0, 0, 0)', | |
| height=400 | |
| ) | |
| return fig | |
| except Exception as e: | |
| print(f"Error creating radar chart: {e}") | |
| return None | |
| def create_sentiment_gauge(score, label): | |
| """Crea gauge de sentimiento""" | |
| try: | |
| # Convertir label a score numérico | |
| if label == "POSITIVE": | |
| gauge_value = 0.5 + score * 0.5 | |
| elif label == "NEGATIVE": | |
| gauge_value = 0.5 - score * 0.5 | |
| else: | |
| gauge_value = 0.5 | |
| gauge_value = max(0, min(1, gauge_value)) * 100 # Normalizar a 0-100 | |
| fig = go.Figure(go.Indicator( | |
| mode = "gauge+number+delta", | |
| value = gauge_value, | |
| domain = {'x': [0, 1], 'y': [0, 1]}, | |
| title = {'text': "Indicador de Sentimiento"}, | |
| delta = {'reference': 50}, | |
| gauge = { | |
| 'axis': {'range': [None, 100]}, | |
| 'bar': {'color': "rgb(74, 185, 241)"}, | |
| 'steps': [ | |
| {'range': [0, 25], 'color': "rgba(255, 107, 107, 0.3)"}, | |
| {'range': [25, 50], 'color': "rgba(255, 193, 7, 0.3)"}, | |
| {'range': [50, 75], 'color': "rgba(40, 167, 69, 0.3)"}, | |
| {'range': [75, 100], 'color': "rgba(74, 185, 241, 0.3)"} | |
| ], | |
| 'threshold': { | |
| 'line': {'color': "red", 'width': 4}, | |
| 'thickness': 0.75, | |
| 'value': 90 | |
| } | |
| } | |
| )) | |
| fig.update_layout( | |
| paper_bgcolor='rgba(0, 0, 0, 0)', | |
| plot_bgcolor='rgba(0, 0, 0, 0)', | |
| font=dict(color='white'), | |
| height=300 | |
| ) | |
| return fig | |
| except Exception as e: | |
| print(f"Error creating gauge: {e}") | |
| return None | |
| def chat_with_therapist(message, chat_history, user_id): | |
| """Interfaz del chatbot terapéutico""" | |
| if not message: | |
| return chat_history, "" | |
| # Analizar contexto emocional del mensaje | |
| emotional_context = emotional_analyzer.analyze_text_emotion(message) | |
| # Generar respuesta terapéutica | |
| bot_response = therapy_bot.generate_response(message, user_id, emotional_context) | |
| # Agregar a historial | |
| chat_history.append([message, bot_response]) | |
| return chat_history, "" | |
| def run_neurofeedback_session(session_type, duration, user_id): | |
| """Ejecuta sesión de neurofeedback""" | |
| if duration < 30 or duration > 600: | |
| return "La duración debe estar entre 30 segundos y 10 minutos.", None, "Error en parámetros" | |
| # Generar datos de la sesión | |
| session_data = neurofeedback_sim.generate_brainwave_data(session_type, duration) | |
| # Crear visualización | |
| visualization = neurofeedback_sim.create_session_visualization(session_data) | |
| # Guardar sesión | |
| conn = sqlite3.connect(synapse_core.db_path) | |
| cursor = conn.cursor() | |
| cursor.execute(''' | |
| INSERT OR IGNORE INTO users (id, created_at, emotional_profile, purpose_data, preferences) | |
| VALUES (?, ?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), "", "", "")) | |
| cursor.execute(''' | |
| INSERT INTO neurofeedback_sessions (user_id, timestamp, session_data, performance_metrics) | |
| VALUES (?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), json.dumps(session_data), json.dumps(session_data["performance_metrics"]))) | |
| conn.commit() | |
| conn.close() | |
| # Formatear resultados | |
| metrics = session_data["performance_metrics"] | |
| results_text = f""" | |
| ## Sesión de {session_type.title()} Completada! 🧠✨ | |
| **Duración:** {duration} segundos | |
| **Métricas de Rendimiento:** | |
| """ | |
| for metric, value in metrics.items(): | |
| results_text += f"- **{metric.replace('_', ' ').title()}:** {value:.1f}%\n" | |
| results_text += f""" | |
| **Interpretación:** | |
| """ | |
| overall_score = metrics.get("overall_score", 50) | |
| if overall_score >= 80: | |
| results_text += "¡Excelente sesión! Tu estado neuroemocional muestra muy buena sincronización." | |
| elif overall_score >= 60: | |
| results_text += "Buena sesión. Tu cerebro está respondiendo positivamente al entrenamiento." | |
| elif overall_score >= 40: | |
| results_text += "Sesión moderada. Seguí practicando para mejorar la sincronización." | |
| else: | |
| results_text += "Sesión inicial. Es normal, el neurofeedback mejora con la práctica." | |
| return results_text, visualization, json.dumps(session_data, indent=2) | |
| def discover_life_purpose(responses, user_id): | |
| """Procesa discovery de propósito vital""" | |
| if not responses or len([r for r in responses if r is not None]) < len(purpose_discovery.purpose_questions): | |
| return "Por favor, completá todas las preguntas para continuar.", None, "" | |
| # Convertir respuestas a índices | |
| response_indices = [] | |
| for i, response in enumerate(responses): | |
| if response is not None: | |
| try: | |
| # Buscar índice de la opción seleccionada | |
| options = purpose_discovery.purpose_questions[i]["options"] | |
| if response in options: | |
| response_indices.append(options.index(response)) | |
| else: | |
| response_indices.append(0) # Default | |
| except: | |
| response_indices.append(0) | |
| # Analizar propósito | |
| purpose_analysis = purpose_discovery.analyze_purpose_responses(response_indices) | |
| if "error" in purpose_analysis: | |
| return f"Error: {purpose_analysis['error']}", None, "" | |
| # Guardar resultados | |
| conn = sqlite3.connect(synapse_core.db_path) | |
| cursor = conn.cursor() | |
| cursor.execute(''' | |
| INSERT OR IGNORE INTO users (id, created_at, emotional_profile, purpose_data, preferences) | |
| VALUES (?, ?, ?, ?, ?) | |
| ''', (user_id, datetime.now().isoformat(), "", "", "")) | |
| cursor.execute(''' | |
| UPDATE users SET purpose_data = ? WHERE id = ? | |
| ''', (json.dumps(purpose_analysis), user_id)) | |
| conn.commit() | |
| conn.close() | |
| # Formatear resultados | |
| primary = purpose_analysis["primary_archetype"] | |
| secondary = purpose_analysis["secondary_archetype"] | |
| roadmap = purpose_analysis["roadmap"] | |
| results_text = f""" | |
| # Tu Arquetipo de Propósito: {primary['profile']['name']} 🎯 | |
| ## Descripción Principal | |
| {primary['profile']['description']} | |
| **Fortalezas Clave:** {', '.join(primary['profile']['strengths'])} | |
| **Caminos Sugeridos:** {', '.join(primary['profile']['paths'])} | |
| --- | |
| ## Arquetipo Secundario: {secondary['profile']['name']} | |
| {secondary['profile']['description']} | |
| --- | |
| ## Tu Roadmap Personalizado | |
| ### 🎯 Objetivos a Corto Plazo (1-6 meses) | |
| """ | |
| for goal in roadmap["short_term"]: | |
| results_text += f"- {goal}\n" | |
| results_text += f""" | |
| ### 🚀 Objetivos a Mediano Plazo (6 meses - 2 años) | |
| """ | |
| for goal in roadmap["medium_term"]: | |
| results_text += f"- {goal}\n" | |
| results_text += f""" | |
| ### 🌟 Visión a Largo Plazo (2+ años) | |
| """ | |
| for goal in roadmap["long_term"]: | |
| results_text += f"- {goal}\n" | |
| # Crear visualización de arquetipos | |
| archetype_viz = create_purpose_visualization(purpose_analysis["all_scores"]) | |
| return results_text, archetype_viz, json.dumps(purpose_analysis, indent=2) | |
| def create_purpose_visualization(scores): | |
| """Crea visualización de arquetipos de propósito""" | |
| try: | |
| archetypes = list(scores.keys()) | |
| values = list(scores.values()) | |
| # Traducir nombres de arquetipos | |
| archetype_names = { | |
| "healer": "Sanador/a", | |
| "creator": "Creador/a", | |
| "teacher": "Maestro/a", | |
| "explorer": "Explorador/a", | |
| "builder": "Constructor/a", | |
| "connector": "Conector/a" | |
| } | |
| translated_names = [archetype_names.get(arch, arch.title()) for arch in archetypes] | |
| fig = go.Figure(data=[ | |
| go.Bar( | |
| x=translated_names, | |
| y=values, | |
| marker_color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD'], | |
| text=values, | |
| textposition='auto', | |
| ) | |
| ]) | |
| fig.update_layout( | |
| title="Tu Perfil de Arquetipos de Propósito", | |
| xaxis_title="Arquetipos", | |
| yaxis_title="Puntuación", | |
| template="plotly_dark", | |
| height=400, | |
| showlegend=False | |
| ) | |
| return fig | |
| except Exception as e: | |
| print(f"Error creating purpose visualization: {e}") | |
| return None | |
| def post_to_community_interface(content, topic, user_id): | |
| """Interfaz para publicar en la comunidad""" | |
| if not content: | |
| return "Por favor, escribí tu mensaje antes de publicar.", None | |
| result = community_hub.post_to_community(user_id, content, topic) | |
| if "error" in result: | |
| return f"Error: {result['error']}", None | |
| # Actualizar feed | |
| updated_feed = get_community_feed_interface(topic) | |
| return f"✅ Tu mensaje fue compartido anónimamente como {result['anonymous_id']}", updated_feed | |
| def get_community_feed_interface(topic_filter=None): | |
| """Obtiene feed de la comunidad para la interfaz""" | |
| feed = community_hub.get_community_feed(topic_filter) | |
| if not feed: | |
| return "No hay mensajes en la comunidad aún. ¡Sé el primero en compartir!" | |
| feed_html = """ | |
| <div style="max-height: 400px; overflow-y: auto; padding: 10px; background: rgba(0,0,0,0.1); border-radius: 10px;"> | |
| """ | |
| for post in feed: | |
| feed_html += f""" | |
| <div style="margin-bottom: 15px; padding: 10px; background: rgba(255,255,255,0.05); border-radius: 8px; border-left: 3px solid #4ECDC4;"> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 5px;"> | |
| <strong style="color: #4ECDC4;">{post['id']}</strong> | |
| <span style="color: #999; font-size: 0.9em;">{post['time_ago']} • {post['topic']}</span> | |
| </div> | |
| <p style="margin: 5px 0; color: #ddd;">{post['content']}</p> | |
| <div style="text-align: right;"> | |
| <span style="font-size: 1.2em;">{post['sentiment_emoji']}</span> | |
| </div> | |
| </div> | |
| """ | |
| feed_html += "</div>" | |
| return feed_html | |
| def get_user_dashboard(user_id): | |
| """Genera dashboard del usuario""" | |
| try: | |
| # Obtener estadísticas del usuario | |
| conn = sqlite3.connect(synapse_core.db_path) | |
| # Sesiones emocionales | |
| cursor = conn.execute(''' | |
| SELECT COUNT(*) FROM emotional_sessions WHERE user_id = ? | |
| ''', (user_id,)) | |
| emotional_sessions = cursor.fetchone()[0] | |
| # Interacciones del chat | |
| cursor = conn.execute(''' | |
| SELECT COUNT(*) FROM chat_interactions WHERE user_id = ? | |
| ''', (user_id,)) | |
| chat_sessions = cursor.fetchone()[0] | |
| # Sesiones de neurofeedback | |
| cursor = conn.execute(''' | |
| SELECT COUNT(*) FROM neurofeedback_sessions WHERE user_id = ? | |
| ''', (user_id,)) | |
| neurofeedback_sessions = cursor.fetchone()[0] | |
| # Posts en comunidad | |
| cursor = conn.execute(''' | |
| SELECT COUNT(*) FROM community_posts WHERE user_id = ? | |
| ''', (user_id,)) | |
| community_posts = cursor.fetchone()[0] | |
| conn.close() | |
| # Generar reporte emocional | |
| emotional_report = emotional_analyzer.generate_emotional_report(user_id) | |
| # Obtener estadísticas de la comunidad | |
| community_stats = community_hub.get_community_stats() | |
| dashboard_text = f""" | |
| # Tu Dashboard SYNAPSE 🧠✨ | |
| ## Resumen de Actividad | |
| - **Análisis Emocionales:** {emotional_sessions} | |
| - **Sesiones de Terapia:** {chat_sessions} | |
| - **Sesiones de Neurofeedback:** {neurofeedback_sessions} | |
| - **Contribuciones a la Comunidad:** {community_posts} | |
| ## Estado Emocional Reciente | |
| """ | |
| if "message" in emotional_report: | |
| dashboard_text += f"*{emotional_report['message']}*" | |
| else: | |
| dashboard_text += f""" | |
| - **Sesiones Analizadas:** {emotional_report.get('total_sessions', 0)} | |
| - **Sentimiento Promedio:** {emotional_report.get('average_sentiment', 0):.2f} | |
| - **Tendencia:** {emotional_report.get('sentiment_trend', 'N/A')} | |
| - **Emoción Más Frecuente:** {emotional_report.get('most_frequent_emotion', 'N/A').title()} | |
| """ | |
| dashboard_text += f""" | |
| ## Estadísticas de la Comunidad | |
| - **Total de Posts:** {community_stats['total_posts']} | |
| - **Posts Recientes (24h):** {community_stats['recent_posts']} | |
| - **Ambiente Comunitario:** {community_stats['community_mood']} | |
| --- | |
| *Seguí utilizando SYNAPSE para continuar tu crecimiento neuroemocional* 🌱 | |
| """ | |
| return dashboard_text | |
| except Exception as e: | |
| return f"Error generando dashboard: {str(e)}" | |
| # CSS personalizado para mejorar la apariencia | |
| custom_css = """ | |
| /* Estilos personalizados para SYNAPSE */ | |
| .gradio-container { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| .gr-button { | |
| background: linear-gradient(45deg, #4ECDC4, #44A08D); | |
| border: none; | |
| color: white; | |
| font-weight: bold; | |
| transition: all 0.3s ease; | |
| } | |
| .gr-button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 4px 15px rgba(78, 205, 196, 0.4); | |
| } | |
| .gr-textbox, .gr-dropdown { | |
| border-radius: 10px; | |
| border: 2px solid rgba(78, 205, 196, 0.3); | |
| background: rgba(255, 255, 255, 0.1); | |
| } | |
| .gr-textbox:focus, .gr-dropdown:focus { | |
| border-color: #4ECDC4; | |
| box-shadow: 0 0 10px rgba(78, 205, 196, 0.5); | |
| } | |
| .gr-panel { | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border-radius: 15px; | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| } | |
| h1, h2, h3 { | |
| color: #4ECDC4; | |
| text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); | |
| } | |
| /* Animaciones sutiles */ | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| .gr-button:active { | |
| animation: pulse 0.3s ease-in-out; | |
| } | |
| """ | |
| # Crear la interfaz principal de Gradio | |
| def create_synapse_interface(): | |
| with gr.Blocks(css=custom_css, title="SYNAPSE - Plataforma de Bienestar Neuroemocional", theme=gr.themes.Glass()) as interface: | |
| # Estado del usuario | |
| user_id_state = gr.State(value=generate_user_id()) | |
| # Header principal | |
| gr.HTML(""" | |
| <div style="text-align: center; padding: 20px; background: linear-gradient(45deg, #4ECDC4, #44A08D); border-radius: 15px; margin-bottom: 20px;"> | |
| <h1 style="margin: 0; color: white; font-size: 2.5em; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);"> | |
| 🧠 SYNAPSE 🧠 | |
| </h1> | |
| <p style="margin: 10px 0 0 0; color: white; font-size: 1.2em; opacity: 0.9;"> | |
| Plataforma de Bienestar Neuroemocional • Tu Compañero de Crecimiento Personal | |
| </p> | |
| </div> | |
| """) | |
| with gr.Tabs() as main_tabs: | |
| # Tab 1: Dashboard Personal | |
| with gr.Tab("🏠 Dashboard Personal"): | |
| gr.Markdown("## Tu Centro de Control Personal") | |
| dashboard_button = gr.Button("🔄 Actualizar Dashboard", variant="primary") | |
| dashboard_output = gr.Markdown() | |
| dashboard_button.click( | |
| fn=get_user_dashboard, | |
| inputs=[user_id_state], | |
| outputs=[dashboard_output] | |
| ) | |
| # Tab 2: Análisis Emocional | |
| with gr.Tab("💭 Análisis Emocional"): | |
| gr.Markdown("## Comprende tus Emociones en Profundidad") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| emotion_text_input = gr.Textbox( | |
| label="¿Cómo te sentís hoy? Contanos qué está pasando...", | |
| placeholder="Escribí aquí tus pensamientos, emociones o lo que está pasando en tu vida...", | |
| lines=4 | |
| ) | |
| analyze_emotion_btn = gr.Button("🔍 Analizar Estado Emocional", variant="primary") | |
| with gr.Column(scale=1): | |
| emotion_analysis_output = gr.Markdown() | |
| with gr.Row(): | |
| emotion_radar_chart = gr.Plot(label="Perfil Neuroemocional") | |
| sentiment_gauge_chart = gr.Plot(label="Indicador de Sentimiento") | |
| analyze_emotion_btn.click( | |
| fn=analyze_text_emotions, | |
| inputs=[emotion_text_input, user_id_state], | |
| outputs=[emotion_analysis_output, emotion_radar_chart, sentiment_gauge_chart] | |
| ) | |
| # Tab 3: Chatbot Terapéutico | |
| with gr.Tab("🤖 Asistente Terapéutico"): | |
| gr.Markdown("## Tu Compañero de Bienestar Mental 24/7") | |
| chatbot_interface = gr.Chatbot( | |
| label="Conversación Terapéutica", | |
| height=400, | |
| placeholder="Iniciá la conversación... Estoy aquí para escucharte y ayudarte." | |
| ) | |
| with gr.Row(): | |
| chat_input = gr.Textbox( | |
| label="Tu mensaje", | |
| placeholder="Contame cómo te sentís o qué te está preocupando...", | |
| scale=4 | |
| ) | |
| chat_send_btn = gr.Button("📤 Enviar", variant="primary", scale=1) | |
| gr.Markdown(""" | |
| *Este asistente utiliza técnicas de Terapia Cognitivo-Conductual (CBT) y Terapia Dialéctica Conductual (DBT). | |
| No reemplaza la terapia profesional, pero puede ser un gran apoyo complementario.* | |
| """) | |
| chat_send_btn.click( | |
| fn=chat_with_therapist, | |
| inputs=[chat_input, chatbot_interface, user_id_state], | |
| outputs=[chatbot_interface, chat_input] | |
| ) | |
| chat_input.submit( | |
| fn=chat_with_therapist, | |
| inputs=[chat_input, chatbot_interface, user_id_state], | |
| outputs=[chatbot_interface, chat_input] | |
| ) | |
| # Tab 4: Neurofeedback | |
| with gr.Tab("🧘 Neurofeedback Virtual"): | |
| gr.Markdown("## Entrena tu Mente con Simulación de Neurofeedback") | |
| with gr.Row(): | |
| with gr.Column(): | |
| nf_session_type = gr.Dropdown( | |
| choices=["relaxation", "focus", "meditation", "creativity"], | |
| value="relaxation", | |
| label="Tipo de Sesión" | |
| ) | |
| nf_duration = gr.Slider( | |
| minimum=30, | |
| maximum=600, | |
| value=120, | |
| step=30, | |
| label="Duración (segundos)" | |
| ) | |
| nf_start_btn = gr.Button("🎯 Iniciar Sesión de Neurofeedback", variant="primary") | |
| with gr.Column(): | |
| nf_results = gr.Markdown() | |
| with gr.Row(): | |
| nf_visualization = gr.Plot(label="Ondas Cerebrales en Tiempo Real") | |
| with gr.Accordion("Datos Técnicos de la Sesión", open=False): | |
| nf_raw_data = gr.Code(language="json", label="Datos de la Sesión") | |
| nf_start_btn.click( | |
| fn=run_neurofeedback_session, | |
| inputs=[nf_session_type, nf_duration, user_id_state], | |
| outputs=[nf_results, nf_visualization, nf_raw_data] | |
| ) | |
| # Tab 5: Descubrimiento de Propósito | |
| with gr.Tab("🎯 Descubrimiento de Propósito"): | |
| gr.Markdown("## Encuentra tu Propósito Vital Auténtico") | |
| gr.Markdown("Respondé estas preguntas para descubrir tu arquetipo de propósito y recibir un roadmap personalizado:") | |
| purpose_responses = [] | |
| for i, question_data in enumerate(purpose_discovery.purpose_questions): | |
| with gr.Group(): | |
| gr.Markdown(f"### {i+1}. {question_data['question']}") | |
| response = gr.Radio( | |
| choices=question_data["options"], | |
| label=f"Pregunta {i+1}", | |
| show_label=False | |
| ) | |
| purpose_responses.append(response) | |
| purpose_analyze_btn = gr.Button("🔮 Descubrir mi Propósito", variant="primary", size="lg") | |
| with gr.Row(): | |
| purpose_results = gr.Markdown() | |
| purpose_visualization = gr.Plot(label="Tu Perfil de Propósito") | |
| with gr.Accordion("Análisis Completo", open=False): | |
| purpose_raw_data = gr.Code(language="json", label="Datos del Análisis") | |
| purpose_analyze_btn.click( | |
| fn=discover_life_purpose, | |
| inputs=purpose_responses + [user_id_state], | |
| outputs=[purpose_results, purpose_visualization, purpose_raw_data] | |
| ) | |
| # Tab 6: Comunidad de Apoyo | |
| with gr.Tab("🤝 Comunidad de Apoyo"): | |
| gr.Markdown("## Conectá con Otros de Forma Anónima y Segura") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("### 📝 Compartir en la Comunidad") | |
| community_content = gr.Textbox( | |
| label="Tu mensaje para la comunidad", | |
| placeholder="Compartí tu experiencia, busca apoyo, ofrece palabras de aliento...", | |
| lines=4 | |
| ) | |
| community_topic = gr.Dropdown( | |
| choices=community_hub.topics, | |
| value=community_hub.topics[0], | |
| label="Tema" | |
| ) | |
| community_post_btn = gr.Button("📤 Compartir Anónimamente", variant="primary") | |
| community_post_result = gr.Markdown() | |
| with gr.Column(scale=2): | |
| gr.Markdown("### 💬 Feed de la Comunidad") | |
| community_topic_filter = gr.Dropdown( | |
| choices=["Todos"] + community_hub.topics, | |
| value="Todos", | |
| label="Filtrar por tema" | |
| ) | |
| community_refresh_btn = gr.Button("🔄 Actualizar Feed") | |
| community_feed = gr.HTML() | |
| # Eventos de la comunidad | |
| community_post_btn.click( | |
| fn=post_to_community_interface, | |
| inputs=[community_content, community_topic, user_id_state], | |
| outputs=[community_post_result, community_feed] | |
| ) | |
| def refresh_community_feed(topic_filter): | |
| if topic_filter == "Todos": | |
| topic_filter = None | |
| return get_community_feed_interface(topic_filter) | |
| community_refresh_btn.click( | |
| fn=refresh_community_feed, | |
| inputs=[community_topic_filter], | |
| outputs=[community_feed] | |
| ) | |
| community_topic_filter.change( | |
| fn=refresh_community_feed, | |
| inputs=[community_topic_filter], | |
| outputs=[community_feed] | |
| ) | |
| # Footer informativo | |
| gr.HTML(""" | |
| <div style="margin-top: 30px; padding: 20px; background: rgba(0,0,0,0.1); border-radius: 10px; text-align: center;"> | |
| <p style="margin: 0; color: #999; font-size: 0.9em;"> | |
| 🔒 Tu privacidad es nuestra prioridad • 🧠 Tecnología de vanguardia • 🤝 Comunidad de apoyo<br> | |
| SYNAPSE - Transformando vidas a través de la neurociencia y la IA | |
| </p> | |
| </div> | |
| """) | |
| # Cargar dashboard inicial | |
| interface.load( | |
| fn=get_user_dashboard, | |
| inputs=[user_id_state], | |
| outputs=[dashboard_output] | |
| ) | |
| # Cargar feed inicial de la comunidad | |
| interface.load( | |
| fn=lambda: get_community_feed_interface(), | |
| outputs=[community_feed] | |
| ) | |
| return interface | |
| # Lanzar la aplicación | |
| if __name__ == "__main__": | |
| # Crear e inicializar la interfaz | |
| synapse_interface = create_synapse_interface() | |
| # Configurar el lanzamiento | |
| synapse_interface.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True, | |
| enable_queue=True, | |
| max_threads=10, | |
| auth=None, # Sin autenticación para demo | |
| show_error=True, | |
| quiet=False, | |
| favicon_path=None, | |
| ssl_verify=False | |
| ) | |