caarleexx commited on
Commit
fd8ef38
·
verified ·
1 Parent(s): f77dbe3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +335 -0
app.py ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ╔════════════════════════════════════════════════════════════════════════════╗
2
+ # ║ PIPELINE v29: PLANEJADOR AUTO-AGENTE | SUPERA PARADOXO MEHON ║
3
+ # ║ 1º: PLANEJA → 2º-N: EXECUTA → N+1: CONVERGE COM HISTÓRICO ║
4
+ # ╚════════════════════════════════════════════════════════════════════════════╝
5
+
6
+ import os
7
+ import json
8
+ import re
9
+ import time
10
+ from datetime import datetime
11
+ import gradio as gr
12
+ import google.generativeai as genai
13
+
14
+ # ==================== 1. CONFIGURAÇÃO GLOBAL ====================
15
+ api_key = os.getenv("GOOGLE_API_KEY")
16
+ if api_key:
17
+ genai.configure(api_key=api_key)
18
+ model_flash = genai.GenerativeModel("gemini-flash-latest")
19
+ model_pro = genai.GenerativeModel("gemini-pro-latest")
20
+ else:
21
+ model_flash = model_pro = None
22
+ print("⚠️ GOOGLE_API_KEY não encontrada. Configure via export GOOGLE_API_KEY=...")
23
+
24
+ ARQUIVO_HISTORY = "history_v29.json"
25
+
26
+ # ==================== 2. UTILIDADES DE PERSISTÊNCIA ====================
27
+ def carregar_history():
28
+ """Carrega histórico persistente"""
29
+ try:
30
+ with open(ARQUIVO_HISTORY, "r", encoding="utf-8") as f:
31
+ return json.load(f)
32
+ except:
33
+ return []
34
+
35
+ def salvar_history(history):
36
+ """Salva histórico automaticamente"""
37
+ try:
38
+ with open(ARQUIVO_HISTORY, "w", encoding="utf-8") as f:
39
+ json.dump(history, f, ensure_ascii=False, indent=2)
40
+ return True
41
+ except:
42
+ return False
43
+
44
+ def ler_anexo(arquivo):
45
+ """Processa arquivos anexados"""
46
+ if not arquivo: return ""
47
+ try:
48
+ with open(arquivo.name, "r", encoding="utf-8") as f:
49
+ nome = os.path.basename(arquivo.name)
50
+ return f"\n\n📎 ANEXO: {nome}\n{f.read()}\n[FIM ANEXO]\n"
51
+ except:
52
+ return "❌ Erro lendo anexo"
53
+
54
+ def exportar_chat(history):
55
+ """Gera TXT para download"""
56
+ if not history: return ""
57
+ timestamp = datetime.now().strftime('%Y-%m-%d_%H%M%S')
58
+ chat_txt = f"MEHON v29 EXPORT - {timestamp}\n\n"
59
+ for i, msg in enumerate(history, 1):
60
+ role = "👤 USUÁRIO" if i % 2 == 1 else "🤖 MEHON"
61
+ chat_txt += f"{role}:\n{msg}\n\n{'-'*80}\n\n"
62
+ return chat_txt
63
+
64
+ # ==================== 3. AGENTE PLANEJADOR (SUPERA MEHON) ====================
65
+ def gerar_plano_auto(input_completo, history_contexto):
66
+ """AGENTE 1: CRIA PLANO DINÂMICO baseando-se em histórico + input"""
67
+ if not model_pro:
68
+ return None, "❌ Sem API_KEY"
69
+
70
+ # Compacta histórico (últimas 5 trocas, 200 chars cada)
71
+ history_resumo = ""
72
+ if len(history_contexto) >= 2:
73
+ history_resumo = "\n".join([
74
+ f"👤: {h[0][:200]}... | 🤖: {h[1][:200]}..."
75
+ for h in history_contexto[-5:]
76
+ ])
77
+
78
+ prompt_planejador = f"""🚀 PLANEJADOR AUTO-AGENTE v29 - SUPERA PARADOXO MEHON
79
+
80
+ CONTEXTO HISTÓRICO DO USUÁRIO:
81
+ {history_resumo}
82
+
83
+ INPUT ATUAL: {input_completo}
84
+
85
+ ---
86
+
87
+ CRIE PLANO ESTRUTURADO DE 3-6 AGENTES para resolver PERFEITAMENTE:
88
+
89
+ 📋 FORMATO OBRIGATÓRIO (JSON VÁLIDO):
90
+ [
91
+ {{"nome": "NomeClaro", "missao": "InstruçãoPrecisade200palavras", "modelo": "flash", "tipo_saida": "texto"}},
92
+ ...
93
+ ]
94
+
95
+ ✅ CRITÉRIOS DO PLANO:
96
+ • DECOMPONHA: problema → análise → cenários → validação → síntese
97
+ • IDENTIFIQUE ambiguidades/possibilidades do input
98
+ • PERSONALIZE com histórico do usuário
99
+ • ÚLTIMO agente SEMPRE gera saída FINAL pro usuário
100
+ • Evite resposta direta - USE CADEIA DE PENSAMENTO
101
+
102
+ EXEMPLO PLANO BOM:
103
+ [
104
+ {{"nome": "AnalisadorInput", "missao": "Identifique elementos principais, ambiguidades e contexto", "modelo": "flash", "tipo_saida": "json"}},
105
+ {{"nome": "ExploradorCenários", "missao": "Liste 3-5 cenários possíveis com probabilidades", "modelo": "pro", "tipo_saida": "json"}},
106
+ {{"nome": "SintetizadorFinal", "missao": "Converja tudo em resposta única e acionável", "modelo": "pro", "tipo_saida": "texto"}}
107
+ ]
108
+
109
+ APENAS JSON VÁLIDO - SEM TEXTO EXTRA!"""
110
+
111
+ try:
112
+ resp = model_pro.generate_content(prompt_planejador, temperature=0.3)
113
+ plano_raw = resp.text.strip().replace('``````','').replace('json','')
114
+ plano = json.loads(plano_raw)
115
+
116
+ # Valida estrutura mínima
117
+ if not isinstance(plano, list) or len(plano) < 2:
118
+ return None, "❌ Plano inválido (precisa 2+ agentes)"
119
+
120
+ return plano, f"✅ Plano: {len(plano)} agentes gerados"
121
+ except Exception as e:
122
+ return None, f"❌ Erro plano: {str(e)[:100]}"
123
+
124
+ # ==================== 4. EXECUTOR DE AGENTES DINÂMICOS ====================
125
+ def executar_agente_especifico(timeline, agente_config, history_contexto):
126
+ """Executa agente específico do plano dinâmico"""
127
+ if not (model_flash or model_pro):
128
+ return {"role": "system", "error": "Sem API"}, "(ERRO: API)", "Sem Google API Key"
129
+
130
+ modelo = model_pro if agente_config.get("modelo") == "pro" else model_flash
131
+
132
+ # Contexto: últimos 8 passos da timeline + histórico
133
+ contexto_timeline = json.dumps(timeline[-8:], ensure_ascii=False, indent=2)
134
+ history_resumo = "\n".join([f"👤: {h[0][:100]}... | 🤖: {h[1][:100]}..." for h in history_contexto[-3:]])
135
+
136
+ prompt = f"""CONTEXTO DA CADEIA DE PENSAMENTO:
137
+ {contexto_timeline}
138
+
139
+ HISTÓRICO RECENTE:
140
+ {history_resumo}
141
+
142
+ AGENTE ATIVO: {agente_config['nome']}
143
+ MISSÃO ESPECÍFICA: {agente_config['missao']}
144
+
145
+ { 'JSON estruturado e válido' if agente_config['tipo_saida']=='json' else 'Resposta clara, completa e finalizada pro usuário' }:"""
146
+
147
+ log = f"🔸 {agente_config['nome']} ({agente_config['modelo']})"
148
+ try:
149
+ inicio = time.time()
150
+ resp = modelo.generate_content(prompt, temperature=0.1 if agente_config['tipo_saida']=='json' else 0.7)
151
+ out = resp.text.strip()
152
+
153
+ # Parse output
154
+ content = json.loads(out.replace('``````','')) if agente_config['tipo_saida']=='json' else out
155
+ tempo = time.time() - inicio
156
+
157
+ log += f" ✓ {tempo:.1f}s"
158
+ return {"role": "assistant", "agent": agente_config['nome'], "content": content}, log, out
159
+
160
+ except Exception as e:
161
+ log += f" ✗ {str(e)[:50]}"
162
+ return {"role": "system", "error": str(e)}, log, str(e)
163
+
164
+ # ==================== 5. ORQUESTRADOR PRINCIPAL (MEHON) ====================
165
+ def pipeline_mehon_completo(texto, arquivo, history):
166
+ """Pipeline completo: PLANEJA → EXECUTA → CONVERGE"""
167
+
168
+ # Processa input
169
+ anexo = ler_anexo(arquivo)
170
+ full_input = f"{texto}{anexo}".strip()
171
+
172
+ if not full_input:
173
+ yield history, [], "ℹ️ Input vazio - digite algo!"
174
+ return
175
+
176
+ # Inicializa pipeline
177
+ history = history + [[full_input, "🧠 Iniciando raciocínio MEHON..."]]
178
+ timeline = [{"role": "user", "content": full_input, "timestamp": datetime.now().isoformat()}]
179
+ logs = f"🚀 MEHON v29 | {datetime.now().strftime('%H:%M:%S')}\n"
180
+
181
+ yield history, timeline, logs
182
+
183
+ # PASSO 1: PLANEJADOR AUTO-GERA plano dinâmico
184
+ history[-1][1] = "🎯 Planejador criando agentes sob medida..."
185
+ yield history, timeline, logs
186
+
187
+ plano, log_plano = gerar_plano_auto(full_input, history)
188
+ if not plano:
189
+ history[-1][1] = f"❌ {log_plano}"
190
+ yield history, timeline, logs
191
+ return
192
+
193
+ logs += f"{log_plano}\n"
194
+ timeline.append({"role": "system", "plano_gerado": plano, "step": "PLANEJAMENTO"})
195
+ yield history, timeline, logs
196
+
197
+ # PASSO 2: EXECUTA plano dinâmico sequencialmente
198
+ resposta_acumulada = ""
199
+ for i, agente in enumerate(plano):
200
+ history[-1][1] = f"⚙️ [{i+1}/{len(plano)}] {agente['nome']} pensando..."
201
+ yield history, timeline, logs
202
+
203
+ resultado, log_add, raw = executar_agente_especifico(timeline, agente, history)
204
+ timeline.append(resultado)
205
+ logs += f" {log_add}\n"
206
+
207
+ # Atualiza chat com output textual
208
+ if agente.get('tipo_saida') == 'texto' and 'content' in resultado:
209
+ resposta_acumulada = resultado['content']
210
+ preview = resposta_acumulada[:900] + "..." if len(resposta_acumulada) > 900 else resposta_acumulada
211
+ history[-1][1] = preview
212
+ yield history, timeline, logs
213
+
214
+ # Finaliza
215
+ logs += f"\n✅ Pipeline MEHON concluído | {len(plano)} agentes | {len(timeline)} passos"
216
+ salvar_history(history) # Auto-save
217
+
218
+ yield history, timeline, logs
219
+
220
+ # ==================== 6. INTERFACE GRADIO COMPLETA ====================
221
+ def criar_app_mehon_v29():
222
+ """UI completa e funcional"""
223
+ css = """
224
+ footer { display: none !important; }
225
+ .gradio-container { max-width: 1400px; }
226
+ .mehon-title { font-size: 1.6em; font-weight: bold; color: #1e40af; text-align: center; }
227
+ .status-bar { background: linear-gradient(90deg, #3b82f6, #1e40af); color: white; padding: 8px; border-radius: 8px; }
228
+ """
229
+
230
+ history_inicial = carregar_history()
231
+
232
+ with gr.Blocks(title="🚀 PIPELINE MEHON v29", css=css, theme=gr.themes.Soft()) as app:
233
+
234
+ # HEADER
235
+ gr.Markdown("### 🧠 PIPELINE MEHON v29 - Raciocínio Estruturado Automático")
236
+ gr.Markdown("*O modelo planeja → executa → converge. Supera respostas probabilísticas diretas.*")
237
+
238
+ with gr.Tabs():
239
+
240
+ # ABA 1: EXECUÇÃO PRINCIPAL
241
+ with gr.Tab("💭 Raciocínio MEHON", icon="🧠"):
242
+ chatbot = gr.Chatbot(
243
+ value=history_inicial,
244
+ height=550,
245
+ show_copy_button=True,
246
+ show_label=False,
247
+ render_markdown=True
248
+ )
249
+
250
+ with gr.Row():
251
+ with gr.Column(scale=8):
252
+ txt_input = gr.Textbox(
253
+ placeholder="""Qualquer pergunta complexa...
254
+ O modelo CRIARÁ seu plano de agentes e executará em cadeia!""",
255
+ lines=4,
256
+ container=False
257
+ )
258
+ with gr.Column(scale=1):
259
+ file_input = gr.File(
260
+ label="📎 Anexo",
261
+ file_types=[".txt", ".py", ".json", ".md", ".yaml", ".csv"]
262
+ )
263
+ with gr.Column(scale=1):
264
+ btn_executar = gr.Button("🚀 EXECUTAR PLANO", variant="primary")
265
+
266
+ status_atual = gr.Markdown("Status: Pronto", visible=True)
267
+
268
+ # ABA 2: DEBUG COMPLETO
269
+ with gr.Tab("🔍 Plano & Execução", icon="🔬"):
270
+ with gr.Row():
271
+ with gr.Column(scale=1):
272
+ gr.Markdown("### 📋 Plano Gerado")
273
+ json_plano = gr.JSON(label="Agentes Dinâmicos", lines=15)
274
+ with gr.Column(scale=1):
275
+ gr.Markdown("### 📊 Timeline Completa")
276
+ timeline_json = gr.JSON(label="Cadeia de Pensamento", lines=15)
277
+
278
+ gr.Markdown("### 📈 Logs de Execução")
279
+ logs_execucao = gr.Textbox(label="Runtime Logs", lines=12)
280
+
281
+ # ABA 3: GERENCIAMENTO
282
+ with gr.Tab("📁 Histórico & Export", icon="💾"):
283
+ gr.Markdown("**Histórico persistente em `history_v29.json`**")
284
+ with gr.Row():
285
+ btn_limpar_chat = gr.Button("🗑️ Limpar Chat", variant="stop")
286
+ btn_export_txt = gr.Button("📥 Download TXT", variant="secondary")
287
+ btn_salvar_manual = gr.Button("💾 Salvar Manual", variant="secondary")
288
+
289
+ export_content = gr.Textbox(label="Conteúdo para Download", lines=20, max_lines=30)
290
+ status_ops = gr.Label("Status: OK", visible=True)
291
+
292
+ # ==================== EVENTOS ====================
293
+ def executar_pipeline_completo(txt, file, hist):
294
+ """Wrapper para generator do pipeline"""
295
+ for resultado in pipeline_mehon_completo(txt, file, hist):
296
+ yield resultado # [chatbot, timeline, logs]
297
+
298
+ # Trigger principal
299
+ btn_executar.click(
300
+ executar_pipeline_completo,
301
+ inputs=[txt_input, file_input, chatbot],
302
+ outputs=[chatbot, timeline_json, logs_execucao]
303
+ ).then(
304
+ lambda: gr.update(value=""),
305
+ outputs=[txt_input]
306
+ )
307
+
308
+ txt_input.submit(
309
+ executar_pipeline_completo,
310
+ inputs=[txt_input, file_input, chatbot],
311
+ outputs=[chatbot, timeline_json, logs_execucao]
312
+ )
313
+
314
+ # Controles
315
+ btn_limpar_chat.click(lambda: [], chatbot)
316
+ btn_export_txt.click(exportar_chat, chatbot, export_content)
317
+ btn_salvar_manual.click(lambda h: salvar_history(h) or "Salvo!", chatbot, status_ops)
318
+
319
+ return app
320
+
321
+ # ==================== LAUNCH ====================
322
+ if __name__ == "__main__":
323
+ print("🚀 Iniciando PIPELINE MEHON v29...")
324
+ print("💡 Configure GOOGLE_API_KEY para uso completo")
325
+ print("📁 History salvo em history_v29.json")
326
+
327
+ app = criar_app_mehon_v29()
328
+ app.launch(
329
+ server_name="0.0.0.0",
330
+ server_port=7861,
331
+ share=False,
332
+ show_error=True,
333
+ quiet=False
334
+ )
335
+