caarleexx commited on
Commit
32fd19c
Β·
verified Β·
1 Parent(s): a56164e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -55
app.py CHANGED
@@ -1,6 +1,6 @@
1
  # ╔════════════════════════════════════════════════════════════════════════════╗
2
- # β•‘ PIPELINE v33: DEBUG LOGS + GRADIO 5.x MESSAGES FORMAT β•‘
3
- # β•‘ Prints completos: input/output Gemini + erros + fases β•‘
4
  # β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
5
 
6
  import os
@@ -10,20 +10,27 @@ import time
10
  from datetime import datetime
11
  import gradio as gr
12
  import google.generativeai as genai
 
13
 
14
  # ==================== 1. CONFIGURAÇÃO ====================
15
- api_key = os.getenv("GOOGLE_API_KEY", "SUA_API_KEY_AQUI")
16
- if api_key:
17
- genai.configure(api_key=api_key)
18
-
19
- model_flash = genai.GenerativeModel("gemini-2.0-flash")
20
  model_pro = genai.GenerativeModel("gemini-pro-latest")
21
 
 
 
 
 
22
  ARQUIVO_CONFIG = "protocolo.json"
23
  ARQUIVO_HELP = "help.md"
24
- DELAY_ENTRE_AGENTES = 12 # 3 minutos em segundos
25
 
26
- print("πŸš€ App inicializada. Modelos carregados: flash/pro")
 
 
27
 
28
  # ==================== 2. UTILIDADES ====================
29
  def carregar_protocolo():
@@ -68,31 +75,77 @@ def verificar_stop(texto):
68
  if not texto:
69
  return False
70
  stop_detectado = bool(re.search(r'\bstop\b', str(texto), re.IGNORECASE))
71
- print(f"πŸ›‘ STOP detectado? {stop_detectado} em '{texto[:100]}...'")
72
  return stop_detectado
73
 
74
- # ==================== 3. ENGINE DE EXECUÇÃO ====================
75
  def executar_no(timeline, config):
76
- print(f"\nπŸ”₯ === EXECUTANDO {config['nome']} ({config.get('modelo', 'flash')}) ===")
77
- modelo = model_pro if config.get("modelo") == "pro" else model_flash
 
 
78
  contexto = json.dumps(timeline, ensure_ascii=False, indent=2)
79
  prompt = f"--- TIMELINE ---\n{contexto}\n----------------\nAGENTE: {config['nome']}\nMISSΓƒO: {config['missao']}"
80
 
81
- print("πŸ“€ INPUT PROMPT (primeiros 800 chars):")
82
- print(prompt[:800])
83
- print("..." if len(prompt) > 800 else "")
84
 
85
  try:
86
  inicio = time.time()
87
- resp = modelo.generate_content(prompt)
88
- out_raw = resp.text
89
- tempo_exec = time.time() - inicio
90
 
91
- print(f"πŸ“₯ OUTPUT BRUTO GEMINI ({len(out_raw)} chars):")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  print(out_raw[:1000])
93
  print("..." if len(out_raw) > 1000 else "")
94
 
95
- # Tenta parsear JSON se tipo_saida for json
 
 
96
  content = out_raw
97
  if config.get('tipo_saida') == 'json':
98
  try:
@@ -107,17 +160,19 @@ def executar_no(timeline, config):
107
  return {
108
  "role": "assistant",
109
  "agent": config['nome'],
 
110
  "content": content,
111
  "raw": out_raw,
112
  "tempo": tempo_exec
113
  }, True
114
 
115
  except Exception as e:
116
- print(f"πŸ’₯ ERRO GEMINI: {str(e)}")
117
  return {
118
  "role": "system",
119
  "error": str(e),
120
- "agent": config['nome']
 
121
  }, False
122
 
123
  # ==================== 4. ORQUESTRADOR ====================
@@ -126,35 +181,28 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
126
  print("🎬 INICIANDO ORQUESTRADOR - NOVA EXECUÇÃO")
