Danielbrdz commited on
Commit
500b4f9
·
verified ·
1 Parent(s): 8ff6f1c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -60
app.py CHANGED
@@ -3,76 +3,78 @@ import os
3
  import json
4
  import requests
5
  from datetime import datetime
6
-
7
- # --- Importar la librería de Supabase ---
8
  from supabase import create_client, Client
9
- # --- FIN de las importaciones de Supabase ---
10
 
 
 
11
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
12
  GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
 
 
13
  SYSTEM_MESSAGE = os.environ.get("System_Prompt")
14
- MODEL_NAME = "meta-llama/llama-4-maverick-17b-128e-instruct"
15
  MAX_TOKENS = 4096
16
  TEMPERATURE = 0.7
17
  TOP_P = 0.95
18
 
19
- # --- Configuración de Supabase ---
20
- # Es CRÍTICO que estas variables de entorno se configuren en tu Hugging Face Space
21
- # Ve a Settings -> Repository secrets y añade SUPABASE_URL y SUPABASE_KEY
22
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
23
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
 
24
 
25
- supabase: Client = None
 
26
  if SUPABASE_URL and SUPABASE_KEY:
27
- try:
28
- supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
29
- print("Supabase cliente inicializado correctamente.")
30
- except Exception as e:
31
- print(f"Error al inicializar Supabase cliente: {e}")
32
  else:
33
- print("Advertencia: SUPABASE_URL o SUPABASE_KEY no están configuradas.")
34
-
35
- # --- FIN de la configuración de Supabase ---
36
-
37
- def persist_data(session_data, user_id="anonymous_user"):
 
 
 
 
38
  if not supabase:
39
- print("Advertencia: El cliente de Supabase no está inicializado. No se guardará la conversación.")
40
- return
41
 
42
  try:
43
- # Prepara los datos de la conversación como una lista de diccionarios
44
- conversation_log = []
45
- for user_msg, assistant_msg in session_data:
46
- conversation_log.append({"role": "user", "content": user_msg})
47
- if assistant_msg:
48
- conversation_log.append({"role": "assistant", "content": assistant_msg})
49
-
50
- # Datos a insertar en la tabla 'conversations'
51
- data_to_insert = {
52
- 'user_id': user_id,
53
- 'messages': conversation_log # El campo 'timestamp' y 'id' se generarán automáticamente por la BD
54
- }
55
-
56
- # Realiza la inserción en Supabase
57
- # .insert() devuelve una tupla, el primer elemento es el resultado y el segundo es el count de registros afectados
58
- response = supabase.table('conversations').insert(data_to_insert).execute()
59
-
60
- # Supabase devuelve el resultado de la inserción en el atributo 'data' del objeto response.
61
- # Verifica si la inserción fue exitosa
62
- if response.data:
63
- print(f"Conversación guardada en Supabase. ID de sesión: {response.data[0].get('id')}")
64
  else:
65
- print(f"Error al guardar en Supabase: No se recibieron datos en la respuesta. {response.status_code} {response.data}")
66
 
67
  except Exception as e:
68
- print(f"Error al persistir los datos en Supabase: {e}")
69
-
70
- def respond(message, history: list[tuple[str, str]]):
71
- # Puedes generar un user_id más sofisticado si lo necesitas,
72
- # por ejemplo, usando la IP del usuario o un ID de sesión más único.
73
- # Por ahora, mantendremos "anonymous_user" o puedes usar algo como "user_" + un timestamp
74
- current_user_id = "anonymous_user"
 
 
 
 
 
 
 
 
75
 
 
76
  messages = [{"role": "system", "content": SYSTEM_MESSAGE}]
77
  for user_msg, assistant_msg in history:
78
  if user_msg:
@@ -94,13 +96,16 @@ def respond(message, history: list[tuple[str, str]]):
94
  "stream": True
95
  }
96
 
97
- response = requests.post(
98
- GROQ_API_URL,
99
- headers=headers,
100
- json=payload,
101
- stream=True
102
- )
 
 
103
 
 
104
  accumulated_response = ""
105
  for line in response.iter_lines():
106
  if line:
@@ -119,15 +124,27 @@ def respond(message, history: list[tuple[str, str]]):
119
  yield accumulated_response
120
  except json.JSONDecodeError:
121
  continue
122
-
123
- if not accumulated_response:
124
- yield "Lo siento, ocurrió un error al procesar tu solicitud."
 
 
 
 
 
125
  else:
126
- current_session = history + [(message, accumulated_response)]
127
- persist_data(current_session, user_id=current_user_id)
 
 
 
 
128
 
