fiel1986 commited on
Commit
318073d
·
verified ·
1 Parent(s): fbc7eee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -146
app.py CHANGED
@@ -46,29 +46,13 @@ def extract_file_text(file):
46
  if not file:
47
  return ""
48
  try:
49
- # Si Gradio pasa una lista de archivos, tomar el primero
50
- if isinstance(file, (list, tuple)):
51
- if len(file) == 0:
52
- return ""
53
- file = file[0]
54
-
55
- # Obtener la ruta del archivo
56
- path = getattr(file, "name", None) or (file if isinstance(file, str) else None)
57
- if not path:
58
- return ""
59
-
60
- # Validar que sea un archivo y no un directorio
61
- if os.path.isdir(path):
62
- return ""
63
- if not os.path.isfile(path):
64
- return ""
65
-
66
  with open(path, 'r', encoding='utf-8', errors='ignore') as f:
67
  return f.read()[:20000]
68
- except Exception as e:
69
- print(f"[DEBUG] extract_file_text error: {e}")
70
  return ""
71
 
 
72
  def get_ext(nombre):
73
  n = nombre.lower()
74
  if n.endswith((".html", ".htm")):
@@ -303,143 +287,128 @@ def history_to_messages(norm_history):
303
 
304
 
305
  def run_chat(message, history, user_context, max_tokens, temperature, top_p, token, file_content, file_name, memoria):
306
- try:
307
- # --- Normalizar history ---
308
- norm_history = normalize_history(history)
309
-
310
- # --- Validar mensaje vacío ---
311
- if not message or not message.strip():
312
- yield [], "", "", "⚠️ Mensaje vacío.", ""
313
- return
314
-
315
- # --- SEGURIDAD ---
316
- for bloqueo in BLOQUEOS_JAILBREAK:
317
- if bloqueo in message.lower():
318
- reply = {"role": "assistant", "content": "Soy Aura, asistente especializado exclusivamente en programación."}
319
- chatbot_output = norm_history + [{"role": "user", "content": message}, reply]
320
- yield chatbot_output, "", "", "⛔ Bloqueado por seguridad.", ""
321
- return
322
 
323
- if not HF_TOKEN:
324
- reply = {"role": "assistant", "content": "⚠️ Falta HF_TOKEN. Configura tu API Key en Settings → Secrets."}
 
 
325
  chatbot_output = norm_history + [{"role": "user", "content": message}, reply]
326
- yield chatbot_output, "", "", "Configura HF_TOKEN.", ""
327
- return
328
-
329
- client = InferenceClient(token=token or HF_TOKEN, model=MODEL_ID)
330
-
331
- # --- Contexto del archivo ---
332
- contexto_archivo = ""
333
- errores_iniciales = []
334
- if file_content and file_name:
335
- errores_iniciales = analizar_todo(file_content, file_name)
336
- contexto_archivo = f"\n--- ARCHIVO ({file_name}) ---\n{file_content}\n"
337
- if errores_iniciales:
338
- contexto_archivo += "\n--- ERRORES ---\n" + "\n".join(errores_iniciales) + "\n"
339
-
340
- final_system = SYSTEM_PROMPT_BASE
341
- if user_context and user_context.strip():
342
- final_system += f"\n\n--- TU CONTEXTO ---\n{user_context}\n"
343
- if memoria and memoria.strip():
344
- final_system += f"\n--- MEMORIA ---\n{memoria}\n"
345
-
346
- # --- Construir messages para la API ---
347
- messages = [{"role": "system", "content": final_system}]
348
- messages.extend(history_to_messages(norm_history))
349
- user_content = message + (contexto_archivo if contexto_archivo else "")
350
- messages.append({"role": "user", "content": user_content})
351
-
352
- # --- Validar mensajes ---
353
- for i, msg in enumerate(messages):
354
- if not isinstance(msg, dict) or "role" not in msg or "content" not in msg:
355
- messages[i] = {"role": "system", "content": "[mensaje corrupto eliminado]"}
356
- msg["content"] = safe_str(msg["content"])
357
-
358
- # --- Streaming ---
359
- resp_text = ""
360
- try:
361
- for chunk in client.chat_completion(
362
- messages=messages,
363
- max_tokens=max_tokens,
364
- stream=True,
365
- temperature=temperature,
366
- top_p=top_p
367
- ):
368
- if chunk.choices and chunk.choices[0].delta.content:
369
- resp_text += chunk.choices[0].delta.content
370
- chatbot_so_far = norm_history + [
371
- {"role": "user", "content": message},
372
- {"role": "assistant", "content": resp_text}
373
- ]
374
- yield chatbot_so_far, "", "", "Generando...", ""
375
- except Exception as e:
376
- error_msg = f"Error IA: {e}"
377
- print(f"[DEBUG] Error streaming: {e}")
378
- chatbot_output = norm_history + [
379
- {"role": "user", "content": message},
380
- {"role": "assistant", "content": error_msg}
381
- ]
382
- yield chatbot_output, "", "", error_msg, ""
383
  return
