# ╔════════════════════════════════════════════════════════════════════════════╗ # ║ PIPELINE v29: PLANEJADOR AUTO-AGENTE | SUPERA PARADOXO MEHON ║ # ║ 1º: PLANEJA → 2º-N: EXECUTA → N+1: CONVERGE COM HISTÓRICO ║ # ╚════════════════════════════════════════════════════════════════════════════╝ import os import json import re import time from datetime import datetime import gradio as gr import google.generativeai as genai # ==================== 1. CONFIGURAÇÃO GLOBAL ==================== api_key = os.getenv("GOOGLE_API_KEY") if api_key: genai.configure(api_key=api_key) model_flash = genai.GenerativeModel("gemini-flash-latest") model_pro = genai.GenerativeModel("gemini-pro-latest") else: model_flash = model_pro = None print("⚠️ GOOGLE_API_KEY não encontrada. Configure via export GOOGLE_API_KEY=...") ARQUIVO_HISTORY = "history_v29.json" # ==================== 2. UTILIDADES DE PERSISTÊNCIA ==================== def carregar_history(): """Carrega histórico persistente""" try: with open(ARQUIVO_HISTORY, "r", encoding="utf-8") as f: return json.load(f) except: return [] def salvar_history(history): """Salva histórico automaticamente""" try: with open(ARQUIVO_HISTORY, "w", encoding="utf-8") as f: json.dump(history, f, ensure_ascii=False, indent=2) return True except: return False def ler_anexo(arquivo): """Processa arquivos anexados""" if not arquivo: return "" try: with open(arquivo.name, "r", encoding="utf-8") as f: nome = os.path.basename(arquivo.name) return f"\n\n📎 ANEXO: {nome}\n{f.read()}\n[FIM ANEXO]\n" except: return "❌ Erro lendo anexo" def exportar_chat(history): """Gera TXT para download""" if not history: return "" timestamp = datetime.now().strftime('%Y-%m-%d_%H%M%S') chat_txt = f"MEHON v29 EXPORT - {timestamp}\n\n" for i, msg in enumerate(history, 1): role = "👤 USUÁRIO" if i % 2 == 1 else "🤖 MEHON" chat_txt += f"{role}:\n{msg}\n\n{'-'*80}\n\n" return chat_txt # ==================== 3. AGENTE PLANEJADOR (SUPERA MEHON) ==================== def gerar_plano_auto(input_completo, history_contexto): """AGENTE 1: CRIA PLANO DINÂMICO baseando-se em histórico + input""" if not model_pro: return None, "❌ Sem API_KEY" # Compacta histórico (últimas 5 trocas, 200 chars cada) history_resumo = "" if len(history_contexto) >= 2: history_resumo = "\n".join([ f"👤: {h[0][:200]}... | 🤖: {h[1][:200]}..." for h in history_contexto[-5:] ]) prompt_planejador = f"""🚀 PLANEJADOR AUTO-AGENTE v29 - SUPERA PARADOXO MEHON CONTEXTO HISTÓRICO DO USUÁRIO: {history_resumo} INPUT ATUAL: {input_completo} --- CRIE PLANO ESTRUTURADO DE 3-6 AGENTES para resolver PERFEITAMENTE: 📋 FORMATO OBRIGATÓRIO (JSON VÁLIDO): [ {{"nome": "NomeClaro", "missao": "InstruçãoPrecisade200palavras", "modelo": "flash", "tipo_saida": "texto"}}, ... ] ✅ CRITÉRIOS DO PLANO: • DECOMPONHA: problema → análise → cenários → validação → síntese • IDENTIFIQUE ambiguidades/possibilidades do input • PERSONALIZE com histórico do usuário • ÚLTIMO agente SEMPRE gera saída FINAL pro usuário • Evite resposta direta - USE CADEIA DE PENSAMENTO EXEMPLO PLANO BOM: [ {{"nome": "AnalisadorInput", "missao": "Identifique elementos principais, ambiguidades e contexto", "modelo": "flash", "tipo_saida": "json"}}, {{"nome": "ExploradorCenários", "missao": "Liste 3-5 cenários possíveis com probabilidades", "modelo": "pro", "tipo_saida": "json"}}, {{"nome": "SintetizadorFinal", "missao": "Converja tudo em resposta única e acionável", "modelo": "pro", "tipo_saida": "texto"}} ] APENAS JSON VÁLIDO - SEM TEXTO EXTRA!""" try: resp = model_pro.generate_content(prompt_planejador, temperature=0.3) plano_raw = resp.text.strip().replace('``````','').replace('json','') plano = json.loads(plano_raw) # Valida estrutura mínima if not isinstance(plano, list) or len(plano) < 2: return None, "❌ Plano inválido (precisa 2+ agentes)" return plano, f"✅ Plano: {len(plano)} agentes gerados" except Exception as e: return None, f"❌ Erro plano: {str(e)[:100]}" # ==================== 4. EXECUTOR DE AGENTES DINÂMICOS ==================== def executar_agente_especifico(timeline, agente_config, history_contexto): """Executa agente específico do plano dinâmico""" if not (model_flash or model_pro): return {"role": "system", "error": "Sem API"}, "(ERRO: API)", "Sem Google API Key" modelo = model_pro if agente_config.get("modelo") == "pro" else model_flash # Contexto: últimos 8 passos da timeline + histórico contexto_timeline = json.dumps(timeline[-8:], ensure_ascii=False, indent=2) history_resumo = "\n".join([f"👤: {h[0][:100]}... | 🤖: {h[1][:100]}..." for h in history_contexto[-3:]]) prompt = f"""CONTEXTO DA CADEIA DE PENSAMENTO: {contexto_timeline} HISTÓRICO RECENTE: {history_resumo} AGENTE ATIVO: {agente_config['nome']} MISSÃO ESPECÍFICA: {agente_config['missao']} { 'JSON estruturado e válido' if agente_config['tipo_saida']=='json' else 'Resposta clara, completa e finalizada pro usuário' }:""" log = f"🔸 {agente_config['nome']} ({agente_config['modelo']})" try: inicio = time.time() resp = modelo.generate_content(prompt, temperature=0.1 if agente_config['tipo_saida']=='json' else 0.7) out = resp.text.strip() # Parse output content = json.loads(out.replace('``````','')) if agente_config['tipo_saida']=='json' else out tempo = time.time() - inicio log += f" ✓ {tempo:.1f}s" return {"role": "assistant", "agent": agente_config['nome'], "content": content}, log, out except Exception as e: log += f" ✗ {str(e)[:50]}" return {"role": "system", "error": str(e)}, log, str(e) # ==================== 5. ORQUESTRADOR PRINCIPAL (MEHON) ==================== def pipeline_mehon_completo(texto, arquivo, history): """Pipeline completo: PLANEJA → EXECUTA → CONVERGE""" # Processa input anexo = ler_anexo(arquivo) full_input = f"{texto}{anexo}".strip() if not full_input: yield history, [], "ℹ️ Input vazio - digite algo!" return # Inicializa pipeline history = history + [[full_input, "🧠 Iniciando raciocínio MEHON..."]] timeline = [{"role": "user", "content": full_input, "timestamp": datetime.now().isoformat()}] logs = f"🚀 MEHON v29 | {datetime.now().strftime('%H:%M:%S')}\n" yield history, timeline, logs # PASSO 1: PLANEJADOR AUTO-GERA plano dinâmico history[-1][1] = "🎯 Planejador criando agentes sob medida..." yield history, timeline, logs plano, log_plano = gerar_plano_auto(full_input, history) if not plano: history[-1][1] = f"❌ {log_plano}" yield history, timeline, logs return logs += f"{log_plano}\n" timeline.append({"role": "system", "plano_gerado": plano, "step": "PLANEJAMENTO"}) yield history, timeline, logs # PASSO 2: EXECUTA plano dinâmico sequencialmente resposta_acumulada = "" for i, agente in enumerate(plano): history[-1][1] = f"⚙️ [{i+1}/{len(plano)}] {agente['nome']} pensando..." yield history, timeline, logs resultado, log_add, raw = executar_agente_especifico(timeline, agente, history) timeline.append(resultado) logs += f" {log_add}\n" # Atualiza chat com output textual if agente.get('tipo_saida') == 'texto' and 'content' in resultado: resposta_acumulada = resultado['content'] preview = resposta_acumulada[:900] + "..." if len(resposta_acumulada) > 900 else resposta_acumulada history[-1][1] = preview yield history, timeline, logs # Finaliza logs += f"\n✅ Pipeline MEHON concluído | {len(plano)} agentes | {len(timeline)} passos" salvar_history(history) # Auto-save yield history, timeline, logs # ==================== 6. INTERFACE GRADIO COMPLETA ==================== def criar_app_mehon_v29(): """UI completa e funcional""" css = """ footer { display: none !important; } .gradio-container { max-width: 1400px; } .mehon-title { font-size: 1.6em; font-weight: bold; color: #1e40af; text-align: center; } .status-bar { background: linear-gradient(90deg, #3b82f6, #1e40af); color: white; padding: 8px; border-radius: 8px; } """ history_inicial = carregar_history() with gr.Blocks(title="🚀 PIPELINE MEHON v29", css=css, theme=gr.themes.Soft()) as app: # HEADER gr.Markdown("### 🧠 PIPELINE MEHON v29 - Raciocínio Estruturado Automático") gr.Markdown("*O modelo planeja → executa → converge. Supera respostas probabilísticas diretas.*") with gr.Tabs(): # ABA 1: EXECUÇÃO PRINCIPAL with gr.Tab("💭 Raciocínio MEHON", icon="🧠"): chatbot = gr.Chatbot( value=history_inicial, height=550, show_copy_button=True, show_label=False, render_markdown=True ) with gr.Row(): with gr.Column(scale=8): txt_input = gr.Textbox( placeholder="""Qualquer pergunta complexa... O modelo CRIARÁ seu plano de agentes e executará em cadeia!""", lines=4, container=False ) with gr.Column(scale=1): file_input = gr.File( label="📎 Anexo", file_types=[".txt", ".py", ".json", ".md", ".yaml", ".csv"] ) with gr.Column(scale=1): btn_executar = gr.Button("🚀 EXECUTAR PLANO", variant="primary") status_atual = gr.Markdown("Status: Pronto", visible=True) # ABA 2: DEBUG COMPLETO with gr.Tab("🔍 Plano & Execução", icon="🔬"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 📋 Plano Gerado") json_plano = gr.JSON(label="Agentes Dinâmicos", lines=15) with gr.Column(scale=1): gr.Markdown("### 📊 Timeline Completa") timeline_json = gr.JSON(label="Cadeia de Pensamento", lines=15) gr.Markdown("### 📈 Logs de Execução") logs_execucao = gr.Textbox(label="Runtime Logs", lines=12) # ABA 3: GERENCIAMENTO with gr.Tab("📁 Histórico & Export", icon="💾"): gr.Markdown("**Histórico persistente em `history_v29.json`**") with gr.Row(): btn_limpar_chat = gr.Button("🗑️ Limpar Chat", variant="stop") btn_export_txt = gr.Button("📥 Download TXT", variant="secondary") btn_salvar_manual = gr.Button("💾 Salvar Manual", variant="secondary") export_content = gr.Textbox(label="Conteúdo para Download", lines=20, max_lines=30) status_ops = gr.Label("Status: OK", visible=True) # ==================== EVENTOS ==================== def executar_pipeline_completo(txt, file, hist): """Wrapper para generator do pipeline""" for resultado in pipeline_mehon_completo(txt, file, hist): yield resultado # [chatbot, timeline, logs] # Trigger principal btn_executar.click( executar_pipeline_completo, inputs=[txt_input, file_input, chatbot], outputs=[chatbot, timeline_json, logs_execucao] ).then( lambda: gr.update(value=""), outputs=[txt_input] ) txt_input.submit( executar_pipeline_completo, inputs=[txt_input, file_input, chatbot], outputs=[chatbot, timeline_json, logs_execucao] ) # Controles btn_limpar_chat.click(lambda: [], chatbot) btn_export_txt.click(exportar_chat, chatbot, export_content) btn_salvar_manual.click(lambda h: salvar_history(h) or "Salvo!", chatbot, status_ops) return app # ==================== LAUNCH ==================== if __name__ == "__main__": print("🚀 Iniciando PIPELINE MEHON v29...") print("💡 Configure GOOGLE_API_KEY para uso completo") print("📁 History salvo em history_v29.json") app = criar_app_mehon_v29() app.launch( server_name="0.0.0.0", server_port=7861, share=False, show_error=True, quiet=False )