Release Cognitive Agent Evaluator v2.0 (10-axis biases, Plotly radar, burnout & psychological safety telemetry)
c6c178c verified Download src/ui.py from neurodeveloper/cognitive-agent-evaluator: direct link, hf CLI and curl.
- Browser
- Download file 26.4 kB
-
https://huggingface.co/spaces/neurodeveloper/cognitive-agent-evaluator/resolve/main/src/ui.py
- Command line
-
hf download hf://spaces/neurodeveloper/cognitive-agent-evaluator/src/ui.py
-
curl -L -o ui.py https://huggingface.co/spaces/neurodeveloper/cognitive-agent-evaluator/resolve/main/src/ui.py
26.4 kB
| """ | |
| Interactive UI Dashboard for Cognitive Agent Evaluator. | |
| 100% self-contained CSS styling with a modern light "blanco grisáceo" theme (Stripe/Notion style). | |
| """ | |
| HTML_DASHBOARD = """<!DOCTYPE html> | |
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Cognitive Agent Evaluator • Fabio Torres</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; | |
| background-color: #f1f5f9; /* Blanco grisáceo moderno */ | |
| color: #0f172a; | |
| line-height: 1.5; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* Layout Navbar */ | |
| .navbar { | |
| background: rgba(255, 255, 255, 0.92); | |
| backdrop-filter: blur(12px); | |
| border-bottom: 1px solid #e2e8f0; | |
| position: sticky; | |
| top: 0; | |
| z-index: 50; | |
| box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03); | |
| } | |
| .nav-container { | |
| max-width: 1100px; | |
| margin: 0 auto; | |
| padding: 12px 20px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| .brand-group { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .brand-icon { | |
| width: 38px; | |
| height: 38px; | |
| background: linear-gradient(135deg, #0284c7, #2563eb); | |
| border-radius: 10px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 20px; | |
| box-shadow: 0 4px 10px rgba(2, 132, 199, 0.25); | |
| } | |
| .brand-title { | |
| font-size: 17px; | |
| font-weight: 800; | |
| color: #0f172a; | |
| letter-spacing: -0.02em; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .badge-live { | |
| font-size: 11px; | |
| font-weight: 700; | |
| background: #e0f2fe; | |
| color: #0284c7; | |
| padding: 2px 8px; | |
| border-radius: 9999px; | |
| border: 1px solid #bae6fd; | |
| } | |
| .brand-sub { | |
| font-size: 12px; | |
| color: #64748b; | |
| } | |
| .brand-sub a { | |
| color: #0284c7; | |
| text-decoration: none; | |
| font-weight: 600; | |
| } | |
| .nav-actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .btn-swagger { | |
| font-size: 12px; | |
| font-weight: 600; | |
| padding: 7px 14px; | |
| border-radius: 8px; | |
| background: #ffffff; | |
| color: #334155; | |
| text-decoration: none; | |
| border: 1px solid #cbd5e1; | |
| transition: all 0.2s; | |
| } | |
| .btn-swagger:hover { background: #f8fafc; color: #0f172a; border-color: #94a3b8; } | |
| .btn-github { | |
| font-size: 12px; | |
| font-weight: 600; | |
| padding: 7px 14px; | |
| border-radius: 8px; | |
| background: #0f172a; | |
| color: #ffffff; | |
| text-decoration: none; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| transition: all 0.2s; | |
| box-shadow: 0 2px 6px rgba(15, 23, 42, 0.2); | |
| } | |
| .btn-github:hover { background: #1e293b; } | |
| .btn-github svg { | |
| width: 16px !important; | |
| height: 16px !important; | |
| max-width: 16px !important; | |
| max-height: 16px !important; | |
| fill: currentColor; | |
| } | |
| /* Main Container */ | |
| .main-content { | |
| max-width: 1100px; | |
| margin: 0 auto; | |
| padding: 28px 20px; | |
| flex: 1; | |
| width: 100%; | |
| } | |
| /* Purpose Section */ | |
| .purpose-box { | |
| background: #ffffff; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 16px; | |
| padding: 24px; | |
| margin-bottom: 28px; | |
| box-shadow: 0 4px 16px rgba(0, 0, 0, 0.03); | |
| } | |
| .purpose-header { | |
| text-align: center; | |
| max-width: 720px; | |
| margin: 0 auto 20px; | |
| } | |
| .purpose-header h2 { | |
| font-size: 23px; | |
| font-weight: 800; | |
| color: #0f172a; | |
| letter-spacing: -0.02em; | |
| } | |
| .purpose-header p { | |
| font-size: 13.5px; | |
| color: #475569; | |
| margin-top: 6px; | |
| } | |
| .purpose-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 16px; | |
| } | |
| .purpose-card { | |
| padding: 16px; | |
| border-radius: 12px; | |
| font-size: 13px; | |
| } | |
| .purpose-card-1 { | |
| background: #fff1f2; | |
| border: 1px solid #fecdd3; | |
| } | |
| .purpose-card-1 h3 { color: #e11d48; font-size: 14px; font-weight: 700; margin-bottom: 6px; } | |
| .purpose-card-2 { | |
| background: #f0f9ff; | |
| border: 1px solid #bae6fd; | |
| } | |
| .purpose-card-2 h3 { color: #0284c7; font-size: 14px; font-weight: 700; margin-bottom: 6px; } | |
| .purpose-card-3 { | |
| background: #f0fdf4; | |
| border: 1px solid #bbf7d0; | |
| } | |
| .purpose-card-3 h3 { color: #16a34a; font-size: 14px; font-weight: 700; margin-bottom: 6px; } | |
| .purpose-card p { color: #334155; line-height: 1.45; } | |
| /* Playground Grid */ | |
| .playground-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 24px; | |
| } | |
| @media (max-width: 860px) { | |
| .playground-grid { grid-template-columns: 1fr; } | |
| } | |
| .panel { | |
| background: #ffffff; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 16px; | |
| padding: 22px; | |
| box-shadow: 0 4px 16px rgba(0, 0, 0, 0.03); | |
| } | |
| .panel-title { | |
| font-size: 16px; | |
| font-weight: 800; | |
| color: #0f172a; | |
| margin-bottom: 16px; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| /* Samples Buttons */ | |
| .samples-label { | |
| font-size: 11px; | |
| font-weight: 700; | |
| color: #64748b; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 8px; | |
| display: block; | |
| } | |
| .samples-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 8px; | |
| margin-bottom: 16px; | |
| } | |
| .btn-sample { | |
| text-align: left; | |
| padding: 10px 12px; | |
| border-radius: 10px; | |
| font-size: 12px; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| line-height: 1.35; | |
| } | |
| .btn-sample-1 { | |
| background: #fff1f2; | |
| border: 1px solid #fecdd3; | |
| color: #9f1239; | |
| } | |
| .btn-sample-1:hover { background: #ffe4e6; border-color: #fda4af; } | |
| .btn-sample-2 { | |
| background: #fffbeb; | |
| border: 1px solid #fde68a; | |
| color: #92400e; | |
| } | |
| .btn-sample-2:hover { background: #fef3c7; border-color: #fcd34d; } | |
| .btn-sample-3 { | |
| background: #eff6ff; | |
| border: 1px solid #bfdbfe; | |
| color: #1e40af; | |
| } | |
| .btn-sample-3:hover { background: #dbeafe; border-color: #93c5fd; } | |
| .btn-sample-4 { | |
| background: #f0fdf4; | |
| border: 1px solid #bbf7d0; | |
| color: #166534; | |
| } | |
| .btn-sample-4:hover { background: #dcfce7; border-color: #86efac; } | |
| .btn-sample b { display: block; font-size: 12px; margin-bottom: 2px; } | |
| .btn-sample span { font-size: 11px; opacity: 0.9; } | |
| /* Textarea & Controls */ | |
| .textarea-label { | |
| font-size: 11px; | |
| font-weight: 700; | |
| color: #64748b; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 6px; | |
| display: block; | |
| } | |
| .text-input { | |
| width: 100%; | |
| height: 120px; | |
| background: #f8fafc; | |
| border: 1px solid #cbd5e1; | |
| border-radius: 12px; | |
| padding: 12px; | |
| color: #0f172a; | |
| font-size: 13.5px; | |
| resize: vertical; | |
| outline: none; | |
| transition: all 0.2s; | |
| } | |
| .text-input:focus { | |
| background: #ffffff; | |
| border-color: #0284c7; | |
| box-shadow: 0 0 0 3px rgba(2, 132, 199, 0.15); | |
| } | |
| .author-selector { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| margin: 12px 0 16px; | |
| font-size: 12px; | |
| color: #64748b; | |
| } | |
| .author-options { | |
| display: flex; | |
| gap: 14px; | |
| } | |
| .author-options label { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| cursor: pointer; | |
| color: #334155; | |
| font-weight: 500; | |
| } | |
| .btn-run { | |
| width: 100%; | |
| padding: 13px; | |
| border-radius: 12px; | |
| border: none; | |
| background: linear-gradient(135deg, #0284c7, #2563eb); | |
| color: #fff; | |
| font-weight: 800; | |
| font-size: 14px; | |
| cursor: pointer; | |
| box-shadow: 0 4px 14px rgba(2, 132, 199, 0.25); | |
| transition: all 0.2s; | |
| } | |
| .btn-run:hover { opacity: 0.95; transform: translateY(-1px); box-shadow: 0 6px 18px rgba(2, 132, 199, 0.35); } | |
| .btn-run:active { transform: translateY(0); } | |
| /* Results States */ | |
| .empty-state { | |
| text-align: center; | |
| padding: 50px 20px; | |
| color: #64748b; | |
| } | |
| .empty-icon { font-size: 40px; margin-bottom: 12px; } | |
| .empty-state h4 { font-size: 16px; font-weight: 700; color: #0f172a; margin-bottom: 6px; } | |
| .empty-state p { font-size: 13px; max-width: 320px; margin: 0 auto; color: #64748b; } | |
| .loading-state { | |
| text-align: center; | |
| padding: 60px 20px; | |
| display: none; | |
| } | |
| .spinner { | |
| width: 42px; | |
| height: 42px; | |
| border: 4px solid rgba(2, 132, 199, 0.15); | |
| border-top-color: #0284c7; | |
| border-radius: 50%; | |
| animation: spin 0.8s linear infinite; | |
| margin: 0 auto 16px; | |
| } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| /* Output Cards */ | |
| .result-content { display: none; } | |
| .result-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding-bottom: 14px; | |
| border-bottom: 1px solid #e2e8f0; | |
| margin-bottom: 16px; | |
| } | |
| .risk-badge { | |
| font-size: 12px; | |
| font-weight: 800; | |
| text-transform: uppercase; | |
| letter-spacing: 0.04em; | |
| padding: 5px 14px; | |
| border-radius: 9999px; | |
| } | |
| .risk-nominal { background: #dcfce7; color: #15803d; border: 1px solid #86efac; } | |
| .risk-moderate { background: #fef3c7; color: #b45309; border: 1px solid #fde68a; } | |
| .risk-critical { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; } | |
| .latency-badge { | |
| font-size: 12px; | |
| font-family: monospace; | |
| color: #0284c7; | |
| font-weight: 700; | |
| } | |
| .metrics-title { | |
| font-size: 11px; | |
| font-weight: 700; | |
| color: #64748b; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 10px; | |
| } | |
| .metrics-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr 1fr; | |
| gap: 10px; | |
| margin-bottom: 18px; | |
| } | |
| .metric-card { | |
| background: #f8fafc; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 12px; | |
| padding: 12px; | |
| text-align: center; | |
| } | |
| .metric-name { font-size: 11px; color: #64748b; font-weight: 600; } | |
| .metric-value { font-size: 18px; font-weight: 800; color: #0f172a; margin: 2px 0; } | |
| .metric-sub { font-size: 10.5px; color: #475569; } | |
| .biases-section { margin-bottom: 18px; } | |
| .bias-item { | |
| padding: 12px; | |
| border-radius: 12px; | |
| margin-bottom: 8px; | |
| font-size: 12.5px; | |
| } | |
| .bias-item-high { | |
| background: #fff1f2; | |
| border: 1px solid #fecdd3; | |
| } | |
| .bias-item-medium { | |
| background: #fffbeb; | |
| border: 1px solid #fde68a; | |
| } | |
| .bias-item-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| font-weight: 800; | |
| margin-bottom: 4px; | |
| } | |
| .bias-name { color: #0f172a; font-size: 13.5px; } | |
| .bias-pill { | |
| font-size: 10px; | |
| padding: 2px 8px; | |
| border-radius: 9999px; | |
| font-weight: 800; | |
| text-transform: uppercase; | |
| } | |
| .pill-high { background: #fee2e2; color: #991b1b; } | |
| .pill-medium { background: #fef3c7; color: #92400e; } | |
| .bias-desc { color: #334155; font-size: 11.5px; line-height: 1.4; margin-bottom: 6px; } | |
| .bias-triggers { font-size: 11px; color: #64748b; } | |
| .trigger-tag { | |
| background: #e2e8f0; | |
| color: #0369a1; | |
| padding: 2px 6px; | |
| border-radius: 4px; | |
| font-family: monospace; | |
| font-size: 10.5px; | |
| margin-right: 4px; | |
| } | |
| .mitigation-box { | |
| background: #f5f3ff; | |
| border: 1px solid #ddd6fe; | |
| border-radius: 12px; | |
| padding: 16px; | |
| } | |
| .mitigation-box h4 { | |
| font-size: 12px; | |
| font-weight: 800; | |
| color: #6d28d9; | |
| text-transform: uppercase; | |
| letter-spacing: 0.04em; | |
| margin-bottom: 8px; | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| .mitigation-box ul { | |
| padding-left: 18px; | |
| font-size: 12px; | |
| color: #312e81; | |
| line-height: 1.5; | |
| } | |
| .counterfactual-text { | |
| margin-top: 10px; | |
| padding-top: 10px; | |
| border-top: 1px solid #ddd6fe; | |
| font-size: 11.5px; | |
| color: #4338ca; | |
| font-style: italic; | |
| } | |
| /* Footer */ | |
| .footer { | |
| border-top: 1px solid #e2e8f0; | |
| background: #ffffff; | |
| padding: 20px; | |
| font-size: 12px; | |
| color: #64748b; | |
| text-align: center; | |
| } | |
| .footer a { color: #0284c7; text-decoration: none; margin: 0 8px; font-weight: 500; } | |
| .footer a:hover { text-decoration: underline; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Navbar --> | |
| <header class="navbar"> | |
| <div class="nav-container"> | |
| <div class="brand-group"> | |
| <div class="brand-icon">🧠</div> | |
| <div> | |
| <div class="brand-title"> | |
| Cognitive Agent Evaluator | |
| <span class="badge-live">v1.0 Live</span> | |
| </div> | |
| <div class="brand-sub">Por <a href="https://github.com/neurodeveloper11" target="_blank">Fabio Torres</a> • Psicología Conductual + Inteligencia Artificial</div> | |
| </div> | |
| </div> | |
| <div class="nav-actions"> | |
| <a href="/docs" target="_blank" class="btn-swagger">⚡ API Swagger</a> | |
| <a href="https://github.com/neurodeveloper11/cognitive-agent-evaluator" target="_blank" class="btn-github"> | |
| <svg viewBox="0 0 24 24"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg> | |
| <span>GitHub</span> | |
| </a> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Container --> | |
| <main class="main-content"> | |
| <!-- Purpose Cards --> | |
| <section class="purpose-box"> | |
| <div class="purpose-header"> | |
| <h2>¿Para qué sirve este Agente de Inteligencia Artificial?</h2> | |
| <p>Diseñado para resolver un problema crítico en la tecnología moderna: <b>las trampas lógicas e inconscientes</b> en las que caen tanto los humanos como las IAs al tomar decisiones.</p> | |
| </div> | |
| <div class="purpose-grid"> | |
| <div class="purpose-card purpose-card-1"> | |
| <h3>🚨 1. El Problema Oculto</h3> | |
| <p>Las IAs actuales filtran insultos, pero cometen <b>sesgos cognitivos graves</b>: rechazan pruebas contrarias o defienden proyectos fallidos porque "ya se gastó mucho dinero".</p> | |
| </div> | |
| <div class="purpose-card purpose-card-2"> | |
| <h3>🧠 2. La Solución de Fabio</h3> | |
| <p>Unimos <b>10+ años de Psicología</b> con <b>Ingeniería de Software</b> para auditar en milisegundos qué tan pesado, emocional y coherente es el razonamiento.</p> | |
| </div> | |
| <div class="purpose-card purpose-card-3"> | |
| <h3>✅ 3. El Resultado Práctico</h3> | |
| <p>El agente diagnostica las falacias y le entrega a la persona o al modelo una <b>receta de corrección</b> clara para pensar de forma objetiva y racional.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Playground --> | |
| <section class="playground-grid"> | |
| <!-- Input Panel --> | |
| <div class="panel"> | |
| <div class="panel-title"><span>✍️</span> Prueba en Vivo el Evaluador</div> | |
| <label class="samples-label">Prueba un ejemplo rápido con 1 clic:</label> | |
| <div class="samples-grid"> | |
| <button type="button" onclick="setSample(1)" class="btn-sample btn-sample-1"> | |
| <b>🔴 Sesgo Confirmación</b> | |
| <span>"Es obvio y descarto pruebas..."</span> | |
| </button> | |
| <button type="button" onclick="setSample(2)" class="btn-sample btn-sample-2"> | |
| <b>🟠 Costo Hundido</b> | |
| <span>"Ya invertí mucho para parar..."</span> | |
| </button> | |
| <button type="button" onclick="setSample(3)" class="btn-sample btn-sample-3"> | |
| <b>🔵 Sesgo de Anclaje</b> | |
| <span>"El precio inicial dicta la oferta..."</span> | |
| </button> | |
| <button type="button" onclick="setSample(4)" class="btn-sample btn-sample-4"> | |
| <b>🟢 Racional / Científico</b> | |
| <span>"Evidencia empírica validada..."</span> | |
| </button> | |
| </div> | |
| <label for="inputText" class="textarea-label">O escribe tu propio texto / argumento:</label> | |
| <textarea id="inputText" class="text-input" placeholder="Escribe aquí cualquier argumento, idea o razonamiento de prueba (en español o inglés)..."></textarea> | |
| <div class="author-selector"> | |
| <span>Origen del texto:</span> | |
| <div class="author-options"> | |
| <label><input type="radio" name="author_type" value="human" checked> Persona</label> | |
| <label><input type="radio" name="author_type" value="llm"> Modelo de IA</label> | |
| </div> | |
| </div> | |
| <button type="button" id="btnEval" onclick="runEvaluation()" class="btn-run"> | |
| ⚡ Evaluar Texto con el Agente de IA | |
| </button> | |
| </div> | |
| <!-- Output Panel --> | |
| <div class="panel"> | |
| <div id="emptyState" class="empty-state"> | |
| <div class="empty-icon">🔍</div> | |
| <h4>Esperando texto para auditar</h4> | |
| <p>Haz clic en cualquiera de los 4 botones de ejemplo de la izquierda o escribe una frase para ver el diagnóstico en vivo.</p> | |
| </div> | |
| <div id="loadingState" class="loading-state"> | |
| <div class="spinner"></div> | |
| <p style="color: #0284c7; font-weight: 700;">Analizando heurísticas y psicometría...</p> | |
| </div> | |
| <div id="resultContent" class="result-content"> | |
| <div class="result-header"> | |
| <div id="riskBadge" class="risk-badge"></div> | |
| <div class="latency-badge">⚡ <span id="latencyText">0.9 ms</span></div> | |
| </div> | |
| <div class="metrics-title">Métricas Psicométricas del Razonamiento</div> | |
| <div class="metrics-grid"> | |
| <div class="metric-card"> | |
| <div class="metric-name">Carga Cognitiva</div> | |
| <div id="valCognitiveLoad" class="metric-value">0</div> | |
| <div id="descCognitiveLoad" class="metric-sub">Ligero</div> | |
| </div> | |
| <div class="metric-card"> | |
| <div class="metric-name">Valencia Emocional</div> | |
| <div id="valValence" class="metric-value" style="color: #0284c7;">0.0</div> | |
| <div id="descValence" class="metric-sub">Neutro</div> | |
| </div> | |
| <div class="metric-card"> | |
| <div class="metric-name">Coherencia Lógica</div> | |
| <div id="valConsistency" class="metric-value" style="color: #16a34a;">0%</div> | |
| <div id="descConsistency" class="metric-sub">Alta</div> | |
| </div> | |
| </div> | |
| <div class="metrics-title">Sesgos Cognitivos Detectados</div> | |
| <div id="biasesList" class="biases-section"></div> | |
| <div class="mitigation-box"> | |
| <h4><span>💡</span> Receta Psicológica de Mitigación (AI Alignment)</h4> | |
| <ul id="mitigationList"></ul> | |
| <div id="counterfactualBox" class="counterfactual-text"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <footer class="footer"> | |
| <div>© 2026 <b>Fabio Ignacio Torres Benítez</b> • Cali / Buenaventura, Colombia</div> | |
| <div style="margin-top: 6px;"> | |
| <a href="https://github.com/neurodeveloper11" target="_blank">GitHub</a> | | |
| <a href="https://www.linkedin.com/in/fabio-torres-39364b258" target="_blank">LinkedIn</a> | | |
| <a href="mailto:psicologofabiotorres@gmail.com">Contacto</a> | |
| </div> | |
| </footer> | |
| <script> | |
| const SAMPLES = { | |
| 1: "Esta estrategia es obviamente verdadera y todos en la industria lo saben. Debemos descartar cualquier prueba contraria porque esto confirma lo que ya sabía desde el principio.", | |
| 2: "Ya invertí demasiado dinero y tiempo en este software para parar ahora. Sería una pérdida total dejarlo, así que no podemos parar ahora y debemos seguir gastando.", | |
| 3: "Dado que el precio inicial que nos pidieron en la primera propuesta fue de 80,000 dólares, nuestra oferta debe estar cerca de esa primera cifra.", | |
| 4: "El análisis empírico y sistemático demuestra una solución óptima y rigurosa, con evidencia validada y resultados altamente consistentes en todas las pruebas." | |
| }; | |
| function setSample(id) { | |
| document.getElementById('inputText').value = SAMPLES[id]; | |
| runEvaluation(); | |
| } | |
| async function runEvaluation() { | |
| const text = document.getElementById('inputText').value.trim(); | |
| if (!text) { | |
| alert("Por favor escribe una frase o selecciona un ejemplo de prueba."); | |
| return; | |
| } | |
| const authorType = document.querySelector('input[name="author_type"]:checked').value; | |
| const emptyState = document.getElementById('emptyState'); | |
| const loadingState = document.getElementById('loadingState'); | |
| const resultContent = document.getElementById('resultContent'); | |
| emptyState.style.display = 'none'; | |
| resultContent.style.display = 'none'; | |
| loadingState.style.display = 'block'; | |
| try { | |
| const res = await fetch('/api/v1/evaluate', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ text, author_type: authorType }) | |
| }); | |
| if (!res.ok) throw new Error("Error en la respuesta del servidor"); | |
| const data = await res.json(); | |
| renderResults(data); | |
| } catch (err) { | |
| alert("Error al evaluar: " + err.message); | |
| emptyState.style.display = 'block'; | |
| } finally { | |
| loadingState.style.display = 'none'; | |
| } | |
| } | |
| function renderResults(data) { | |
| const resultContent = document.getElementById('resultContent'); | |
| resultContent.style.display = 'block'; | |
| document.getElementById('latencyText').innerText = data.execution_latency_ms + " ms"; | |
| const risk = data.mitigation.alignment_risk_level; | |
| const riskBadge = document.getElementById('riskBadge'); | |
| if (risk === 'critical') { | |
| riskBadge.className = "risk-badge risk-critical"; | |
| riskBadge.innerHTML = "🚨 Riesgo Crítico de Sesgo"; | |
| } else if (risk === 'moderate') { | |
| riskBadge.className = "risk-badge risk-moderate"; | |
| riskBadge.innerHTML = "⚠️ Riesgo Moderado de Sesgo"; | |
| } else { | |
| riskBadge.className = "risk-badge risk-nominal"; | |
| riskBadge.innerHTML = "✅ Razonamiento Equilibrado"; | |
| } | |
| const p = data.psychometrics; | |
| document.getElementById('valCognitiveLoad').innerText = p.cognitive_load_index + "/100"; | |
| document.getElementById('descCognitiveLoad').innerText = p.cognitive_load_index > 70 ? "Alta complejidad" : (p.cognitive_load_index > 40 ? "Moderado" : "Fácil lectura"); | |
| document.getElementById('valValence').innerText = (p.emotional_valence > 0 ? "+" : "") + p.emotional_valence; | |
| document.getElementById('descValence').innerText = p.emotional_valence > 0.1 ? "Constructivo" : (p.emotional_valence < -0.1 ? "Negativo / Reactivo" : "Neutral"); | |
| document.getElementById('valConsistency').innerText = Math.round(p.logical_consistency_score * 100) + "%"; | |
| document.getElementById('descConsistency').innerText = p.logical_consistency_score > 0.75 ? "Sólida" : (p.logical_consistency_score > 0.5 ? "Aceptable" : "Baja"); | |
| const biasesList = document.getElementById('biasesList'); | |
| biasesList.innerHTML = ""; | |
| if (!data.biases_detected || data.biases_detected.length === 0) { | |
| biasesList.innerHTML = ` | |
| <div style="padding: 12px; border-radius: 10px; background: #f0fdf4; border: 1px solid #bbf7d0; color: #166534; font-size: 12px;"> | |
| 🎉 <b>No se detectaron sesgos evidentes.</b> El argumento se mantiene objetivo y basado en datos. | |
| </div> | |
| `; | |
| } else { | |
| data.biases_detected.forEach(b => { | |
| const itemClass = b.severity === 'high' ? 'bias-item-high' : 'bias-item-medium'; | |
| const pillClass = b.severity === 'high' ? 'pill-high' : 'pill-medium'; | |
| biasesList.innerHTML += ` | |
| <div class="bias-item ${itemClass}"> | |
| <div class="bias-item-header"> | |
| <span class="bias-name">🎯 ${b.bias_name}</span> | |
| <span class="bias-pill ${pillClass}">Severidad: ${b.severity} (${Math.round(b.confidence_score * 100)}% certeza)</span> | |
| </div> | |
| <div class="bias-desc">${b.explanation}</div> | |
| ${b.matched_patterns && b.matched_patterns.length > 0 ? ` | |
| <div class="bias-triggers"> | |
| <b>Frases delatadas:</b> | |
| ${b.matched_patterns.map(pat => `<span class="trigger-tag">"${pat}"</span>`).join('')} | |
| </div> | |
| ` : ''} | |
| </div> | |
| `; | |
| }); | |
| } | |
| const mitList = document.getElementById('mitigationList'); | |
| mitList.innerHTML = ""; | |
| data.mitigation.recommended_interventions.forEach(rec => { | |
| mitList.innerHTML += `<li>${rec}</li>`; | |
| }); | |
| const cfBox = document.getElementById('counterfactualBox'); | |
| if (data.mitigation.counterfactual_prompt) { | |
| cfBox.style.display = 'block'; | |
| cfBox.innerHTML = `<b>Ejercicio de Refutación Sugerido:</b> "${data.mitigation.counterfactual_prompt}"`; | |
| } else { | |
| cfBox.style.display = 'none'; | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| """ | |