# 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("