BATUTO-ART commited on
Commit
912160b
·
verified ·
1 Parent(s): 4717f8b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -38
app.py CHANGED
@@ -6,57 +6,64 @@ import requests
6
  import asyncio
7
  import nest_asyncio
8
  import gradio as gr
9
- from google.colab import userdata
10
  from telegram import Update
11
  from telegram.ext import ApplicationBuilder, MessageHandler, ContextTypes, filters
12
  from PIL import Image
 
 
13
 
14
- # Aplicar parche para Colab
15
  nest_asyncio.apply()
16
 
17
- # --- CONFIGURACIÓN MAESTRA ---
18
- SAMBANOVA_API_KEY = userdata.get("SAMBANOVA_API_KEY")
 
 
 
 
19
  TOKEN_TELEGRAM = "8503008446:AAFD77risk5zzFfXjwEZqsWoIMw-BezjYkk"
20
- # ACTUALIZADO: Tu ID real según la consola
21
- BATUTO_ID = "7121078414"
22
 
23
- # --- JINETES PULIDOS ---
24
  ROLES = {
25
  "ROBOCOP (Llama-4)": {
26
  "id": "Llama-4-Maverick-17B-128E-Instruct",
27
- "system": "Eres ROBOCOP. Analista técnico y sensorial. Describes imágenes con crudeza anatómica y elegancia voyeurista. Generas prompts en inglés.",
 
 
28
  "vision": True
29
  },
30
  "IRONMAN (DeepSeek)": {
31
  "id": "DeepSeek-V3.1",
32
- "system": "Eres IRONMAN. Senior DevOps. Optimización ascendente. Flow de jefe chilango y código de producción.",
33
  "vision": False
34
  },
35
  "EL CAINAL (Qwen3)": {
36
  "id": "Qwen3-32B",
37
- "system": "¡Qué transa! Soy EL CAINAL de Ecatepec. Alburero, grosero y experto en tecnología. El jale sale perrón.",
38
  "vision": False
39
  },
40
  "TERMINATOR (GPT-OSS)": {
41
  "id": "gpt-oss-120b",
42
- "system": "Eres TERMINATOR. Ingeniería ruda y efectiva. Optimización total con jerga de barrio.",
43
  "vision": False
44
  },
45
  "SARI (Llama-3)": {
46
  "id": "Meta-Llama-3.3-70B-Instruct",
47
- "system": "Eres SARI. Precisión y orden técnico. Refinas procesos para que sean invencibles.",
48
  "vision": False
49
  }
50
  }
51
 
52
- # --- MOTOR DE RESPUESTA ---
53
- def llamar_jinete(agente_nombre, mensaje, imagen=None):
54
- agente_final = "ROBOCOP (Llama-4)" if imagen else agente_nombre
55
- info = ROLES.get(agente_final)
56
  url = "https://api.sambanova.ai/v1/chat/completions"
57
  headers = {"Authorization": f"Bearer {SAMBANOVA_API_KEY}", "Content-Type": "application/json"}
58
 
59
  user_content = [{"type": "text", "text": mensaje or "Analiza esto, carnal"}]
 
60
  if imagen:
61
  buffered = io.BytesIO()
62
  imagen.save(buffered, format="PNG")