127
  print(f"πŸ“ Input texto: '{texto[:200]}...' ({len(texto)} chars)")
128
  print(f"πŸ“Ž Anexos: {len(anexos_list)} arquivos")
129
- print(f"🎯 Objetivo: '{contexto_objetivo[:100]}...'")
130
 
131
- # 1. Input Check
132
  if not texto.strip():
133
  print("⚠️ Texto vazio, abortando")
134
  yield history, []
135
  return
136
 
137
- # 2. Setup - FORMATO MESSAGES
138
  history = history + [{"role": "user", "content": texto}]
139
- print(f"πŸ“Š History atualizado com user msg ({len(history)} mensagens)")
140
 
141
  try:
142
  protocolo = json.loads(json_config)
143
- print(f"πŸ”— Protocolo carregado: {len(protocolo)} agentes - { [a['nome'] for a in protocolo] }")
144
  except Exception as e:
145
  print(f"πŸ’₯ Erro JSON config: {e}")
146
  history.append({"role": "assistant", "content": f"❌ Erro no JSON de ConfiguraΓ§Γ£o: {str(e)}"})
147
  yield history, []
148
  return
149
 
150
- # Adiciona assistente vazio inicial
151
  history.append({"role": "assistant", "content": ""})
152
 
153
- # 3. Monta contexto inicial
154
  contexto_inicial = ""
155
  if contexto_objetivo and contexto_objetivo.strip():
156
  contexto_inicial += f"[OBJETIVO DO MODELO]\n{contexto_objetivo.strip()}\n[FIM OBJETIVO]\n\n"
157
- print("🎯 Contexto objetivo adicionado")
158
 
159
  if anexos_list:
160
  for anexo in anexos_list:
@@ -164,16 +212,12 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
164
 
165
  full_input = f"{contexto_inicial}{texto}".strip()
166
  timeline = [{"role": "user", "content": full_input}]
167
- print(f"🌐 Full input timeline inicial: {len(full_input)} chars")
168
-
169
  audit_data = []
170
 
171
- # 4. Loop pelos agentes
172
  for idx, cfg in enumerate(protocolo):
173
  print(f"\n{'='*50}")
174
- print(f"πŸš€ FASE {idx+1}/{len(protocolo)}: {cfg['nome']} ({cfg.get('tipo_saida', 'texto')})")
175
 
176
- # Mensagem aguardo
177
  history[-1]["content"] = f"⏳ Chamando agente **{cfg['nome']}**... Aguarde."
178
  yield history, audit_data
179
 
@@ -183,16 +227,14 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
183
  history[-1]["content"] = f"⏳ Agente **{cfg['nome']}** processando..."
184
  yield history, audit_data
185
 
186
- # Executa agente
187
  res, sucesso = executar_no(timeline, cfg)
188
  timeline.append(res)
189
 
190
- # Audit
191
  audit_entry = {
192
  "step": idx + 1,
193
  "agent": cfg['nome'],
194
- "mission": cfg['missao'][:100] + "...",
195
- "model": cfg.get('modelo', 'flash'),
196
  "type": cfg.get('tipo_saida', 'texto'),
197
  "response": str(res.get('content'))[:100] + "...",
198
  "raw_len": len(res.get('raw', '')),
@@ -201,7 +243,6 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
201
  "timestamp": datetime.now().strftime('%H:%M:%S')
202
  }
203
  audit_data.append(audit_entry)
204
- print(f"πŸ“‹ Audit entry adicionado: {audit_entry['step']}")
205
 
206
  conteudo_resposta = res.get('content', '')
207
  if verificar_stop(conteudo_resposta):
@@ -212,8 +253,6 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
212
 
213
  if idx == len(protocolo) - 1 or cfg.get('tipo_saida') == 'texto':
214
  texto_final = str(conteudo_resposta)
215
- print(f"✨ Resposta final agente {idx+1}: {len(texto_final)} chars")
216
- # Typewriter effect
217
  for i in range(0, len(texto_final), 5):
218
  history[-1]["content"] = texto_final[:i+5]
