SINTESIS_V2 / app.py
Lukeetah's picture
Create app.py
28ba577 verified
# 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
)