384
 
385
- # --- Auto-corrección ---
386
- intentos = 0
387
- ultima_ejecucion = ""
388
- code_blocks = re.findall(r'```(?:python|javascript|js|html|sql)?\n(.*?)\n```', resp_text, re.DOTALL)
389
-
390
- if code_blocks:
391
- main_code = max(code_blocks, key=len)
392
- detected_ext = get_ext(file_name) if file_name else ("js" if ("function" in main_code or "const " in main_code) else "py")
393
- filename_for_exec = f"test.{detected_ext}"
394
-
395
- while intentos < MAX_AUTOFIX:
396
- exito, resultado_exec = ejecutar_codigo_sandbox(main_code, filename_for_exec)
397
- ultima_ejecucion = resultado_exec
398
- if exito:
399
- break
400
- intentos += 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  chatbot_so_far = norm_history + [
402
  {"role": "user", "content": message},
403
- {"role": "assistant", "content": f"{resp_text}\n\n🔄 *Auto-corrigiendo ({intentos}/{MAX_AUTOFIX})...*"}
404
  ]
405
- yield chatbot_so_far, "", "", ultima_ejecucion, ""
406
- try:
407
- new_resp = ""
408
- for chunk in client.chat_completion(
409
- messages=[
410
- {"role": "system", "content": final_system},
411
- {"role": "user", "content": f"CORRIGE ESTE ERROR:\n{resultado_exec}\nDevuelve SOLO el código corregido en ```{detected_ext}."}
412
- ],
413
- max_tokens=max_tokens,
414
- stream=True,
415
- temperature=0.2
416
- ):
417
- if chunk.choices and chunk.choices[0].delta.content:
418
- new_resp += chunk.choices[0].delta.content
419
- new_blocks = re.findall(r'```(?:python|javascript|js|html|sql)?\n(.*?)\n```', new_resp, re.DOTALL)
420
- if new_blocks:
421
- main_code = max(new_blocks, key=len)
422
- resp_text += f"\n\n--- CORRECCIÓN {intentos} ---\n{new_resp}"
423
- else:
424
- break
425
- except Exception as e:
426
- print(f"\n[DEBUG] Error auto-corrección {intentos}: {e}")
427
- break
428
-
429
- # --- Output final ---
430
  chatbot_output = norm_history + [
431
  {"role": "user", "content": message},
432
- {"role": "assistant", "content": resp_text}
433
  ]
434
- yield chatbot_output, resp_text, resp_text, ultima_ejecucion, memoria
435
-
436
- except Exception as e:
437
- # CATCH-ALL: Si algo explota antes del primer yield, esto lo salva
438
- import traceback
439
- error_trace = traceback.format_exc()
440
- print(f"[DEBUG] CRASH EN RUN_CHAT: {error_trace}")
441
- yield [], "", "", f"💥 Error interno: {str(e)}", ""
442
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  # ============================================
444
  # INTERFAZ GRADIO
445
  # ============================================
 
46
  if not file:
47
  return ""
48
  try:
49
+ path = file.name if hasattr(file, 'name') else file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  with open(path, 'r', encoding='utf-8', errors='ignore') as f:
51
  return f.read()[:20000]
52
+ except Exception:
 
53
  return ""
54
 
55
+
56
  def get_ext(nombre):
57
  n = nombre.lower()
58
  if n.endswith((".html", ".htm")):
 
287
 
288
 
289
  def run_chat(message, history, user_context, max_tokens, temperature, top_p, token, file_content, file_name, memoria):
290
+ # --- Normalizar history ---
291
+ norm_history = normalize_history(history)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
+ # --- SEGURIDAD ---
294
+ for bloqueo in BLOQUEOS_JAILBREAK:
295
+ if bloqueo in message.lower():
296
+ reply = {"role": "assistant", "content": "Soy Aura, asistente especializado exclusivamente en programación."}
297
  chatbot_output = norm_history + [{"role": "user", "content": message}, reply]
298
+ yield chatbot_output, "", "", "⛔ Bloqueado por seguridad.", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  return
300
 
