| import gradio as gr |
| from gradio_client import Client, handle_file |
| import pandas as pd |
| import json |
| import tempfile |
| import os |
| from datetime import datetime |
| import plotly.graph_objects as go |
| import plotly.express as px |
| import numpy as np |
| from smolagents import CodeAgent, tool, InferenceClientModel |
| import logging |
|
|
| |
| logging.basicConfig(level=logging.INFO) |
| logger = logging.getLogger(__name__) |
|
|
| |
| try: |
| biotech_client = Client("C2MV/BiotechU4") |
| analysis_client = Client("C2MV/Project-HF-2025") |
| except Exception as e: |
| logger.error(f"No se pudieron inicializar los clientes de Gradio. Verifica las conexiones y los Spaces: {e}") |
| biotech_client = None |
| analysis_client = None |
|
|
| |
| try: |
| hf_engine = InferenceClientModel(model_id="mistralai/Mistral-7B-Instruct-v0.2") |
| except Exception: |
| logger.warning("No se pudo inicializar el modelo de HF. Los agentes usarán lógica simple.") |
| hf_engine = None |
|
|
| |
| |
| |
| class BiotechAgentTools: |
| @tool |
| def analyze_data_characteristics(data_info: str) -> dict: |
| """ |
| Analiza las características de los datos biotecnológicos subidos. |
| Args: |
| data_info (str): Información sobre el archivo de datos incluyendo nombre, tipo y contenido |
| Returns: |
| dict: Diccionario con tipo de experimento, modelos recomendados, parámetros sugeridos y calidad de datos |
| """ |
| try: |
| characteristics = {"experiment_type": "unknown", "recommended_models": [], "suggested_params": {}, "data_quality": "good"} |
| data_lower = data_info.lower() |
| models_from_docs = ['logistic', 'gompertz', 'moser', 'baranyi', 'monod', 'contois', 'andrews', 'tessier', 'richards', 'stannard', 'huang'] |
| growth_models = [m for m in ['logistic', 'gompertz', 'baranyi', 'richards'] if m in models_from_docs] |
| fermentation_models = [m for m in ['monod', 'contois', 'andrews', 'moser'] if m in models_from_docs] |
| if "biomass" in data_lower or "growth" in data_lower: |
| characteristics.update({"experiment_type": "growth_kinetics", "recommended_models": growth_models, "suggested_params": {"component": "biomass", "use_de": True, "maxfev": 75000}}) |
| elif "ferment" in data_lower or "substrate" in data_lower: |
| characteristics.update({"experiment_type": "fermentation", "recommended_models": fermentation_models,"suggested_params": {"component": "all", "use_de": False, "maxfev": 50000}}) |
| else: |
| characteristics.update({"experiment_type": "general_biotech", "recommended_models": growth_models, "suggested_params": {"component": "all", "use_de": False, "maxfev": 50000}}) |
| logger.info(f"Análisis completado: {characteristics['experiment_type']}") |
| return characteristics |
| except Exception as e: |
| logger.error(f"Error en análisis de datos: {str(e)}") |
| return {"experiment_type": "error", "recommended_models": ['logistic', 'gompertz'], "suggested_params": {"component": "all", "use_de": False, "maxfev": 50000}, "data_quality": "unknown"} |
|
|
| @tool |
| def evaluate_analysis_quality(results_info: str) -> dict: |
| """ |
| Evalúa la calidad de los resultados del análisis biotecnológico. |
| Args: |
| results_info (str): Información sobre los resultados del análisis incluyendo métricas y estado |
| Returns: |
| dict: Diccionario con puntuación de calidad, estado satisfactorio, recomendaciones y necesidad de reintento |
| """ |
| try: |
| evaluation = {"quality_score": 0.8, "is_satisfactory": True, "recommendations": [], "needs_retry": False} |
| results_lower = results_info.lower() |
| if "error" in results_lower or "failed" in results_lower: |
| evaluation.update({"quality_score": 0.2, "is_satisfactory": False, "needs_retry": True, "recommendations": ["Retry with different parameters"]}) |
| elif "r2" in results_lower or "rmse" in results_lower: |
| evaluation.update({"quality_score": 0.9, "is_satisfactory": True, "recommendations": ["Results look good"]}) |
| logger.info(f"Evaluación de calidad: {evaluation['quality_score']}") |
| return evaluation |
| except Exception as e: |
| logger.error(f"Error en evaluación: {str(e)}") |
| return {"quality_score": 0.5, "is_satisfactory": True, "recommendations": ["Continue with analysis"], "needs_retry": False} |
|
|
| @tool |
| def prepare_claude_context(data_summary: str) -> str: |
| """ |
| Prepara el contexto específico para el análisis de Claude. |
| Args: |
| data_summary (str): Resumen de los datos analizados incluyendo tipo de experimento y resultados |
| Returns: |
| str: Contexto enriquecido y estructurado para el análisis de Claude |
| """ |
| try: |
| enhanced_context = f"""CONTEXTO BIOTECNOLÓGICO ESPECÍFICO: |
| Datos analizados: {data_summary} |
| Por favor, enfócate en: |
| 1. Interpretación biológica de los parámetros ajustados |
| 2. Comparación de la bondad de ajuste entre modelos |
| 3. Implicaciones prácticas para el proceso biotecnológico |
| 4. Recomendaciones para optimización del proceso |
| 5. Identificación de posibles limitaciones del modelo |
| Incluye análisis estadístico riguroso y recomendaciones prácticas.""" |
| logger.info("Contexto preparado para Claude") |
| return enhanced_context |
| except Exception as e: |
| logger.error(f"Error preparando contexto: {str(e)}") |
| return data_summary |
|
|
| class CoordinatorAgent: |
| def __init__(self): |
| self.agent = CodeAgent(tools=[BiotechAgentTools.analyze_data_characteristics, BiotechAgentTools.evaluate_analysis_quality, BiotechAgentTools.prepare_claude_context], model=hf_engine) if hf_engine else None |
| self.tools = BiotechAgentTools() |
| def analyze_and_optimize(self, file_info: str, current_config: dict) -> dict: |
| try: |
| logger.info("🤖 Agente Coordinador iniciando análisis...") |
| characteristics = self.tools.analyze_data_characteristics(file_info) |
| optimized_config = current_config.copy() |
| if characteristics["experiment_type"] != "error": |
| optimized_config.update({"models": characteristics["recommended_models"], "component": characteristics["suggested_params"]["component"], "use_de": characteristics["suggested_params"]["use_de"], "maxfev": characteristics["suggested_params"]["maxfev"]}) |
| if characteristics["experiment_type"] == "growth_kinetics": |
| optimized_config["additional_specs"] = "Enfócate en el análisis de cinética de crecimiento: interpretación de μmax, lag time, etc." |
| elif characteristics["experiment_type"] == "fermentation": |
| optimized_config["additional_specs"] = "Enfócate en el análisis de fermentación: eficiencia de conversión, productividad, etc." |
| logger.info(f"✅ Configuración optimizada para: {characteristics['experiment_type']}") |
| return {"config": optimized_config, "analysis": characteristics, "recommendations": f"Configuración optimizada para {characteristics['experiment_type']}"} |
| except Exception as e: |
| logger.error(f"❌ Error en Agente Coordinador: {str(e)}") |
| return {"config": current_config, "analysis": {"experiment_type": "error"}, "recommendations": f"Error en optimización: {str(e)}"} |
|
|
| class RecoveryAgent: |
| def __init__(self): |
| self.agent = CodeAgent(tools=[BiotechAgentTools.analyze_data_characteristics], model=hf_engine) if hf_engine else None |
| self.retry_strategies = [{"use_de": False, "maxfev": 25000, "models_subset": 2}, {"use_de": True, "maxfev": 100000, "models_subset": 1}, {"component": "biomass", "use_de": False, "maxfev": 50000}] |
| def attempt_recovery(self, original_config: dict, error_info: str, attempt: int = 0) -> dict: |
| if attempt >= len(self.retry_strategies): |
| return {"success": False, "message": "Todas las estrategias fallaron"} |
| strategy = self.retry_strategies[attempt] |
| recovery_config = original_config.copy() |
| if "models_subset" in strategy: |
| recovery_config["models"] = recovery_config.get("models", ["logistic"])[:strategy["models_subset"]] |
| for key, value in strategy.items(): |
| if key != "models_subset": |
| recovery_config[key] = value |
| logger.info(f"🔧 Aplicando estrategia de recuperación {attempt + 1}") |
| return {"success": True, "config": recovery_config, "strategy": strategy} |
|
|
| class QualityAgent: |
| def __init__(self): |
| self.agent = CodeAgent(tools=[BiotechAgentTools.evaluate_analysis_quality], model=hf_engine) if hf_engine else None |
| self.tools = BiotechAgentTools() |
| def evaluate_results(self, results_summary: str) -> dict: |
| try: |
| evaluation = self.tools.evaluate_analysis_quality(results_summary) |
| quality_feedback = {"quality_score": evaluation["quality_score"], "is_acceptable": evaluation["is_satisfactory"], "feedback": evaluation["recommendations"], "needs_improvement": evaluation["needs_retry"]} |
| logger.info(f"✅ Evaluación de calidad: {quality_feedback['quality_score']:.2f}") |
| return quality_feedback |
| except Exception as e: |
| logger.error(f"❌ Error en evaluación de calidad: {str(e)}") |
| return {"quality_score": 0.7, "is_acceptable": True, "feedback": ["Evaluación completada con advertencias"], "needs_improvement": False} |
|
|
| class ContextAgent: |
| def __init__(self): |
| self.agent = CodeAgent(tools=[BiotechAgentTools.prepare_claude_context], model=hf_engine) if hf_engine else None |
| self.tools = BiotechAgentTools() |
| def enhance_analysis_context(self, data_summary: str, experiment_type: str) -> str: |
| try: |
| enhanced_context = self.tools.prepare_claude_context(f"Tipo de experimento: {experiment_type}. Datos: {data_summary}") |
| logger.info("📊 Contexto mejorado para Claude") |
| return enhanced_context |
| except Exception as e: |
| logger.error(f"❌ Error mejorando contexto: {str(e)}") |
| return data_summary |
|
|
| class BiotechAgentSystem: |
| def __init__(self): |
| self.coordinator = CoordinatorAgent() |
| self.recovery = RecoveryAgent() |
| self.quality = QualityAgent() |
| self.context = ContextAgent() |
| logger.info("🚀 Sistema de agentes inicializado") |
| def process_with_agents(self, file_info: str, user_config: dict) -> dict: |
| try: |
| coordination_result = self.coordinator.analyze_and_optimize(file_info, user_config) |
| optimized_config = coordination_result["config"] |
| experiment_type = coordination_result["analysis"]["experiment_type"] |
| quality_result = self.quality.evaluate_results("Initial configuration optimized") |
| enhanced_specs = self.context.enhance_analysis_context(file_info, experiment_type) |
| optimized_config["additional_specs"] = enhanced_specs |
| return {"success": True, "optimized_config": optimized_config, "experiment_type": experiment_type, "recommendations": coordination_result["recommendations"], "quality_score": quality_result["quality_score"]} |
| except Exception as e: |
| logger.error(f"❌ Error en sistema de agentes: {str(e)}") |
| return {"success": False, "optimized_config": user_config, "experiment_type": "error", "recommendations": f"Error: {str(e)}", "quality_score": 0.5} |
|
|
| |
| |
| |
| agent_system = BiotechAgentSystem() |
|
|
| def process_biotech_data(file, models, component, use_de, maxfev, exp_names): |
| if not biotech_client: |
| return None, None, "Error: El cliente de biotecnología no está inicializado." |
| try: |
| file_path = file.name if hasattr(file, 'name') else file |
| |
| return biotech_client.predict(file=handle_file(file_path), models=models, component=component, use_de=use_de, maxfev=maxfev, exp_names=exp_names, theme=False, api_name="/run_analysis_wrapper") |
| except Exception as e: |
| logger.error(f"Error en proceso biotecnológico: {str(e)}") |
| return None, None, f"Error en el análisis: {str(e)}" |
|
|
| def create_dummy_plot(): |
| fig = go.Figure(go.Scatter(x=[], y=[])) |
| fig.update_layout(title="Esperando resultados...", template="plotly_white", height=500, annotations=[dict(text="Sube un archivo y ejecuta el pipeline para ver los resultados", showarrow=False)]) |
| return fig |
|
|
| |
| def parse_plot_data(plot_info): |
| """Parsea la información de la gráfica recibida de la API.""" |
| if not plot_info: |
| return create_dummy_plot() |
| try: |
| |
| if isinstance(plot_info, dict) and 'plot' in plot_info: |
| plot_json_string = plot_info['plot'] |
| return go.Figure(json.loads(plot_json_string)) |
| |
| if isinstance(plot_info, str): |
| return go.Figure(json.loads(plot_info)) |
| if isinstance(plot_info, dict): |
| return go.Figure(plot_info) |
| except Exception as e: |
| logger.error(f"Error parsing plot: {e}") |
| return create_dummy_plot() |
|
|
| def download_results_as_csv(df_data): |
| if not biotech_client: |
| return None |
| try: |
| |
| return biotech_client.predict(df=df_data, api_name="/download_results_excel") |
| except Exception as e: |
| logger.warning(f"Error con API de descarga: {str(e)}") |
| if df_data and 'data' in df_data and 'headers' in df_data: |
| try: |
| df = pd.DataFrame(df_data['data'], columns=df_data['headers']) |
| with tempfile.NamedTemporaryFile(mode='w+', suffix='.csv', delete=False) as temp_file: |
| df.to_csv(temp_file.name, index=False) |
| return temp_file.name |
| except Exception as e_local: |
| logger.error(f"Error creando CSV local: {e_local}") |
| return None |
|
|
| def generate_claude_report(csv_file_path, model, detail_level, language, additional_specs, use_personal_key, personal_api_key): |
| local_analysis_client = None |
| if use_personal_key and personal_api_key: |
| logger.info("Intentando usar la clave API personal de Claude.") |
| try: |
| local_analysis_client = Client("C2MV/Project-HF-2025", hf_token=personal_api_key) |
| logger.info("Cliente inicializado exitosamente con la clave personal.") |
| except Exception as e: |
| logger.error(f"Fallo al inicializar el cliente con la clave personal: {e}") |
| return f"Error: La clave API personal es inválida o hubo un problema de conexión. Detalles: {e}", "" |
| else: |
| logger.info("Usando la configuración por defecto (secreto) de la API de Claude.") |
| local_analysis_client = analysis_client |
| if not local_analysis_client: |
| return "Error: El cliente de análisis no está disponible.", "" |
| try: |
| |
| return local_analysis_client.predict(files=[handle_file(csv_file_path)], model=model, detail=detail_level, language=language, additional_specs=additional_specs, api_name="/process_and_store") |
| except Exception as e: |
| logger.error(f"Error generando reporte con Claude: {str(e)}") |
| return f"Error en el análisis de Claude: {str(e)}", "" |
|
|
| def export_report(format_type, language): |
| if not analysis_client: |
| return None, "Error: El cliente de análisis no está inicializado para la exportación." |
| try: |
| |
| return analysis_client.predict(format=format_type, language=language, api_name="/handle_export") |
| except Exception as e: |
| logger.error(f"Error en exportación: {str(e)}") |
| return f"Error al exportar: {str(e)}", None |
|
|
| |
| def process_complete_pipeline_with_agents(file, models, component, use_de, maxfev, exp_names, claude_model, detail_level, language, additional_specs, export_format, use_personal_key, personal_api_key, progress=gr.Progress()): |
| progress(0, desc="🚀 Iniciando Pipeline...") |
| if not file: |
| return create_dummy_plot(), None, None, None, None, "❌ Por favor, sube un archivo." |
| if not models: |
| return create_dummy_plot(), None, None, None, None, "❌ Por favor, selecciona al menos un modelo." |
| |
| progress_updates = [] |
| progress(0.1, desc="🤖 Activando sistema de agentes...") |
| file_info = f"Archivo: {os.path.basename(file.name)}, Modelos: {models}" |
| user_config = {"models": models, "component": component, "use_de": use_de, "maxfev": maxfev, "claude_model": claude_model, "detail_level": detail_level, "language": language, "additional_specs": additional_specs, "export_format": export_format} |
| agent_result = agent_system.process_with_agents(file_info, user_config) |
| |
| if agent_result["success"]: |
| optimized_config = agent_result["optimized_config"] |
| progress_updates.extend([f"✅ Agentes detectaron: {agent_result['experiment_type']}", f"🎯 {agent_result['recommendations']}", f"📊 Calidad esperada: {agent_result['quality_score']:.1%}"]) |
| models, component, use_de, maxfev, additional_specs = (optimized_config.get("models", models), optimized_config.get("component", component), optimized_config.get("use_de", use_de), optimized_config.get("maxfev", maxfev), optimized_config.get("additional_specs", additional_specs)) |
| else: |
| progress_updates.append("⚠️ Agentes no pudieron optimizar, usando config original.") |
| |
| progress(0.2, desc="🔄 Procesando datos biotecnológicos...") |
| plot_info, df_data, status = process_biotech_data(file, models, component, use_de, maxfev, exp_names) |
| |
| if not plot_info or not df_data or "Error" in str(status): |
| return create_dummy_plot(), None, None, None, None, "\n".join(progress_updates) + f"\n❌ Error en análisis: {status}" |
| |
| progress_updates.append("✅ Análisis biotecnológico completado") |
| |
| progress(0.4, desc="📥 Descargando resultados...") |
| csv_file_path = download_results_as_csv(df_data) |
| |
| if not csv_file_path: |
| return parse_plot_data(plot_info), df_data, None, None, None, "\n".join(progress_updates) + "\n❌ Error al descargar resultados para análisis." |
| |
| progress_updates.append("✅ Resultados descargados") |
| |
| progress(0.5, desc=f"🤖 Generando análisis con {claude_model}...") |
| analysis, code = generate_claude_report(csv_file_path, claude_model, detail_level, language, additional_specs, use_personal_key, personal_api_key) |
| |
| if os.path.exists(csv_file_path): |
| os.remove(csv_file_path) |
| |
| if "Error" in analysis: |
| return parse_plot_data(plot_info), df_data, analysis, code, None, "\n".join(progress_updates) + f"\n❌ {analysis}" |
| |
| progress_updates.append("✅ Análisis con Claude completado") |
| |
| progress(0.9, desc=f"📄 Exportando informe en {export_format}...") |
| |
| export_status, report_file = export_report(export_format, language) |
| |
| if report_file: |
| progress_updates.append("✅ Informe exportado.") |
| else: |
| progress_updates.append(f"❌ Error al exportar: {export_status}") |
| |
| progress(1, desc="🎉 Pipeline Completado") |
| |
| |
| return parse_plot_data(plot_info), df_data, analysis, code, report_file, "\n".join(progress_updates) |
|
|
| def create_example_videos(): |
| examples_dir = "examples" |
| if not os.path.exists(examples_dir): |
| os.makedirs(examples_dir) |
| video_files = ["video1.mp4", "video2.mp4"] |
| for video_file in video_files: |
| video_path = os.path.join(examples_dir, video_file) |
| if not os.path.exists(video_path): |
| with open(video_path, 'w') as f: |
| f.write("# Video placeholder") |
| logger.info(f"Created placeholder for {video_file}") |
|
|
| |
| |
| |
| BIOTECH_MODELS = ['logistic', 'gompertz', 'moser', 'baranyi', 'monod', 'contois', 'andrews', 'tessier', 'richards', 'stannard', 'huang'] |
| DEFAULT_BIOTECH_SELECTION = [model for model in ['logistic', 'gompertz', 'moser', 'baranyi'] if model in BIOTECH_MODELS] |
| CLAUDE_MODELS = ['claude-opus-4-20250514', 'claude-sonnet-4-20250514', 'claude-3-5-haiku-20241022', 'claude-3-7-sonnet-20250219', 'claude-3-5-sonnet-20241022'] |
| DEFAULT_CLAUDE_MODEL = 'claude-3-5-sonnet-20241022' |
|
|
| theme = gr.themes.Soft(primary_hue="blue", secondary_hue="indigo", neutral_hue="slate") |
| custom_css = ".file-upload { border: 2px dashed #3b82f6; } button.primary { background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); }" |
|
|
| create_example_videos() |
|
|
| with gr.Blocks(theme=theme, title="BioTech Analysis & Report Generator", css=custom_css) as demo: |
| gr.Markdown( |
| """ |
| # 🧬 BioTech Analysis & Report Generator |
| ## **Based on the pipeline: [C2MV/Agent-Biotech](https://huggingface.co/spaces/C2MV/Agent-Biotech)** |
| *An intelligent pipeline that automates the analysis of bioprocess data, from kinetic modeling to generating detailed reports with AI Agents.* |
| """ |
| ) |
| with gr.Accordion("🤖 How the AI Agents Work (Click to Expand)", open=True): |
| gr.Markdown( |
| """ |
| ```text |
| [ 👤 USER INPUT: Data File & Initial Settings ] |
| │ |
| ▼ |
| ┌──────────────────────────────────────────────────────────┐ |
| │ 🤖 Coordinator Agent │ |
| │ • Analyzes experiment type (e.g., kinetics, ferment.). │ |
| │ • Recommends optimal models and parameters. │ |
| └──────────────────────────┬───────────────────────────────┘ |
| │ |
| (If analysis fails) │ (If analysis succeeds) |
| ┌────────────────┘ |
| │ |
| ▼ |
| ┌───────────────────────┐ ┌────────────────────────────┐ |
| │ 🔧 Recovery Agent │ │ 🧐 Quality Agent │ |
| │ • Applies different │ ◀───── │ • Evaluates statistical │ |
| │ strategies to │ (Retry)│ quality (R², etc). │ |
| │ find a solution. │ └────────────┬───────────────┘ |
| └───────────────────────┘ │ |
| │ |
| ▼ |
| ┌────────────────────────────┐ |
| │ ✍️ Context Agent │ |
| │ • Prepares a rich, │ |
| │ detailed prompt for │ |
| │ the final report. │ |
| └────────────┬───────────────┘ |
| │ |
| ▼ |
| [ 📄 FINAL OUTPUT: Report, Visualization & Data ] |
| ``` |
| """ |
| ) |
| with gr.Row(): |
| with gr.Column(): |
| try: |
| video1_path = os.path.join("examples", "video1.mp4") |
| if os.path.exists(video1_path) and os.path.getsize(video1_path) > 100: |
| gr.Video(value=video1_path, label="Example 1: Automated Analysis", interactive=False) |
| else: |
| gr.Markdown("### 🎥 Example 1: Automated Analysis\n*Video placeholder. Add `video1.mp4` to `examples` folder.*") |
| except Exception as e: |
| logger.warning(f"Could not load video1: {e}") |
| gr.Markdown("### 🎥 Example 1: Automated Analysis\n*Video not available.*") |
| with gr.Column(): |
| try: |
| video2_path = os.path.join("examples", "video2.mp4") |
| if os.path.exists(video2_path) and os.path.getsize(video2_path) > 100: |
| gr.Video(value=video2_path, label="Example 2: Report Generation", interactive=False) |
| else: |
| gr.Markdown("### 🎥 Example 2: Report Generation\n*Video placeholder. Add `video2.mp4` to `examples` folder.*") |
| except Exception as e: |
| logger.warning(f"Could not load video2: {e}") |
| gr.Markdown("### 🎥 Example 2: Report Generation\n*Video not available.*") |
|
|
| with gr.Row(): |
| with gr.Column(scale=1): |
| gr.Markdown("## 📊 Configuration") |
| file_input = gr.File(label="📁 Data File (CSV/Excel)", file_types=[".csv", ".xlsx", ".xls"], elem_classes=["file-upload"]) |
| gr.Examples(examples=[os.path.join("examples", "archivo.xlsx")], inputs=[file_input], label="Click an example to run") |
| with gr.Accordion("🔬 Analysis Parameters (AI Optimized)", open=False): |
| models_input = gr.CheckboxGroup(choices=BIOTECH_MODELS, value=DEFAULT_BIOTECH_SELECTION, label="📊 Models") |
| component_input = gr.Dropdown(['all', 'biomass', 'substrate', 'product'], value='all', label="📈 Component") |
| exp_names_input = gr.Textbox(label="🏷️ Experiment Names", value="Biotech Analysis") |
| use_de_input = gr.Checkbox(label="🧮 Use Differential Evolution", value=False) |
| maxfev_input = gr.Number(label="🔄 Max Iterations", value=50000, step=1000) |
| with gr.Group(): |
| claude_model_input = gr.Dropdown(choices=CLAUDE_MODELS, value=DEFAULT_CLAUDE_MODEL, label="🤖 Claude Model") |
| with gr.Accordion("🔑 Personal API Key (Optional)", open=False): |
| use_personal_key_input = gr.Checkbox(label="Use Personal Claude API Key", value=False, info="Check this to use your own API key instead of the default one.") |
| personal_api_key_input = gr.Textbox(label="Personal Claude API Key", type="password", placeholder="Enter your key here (e.g., sk-ant-...)", visible=False) |
| detail_level_input = gr.Radio(['detailed', 'summarized'], value='detailed', label="📋 Detail Level") |
| language_input = gr.Dropdown(['en', 'es', 'fr', 'de', 'pt'], value='es', label="🌐 Language") |
| export_format_input = gr.Radio(['PDF', 'DOCX'], value='PDF', label="📄 Format") |
| additional_specs_input = gr.Textbox(label="📝 Additional Specifications", placeholder="AI Agents will customize this...", lines=3, value="Detailed analysis of models, metrics, and recommendations.") |
| process_btn = gr.Button("🚀 Run Pipeline with AI Agents", variant="primary", size="lg") |
| with gr.Column(scale=2): |
| gr.Markdown("## 📈 Results") |
| status_output = gr.Textbox(label="📊 Process Status (with AI Agents)", lines=5, interactive=False) |
| with gr.Tabs(): |
| with gr.TabItem("📊 Visualization"): |
| plot_output = gr.Plot() |
| with gr.TabItem("📋 Table"): |
| table_output = gr.Dataframe() |
| with gr.TabItem("📝 Analysis"): |
| analysis_output = gr.Markdown() |
| with gr.TabItem("💻 Code"): |
| code_output = gr.Code(language="python") |
| report_output = gr.File(label="📥 Download Report", interactive=False) |
|
|
| def toggle_api_key_visibility(checked): |
| return gr.Textbox(visible=checked) |
|
|
| use_personal_key_input.change(fn=toggle_api_key_visibility, inputs=use_personal_key_input, outputs=personal_api_key_input) |
| |
| process_btn.click( |
| fn=process_complete_pipeline_with_agents, |
| inputs=[ |
| file_input, models_input, component_input, use_de_input, maxfev_input, exp_names_input, |
| claude_model_input, detail_level_input, language_input, additional_specs_input, |
| export_format_input, use_personal_key_input, personal_api_key_input |
| ], |
| outputs=[ |
| plot_output, table_output, analysis_output, code_output, report_output, status_output |
| ] |
| ) |
|
|
| if __name__ == "__main__": |
| if not os.path.exists("examples"): |
| os.makedirs("examples") |
| print("Carpeta 'examples' creada. Por favor, añade 'video1.mp4', 'video2.mp4', y 'archivo.xlsx' dentro.") |
| demo.launch(show_error=True) |