129
  demo = gr.ChatInterface(
130
  respond,
 
 
 
131
  examples=[["¡Bienvenido a Tu Aliado Momentum!"],
132
  ["¿En qué consiste el programa y para quién es?"],
133
  ["¿Qué beneficios obtengo y con qué empresas me conecto?"],
 
3
  import json
4
  import requests
5
  from datetime import datetime
6
+ import uuid # Necesario para generar IDs únicos para cada conversación
 
7
  from supabase import create_client, Client
 
8
 
9
+ # --- CONFIGURACIÓN ---
10
+ # Clave de la API de Groq
11
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
12
  GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
13
+
14
+ # Configuración del modelo y el sistema
15
  SYSTEM_MESSAGE = os.environ.get("System_Prompt")
16
+ MODEL_NAME = "llama3-70b-8192" # Modelo actualizado y recomendado
17
  MAX_TOKENS = 4096
18
  TEMPERATURE = 0.7
19
  TOP_P = 0.95
20
 
21
+ # --- NUEVA CONFIGURACIÓN DE SUPERBASE ---
 
 
22
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
23
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
24
+ TABLE_NAME = "conversations" # Asegúrate que este sea el nombre de tu tabla
25
 
26
+ # Inicializar el cliente de Supabase
27
+ # Se verifica que las credenciales existan antes de crear el cliente
28
  if SUPABASE_URL and SUPABASE_KEY:
29
+ supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
 
 
 
 
30
  else:
31
+ supabase = None
32
+ print("Advertencia: Las credenciales de Supabase no están configuradas. El historial de chat no se guardará.")
33
+
34
+ # --- FUNCIÓN DE PERSISTENCIA MODIFICADA PARA SUPABASE ---
35
+ def persist_conversation(conversation_id: uuid.UUID, user_id: str, messages_data: list):
36
+ """
37
+ Guarda o actualiza una conversación completa en la tabla de Supabase.
38
+ Usa 'upsert' para insertar si es nueva o actualizar si ya existe.
39
+ """
40
  if not supabase:
41
+ return # No hacer nada si el cliente no se inicializó
 
42
 
43
  try:
44
+ # El método 'upsert' es ideal: inserta una nueva fila si el 'id' no existe,
45
+ # o la actualiza si ya existe. Esto es perfecto para guardar el estado de
46
+ # una conversación en curso.
47
+ response = supabase.table(TABLE_NAME).upsert({
48
+ "id": str(conversation_id),
49
+ "timestamp": datetime.now().isoformat(), # Usamos formato ISO 8601 que Supabase entiende
50
+ "user_id": str(user_id), # Basado en tu columna 'user_id'
51
+ "messages": messages_data # Guardamos la lista de mensajes como JSONB
52
+ }).execute()
53
+
54
+ # Opcional: Verificar si hubo un error en la respuesta de Supabase
55
+ if hasattr(response, 'error') and response.error:
56
+ print(f"Error al guardar en Supabase: {response.error}")
 
 
 
 
 
 
 
 
57
  else:
58
+ print(f"Conversación {conversation_id} guardada/actualizada en Supabase.")
59
 
60
  except Exception as e:
61
+ print(f"Ocurrió una excepción al intentar guardar en Supabase: {e}")
62
+
63
+ # --- FUNCIÓN PRINCIPAL DEL CHATBOT (MODIFICADA) ---
64
+ def respond(message: str, history: list[tuple[str, str]], conversation_id: uuid.UUID):
65
+ """
66
+ Función principal que procesa la entrada del usuario, llama a la API de Groq y guarda la conversación.
67
+ """
68
+ # Si 'conversation_id' es None, significa que es el primer mensaje de una nueva conversación.
69
+ if conversation_id is None:
70
+ conversation_id = uuid.uuid4()
71
+ # Para la columna 'user_id', podemos usar el mismo ID de la conversación
72
+ # si no tienes un sistema de usuarios más complejo.
73
+ user_id = conversation_id
74
+ else:
75
+ user_id = conversation_id # Mantener el mismo user_id
76
 
77
+ # Construir el payload para la API de Groq
78
  messages = [{"role": "system", "content": SYSTEM_MESSAGE}]
79
  for user_msg, assistant_msg in history:
80
  if user_msg:
 
96
  "stream": True
97
  }
98
 
99
+ # Llamada a la API de Groq
100
+ try:
101
+ response = requests.post(GROQ_API_URL, headers=headers, json=payload, stream=True, timeout=10)
102
+ response.raise_for_status() # Lanza un error si la respuesta es 4xx o 5xx
103
+ except requests.exceptions.RequestException as e:
104
+ print(f"Error en la petición a la API de Groq: {e}")
105
+ yield "Lo siento, no pude conectarme con el servicio en este momento. Inténtalo de nuevo más tarde."
106
+ return
107
 
108
+ # Procesar la respuesta en streaming
109
  accumulated_response = ""
110
  for line in response.iter_lines():
111
  if line:
 
124
  yield accumulated_response
125
  except json.JSONDecodeError:
126
  continue
127
+
128
+ # Después de obtener la respuesta completa, la guardamos en Supabase
129
+ if accumulated_response:
130
+ # Formateamos el historial completo para la columna 'messages' (JSONB)
131
+ # Esto es mucho más útil que un archivo de texto plano.
132
+ full_history_for_db = messages + [{"role": "assistant", "content": accumulated_response}]
133
+
134
+ persist_conversation(conversation_id, user_id, full_history_for_db)
135
  else:
136
+ yield "Lo siento, ocurrió un error al procesar tu solicitud."
137
+
138
+ # --- INTERFAZ DE GRADIO (MODIFICADA) ---
139
+ # Usamos gr.State para mantener el ID de la conversación a través de múltiples turnos
140
+ # en la misma sesión del navegador.
141
+ conversation_id_state = gr.State(value=None)
142
 
143
  demo = gr.ChatInterface(
144
  respond,
145
+ additional_inputs=[conversation_id_state], # Pasamos el estado como una entrada adicional
146
+ title="Tu Aliado Momentum",
147
+ description="Chatea conmigo para saber más sobre el programa Momentum.",
148
  examples=[["¡Bienvenido a Tu Aliado Momentum!"],
149
  ["¿En qué consiste el programa y para quién es?"],
150
  ["¿Qué beneficios obtengo y con qué empresas me conecto?"],