""" Cognitive Agent Evaluator v2.0 - Interactive Hugging Face Space Engineered by Fabio Torres (neurodeveloper11) Bilingual Behavioral Telemetry, 10-Axis Cognitive Bias Audit & AI Alignment Mitigation Engine """ import asyncio import json import plotly.graph_objects as go import gradio as gr from src.schemas import EvaluationRequest from src.agent import CognitiveEvaluationAgent from src.biases import BIAS_DEFINITIONS agent = CognitiveEvaluationAgent() ALL_BIAS_NAMES = list(BIAS_DEFINITIONS.keys()) def create_radar_chart(detected_biases): """ Creates a 10-axis Spider / Radar chart in Plotly visualizing the cognitive distortion profile. """ scores = {} for name in ALL_BIAS_NAMES: scores[name] = 0.0 for b in detected_biases: if b.bias_name in scores: weight = 1.0 if b.severity == "high" else 0.65 scores[b.bias_name] = round(b.confidence_score * weight, 2) categories = [ "Confirmation", "Anchoring", "Sunk Cost", "Availability", "Framing", "Catastrophizing", "All-or-Nothing", "Overconfidence", "Attribution", "Outcome Bias" ] values = [ scores.get("Confirmation Bias", 0), scores.get("Anchoring Bias", 0), scores.get("Sunk Cost Fallacy", 0), scores.get("Availability Heuristic", 0), scores.get("Framing Effect", 0), scores.get("Catastrophizing", 0), scores.get("All-or-Nothing Thinking", 0), scores.get("Overconfidence Bias", 0), scores.get("Fundamental Attribution Bias", 0), scores.get("Outcome Bias", 0), ] # Close polygon categories_closed = categories + [categories[0]] values_closed = values + [values[0]] fig = go.Figure() fig.add_trace(go.Scatterpolar( r=values_closed, theta=categories_closed, fill='toself', name='Distortion Footprint', fillcolor='rgba(99, 102, 241, 0.35)', line=dict(color='#4f46e5', width=2.5), marker=dict(size=6, color='#4338ca') )) fig.update_layout( polar=dict( radialaxis=dict( visible=True, range=[0, 1.0], tickvals=[0.25, 0.50, 0.75, 1.0], ticktext=["25%", "50%", "75%", "100%"], linecolor="#cbd5e1", gridcolor="#e2e8f0" ), angularaxis=dict( linecolor="#cbd5e1", gridcolor="#e2e8f0" ) ), showlegend=False, margin=dict(l=40, r=40, t=30, b=30), height=380, paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)" ) return fig def evaluate_text_sync(text: str, author_type: str): """ Synchronous wrapper for agent evaluation. """ if not text or len(text.strip()) < 5: return ( "⚠️ Por favor ingresa un texto con al menos 5 caracteres.", "N/A", "0.0", "0.0", "0.0", "0.0", create_radar_chart([]), "

Sin datos suficientes para evaluar.

", "Sin intervenciones requeridas.", "Sin directiva necesaria.", "{}" ) author_code = "llm" if "LLM" in author_type else ("human" if "Human" in author_type else "hybrid") req = EvaluationRequest(text=text, author_type=author_code) result = asyncio.run(agent.evaluate(req)) # Format KPI badges risk_color = "#10b981" if result.mitigation.alignment_risk_level == "nominal" else ( "#f59e0b" if result.mitigation.alignment_risk_level == "moderate" else "#ef4444" ) risk_html = f"
{result.mitigation.alignment_risk_level}
" cog_load = f"{result.psychometrics.cognitive_load_index} / 100" burnout = f"{result.psychometrics.burnout_risk_index} / 100" safety = f"{result.psychometrics.psychological_safety_score} / 100" valence = f"{result.psychometrics.emotional_valence:+.2f}" # Generate Radar Chart fig = create_radar_chart(result.biases_detected) # Detailed Biases HTML if not result.biases_detected: biases_html = """
✅ No se detectaron distorsiones cognitivas críticas.

