Update app.py
Browse files
app.py
CHANGED
|
@@ -222,20 +222,74 @@ def ejecutar_codigo_sandbox(codigo, nombre):
|
|
| 222 |
return False, "❌ Lenguaje no soportado"
|
| 223 |
|
| 224 |
|
| 225 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
"""
|
| 227 |
-
|
| 228 |
-
[{"user": "saludo", "assistant": "hola"}, ...]
|
| 229 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
# --- SEGURIDAD ---
|
| 231 |
for bloqueo in BLOQUEOS_JAILBREAK:
|
| 232 |
if bloqueo in message.lower():
|
| 233 |
-
chatbot_output =
|
| 234 |
yield chatbot_output, "", "", "⛔ Bloqueado por seguridad.", ""
|
| 235 |
return
|
| 236 |
|
| 237 |
if not HF_TOKEN:
|
| 238 |
-
chatbot_output =
|
| 239 |
yield chatbot_output, "", "", "Configura HF_TOKEN.", ""
|
| 240 |
return
|
| 241 |
|
|
@@ -256,27 +310,9 @@ def run_chat(message, history, user_context, max_tokens, temperature, top_p, tok
|
|
| 256 |
if memoria and memoria.strip():
|
| 257 |
final_system += f"\n--- MEMORIA ---\n{memoria}\n"
|
| 258 |
|
| 259 |
-
# ---
|
| 260 |
messages = [{"role": "system", "content": final_system}]
|
| 261 |
-
|
| 262 |
-
if not isinstance(history, list):
|
| 263 |
-
history = []
|
| 264 |
-
|
| 265 |
-
for item in history:
|
| 266 |
-
if isinstance(item, dict):
|
| 267 |
-
# Formato Gradio moderno: {"user": ..., "assistant": ...}
|
| 268 |
-
user_msg = item.get("user", "") or item.get("message", "")
|
| 269 |
-
assistant_msg = item.get("assistant", "") or item.get("response", "")
|
| 270 |
-
if user_msg:
|
| 271 |
-
messages.append({"role": "user", "content": user_msg})
|
| 272 |
-
if assistant_msg:
|
| 273 |
-
messages.append({"role": "assistant", "content": assistant_msg})
|
| 274 |
-
elif isinstance(item, (list, tuple)) and len(item) >= 2:
|
| 275 |
-
# Formato legacy: (user, assistant)
|
| 276 |
-
if item[0]:
|
| 277 |
-
messages.append({"role": "user", "content": item[0]})
|
| 278 |
-
if item[1]:
|
| 279 |
-
messages.append({"role": "assistant", "content": item[1]})
|
| 280 |
|
| 281 |
user_content = message + (contexto_archivo if contexto_archivo else "")
|
| 282 |
messages.append({"role": "user", "content": user_content})
|
|
@@ -293,10 +329,10 @@ def run_chat(message, history, user_context, max_tokens, temperature, top_p, tok
|
|
| 293 |
):
|
| 294 |
if chunk.choices and chunk.choices[0].delta.content:
|
| 295 |
resp_text += chunk.choices[0].delta.content
|
| 296 |
-
chatbot_so_far =
|
| 297 |
yield chatbot_so_far, "", "", "Generando...", ""
|
| 298 |
except Exception as e:
|
| 299 |
-
chatbot_output =
|
| 300 |
yield chatbot_output, "", "", str(e), ""
|
| 301 |
return
|
| 302 |
|
|
@@ -316,7 +352,7 @@ def run_chat(message, history, user_context, max_tokens, temperature, top_p, tok
|
|
| 316 |
if exito:
|
| 317 |
break
|
| 318 |
intentos += 1
|
| 319 |
-
chatbot_so_far =
|
| 320 |
yield chatbot_so_far, "", "", ultima_ejecucion, ""
|
| 321 |
try:
|
| 322 |
new_resp = ""
|
|
@@ -341,10 +377,8 @@ def run_chat(message, history, user_context, max_tokens, temperature, top_p, tok
|
|
| 341 |
break
|
| 342 |
|
| 343 |
# --- Output final ---
|
| 344 |
-
chatbot_output =
|
| 345 |
yield chatbot_output, resp_text, resp_text, ultima_ejecucion, memoria
|
| 346 |
-
|
| 347 |
-
|
| 348 |
# ============================================
|
| 349 |
# INTERFAZ GRADIO
|
| 350 |
# ============================================
|
|
|
|
| 222 |
return False, "❌ Lenguaje no soportado"
|
| 223 |
|
| 224 |
|
| 225 |
+
def normalize_history(history):
|
| 226 |
+
"""
|
| 227 |
+
Normaliza history a una lista de dicts limpios con claves 'user' y 'assistant'.
|
| 228 |
+
Soporta todos los formatos posibles de Gradio.
|
| 229 |
+
"""
|
| 230 |
+
normalized = []
|
| 231 |
+
if not isinstance(history, list):
|
| 232 |
+
return normalized
|
| 233 |
+
|
| 234 |
+
for item in history:
|
| 235 |
+
user_msg = ""
|
| 236 |
+
assistant_msg = ""
|
| 237 |
+
|
| 238 |
+
if isinstance(item, dict):
|
| 239 |
+
# Formato moderno: {"user": ..., "assistant": ...}
|
| 240 |
+
if "user" in item or "assistant" in item:
|
| 241 |
+
user_msg = str(item.get("user", "") or "")
|
| 242 |
+
assistant_msg = str(item.get("assistant", "") or "")
|
| 243 |
+
# Formato alternativo: {"message": ..., "response": ...}
|
| 244 |
+
elif "message" in item or "response" in item:
|
| 245 |
+
user_msg = str(item.get("message", "") or "")
|
| 246 |
+
assistant_msg = str(item.get("response", "") or "")
|
| 247 |
+
# Formato API: {"role": ..., "content": ...} — improbable pero por si acaso
|
| 248 |
+
elif "role" in item and "content" in item:
|
| 249 |
+
role = item["role"]
|
| 250 |
+
content = str(item.get("content", "") or "")
|
| 251 |
+
if role == "user":
|
| 252 |
+
user_msg = content
|
| 253 |
+
elif role == "assistant":
|
| 254 |
+
assistant_msg = content
|
| 255 |
+
elif isinstance(item, (list, tuple)) and len(item) >= 2:
|
| 256 |
+
# Formato legacy: (user, assistant)
|
| 257 |
+
user_msg = str(item[0] or "")
|
| 258 |
+
assistant_msg = str(item[1] or "")
|
| 259 |
+
|
| 260 |
+
# Solo agregar si tiene contenido
|
| 261 |
+
if user_msg.strip() or assistant_msg.strip():
|
| 262 |
+
normalized.append({"user": user_msg, "assistant": assistant_msg})
|
| 263 |
+
|
| 264 |
+
return normalized
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def history_to_messages(normalized_history):
|
| 268 |
"""
|
| 269 |
+
Convierte historial normalizado a formato messages para la API.
|
|
|
|
| 270 |
"""
|
| 271 |
+
messages = []
|
| 272 |
+
for item in normalized_history:
|
| 273 |
+
if item["user"].strip():
|
| 274 |
+
messages.append({"role": "user", "content": item["user"]})
|
| 275 |
+
if item["assistant"].strip():
|
| 276 |
+
messages.append({"role": "assistant", "content": item["assistant"]})
|
| 277 |
+
return messages
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
def run_chat(message, history, user_context, max_tokens, temperature, top_p, token, file_content, file_name, memoria):
|
| 281 |
+
# --- Normalizar history al inicio ---
|
| 282 |
+
norm_history = normalize_history(history)
|
| 283 |
+
|
| 284 |
# --- SEGURIDAD ---
|
| 285 |
for bloqueo in BLOQUEOS_JAILBREAK:
|
| 286 |
if bloqueo in message.lower():
|
| 287 |
+
chatbot_output = norm_history + [{"user": message, "assistant": "Soy Aura, asistente especializado exclusivamente en programación."}]
|
| 288 |
yield chatbot_output, "", "", "⛔ Bloqueado por seguridad.", ""
|
| 289 |
return
|
| 290 |
|
| 291 |
if not HF_TOKEN:
|
| 292 |
+
chatbot_output = norm_history + [{"user": message, "assistant": "⚠️ Falta HF_TOKEN. Configura tu API Key en Settings → Secrets."}]
|
| 293 |
yield chatbot_output, "", "", "Configura HF_TOKEN.", ""
|
| 294 |
return
|
| 295 |
|
|
|
|
| 310 |
if memoria and memoria.strip():
|
| 311 |
final_system += f"\n--- MEMORIA ---\n{memoria}\n"
|
| 312 |
|
| 313 |
+
# --- Construir messages para la API ---
|
| 314 |
messages = [{"role": "system", "content": final_system}]
|
| 315 |
+
messages.extend(history_to_messages(norm_history))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
|
| 317 |
user_content = message + (contexto_archivo if contexto_archivo else "")
|
| 318 |
messages.append({"role": "user", "content": user_content})
|
|
|
|
| 329 |
):
|
| 330 |
if chunk.choices and chunk.choices[0].delta.content:
|
| 331 |
resp_text += chunk.choices[0].delta.content
|
| 332 |
+
chatbot_so_far = norm_history + [{"user": message, "assistant": resp_text}]
|
| 333 |
yield chatbot_so_far, "", "", "Generando...", ""
|
| 334 |
except Exception as e:
|
| 335 |
+
chatbot_output = norm_history + [{"user": message, "assistant": f"Error IA: {e}"}]
|
| 336 |
yield chatbot_output, "", "", str(e), ""
|
| 337 |
return
|
| 338 |
|
|
|
|
| 352 |
if exito:
|
| 353 |
break
|
| 354 |
intentos += 1
|
| 355 |
+
chatbot_so_far = norm_history + [{"user": message, "assistant": f"{resp_text}\n\n🔄 *Auto-corrigiendo ({intentos}/{MAX_AUTOFIX})...*"}]
|
| 356 |
yield chatbot_so_far, "", "", ultima_ejecucion, ""
|
| 357 |
try:
|
| 358 |
new_resp = ""
|
|
|
|
| 377 |
break
|
| 378 |
|
| 379 |
# --- Output final ---
|
| 380 |
+
chatbot_output = norm_history + [{"user": message, "assistant": resp_text}]
|
| 381 |
yield chatbot_output, resp_text, resp_text, ultima_ejecucion, memoria
|
|
|
|
|
|
|
| 382 |
# ============================================
|
| 383 |
# INTERFAZ GRADIO
|
| 384 |
# ============================================
|