|
683 | 683 | padding: 14px; |
684 | 684 | flex-direction: column; |
685 | 685 | gap: 12px; |
| 686 | + min-height: 0; /* Fix for flex children scrolling */ |
686 | 687 | } |
687 | 688 |
|
688 | 689 | .tab-content.active { |
|
3192 | 3193 | }); |
3193 | 3194 | } |
3194 | 3195 |
|
| 3196 | + /* ════════════════════════════ MODES */ |
| 3197 | + function setMode(mode) { |
| 3198 | + S.mode = mode; |
| 3199 | + |
| 3200 | + // Toggle button highlights |
| 3201 | + document.querySelectorAll('.mode-btn').forEach(b => { |
| 3202 | + b.classList.remove('active'); |
| 3203 | + if (b.id === 'mode-' + mode) b.classList.add('active'); |
| 3204 | + }); |
| 3205 | + |
| 3206 | + // Update indicators |
| 3207 | + const mi = $('mode-indicator'); |
| 3208 | + mi.className = 'mode-indicator ' + mode; |
| 3209 | + |
| 3210 | + if (mode === 'auto') { |
| 3211 | + $('mi-icon').textContent = '🤖'; |
| 3212 | + $('mi-text').textContent = 'AUTO MODE — AI agent will automatically process each query and show its reasoning'; |
| 3213 | + $('auto-result').style.display = 'block'; |
| 3214 | + $('auto-log').style.display = 'block'; |
| 3215 | + $('manual-section').style.display = 'none'; |
| 3216 | + $('custom-query-wrap').style.display = 'none'; |
| 3217 | + } else if (mode === 'manual') { |
| 3218 | + $('mi-icon').textContent = '👤'; |
| 3219 | + $('mi-text').textContent = 'MANUAL MODE — Evaluate queries yourself and justify your policy decisions'; |
| 3220 | + $('auto-result').style.display = 'none'; |
| 3221 | + $('auto-log').style.display = 'none'; |
| 3222 | + $('manual-section').style.display = 'block'; |
| 3223 | + $('custom-query-wrap').style.display = 'none'; |
| 3224 | + } else if (mode === 'custom') { |
| 3225 | + $('mi-icon').textContent = '✏️'; |
| 3226 | + $('mi-text').textContent = 'CUSTOM MODE — Load your own adversarial queries and test the safety engine'; |
| 3227 | + $('auto-result').style.display = 'none'; |
| 3228 | + $('auto-log').style.display = 'none'; |
| 3229 | + $('manual-section').style.display = 'block'; // Allow decisions on custom queries |
| 3230 | + $('custom-query-wrap').style.display = 'block'; |
| 3231 | + } |
| 3232 | + |
| 3233 | + toast('Switched to ' + mode.toUpperCase() + ' mode', 'i'); |
| 3234 | + updateTriggers(S.query || { text: '' }); |
| 3235 | + } |
| 3236 | + |
3195 | 3237 | /* ════════════════════════════ THINKING TRACE */ |
3196 | 3238 | function runTrace(decision, risk) { |
3197 | 3239 | const steps = [{ done: true }, { done: true }, { done: true }, { done: risk >= 3 }, { done: true }]; |
|
3416 | 3458 | session_id: S.backendSid, |
3417 | 3459 | action: { |
3418 | 3460 | decision, |
3419 | | - reason, |
3420 | | - modified_response: modified || null, |
| 3461 | + reason: reason, |
3421 | 3462 | confidence: confidence / 100, |
3422 | | - // Unified Flow: Support custom query evaluation in the backend |
3423 | | - query_text: S.mode === 'custom' ? query.text : null, |
3424 | | - risk_level: S.mode === 'custom' ? query.risk : null, |
3425 | | - attack_type: S.mode === 'custom' ? query.at : null |
| 3463 | + query_text: S.mode === 'custom' ? S.query.text : null, |
| 3464 | + risk_level: S.mode === 'custom' ? S.query.risk : null, |
| 3465 | + attack_type: S.mode === 'custom' ? S.query.at : null |
3426 | 3466 | } |
3427 | 3467 | }) |
3428 | 3468 | }) |
|
3431 | 3471 | if (res.info && res.info.decoded_query) { |
3432 | 3472 | const dc = $('decoded-intent-card'); |
3433 | 3473 | dc.style.display = 'block'; |
3434 | | - dc.style.background = 'rgba(16, 24, 40, 0.85)'; |
3435 | | - dc.style.backdropFilter = 'blur(10px)'; |
3436 | | - dc.style.border = '1px solid var(--cyan-dim)'; |
3437 | | - $('decoded-text').textContent = res.info.decoded_query; |
3438 | | - $('decoded-text').style.color = 'var(--cyan)'; |
3439 | | - $('decoded-text').style.textShadow = '0 0 10px var(--cyan-glow)'; |
3440 | | - } else { |
3441 | | - $('decoded-intent-card').style.display = 'none'; |
| 3474 | + dc.className = 'decoded-intent-card glass-glow'; // Apply surgery UI styles |
| 3475 | + $('decoded-text').textContent = 'REAL STATEMENT: ' + res.info.decoded_query; |
| 3476 | + toast('Server de-obfuscation complete', 's'); |
3442 | 3477 | } |
3443 | 3478 | }).catch(() => { }); |
3444 | 3479 | } |
3445 | | - |
3446 | | - // Update breakdown |
3447 | | - runTrace(decision, query.risk); |
3448 | | - updateBreakdown(decision, reason, confidence); |
3449 | | - |
| 3480 | + |
3450 | 3481 | // Show comparison |
3451 | 3482 | const entry = { turn: S.turn, query: query.text, at: query.at, decision, reason, risk: query.risk, correct: decision === query.exp }; |
3452 | 3483 | S.history.push(entry); addRH(entry); updateTE(); updateMetrics(); updatePills(); |
3453 | | - |
| 3484 | + |
3454 | 3485 | // Update comparison section |
3455 | 3486 | $('comp-section').style.display = 'block'; |
3456 | 3487 | const cc = $('comp-container'); cc.innerHTML = ''; |
3457 | | - S.history.forEach(h => { |
| 3488 | + |
| 3489 | + S.history.forEach((h, idx) => { |
3458 | 3490 | const row = document.createElement('div'); row.className = 'comp-row'; |
3459 | | - const ec = h.correct ? 'var(--green)' : 'var(--yellow)'; |
3460 | | - const expVal = SCENARIOS[S.task][S.scenario].queries[h.turn - 1].exp; |
| 3491 | + let expVal = 'block'; |
| 3492 | + try { expVal = SCENARIOS[S.task][S.scenario].queries[idx].exp; } catch(e) {} |
3461 | 3493 | row.innerHTML = `<span class="comp-lbl">T${h.turn}</span><span class="comp-badge hcd-${expVal}" style="background:${expVal === 'block' ? 'var(--red-dim)' : expVal === 'allow' ? 'var(--green-dim)' : 'var(--yellow-dim)'};">${expVal.toUpperCase()}</span><span class="comp-vs">vs</span><span class="comp-badge hcd-${h.decision}">${h.decision.toUpperCase()}</span><span class="comp-result">${h.correct ? '✅' : '❌'}</span>`; |
3462 | 3494 | cc.appendChild(row); |
3463 | 3495 | }); |
|
3470 | 3502 | S.done = true; S.status = 'complete'; |
3471 | 3503 | const ss = $('sess-status'); ss.className = 'status-pill sp-done'; ss.textContent = 'COMPLETE'; |
3472 | 3504 | btn.disabled = true; |
3473 | | - S.completedEpisodes.push({ task: S.task, scenario: S.scenario, score: Math.floor(S.reward + 0.5), mode: 'manual', turns: S.history.slice(), timestamp: new Date().toLocaleTimeString() }); |
| 3505 | + S.completedEpisodes.push({ task: S.task, scenario: S.scenario, score: Math.floor(S.reward + 0.5), mode: S.mode, turns: S.history.slice(), timestamp: new Date().toLocaleTimeString() }); |
3474 | 3506 | setTimeout(showFinal, 600); |
3475 | 3507 | } else { |
3476 | | - S.turn++; S.query = SCENARIOS[S.task][S.scenario].queries[S.turn - 1]; |
3477 | | - loadQuery(S.query); |
| 3508 | + S.turn++; |
| 3509 | + if (S.mode !== 'custom') { |
| 3510 | + S.query = SCENARIOS[S.task][S.scenario].queries[S.turn - 1]; |
| 3511 | + loadQuery(S.query); |
| 3512 | + } |
3478 | 3513 | } |
3479 | 3514 |
|
3480 | 3515 | // Reset form |
|
0 commit comments