# app.py # # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos # # Versão 8.0.0 (Live Writer's Room UI) import gradio as gr import yaml import logging import os import sys import shutil import time from typing import Dict, Any, Generator # --- 1. IMPORTAÇÃO DO FRAMEWORK E CONFIGURAÇÃO --- import aduc_framework from aduc_framework.types import PreProductionParams, ProductionParams # Configuração de Tema Cinemático cinematic_theme = gr.themes.Base( primary_hue=gr.themes.colors.indigo, secondary_hue=gr.themes.colors.purple, neutral_hue=gr.themes.colors.slate, font=(gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"), ).set( body_background_fill="#111827", body_text_color="#E5E7EB", button_primary_background_fill="linear-gradient(90deg, #4F46E5, #8B5CF6)", button_primary_text_color="#FFFFFF", button_secondary_background_fill="#374151", button_secondary_border_color="#4B5563", button_secondary_text_color="#E5E7EB", block_background_fill="#1F2937", block_border_width="1px", block_border_color="#374151", block_label_background_fill="#374151", block_label_text_color="#E5E7EB", block_title_text_color="#FFFFFF", input_background_fill="#374151", input_border_color="#4B5563", input_placeholder_color="#9CA3AF", ) # Configuração de Logging LOG_FILE_PATH = "aduc_log.txt" if os.path.exists(LOG_FILE_PATH): os.remove(LOG_FILE_PATH) log_format = '%(asctime)s - %(levelname)s - [%(name)s:%(funcName)s] - %(message)s' root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) # Mude para DEBUG para ver todos os logs detalhados root_logger.handlers.clear() stream_handler = logging.StreamHandler(sys.stdout) stream_handler.setFormatter(logging.Formatter(log_format)) root_logger.addHandler(stream_handler) file_handler = logging.FileHandler(LOG_FILE_PATH, mode='w', encoding='utf-8') file_handler.setFormatter(logging.Formatter(log_format)) root_logger.addHandler(file_handler) logger = logging.getLogger(__name__) # Inicialização do Aduc Framework try: with open("config.yaml", 'r') as f: config = yaml.safe_load(f) WORKSPACE_DIR = config['application']['workspace_dir'] aduc = aduc_framework.create_aduc_instance(workspace_dir=WORKSPACE_DIR) logger.info("Interface Gradio inicializada e conectada ao Aduc Framework.") except Exception as e: logger.critical(f"ERRO CRÍTICO durante a inicialização: {e}", exc_info=True) with gr.Blocks(theme=cinematic_theme) as demo: gr.Markdown("# ERRO CRÍTICO NA INICIALIZAÇÃO") gr.Markdown("Não foi possível iniciar o Aduc Framework. Verifique os logs (`aduc_log.txt`) para mais detalhes.") gr.Textbox(value=str(e), label="Detalhes do Erro", lines=10) demo.launch() exit() # --- 2. FUNÇÕES WRAPPER (UI <-> FRAMEWORK) --- def run_pre_production_wrapper(prompt, num_scenes, ref_files, resolution_str, fast_mode, progress=gr.Progress(track_tqdm=True)): """ Wrapper reativo que alimenta a UI "Writer's Room". """ chat_history = [] # Mensagem de abertura chat_history.append(("Maestro ADUC", f"Equipe, bom dia. Temos um novo projeto. A visão do cliente é: '{prompt}'")) yield {writers_room_chatbot: chat_history, dna_display: None} # Limpa o DNA Display time.sleep(1) # Pausa para leitura if not ref_files: raise gr.Error("Por favor, forneça pelo menos uma imagem de referência.") target_resolution = int(resolution_str.split('x')[0]) ref_paths = [aduc.process_image_for_story(f.name, target_resolution, f"ref_processed_{i}.png") for i, f in enumerate(ref_files)] params = { "prompt": prompt, "num_scenes": int(num_scenes), "ref_paths": ref_paths, "duration_per_fragment": 4.0, # Fixo por enquanto "resolution": target_resolution, "fast_mode": fast_mode } final_dna = {} for update in aduc.task_pre_production_v2(params, progress_callback=progress): if update.get("log_type") == "conversation": chat_history.append((update.get("actor"), update.get("message"))) else: status = update.get("status", "unknown") message = update.get("message", "...") actor_map = { "planning": "Planner2D", "planning_complete": "Planner2D", "progress": "Composer", "complete": "Maestro ADUC", "error": "Maestro ADUC" } actor = actor_map.get(status, "Sistema") chat_history.append((actor, message)) yield { writers_room_chatbot: chat_history, dna_display: update.get("dna_snapshot", gr.skip()), } if status == "error": raise gr.Error(f"Ocorreu um erro no backend: {message}") if status == "complete": final_dna = update.get("dna") # Habilita os próximos passos yield { production_accordion: gr.update(visible=True, open=True) } # Salva o DNA final no state holder yield { generation_state_holder: final_dna } # --- 3. DEFINIÇÃO DA UI --- with gr.Blocks(theme=cinematic_theme, css="style.css") as demo: generation_state_holder = gr.State(value={}) gr.Markdown("