301
+ if not HF_TOKEN:
302
+ reply = {"role": "assistant", "content": "⚠️ Falta HF_TOKEN. Configura tu API Key en Settings → Secrets."}
303
+ chatbot_output = norm_history + [{"role": "user", "content": message}, reply]
304
+ yield chatbot_output, "", "", "Configura HF_TOKEN.", ""
305
+ return
306
+
307
+ client = InferenceClient(token=token or HF_TOKEN, model=MODEL_ID)
308
+
309
+ # --- Contexto del archivo ---
310
+ contexto_archivo = ""
311
+ errores_iniciales = []
312
+ if file_content and file_name:
313
+ errores_iniciales = analizar_todo(file_content, file_name)
314
+ contexto_archivo = f"\n--- ARCHIVO ({file_name}) ---\n{file_content}\n"
315
+ if errores_iniciales:
316
+ contexto_archivo += "\n--- ERRORES ---\n" + "\n".join(errores_iniciales) + "\n"
317
+
318
+ final_system = SYSTEM_PROMPT_BASE
319
+ if user_context and user_context.strip():
320
+ final_system += f"\n\n--- TU CONTEXTO ---\n{user_context}\n"
321
+ if memoria and memoria.strip():
322
+ final_system += f"\n--- MEMORIA ---\n{memoria}\n"
323
+
324
+ # --- Construir messages para la API ---
325
+ messages = [{"role": "system", "content": final_system}]
326
+ messages.extend(history_to_messages(norm_history))
327
+ user_content = message + (contexto_archivo if contexto_archivo else "")
328
+ messages.append({"role": "user", "content": user_content})
329
+
330
+ # --- Validar mensajes ---
331
+ for i, msg in enumerate(messages):
332
+ if not isinstance(msg, dict) or "role" not in msg or "content" not in msg:
333
+ messages[i] = {"role": "system", "content": "[mensaje corrupto eliminado]"}
334
+ msg["content"] = safe_str(msg["content"])
335
+
336
+ # --- Streaming ---
337
+ resp_text = ""
338
+ try:
339
+ for chunk in client.chat_completion(
340
+ messages=messages,
341
+ max_tokens=max_tokens,
342
+ stream=True,
343
+ temperature=temperature,
344
+ top_p=top_p
345
+ ):
346
+ if chunk.choices and chunk.choices[0].delta.content:
347
+ resp_text += chunk.choices[0].delta.content
348
  chatbot_so_far = norm_history + [
349
  {"role": "user", "content": message},
350
+ {"role": "assistant", "content": resp_text}
351
  ]
352
+ yield chatbot_so_far, "", "", "Generando...", ""
353
+ except Exception as e:
354
+ error_msg = f"Error IA: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  chatbot_output = norm_history + [
356
  {"role": "user", "content": message},
357
+ {"role": "assistant", "content": error_msg}
358
  ]
359
+ yield chatbot_output, "", "", error_msg, ""
360
+ return
361
+
362
+ # --- Auto-corrección ---
363
+ intentos = 0
364
+ ultima_ejecucion = ""
365
+ code_blocks = re.findall(r'```(?:python|javascript|js|html|sql)?\n(.*?)\n```', resp_text, re.DOTALL)
366
+
367
+ if code_blocks:
368
+ main_code = max(code_blocks, key=len)
369
+ detected_ext = get_ext(file_name) if file_name else ("js" if ("function" in main_code or "const " in main_code) else "py")
370
+ filename_for_exec = f"test.{detected_ext}"
371
+
372
+ while intentos < MAX_AUTOFIX:
373
+ exito, resultado_exec = ejecutar_codigo_sandbox(main_code, filename_for_exec)
374
+ ultima_ejecucion = resultado_exec
375
+ if exito:
376
+ break
377
+ intentos += 1
378
+ chatbot_so_far = norm_history + [
379
+ {"role": "user", "content": message},
380
+ {"role": "assistant", "content": f"{resp_text}\n\n🔄 *Auto-corrigiendo ({intentos}/{MAX_AUTOFIX})...*"}
381
+ ]
382
+ yield chatbot_so_far, "", "", ultima_ejecucion, ""
383
+ try:
384
+ new_resp = ""
385
+ for chunk in client.chat_completion(
386
+ messages=[
387
+ {"role": "system", "content": final_system},
388
+ {"role": "user", "content": f"CORRIGE ESTE ERROR:\n{resultado_exec}\nDevuelve SOLO el código corregido en ```{detected_ext}."}
389
+ ],
390
+ max_tokens=max_tokens,
391
+ stream=True,
392
+ temperature=0.2
393
+ ):
394
+ if chunk.choices and chunk.choices[0].delta.content:
395
+ new_resp += chunk.choices[0].delta.content
396
+ new_blocks = re.findall(r'```(?:python|javascript|js|html|sql)?\n(.*?)\n```', new_resp, re.DOTALL)
397
+ if new_blocks:
398
+ main_code = max(new_blocks, key=len)
399
+ resp_text += f"\n\n--- CORRECCIÓN {intentos} ---\n{new_resp}"
400
+ else:
401
+ break
402
+ except Exception as e:
403
+ print(f"\n[DEBUG] Error auto-corrección {intentos}: {e}")
404
+ break
405
+
406
+ # --- Output final ---
407
+ chatbot_output = norm_history + [
408
+ {"role": "user", "content": message},
409
+ {"role": "assistant", "content": resp_text}
410
+ ]
411
+ yield chatbot_output, resp_text, resp_text, ultima_ejecucion, memoria
412
  # ============================================
413
  # INTERFAZ GRADIO
414
  # ============================================