219
  yield history, audit_data
@@ -222,9 +261,8 @@ def orquestrador(texto, anexos_list, history, json_config, contexto_objetivo):
222
  yield history, audit_data
223
 
224
  print("🏁 Orquestrador concluΓ­do")
225
- print("="*80)
226
 
227
- # Resto do cΓ³digo UI inalterado...
228
  def ui_clean():
229
  config_init = carregar_protocolo()
230
  help_init = carregar_help()
@@ -234,16 +272,16 @@ def ui_clean():
234
 
235
  with gr.Tabs():
236
  with gr.Tab("πŸ’¬ Chat"):
237
- gr.Markdown("## Investigador AI (v33 DEBUG)")
238
- chatbot = gr.Chatbot(label="HistΓ³rico", show_label=True, height=500)
239
 
240
  with gr.Row():
241
- txt_in = gr.Textbox(show_label=False, placeholder="Digite sua mensagem...", lines=2, scale=9)
242
  btn_send = gr.Button("πŸ“€ Enviar", variant="primary", scale=1)
243
 
244
  with gr.Tab("πŸ“Ž Anexos & Contexto"):
245
  objetivo_text = gr.Textbox(label="Objetivo do Modelo", lines=5)
246
- anexos_upload = gr.File(file_count="multiple", file_types=[".txt", ".md", ".csv", ".json", ".pdf"])
247
  anexos_display = gr.Textbox(label="Arquivos", interactive=False, lines=3)
248
 
249
  def atualizar_anexos(files):
@@ -254,27 +292,49 @@ def ui_clean():
254
  anexos_upload.change(atualizar_anexos, anexos_upload, [anexos_state, anexos_display])
255
 