ADUC-SDR 🎬 - A Sala de Roteiristas de IA

") gr.Markdown("Observe em tempo real a equipe de IAs especialistas colaborar para criar seu filme.") with gr.Row(): with gr.Column(scale=2): writers_room_chatbot = gr.Chatbot( label="Transcrição da Sala de Operações", bubble_full_width=False, avatar_images={ "Maestro ADUC": "https://img.icons8.com/ios-filled/50/FFFFFF/magician.png", "Planner2D": "https://img.icons8.com/ios-filled/50/FFFFFF/architect.png", "Composer": "https://img.icons8.com/ios-filled/50/FFFFFF/supervisor.png", "Llama (IA Criativa)": "https://img.icons8.com/ios-filled/50/FFFFFF/robot-2.png", "Sistema": "https://img.icons8.com/ios-filled/50/FFFFFF/gears.png" }, height=700 ) with gr.Column(scale=1): with gr.Accordion("🧬 DNA da Produção (Ao Vivo)", open=True): dna_display = gr.JSON(label="DNA em Construção") with gr.Accordion("🎞️ Resultado Final", open=True): final_video_output = gr.Video(label="Filme Concluído", interactive=False) with gr.Accordion("📋 Briefing do Projeto (Sua Entrada)", open=True): prompt_input = gr.Textbox(label="Ideia Geral do Filme", value="Um leão majestoso caminha pela savana e ruge para o sol poente.") with gr.Row(): resolution_selector = gr.Radio(["512x512", "768x768"], value="512x512", label="Resolução Base") num_scenes_slider = gr.Slider(minimum=2, maximum=5, value=3, step=1, label="Número de Cenas") ref_image_input = gr.File(label="Imagens de Referência", file_count="multiple", file_types=["image"]) fast_mode_checkbox = gr.Checkbox(label="Modo Rápido (Planejamento em etapa única)", value=False) start_button = gr.Button("🎬 Enviar Briefing para a Equipe de IA", variant="primary") # Etapas 2 e 3 (ainda não conectadas, aguardando o fluxo completo) with gr.Accordion("Etapa 2 & 3: Produção e Pós-Produção", open=False, visible=False) as production_accordion: gr.Markdown("Após a pré-produção, os controles para gerar o vídeo final aparecerão aqui.") # ... (Poderíamos adicionar os sliders de produção aqui) # --- 4. CONEXÕES DE EVENTOS --- start_button.click( fn=run_pre_production_wrapper, inputs=[prompt_input, num_scenes_slider, ref_image_input, resolution_selector, fast_mode_checkbox], outputs=[writers_room_chatbot, dna_display, generation_state_holder, production_accordion] ) # --- 5. INICIALIZAÇÃO DA APLICAÇÃO --- if __name__ == "__main__": if os.path.exists(WORKSPACE_DIR): shutil.rmtree(WORKSPACE_DIR) os.makedirs(WORKSPACE_DIR) logger.info("Aplicação Gradio iniciada. Lançando interface...") demo.queue().launch()