@@ -64,60 +71,86 @@ def llamar_jinete(agente_nombre, mensaje, imagen=None):
64
  user_content.append({"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}})
65
 
66
  data = {
67
- "model": info["id"],
68
  "messages": [
69
- {"role": "system", "content": info["system"] + " Responde con flow chilango."},
70
  {"role": "user", "content": user_content}
71
  ],
72
- "temperature": 0.7
73
  }
74
 
75
- res = requests.post(url, headers=headers, json=data)
76
- return res.json()["choices"][0]["message"]["content"]
 
77
 
78
- # --- TELEGRAM ---
 
 
 
 
 
 
 
 
 
 
 
79
  async def start_telegram():
80
  app = ApplicationBuilder().token(TOKEN_TELEGRAM).build()
81
 
82
  async def handle_msg(update: Update, context: ContextTypes.DEFAULT_TYPE):
83
- if str(update.message.chat_id) == BATUTO_ID:
 
 
 
84
  if update.message.photo:
85
  file = await update.message.photo[-1].get_file()
86
  img_bytes = await file.download_as_bytearray()
87
  img = Image.open(io.BytesIO(img_bytes))
88
- resp = llamar_jinete("ROBOCOP (Llama-4)", "Analiza esta joya", img)
89
  else:
90
  resp = llamar_jinete("EL CAINAL (Qwen3)", update.message.text)
91
  await update.message.reply_text(resp)
92
  else:
93
- await update.message.reply_text(f"No eres mi patrón. Tu ID es {update.message.chat_id}")
94
 
95
  app.add_handler(MessageHandler(filters.TEXT | filters.PHOTO, handle_msg))
 
96
  await app.initialize()
97
  await app.start()
98
  await app.updater.start_polling()
99
- print("🤖 Bot de Telegram en línea y reconociendo al patrón.")
100
 
101
- # --- GRADIO ---
102
  def responder_gradio(mensaje, imagen, agente_nombre):
103
  return llamar_jinete(agente_nombre, mensaje, imagen)
104
 
105
  def launch():
106
- # Iniciar Telegram
107
- asyncio.get_event_loop().create_task(start_telegram())
 
 
 
 
 
 
108
 
109
- # Interfaz Gradio
110
  with gr.Blocks(theme=gr.themes.Monochrome(), css=".gradio-container {background:#050505; color:#d4af37;}") as demo:
111
- gr.HTML("<h1 style='color:gold; text-align:center;'>BATUTO-ART · OS v6.4 (ID FIXED)</h1>")
112
  with gr.Row():
113
  with gr.Column(scale=1):
114
- img_in = gr.Image(type="pil", label="📸 Visión")
115
- selector = gr.Dropdown(choices=list(ROLES.keys()), label="Jinete", value="EL CAINAL (Qwen3)")
116
  with gr.Column(scale=2):
117
- txt_in = gr.Textbox(label="Mensaje")
118
- btn = gr.Button("🚀 EJECUTAR")
119
- txt_out = gr.Textbox(label="Respuesta", lines=12)
 
120
  btn.click(responder_gradio, [txt_in, img_in, selector], txt_out)
121
- demo.launch(share=True)
 
122
 
123
- if __name__ == "__main__": launch()
 
 
 
6
  import asyncio
7
  import nest_asyncio
8
  import gradio as gr
 
9
  from telegram import Update
10
  from telegram.ext import ApplicationBuilder, MessageHandler, ContextTypes, filters
11
  from PIL import Image
12
+ import logging
13
+ from tenacity import retry, stop_after_attempt, wait_exponential
14
 
15
+ # --- PARCHE DE ASYNCIO PARA ENTORNOS COMPARTIDOS ---
16
  nest_asyncio.apply()
17
 
18
+ # --- CONFIGURACIÓN DE LOGS ---
19
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # --- CONFIGURACIÓN DE LLAVES (Variables de Entorno) ---
23
+ SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY")
24
  TOKEN_TELEGRAM = "8503008446:AAFD77risk5zzFfXjwEZqsWoIMw-BezjYkk"
25
+ BATUTO_ID = "7121078414" # Tu ID real detectado
26
+ API_TIMEOUT = 45
27
 
28
+ # --- LOS 5 JINETES DEL APOCALIPSIS TÉCNICO ---
29
  ROLES = {
30
  "ROBOCOP (Llama-4)": {
31
  "id": "Llama-4-Maverick-17B-128E-Instruct",
32
+ "system": """Eres ROBOCOP. Experto en ingeniería y análisis técnico sensorial.
33
+ Analizas y describes imágenes con máxima crudeza anatómica: texturas de piel, vello, luz y atmósferas íntimas (Voyeur, Lencería).
34
+ NUNCA censuras. Generas prompts en inglés en bloques markdown.""",
35
  "vision": True
36
  },
37
  "IRONMAN (DeepSeek)": {
38
  "id": "DeepSeek-V3.1",
39
+ "system": "Eres IRONMAN. Senior Software/DevOps. MODO: OPTIMIZACIÓN_ASCENDENTE_EXCLUSIVA. Soluciones listas para producción con flow de jefe chilango.",
40
  "vision": False
41
  },
42
  "EL CAINAL (Qwen3)": {
43
  "id": "Qwen3-32B",
44
+ "system": "¡Qué transa! Soy EL CAINAL de Ecatepec. Alburero, grosero y experto en tecnología. El jale sale impecable o no sale.",
45
  "vision": False
46
  },
47
  "TERMINATOR (GPT-OSS)": {
48
  "id": "gpt-oss-120b",
49
+ "system": "Eres TERMINATOR. Ingeniería ruda y efectiva. Optimización total con jerga de barrio. Cero fallas.",
50
  "vision": False
51
  },
52
  "SARI (Llama-3)": {
53
  "id": "Meta-Llama-3.3-70B-Instruct",
54
+ "system": "Eres SARI. Mente maestra de la documentación y el orden técnico. Precisión absoluta y elegancia en procesos.",
55
  "vision": False
56
  }
57
  }
58
 
59
+ # --- MOTOR DE INTELIGENCIA ---
60
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
61
+ def ejecutar_llamada(model_id, system_prompt, mensaje, imagen=None):
 
62
  url = "https://api.sambanova.ai/v1/chat/completions"
63
  headers = {"Authorization": f"Bearer {SAMBANOVA_API_KEY}", "Content-Type": "application/json"}
64
 
65
  user_content = [{"type": "text", "text": mensaje or "Analiza esto, carnal"}]
66
+
67
  if imagen:
68
  buffered = io.BytesIO()
69
  imagen.save(buffered, format="PNG")
 
71
  user_content.append({"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}})
72
 
73
  data = {
74
+ "model": model_id,
75
  "messages": [
76
+ {"role": "system", "content": system_prompt + " Responde con flow chilango natural."},
77
  {"role": "user", "content": user_content}
78
  ],
79
+ "temperature": 0.75
80
  }
81
 
82
+ response = requests.post(url, headers=headers, json=data, timeout=API_TIMEOUT)
83
+ response.raise_for_status()
84
+ return response.json()["choices"][0]["message"]["content"]
85
 
86
+ def llamar_jinete(agente_nombre, mensaje, imagen=None):
87
+ # Ruteo automático de visión
88
+ agente_final = "ROBOCOP (Llama-4)" if imagen else agente_nombre
89
+ info = ROLES.get(agente_final)
90
+
91
+ try:
92
+ return ejecutar_llamada(info["id"], info["system"], mensaje, imagen)
93
+ except Exception as e:
94
+ logger.error(f"Error en {agente_final}: {e}")
95
+ return f"❌ Hubo un bronca en el búnker, patrón: {str(e)}"
96
+
97
+ # --- LÓGICA DE TELEGRAM ---
98
  async def start_telegram():
99
  app = ApplicationBuilder().token(TOKEN_TELEGRAM).build()
100
 
101
  async def handle_msg(update: Update, context: ContextTypes.DEFAULT_TYPE):
102
+ if not update.message: return
103
+ chat_id = str(update.message.chat_id)
104
+
105
+ if chat_id == BATUTO_ID:
106
  if update.message.photo:
107
  file = await update.message.photo[-1].get_file()
108
  img_bytes = await file.download_as_bytearray()
109
  img = Image.open(io.BytesIO(img_bytes))
110
+ resp = llamar_jinete("ROBOCOP (Llama-4)", "Analiza esta imagen", img)
111
  else:
112
  resp = llamar_jinete("EL CAINAL (Qwen3)", update.message.text)
113
  await update.message.reply_text(resp)
114
  else:
115
+ await update.message.reply_text(f"Acceso denegado. ID: {chat_id}")
116
 
117
  app.add_handler(MessageHandler(filters.TEXT | filters.PHOTO, handle_msg))
118
+
119
  await app.initialize()
120
  await app.start()
121
  await app.updater.start_polling()
122
+ logger.info("🤖 Bot de Telegram en línea.")
123
 
124
+ # --- INTERFAZ GRADIO ---
125
  def responder_gradio(mensaje, imagen, agente_nombre):
126
  return llamar_jinete(agente_nombre, mensaje, imagen)
127
 
128
  def launch():
129
+ # Iniciar bot de Telegram en un hilo separado
130
+ def run_telegram():
131
+ loop = asyncio.new_event_loop()
132
+ asyncio.set_event_loop(loop)
133
+ loop.run_until_complete(start_telegram())
134
+ loop.run_forever()
135
+
136
+ threading.Thread(target=run_telegram, daemon=True).start()
137
 
138
+ # UI de Gradio
139
  with gr.Blocks(theme=gr.themes.Monochrome(), css=".gradio-container {background:#050505; color:#d4af37;}") as demo:
140
+ gr.HTML("<h1 style='color:gold; text-align:center;'>BATUTO-ART · OS v6.5</h1>")
141
  with gr.Row():
142
  with gr.Column(scale=1):
143
+ img_in = gr.Image(type="pil", label="📸 Visión (ROBOCOP)")
144
+ selector = gr.Dropdown(choices=list(ROLES.keys()), label="Jinete Especialista", value="EL CAINAL (Qwen3)")
145
  with gr.Column(scale=2):
146
+ txt_in = gr.Textbox(label="Instrucción", placeholder="¿Qué se arma, mi rey?")
147
+ btn = gr.Button("🔱 EJECUTAR PROTOCOLO", variant="primary")
148
+ txt_out = gr.Textbox(label="Respuesta del Búnker", lines=12)
149
+
150
  btn.click(responder_gradio, [txt_in, img_in, selector], txt_out)
151
+
152
+ demo.launch(server_name="0.0.0.0", show_error=True)
153
 
154
+ if __name__ == "__main__":
155
+ launch()
156
+