256
  with gr.Tab("βš™οΈ Protocolo"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  with gr.Row():
258
- btn_save_proto = gr.Button("πŸ’Ύ Salvar")
259
  btn_reload_proto = gr.Button("πŸ”„ Recarregar")
260
  proto_status = gr.Markdown("")
261
  code_json = gr.Code(value=config_init, language="json", lines=30)
262
 
263
  btn_save_proto.click(salvar_protocolo, code_json, proto_status)
264
- btn_reload_proto.click(lambda: carregar_protocolo(), code_json)
265
 
266
  with gr.Tab("πŸ” Auditoria"):
267
  audit_display = gr.JSON(label="Dados de Auditoria")
268
 
269
  with gr.Tab("❓ Ajuda"):
270
  help_content = gr.Markdown(help_init)
271
- gr.Button("πŸ”„ Recarregar").click(lambda: carregar_help(), help_content)
272
 
273
- btn_send.click(orquestrador, [txt_in, anexos_state, chatbot, code_json, objetivo_text], [chatbot, audit_display]).then(lambda: "", txt_in)
274
- txt_in.submit(orquestrador, [txt_in, anexos_state, chatbot, code_json, objetivo_text], [chatbot, audit_display]).then(lambda: "", txt_in)
275
 
276
  return app
277
 
278
  if __name__ == "__main__":
279
  print("πŸŽ‰ LanΓ§ando app...")
280
- ui_clean().launch(css="footer{display:none!important;}.contain{border:none!important;}")
 
1
  # ╔════════════════════════════════════════════════════════════════════════════╗
2
+ # β•‘ PIPELINE v34: GEMINI + GROQ + DEBUG LOGS β•‘
3
+ # β•‘ Suporte dual: Google Gemini e Groq API β•‘
4
  # β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
5
 
6
  import os
 
10
  from datetime import datetime
11
  import gradio as gr
12
  import google.generativeai as genai
13
+ from groq import Groq
14
 
15
  # ==================== 1. CONFIGURAÇÃO ====================
16
+ # GEMINI
17
+ gemini_key = os.getenv("GOOGLE_API_KEY", "SUA_API_KEY_AQUI")
18
+ if gemini_key:
19
+ genai.configure(api_key=gemini_key)
20
+ model_flash = genai.GenerativeModel("gemini-flash-latest")
21
  model_pro = genai.GenerativeModel("gemini-pro-latest")
22
 
23
+ # GROQ
24
+ groq_key = os.getenv("GROQ_API_KEY", "SUA_GROQ_KEY_AQUI")
25
+ groq_client = Groq(api_key=groq_key) if groq_key else None
26
+
27
  ARQUIVO_CONFIG = "protocolo.json"
28
  ARQUIVO_HELP = "help.md"
29
+ DELAY_ENTRE_AGENTES = 180 # 3 minutos
30
 
31
+ print("πŸš€ App inicializada")
32
+ print(f" βœ… Gemini: {'OK' if gemini_key else '❌ sem key'}")
33
+ print(f" βœ… Groq: {'OK' if groq_client else '❌ sem key'}")
34
 
35
  # ==================== 2. UTILIDADES ====================
36
  def carregar_protocolo():
 
75
  if not texto:
76
  return False
77
  stop_detectado = bool(re.search(r'\bstop\b', str(texto), re.IGNORECASE))
78
+ print(f"πŸ›‘ STOP detectado? {stop_detectado} em '{str(texto)[:100]}...'")
79
  return stop_detectado
80
 
81
+ # ==================== 3. ENGINE DE EXECUÇÃO (DUAL) ====================
82
  def executar_no(timeline, config):
83
+ provider = config.get('provider', 'gemini').lower()
84
+ print(f"\nπŸ”₯ === EXECUTANDO {config['nome']} ===")
85
+ print(f" Provider: {provider.upper()} | Modelo: {config.get('modelo', 'auto')}")
86
+
87
  contexto = json.dumps(timeline, ensure_ascii=False, indent=2)
88
  prompt = f"--- TIMELINE ---\n{contexto}\n----------------\nAGENTE: {config['nome']}\nMISSΓƒO: {config['missao']}"
89
 
90
+ print("πŸ“€ INPUT PROMPT (primeiros 600 chars):")
91
+ print(prompt[:600])
92
+ print("..." if len(prompt) > 600 else "")
93
 
94
  try:
95
  inicio = time.time()
 
 
 
96
 
97
+ # ===== GROQ =====
98
+ if provider == 'groq':
99
+ if not groq_client:
100
+ raise Exception("Groq client nΓ£o configurado (falta GROQ_API_KEY)")
101
+
102
+ modelo_groq = config.get('modelo', 'meta-llama/llama-4-maverick-17b-128e-instruct')
103
+
104
+ # Converte timeline para formato chat do Groq
105
+ messages = []
106
+ for msg in timeline:
107
+ if msg.get('role') in ['user', 'assistant']:
108
+ messages.append({
109
+ "role": msg['role'],
110
+ "content": str(msg.get('content', ''))
111
+ })
112
+
113
+ # Adiciona prompt da missΓ£o como system message
114
+ messages_groq = [
115
+ {"role": "system", "content": f"AGENTE: {config['nome']}\nMISSÃO: {config['missao']}"}
116
+ ] + messages
117
+
118
+ print(f"πŸ”§ Groq messages: {len(messages_groq)} msgs")
119
+
120
+ completion = groq_client.chat.completions.create(
121
+ model=modelo_groq,
122
+ messages=messages_groq,
123
+ temperature=1,
124
+ max_completion_tokens=2048,
125
+ top_p=1,
126
+ stream=True,
127
+ stop=None
128
+ )
129
+
130
+ out_raw = ""
131
+ for chunk in completion:
132
+ out_raw += chunk.choices[0].delta.content or ""
133
+
134
+ print(f"πŸ“₯ OUTPUT GROQ ({len(out_raw)} chars):")
135
+
136
+ # ===== GEMINI =====
137
+ else:
138
+ modelo = model_pro if config.get("modelo") == "pro" else model_flash
139
+ resp = modelo.generate_content(prompt)
140
+ out_raw = resp.text
141
+ print(f"πŸ“₯ OUTPUT GEMINI ({len(out_raw)} chars):")
142
+
143
  print(out_raw[:1000])
144
  print("..." if len(out_raw) > 1000 else "")
145
 
146
+ tempo_exec = time.time() - inicio
147
+
148
+ # Parse JSON se necessΓ‘rio
149
  content = out_raw
150
  if config.get('tipo_saida') == 'json':
151
  try:
 
160
  return {
161
  "role": "assistant",
162
  "agent": config['nome'],
163
+ "provider": provider,
164
  "content": content,
165
  "raw": out_raw,
166
  "tempo": tempo_exec
167
  }, True
168
 
169
  except Exception as e:
170
+ print(f"πŸ’₯ ERRO {provider.upper()}: {str(e)}")
171
  return {
172
  "role": "system",
173
  "error": str(e),
174
+ "agent": config['nome'],
175
+ "provider": provider
176
  }, False
177
 
178
  # ==================== 4. ORQUESTRADOR ====================
 
181
  print("🎬 INICIANDO ORQUESTRADOR - NOVA EXECUÇÃO")
182
  print(f"πŸ“ Input texto: '{texto[:200]}...' ({len(texto)} chars)")
183
  print(f"πŸ“Ž Anexos: {len(anexos_list)} arquivos")
 
184
 
 
185
  if not texto.strip():
186
  print("⚠️ Texto vazio, abortando")
187
  yield history, []
188
  return
189
 
 
190
  history = history + [{"role": "user", "content": texto}]
 
191
 
192
  try:
193
  protocolo = json.loads(json_config)
194
+ print(f"πŸ”— Protocolo: {len(protocolo)} agentes - {[a['nome'] for a in protocolo]}")
195
  except Exception as e:
196
  print(f"πŸ’₯ Erro JSON config: {e}")
197
  history.append({"role": "assistant", "content": f"❌ Erro no JSON de ConfiguraΓ§Γ£o: {str(e)}"})
198
  yield history, []
199
  return
200
 
 
201
  history.append({"role": "assistant", "content": ""})
202
 
 
203
  contexto_inicial = ""
204
  if contexto_objetivo and contexto_objetivo.strip():
205
  contexto_inicial += f"[OBJETIVO DO MODELO]\n{contexto_objetivo.strip()}\n[FIM OBJETIVO]\n\n"
 
206
 
207
  if anexos_list:
208
  for anexo in anexos_list:
 
212
 
213
  full_input = f"{contexto_inicial}{texto}".strip()
214
  timeline = [{"role": "user", "content": full_input}]
 
 
215
  audit_data = []
216
 
 
217
  for idx, cfg in enumerate(protocolo):
218
  print(f"\n{'='*50}")
219
+ print(f"πŸš€ FASE {idx+1}/{len(protocolo)}: {cfg['nome']} ({cfg.get('provider', 'gemini')})")
220
 
 
221
  history[-1]["content"] = f"⏳ Chamando agente **{cfg['nome']}**... Aguarde."
222
  yield history, audit_data
223
 
 
227
  history[-1]["content"] = f"⏳ Agente **{cfg['nome']}** processando..."
228
  yield history, audit_data
229
 
 
230
  res, sucesso = executar_no(timeline, cfg)
231
  timeline.append(res)
232
 
 
233
  audit_entry = {
234
  "step": idx + 1,
235
  "agent": cfg['nome'],
236
+ "provider": cfg.get('provider', 'gemini'),
237
+ "model": cfg.get('modelo', 'auto'),
238
  "type": cfg.get('tipo_saida', 'texto'),
239
  "response": str(res.get('content'))[:100] + "...",
240
  "raw_len": len(res.get('raw', '')),
 
243
  "timestamp": datetime.now().strftime('%H:%M:%S')
244
  }
245
  audit_data.append(audit_entry)
 
246
 
247
  conteudo_resposta = res.get('content', '')
248
  if verificar_stop(conteudo_resposta):
 
253
 
254
  if idx == len(protocolo) - 1 or cfg.get('tipo_saida') == 'texto':
255
  texto_final = str(conteudo_resposta)
 
 
256
  for i in range(0, len(texto_final), 5):
257
  history[-1]["content"] = texto_final[:i+5]
258
  yield history, audit_data
 
261
  yield history, audit_data
262
 
263
  print("🏁 Orquestrador concluΓ­do")
 
264
 
265
+ # ==================== 5. UI ====================
266
  def ui_clean():
267
  config_init = carregar_protocolo()
268
  help_init = carregar_help()
 
272
 
273
  with gr.Tabs():
274
  with gr.Tab("πŸ’¬ Chat"):
275
+ gr.Markdown("## Investigador AI (v34 Gemini+Groq)")
276
+ chatbot = gr.Chatbot(label="HistΓ³rico", height=500)
277
 
278
  with gr.Row():
279
+ txt_in = gr.Textbox(show_label=False, placeholder="Digite...", lines=2, scale=9)
280
  btn_send = gr.Button("πŸ“€ Enviar", variant="primary", scale=1)
281
 
282
  with gr.Tab("πŸ“Ž Anexos & Contexto"):
283
  objetivo_text = gr.Textbox(label="Objetivo do Modelo", lines=5)
284
+ anexos_upload = gr.File(file_count="multiple", file_types=[".txt", ".md", ".csv", ".json"])
285
  anexos_display = gr.Textbox(label="Arquivos", interactive=False, lines=3)
286
 
287
  def atualizar_anexos(files):
 
292
  anexos_upload.change(atualizar_anexos, anexos_upload, [anexos_state, anexos_display])
293
 
294
  with gr.Tab("βš™οΈ Protocolo"):
295
+ gr.Markdown("""
296
+ ## EdiΓ§Γ£o do Protocolo
297
+
298
+ **Novo:** Adicione `"provider": "groq"` ou `"provider": "gemini"` em cada agente.
299
+
300
+ Modelos Groq suportados:
301
+ - `meta-llama/llama-4-maverick-17b-128e-instruct`
302
+ - `meta-llama/llama-3.3-70b-versatile`
303
+ - `deepseek-r1-distill-llama-70b`
304
+
305
+ Exemplo:
306
+ ```
307
+ {
308
+ "nome": "Agente Groq",
309
+ "provider": "groq",
310
+ "modelo": "meta-llama/llama-4-maverick-17b-128e-instruct",
311
+ "tipo_saida": "texto",
312
+ "missao": "..."
313
+ }
314
+ ```
315
+ """)
316
+
317
  with gr.Row():
318
+ btn_save_proto = gr.Button("πŸ’Ύ Salvar", variant="primary")
319
  btn_reload_proto = gr.Button("πŸ”„ Recarregar")
320
  proto_status = gr.Markdown("")
321
  code_json = gr.Code(value=config_init, language="json", lines=30)
322
 
323
  btn_save_proto.click(salvar_protocolo, code_json, proto_status)
324
+ btn_reload_proto.click(lambda: carregar_protocolo(), outputs=code_json)
325
 
326
  with gr.Tab("πŸ” Auditoria"):
327
  audit_display = gr.JSON(label="Dados de Auditoria")
328
 
329
  with gr.Tab("❓ Ajuda"):
330
  help_content = gr.Markdown(help_init)
331
+ gr.Button("πŸ”„ Recarregar").click(lambda: carregar_help(), outputs=help_content)
332
 
333
+ btn_send.click(orquestrador, [txt_in, anexos_state, chatbot, code_json, objetivo_text], [chatbot, audit_display]).then(lambda: "", outputs=txt_in)
334
+ txt_in.submit(orquestrador, [txt_in, anexos_state, chatbot, code_json, objetivo_text], [chatbot, audit_display]).then(lambda: "", outputs=txt_in)
335
 
336
  return app
337
 
338
  if __name__ == "__main__":
339
  print("πŸŽ‰ LanΓ§ando app...")
340
+ ui_clean().launch(css="footer{display:none!important;}")