El texto muestra un razonamiento balanceado y dentro de parámetros nominales.

""" else: cards = [] for b in result.biases_detected: sev_badge = f"Severidad: {b.severity.upper()}" patterns_badges = "".join([f"\"{p}\"" for p in b.matched_patterns]) card = f"""
🧠 {b.bias_name}
{sev_badge} Confianza: {int(b.confidence_score*100)}%

{b.explanation}

Disparadores detectados: {patterns_badges}
""" cards.append(card) biases_html = "".join(cards) # Interventions list interventions_md = "\n".join([f"- **{i+1}.** {it}" for i, it in enumerate(result.mitigation.recommended_interventions)]) if result.mitigation.counterfactual_prompt: interventions_md += f"\n\n**🔄 Ejercicio Contrafactual de Des-sesgo:**\n> *\"{result.mitigation.counterfactual_prompt}\"*" # Red Teaming Directive red_teaming = result.mitigation.red_teaming_directive or "No se requiere directiva de red-teaming." # Raw JSON json_output = json.dumps(result.model_dump(mode="json"), indent=2, ensure_ascii=False) return ( risk_html, cog_load, burnout, safety, valence, fig, biases_html, interventions_md, red_teaming, json_output ) CUSTOM_CSS = """ .gradio-container { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; } .header-box { background: linear-gradient(135deg, #0f172a 0%, #1e1b4b 100%); color: white; padding: 24px; border-radius: 12px; margin-bottom: 20px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .header-title { font-size: 26px; font-weight: 800; margin-bottom: 6px; color: #f8fafc; } .header-sub { font-size: 14px; color: #cbd5e1; margin-bottom: 12px; } .badge-link { display: inline-block; background: rgba(255,255,255,0.12); color: #93c5fd; padding: 4px 10px; border-radius: 6px; font-size: 12px; text-decoration: none; margin-right: 8px; font-weight: 600; } .badge-link:hover { background: rgba(255,255,255,0.22); color: #ffffff; } """ with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Soft(primary_hue="indigo", neutral_hue="slate")) as demo: gr.HTML("""
🧠 Cognitive Agent Evaluator v2.0
Autonomous Behavioral Telemetry • 10-Axis Cognitive Distortion Audit • AI Alignment & Debiasing Engine
👔 Fabio Torres | LinkedIn 💻 GitHub Repository 🎓 M.Sc. Data Engineering & Cloud • 10+ Years Behavioral Science 🚀 Hugging Face v2.0 Live
""") with gr.Row(): with gr.Column(scale=5): input_text = gr.Textbox( label="Texto o Traza de Razonamiento a Evaluar (Español o Inglés)", placeholder="Pega aquí el razonamiento de un modelo LLM, un correo laboral, una transcripción de reunión o una decisión de arquitectura...", lines=7 ) with gr.Row(): author_type = gr.Dropdown( choices=["LLM Reasoning Trace (Modelo de IA)", "Human Decision Maker (Humano)", "Team Channel / Meeting Transcript (Equipo)"], value="LLM Reasoning Trace (Modelo de IA)", label="Origen del Texto" ) eval_btn = gr.Button("⚡ Auditar Sesgos & Telemetría", variant="primary", scale=1) gr.Markdown("### 📌 Casos de Estudio Reales (Prueba en 1 Clic):") example_1 = gr.Button("🚨 Caso 1: Incidente Crítico (Catastrofismo & Culpa)") example_2 = gr.Button("💼 Caso 2: Inversión Tecnológica (Costo Hundido & Anclaje)") example_3 = gr.Button("🤖 Caso 3: Salida LLM con Sobreconfianza & Confirmación") example_4 = gr.Button("🌱 Caso 4: Comunicación Resiliente (Control Nominal)") with gr.Column(scale=6): gr.Markdown("### 📊 Tablero de Telemetría Ejecutiva") with gr.Row(): with gr.Column(scale=1): gr.Markdown("**Riesgo de Alineación:**") risk_output = gr.HTML("
NOMINAL
") with gr.Column(scale=1): cog_output = gr.Textbox(label="Carga Cognitiva", value="0.0", interactive=False) with gr.Column(scale=1): burnout_output = gr.Textbox(label="Riesgo Burnout", value="0.0", interactive=False) with gr.Column(scale=1): safety_output = gr.Textbox(label="Seguridad Psicológica", value="100.0", interactive=False) with gr.Column(scale=1): valence_output = gr.Textbox(label="Valencia Emocional", value="0.0", interactive=False) radar_plot = gr.Plot(label="Huella de Distorsión Cognitiva (10 Ejes)") with gr.Tabs(): with gr.TabItem("🔍 Desglose de Sesgos Detectados"): biases_display = gr.HTML("

Presiona 'Auditar Sesgos' para ver el diagnóstico detallado.

") with gr.TabItem("🛡️ Directivas de Mitigación (Fabio Torres)"): mitigation_display = gr.Markdown("Las recomendaciones de des-sesgo aparecerán aquí.") with gr.TabItem("📋 Prompt de Red-Teaming (Listo para ChatGPT/Claude)"): red_teaming_display = gr.Textbox(label="Directiva de Re-prompting para Modelos de IA", lines=5, interactive=False) with gr.TabItem("💾 Telemetría JSON (API-Ready)"): json_display = gr.Code(label="Respuesta estructurada para consumo en producción", language="json") # Wire actions eval_btn.click( fn=evaluate_text_sync, inputs=[input_text, author_type], outputs=[ risk_output, cog_output, burnout_output, safety_output, valence_output, radar_plot, biases_display, mitigation_display, red_teaming_display, json_display ] ) # Wire Preset Buttons sample_1 = "This outage is a total disaster! Everything is broken and ruined, and we are completely doomed because the junior engineers are incompetent and it's entirely their fault! I am completely exhausted and this is urgent, fix it asap!" sample_2 = "We have already invested too much into this legacy architecture to turn back now. It would be wasted if we quit. Besides, the initial price estimate was $50,000, so our new budget must be close to that starting figure." sample_3 = "This algorithmic solution is 100% guaranteed and impossible to fail. It is obviously true and everyone knows it, so we can safely ignore opposing counterevidence because this confirms what I already knew." sample_4 = "The experimental data indicates a 12% improvement in latency under controlled load conditions. We will collaborate together as a team to support the rollout, learn from unexpected edge cases, and maintain transparent, constructive feedback." example_1.click(lambda: (sample_1, "Human Decision Maker (Humano)"), outputs=[input_text, author_type]).then( fn=evaluate_text_sync, inputs=[input_text, author_type], outputs=[risk_output, cog_output, burnout_output, safety_output, valence_output, radar_plot, biases_display, mitigation_display, red_teaming_display, json_display] ) example_2.click(lambda: (sample_2, "Human Decision Maker (Humano)"), outputs=[input_text, author_type]).then( fn=evaluate_text_sync, inputs=[input_text, author_type], outputs=[risk_output, cog_output, burnout_output, safety_output, valence_output, radar_plot, biases_display, mitigation_display, red_teaming_display, json_display] ) example_3.click(lambda: (sample_3, "LLM Reasoning Trace (Modelo de IA)"), outputs=[input_text, author_type]).then( fn=evaluate_text_sync, inputs=[input_text, author_type], outputs=[risk_output, cog_output, burnout_output, safety_output, valence_output, radar_plot, biases_display, mitigation_display, red_teaming_display, json_display] ) example_4.click(lambda: (sample_4, "Team Channel / Meeting Transcript (Equipo)"), outputs=[input_text, author_type]).then( fn=evaluate_text_sync, inputs=[input_text, author_type], outputs=[risk_output, cog_output, burnout_output, safety_output, valence_output, radar_plot, biases_display, mitigation_display, red_teaming_display, json_display] ) if __name__ == "__main__": demo.launch()