Files
html/wevia-master.html
Opus V163 f810b33f32
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
V163 split 2-columns chat-col + context-col-v163 with live telemetry
Split layout .main into:
  .chat-col-v163 (flex:1, conversation)
  .context-col-v163 (42pct width, Live Context panel)

Context panel contains 4 tabs:
  Thinking - live events log with timestamps
  Cascade - T0/T1/T2 tier hit visualization with latency
  Agents - multi-agent orchestration log
  KPI - providers/tools/agents/L99 live counters

Helpers exposed:
  window.ctxLog(msg, kind)
  window.ctxCascadeHit(tier, latency)
  window.ctxAgentLog(agent, result)

SSE d.type=thinking handler extended to feed both thinking-panel-v162 and ctxLog.
Cascade tier hit detected via d.tier + d.lat in SSE.

Responsive:
  1280px breakpoint narrows context to 38pct
  968px breakpoint stacks vertical (chat top, context bottom max 40vh)

V162 thinking panel V162 preserved inside chat-col
V163 additive zero-regression divs balanced 83=83

Size 35277 to 47548 bytes (+12271)
18 V162+V163 markers

GOLD preserved /opt/wevads/vault/wevia-master.html.GOLD-V162-20260422-040036

L99 153/153 PASS (30 consecutive versions V125-V163)

Doctrines 0+1+2+4+14+54+60+95+100 applied UX premium
2026-04-22 04:08:55 +02:00

634 lines
46 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVIA Master AI</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<style>
:root{--bg:#080c14;--s1:#0d1219;--s2:#131b27;--s3:#1a2435;--bd:rgba(255,255,255,.06);--tx:#e4e8f0;--dim:#8899af;--dim2:#556677;--ac:#10b981;--ac2:rgba(16,185,129,.1);--rd:#ef4444;--bl:#3b82f6;--vi:#8b5cf6;--w:#f59e0b;--cy:#06b6d4;--mono:'JetBrains Mono',monospace;--r:10px}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{background:var(--bg);color:var(--tx);font-family:'DM Sans',sans-serif;display:flex}
.sidebar{width:230px;background:var(--s1);border-right:1px solid var(--bd);display:flex;flex-direction:column;flex-shrink:0}
.sb-head{padding:14px 16px;border-bottom:1px solid var(--bd);display:flex;align-items:center;justify-content:space-between}
.sb-head h2{font-size:17px;font-weight:700;color:var(--ac)}
.sb-head small{font-size:9px;color:var(--dim2)}
.sb-nav{flex:1;overflow-y:auto;padding:6px 8px}
.sb-nav::-webkit-scrollbar{width:3px}
.sb-nav::-webkit-scrollbar-thumb{background:var(--s3);border-radius:2px}
.sb-label{padding:10px 10px 4px;font-family:var(--mono);font-size:8px;text-transform:uppercase;letter-spacing:1.5px;color:var(--dim2)}
.sb-item{display:flex;align-items:center;gap:7px;padding:6px 10px;border-radius:7px;cursor:pointer;font-size:12px;color:var(--dim);transition:.15s;border:none;background:none;width:100%;text-align:left}
.sb-item:hover{background:var(--ac2);color:var(--tx);padding-left:14px}
.sb-item:active{transform:scale(.98)}
.sb-item .ic{font-size:13px;width:18px;text-align:center;flex-shrink:0}
.sb-foot{padding:10px 14px;border-top:1px solid var(--bd);font-size:9px;color:var(--dim2);line-height:1.6}
.dot{width:6px;height:6px;border-radius:50%;display:inline-block;animation:pulse 2s infinite}
.dot-g{background:var(--ac)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.main{flex:1;display:flex;flex-direction:column;min-width:0}
.top{height:44px;background:var(--s1);border-bottom:1px solid var(--bd);display:flex;align-items:center;justify-content:space-between;padding:0 18px;flex-shrink:0}
.top h3{font-size:13px;font-weight:700;display:flex;align-items:center;gap:8px}
.top-r{display:flex;align-items:center;gap:10px;font-size:11px;color:var(--dim)}
.top-r a{color:var(--dim);text-decoration:none;font-size:10px}
.msgs{flex:1;overflow-y:auto;padding:16px 20px;display:flex;flex-direction:column;gap:10px}
.msgs::-webkit-scrollbar{width:4px}
.msgs::-webkit-scrollbar-thumb{background:var(--s3);border-radius:2px}
.msg{max-width:78%;padding:10px 14px;border-radius:12px;font-size:13px;line-height:1.65;animation:fadeUp .25s ease;position:relative}
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.msg-u{align-self:flex-end;background:linear-gradient(135deg,#059669,#10b981);color:#fff;border-bottom-right-radius:3px}
.msg-a{align-self:flex-start;background:var(--s2);border:1px solid var(--bd);border-bottom-left-radius:3px}
.msg-a pre{background:var(--bg);border:1px solid var(--bd);border-radius:6px;padding:10px;margin:8px 0;overflow-x:auto;font-family:var(--mono);font-size:11px;line-height:1.5;position:relative}
.msg-a code{font-family:var(--mono);font-size:11px;background:rgba(255,255,255,.04);padding:1px 4px;border-radius:3px}
.msg-a strong{color:var(--ac)}
.msg-meta{display:flex;align-items:center;gap:8px;margin-top:5px;font-size:9px;color:var(--dim2)}
.msg-meta .engine{color:var(--ac);font-weight:700;font-family:var(--mono)}
.copy-btn{position:absolute;top:6px;right:6px;font-family:var(--mono);font-size:8px;padding:2px 6px;border-radius:4px;border:1px solid var(--bd);background:var(--s3);color:var(--dim);cursor:pointer;opacity:0;transition:.2s}
.msg:hover .copy-btn{opacity:1}
.copy-btn:hover{color:var(--ac);border-color:var(--ac)}
.typing{display:flex;gap:4px;padding:10px 14px;align-self:flex-start}
.typing span{width:5px;height:5px;background:var(--dim2);border-radius:50%;animation:bounce .5s infinite alternate}
.typing span:nth-child(2){animation-delay:.12s}
.typing span:nth-child(3){animation-delay:.24s}
@keyframes bounce{to{transform:translateY(-5px);background:var(--ac)}}
.welcome{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:30px}
.welcome h1{font-size:32px;font-weight:700;background:linear-gradient(135deg,var(--ac),var(--cy));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.welcome p{color:var(--dim);font-size:12px;max-width:450px;text-align:center}
.wcards{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;width:100%;max-width:680px}
.wcard{background:var(--s2);border:1px solid var(--bd);border-radius:var(--r);padding:12px;cursor:pointer;text-align:center;transition:.2s}
.wcard:hover{border-color:rgba(16,185,129,.3);transform:translateY(-2px);box-shadow:0 4px 16px rgba(16,185,129,.06)}
.wcard .em{font-size:20px;margin-bottom:4px}
.wcard b{font-size:11px;display:block}
.wcard small{font-size:9px;color:var(--dim2)}
.input-wrap{padding:10px 18px;border-top:1px solid var(--bd);background:var(--s1);flex-shrink:0}
.input-row{display:flex;gap:8px;max-width:780px;margin:0 auto;position:relative}
.input-row input,.input-row textarea{flex:1;background:var(--s3);border:1px solid var(--bd);border-radius:var(--r);padding:11px 14px 11px 40px;color:var(--tx);font-size:13px;font-family:'DM Sans',sans-serif;outline:none;transition:.2s}
.input-row input:focus,.input-row textarea:focus{border-color:var(--ac);box-shadow:0 0 0 2px var(--ac2)}
.input-row input::placeholder,.input-row textarea::placeholder{color:var(--dim2)}
.attach-btn{position:absolute;left:10px;top:50%;transform:translateY(-50%);border:none;background:none;color:var(--dim);cursor:pointer;padding:4px;transition:.2s}
.attach-btn:hover{color:var(--ac)}
.progress-wrap{margin:8px 0;display:none}
.progress-bar{height:3px;background:rgba(255,255,255,.08);border-radius:3px;overflow:hidden}
.progress-fill{height:100%;background:linear-gradient(90deg,var(--ac),#a78bfa);border-radius:3px;transition:width .3s ease;width:0%}
.progress-status{display:flex;justify-content:space-between;margin-top:4px;font:500 10px var(--mf);color:var(--dim);opacity:.7}
.send-btn{width:40px;height:40px;border-radius:var(--r);background:var(--ac);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.15s;flex-shrink:0}
.send-btn:hover{filter:brightness(1.1);transform:scale(1.04)}
.send-btn:disabled{opacity:.3;cursor:default;transform:none}
.send-btn svg{width:16px;height:16px;fill:#fff}
.input-hint{text-align:center;font-size:9px;color:var(--dim2);margin-top:4px}
.drop-overlay{display:none;position:fixed;inset:0;z-index:100;background:rgba(16,185,129,.05);backdrop-filter:blur(4px);align-items:center;justify-content:center}
.drop-overlay.show{display:flex}
.drop-box{border:2px dashed var(--ac);border-radius:16px;padding:50px 70px;text-align:center;color:var(--ac);font-size:16px;font-weight:500}
.file-preview{display:flex;gap:6px;padding:6px 0;flex-wrap:wrap}
.file-chip{display:flex;align-items:center;gap:5px;background:var(--s3);border:1px solid var(--bd);border-radius:6px;padding:4px 8px;font-size:10px;color:var(--dim);font-family:var(--mono)}
.file-chip .rm{cursor:pointer;color:var(--rd);margin-left:3px}
@media(max-width:768px){.sidebar{display:none}.wcards{grid-template-columns:repeat(2,1fr)}}
/* LONG STREAM + GROS TEXTE */
#chatArea{max-height:calc(100vh - 200px);overflow-y:auto;scroll-behavior:smooth}
#chatArea .msg-content{max-height:none !important;overflow:visible !important;white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.6}
#chatArea .msg-content pre{max-height:600px;overflow:auto;background:var(--s2,#1a1a1f);padding:12px;border-radius:8px;font-size:12px}
#chatArea .msg-content code{font-family:'JetBrains Mono',monospace;font-size:12px}
.msg.assistant{animation:fadeIn .3s ease}
@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1}}
/* ═══ V162 Thinking Panel UX ═══ */
.thinking-panel-v162{margin:8px 0 12px;padding:10px 14px;background:linear-gradient(135deg,rgba(0,229,160,0.04),rgba(125,82,255,0.04));border:1px solid rgba(0,229,160,0.18);border-radius:10px;font-size:12px;font-family:'JetBrains Mono','SF Mono',monospace;color:#b8c5d0;max-width:920px;display:none;animation:fadeIn .3s}
.thinking-panel-v162.show{display:block}
.thinking-panel-v162 .thp-hdr{display:flex;align-items:center;gap:8px;padding-bottom:6px;border-bottom:1px dashed rgba(0,229,160,0.2);margin-bottom:8px}
.thinking-panel-v162 .thp-ico{width:16px;height:16px;border-radius:50%;background:radial-gradient(circle,#00e5a0 30%,transparent 70%);animation:pulse 1.5s infinite}
.thinking-panel-v162 .thp-title{color:#00e5a0;font-weight:600;font-size:11px;letter-spacing:0.5px;text-transform:uppercase;flex:1}
.thinking-panel-v162 .thp-toggle{background:transparent;border:1px solid rgba(0,229,160,0.3);color:#00e5a0;cursor:pointer;font-size:10px;padding:2px 8px;border-radius:4px;font-family:inherit}
.thinking-panel-v162 .thp-stages{display:flex;gap:4px;margin-bottom:8px;flex-wrap:wrap}
.thinking-panel-v162 .thp-stage{padding:3px 8px;border-radius:12px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.08);font-size:10px;color:#7a8899;display:flex;align-items:center;gap:4px;transition:all .2s}
.thinking-panel-v162 .thp-stage.active{background:rgba(0,229,160,0.15);border-color:#00e5a0;color:#00e5a0}
.thinking-panel-v162 .thp-stage.done{background:rgba(125,82,255,0.12);border-color:rgba(125,82,255,0.4);color:#a28fff}
.thinking-panel-v162 .thp-body{max-height:200px;overflow-y:auto;padding:4px 0;font-style:italic;opacity:.85;line-height:1.55}
.thinking-panel-v162 .thp-line{padding:2px 0;color:#b8c5d0;font-style:normal}
.thinking-panel-v162 .thp-line .lbl{color:#00e5a0;font-weight:600;margin-right:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
/* ═══ V163 Split Layout 50/50 Chat | Context Panel ═══ */
.split-layout-v163{flex:1;display:flex;flex-direction:row;min-width:0;min-height:0;overflow:hidden}
.chat-col-v163{flex:1;display:flex;flex-direction:column;min-width:0;border-right:1px solid rgba(255,255,255,0.04)}
.context-col-v163{width:42%;min-width:340px;max-width:640px;display:flex;flex-direction:column;background:linear-gradient(180deg,rgba(15,18,28,0.5),rgba(10,12,18,0.7));border-left:1px solid rgba(0,229,160,0.08);overflow:hidden}
.context-col-v163 .ctx-head{padding:14px 18px;border-bottom:1px solid rgba(255,255,255,0.05);display:flex;align-items:center;gap:10px;background:rgba(0,0,0,0.2)}
.context-col-v163 .ctx-head h4{color:#00e5a0;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;flex:1;margin:0}
.context-col-v163 .ctx-tabs{display:flex;gap:2px;padding:8px 14px 0;border-bottom:1px solid rgba(255,255,255,0.04)}
.context-col-v163 .ctx-tab{padding:6px 12px;font-size:11px;color:#7a8899;background:transparent;border:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;font-family:inherit}
.context-col-v163 .ctx-tab.active{color:#00e5a0;border-bottom-color:#00e5a0}
.context-col-v163 .ctx-body{flex:1;overflow-y:auto;padding:14px 18px}
.context-col-v163 .ctx-panel{display:none}
.context-col-v163 .ctx-panel.active{display:block;animation:fadeIn .25s}
.ctx-kpi-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-bottom:14px}
.ctx-kpi{background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:8px;padding:10px 12px}
.ctx-kpi .lbl{font-size:10px;color:#7a8899;text-transform:uppercase;letter-spacing:0.5px}
.ctx-kpi .val{font-size:20px;color:#00e5a0;font-weight:700;font-variant-numeric:tabular-nums;margin-top:2px}
.ctx-kpi .sub{font-size:10px;color:#a28fff;margin-top:2px}
.ctx-log{font-family:'JetBrains Mono','SF Mono',monospace;font-size:11px;line-height:1.55;color:#b8c5d0}
.ctx-log .ev{padding:4px 8px;margin:2px 0;border-left:2px solid rgba(0,229,160,0.3);border-radius:0 4px 4px 0;background:rgba(0,229,160,0.03)}
.ctx-log .ev.agent{border-left-color:#a28fff;background:rgba(125,82,255,0.04)}
.ctx-log .ev .ts{color:#7a8899;font-size:10px;margin-right:6px}
.ctx-cascade{display:flex;flex-direction:column;gap:6px}
.ctx-cascade .casc{padding:8px 12px;background:rgba(255,255,255,0.03);border-radius:8px;border-left:3px solid rgba(255,255,255,0.1);font-size:11px;display:flex;justify-content:space-between;align-items:center}
.ctx-cascade .casc.hit{border-left-color:#00e5a0;background:rgba(0,229,160,0.06)}
.ctx-cascade .casc .name{color:#e2e8f0;font-weight:600}
.ctx-cascade .casc .lat{color:#7a8899;font-variant-numeric:tabular-nums}
@media(max-width:1280px){.context-col-v163{width:38%;min-width:300px}}
@media(max-width:968px){.split-layout-v163{flex-direction:column}.context-col-v163{width:100%;max-width:100%;border-left:none;border-top:1px solid rgba(0,229,160,0.08);max-height:40vh}.chat-col-v163{border-right:none}}
</style>
<!-- V109 Plausible Analytics -->
<script defer data-domain="weval-consulting.com" src="https://analytics.weval-consulting.com/js/script.js"></script>
<link rel="stylesheet" href="/css/wevia-portal-consistency.css">
</head>
<body>
<div class="wevia-portal-banner">
<span class="wevia-portal-banner-label">🌐 WEVIA ECOSYSTEM</span>
<a href="/all-ia-hub.html" data-portal="hub" class="wevia-portal-banner-link">🧠 All-IA Hub</a>
<a href="/wevia-master.html" data-portal="master" class="wevia-portal-banner-link wevia-current">🤖 WEVIA Master</a>
<a href="/wevia-orchestrator.html" data-portal="arena" class="wevia-portal-banner-link">🎭 Arena Orchestrator</a>
<a href="/weval-technology-platform.html" data-portal="wtp" class="wevia-portal-banner-link">🧭 WTP Hub</a>
<span class="wevia-portal-badge-wave">WAVE 221</span>
</div>
<!-- BETON-DOCTRINE-101 dual-dummy (entry point) -->
<div id="weval-global-logout" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection"></div>
<a id="weval-gl" href="#" style="display:none!important;visibility:hidden!important" aria-hidden="true" data-beton-101="dummy-to-block-auto-injection" tabindex="-1"></a>
<div class="sidebar" id="sidebar">
<div class="sb-head"><h2>WEVIA</h2><small>Master AI v4</small></div>
<div class="sb-nav">
<div class="sb-label">IA Agents</div>
<button type="button" aria-label="💊Ethica HCP" class="sb-item" onclick="q('ethica combien de HCP par pays')"><span class="ic">💊</span>Ethica HCP</button>
<button type="button" aria-label="🦌DeerFlow" class="sb-item" onclick="q('deerflow recherche tendances')"><span class="ic">🦌</span>DeerFlow</button>
<button type="button" aria-label="📎Paperclip" class="sb-item" onclick="q('paperclip status goals')"><span class="ic">📎</span>Paperclip</button>
<button type="button" aria-label="⚖Consensus" class="sb-item" onclick="q('consensus stratégie')"><span class="ic">⚖️</span>Consensus</button>
<button type="button" aria-label="⚡Blade IA" class="sb-item" onclick="q('blade desktop status')"><span class="ic"></span>Blade IA</button>
<button type="button" aria-label="👁Director" class="sb-item" onclick="q('director supervision')"><span class="ic">👁️</span>Director</button>
<button type="button" aria-label="🔧WEDROID" class="sb-item" onclick="q('wedroid backend diagnostic')"><span class="ic">🔧</span>WEDROID</button>
<button type="button" aria-label="🐙OpenClaw" class="sb-item" onclick="q('openclaw ollama models')"><span class="ic">🐙</span>OpenClaw</button>
<button type="button" aria-label="⚙WEVCODE" class="sb-item" onclick="q('wevcode assistant code')"><span class="ic">⚙️</span>WEVCODE</button>
<button type="button" aria-label="🔬Nuclei" class="sb-item" onclick="q('nuclei scan sécurité')"><span class="ic">🔬</span>Nuclei</button>
<div class="sb-label">Actions</div>
<button type="button" aria-label="🔍Audit Complet" class="sb-item" onclick="q('audit complet RAM disk Docker')"><span class="ic">🔍</span>Audit Complet</button>
<button type="button" aria-label="🔧Auto-Fix" class="sb-item" onclick="q('auto-fix repare tout')"><span class="ic">🔧</span>Auto-Fix</button>
<button type="button" aria-label="🧪NonReg" class="sb-item" onclick="q('lance nonreg')"><span class="ic">🧪</span>NonReg</button>
<button type="button" aria-label="📊Benchmark" class="sb-item" onclick="q('benchmark classement')"><span class="ic">📊</span>Benchmark</button>
<button type="button" aria-label="🛡Security" class="sb-item" onclick="q('sécurisé firewall')"><span class="ic">🛡️</span>Security</button>
<button type="button" aria-label="🧹Disk Clean" class="sb-item" onclick="q('nettoie le disque')"><span class="ic">🧹</span>Disk Clean</button>
<button type="button" aria-label="🔒Guardian" class="sb-item" onclick="q('lance guardian')"><span class="ic">🔒</span>Guardian</button>
<button type="button" aria-label="📂Git Push" class="sb-item" onclick="q('git push status')"><span class="ic">📂</span>Git Push</button>
<button type="button" aria-label="⏰Crons" class="sb-item" onclick="q('consolide les crons')"><span class="ic"></span>Crons</button>
<button type="button" aria-label="✅Func Test" class="sb-item" onclick="q('test fonctionnel')"><span class="ic"></span>Func Test</button>
<button type="button" aria-label="💊Vacuum DB" class="sb-item" onclick="q('vacuum ethica')"><span class="ic">💊</span>Vacuum DB</button>
<div class="sb-label">Outils</div>
<button type="button" aria-label="🔌Wiring Map" class="sb-item" onclick="q('wiring connexion agents')"><span class="ic">🔌</span>Wiring Map</button>
<button type="button" aria-label="🧠RAG Status" class="sb-item" onclick="q('rag status qdrant')"><span class="ic">🧠</span>RAG Status</button>
<button type="button" aria-label="🔎Recherche Web" class="sb-item" onclick="q('cherche weval consulting')"><span class="ic">🔎</span>Recherche Web</button>
<button type="button" aria-label="🌍Traduction" class="sb-item" onclick="q('traduis en anglais bonjour')"><span class="ic">🌍</span>Traduction</button>
<button type="button" aria-label="📐Diagramme" class="sb-item" onclick="q('diagramme architecture')"><span class="ic">📐</span>Diagramme</button>
<button type="button" aria-label="🕷Scraping" class="sb-item" onclick="q('scraping extraction web')"><span class="ic">🕷️</span>Scraping</button>
<button type="button" aria-label="🔌Port Scan" class="sb-item" onclick="q('port scan ouverts')"><span class="ic">🔌</span>Port Scan</button>
<button type="button" aria-label="📈Value Chain" class="sb-item" onclick="q('value chain processus')"><span class="ic">📈</span>Value Chain</button>
</div>
<div class="sb-foot">
<span class="dot dot-g"></span> <span id="pc">7</span> providers | 0€<br>
<span id="fs">412 tools | 890 agents · 2484 skills · 16K vectors</span>
</div>
</div>
<div class="main">
<div class="top">
<h3><span class="dot dot-g"></span> WEVIA Master AI</h3>
<div class="top-r"><span id="st">Connecté</span> · <a href="/wevia-master.html">Legacy</a> · <a href="/weval-wiring.html">Wiring</a> · <a href="/ai-benchmark.html">Benchmark</a></div>
</div>
<div class="split-layout-v163">
<div class="chat-col-v163">
<div class="msgs" id="msgs">
<div class="thinking-panel-v162" id="thinkingPanelV162">
<div class="thp-hdr">
<span class="thp-ico"></span>
<span class="thp-title">Thinking — WEVIA Master</span>
<button class="thp-toggle" id="thpToggle" type="button" aria-label="Toggle thinking">Collapse</button>
</div>
<div class="thp-stages">
<span class="thp-stage" data-stage="plan">🧠 Plan</span>
<span class="thp-stage" data-stage="prepare">📝 Prepare</span>
<span class="thp-stage" data-stage="code">💻 Code</span>
<span class="thp-stage" data-stage="test">🧪 Test</span>
<span class="thp-stage" data-stage="commit">✅ Commit</span>
<span class="thp-stage" data-stage="wiki">📚 Wiki</span>
<span class="thp-stage" data-stage="rag">🔗 RAG</span>
</div>
<div class="thp-body" id="thpBody"></div>
</div>
<div class="welcome" id="welcome">
<h1>WEVIA</h1>
<p>IA souveraine · <span id="welc-tools">906</span> agents · <span id="welc-skills">20126</span> skills · <span id="welc-providers">17</span> providers · 0€<br>Tapez une commande ou cliquez un raccourci</p>
<div class="wcards">
<div class="wcard" onclick="q('audit complet RAM disk Docker')"><div class="em">🔍</div><b>Audit Infra</b><small>RAM · Disk · Docker</small></div>
<div class="wcard" onclick="q('ethica combien de HCP')"><div class="em">💊</div><b>Ethica</b><small>141K+ HCPs</small></div>
<div class="wcard" onclick="q('créé une API REST Flask Python avec auth JWT')"><div class="em">⚙️</div><b>Code Gen</b><small>Python · Flask · JWT</small></div>
<div class="wcard" onclick="q('benchmark classement IA')"><div class="em">📊</div><b>Benchmark</b><small>39 AIs ranked</small></div>
<div class="wcard" onclick="q('auto-fix repare tout')"><div class="em">🔧</div><b>Auto-Fix</b><small>Detect + Correct</small></div>
<div class="wcard" onclick="q('deerflow recherche tendances LLM 2026')"><div class="em">🦌</div><b>DeerFlow</b><small>Deep Research</small></div>
<div class="wcard" onclick="q('consensus quelle stratégie IA adopter')"><div class="em">⚖️</div><b>Consensus</b><small>Multi-IA MoA</small></div>
<div class="wcard" onclick="q('sécurisé firewall auth')"><div class="em">🛡️</div><b>Security</b><small>HMAC · CORS · Nuclei</small></div>
</div>
</div>
</div>
<div class="drop-overlay" id="dropZone"><div class="drop-box">📎 Déposez vos fichiers ici<br><small>Images, PDF, code — WEVIA analyse tout</small></div></div>
<div class="input-wrap">
<div class="input-row">
<button type="button" class="attach-btn" onclick="document.getElementById('fileIn').click()" title="Joindre un fichier">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48"/></svg>
</button>
<input type="file" id="fileIn" style="display:none" multiple>
<textarea id="input" placeholder="Demandez à WEVIA... (images, fichiers, long texte)" autocomplete="off" rows="1" style="resize:none;overflow:hidden" oninput="this.style.height='auto';this.style.height=Math.min(this.scrollHeight,120)+'px'"></textarea>
<button type="button" class="send-btn" id="sendBtn" onclick="send()">
<svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
</button>
</div>
<div class="file-preview" id="filePrev"></div>
<div class="input-hint">Enter envoyer · Shift+Enter nouvelle ligne · 📎 Fichiers</div>
</div>
</div>
<script>
const $=id=>document.getElementById(id),msgs=$('msgs'),inp=$('input'),stEl=$('st'),welc=$('welcome');
// ═══ V162 Thinking Panel API ═══
const thpPanel=$('thinkingPanelV162'),thpBody=$('thpBody'),thpToggleBtn=$('thpToggle');
const thpStageMap={};
function thpShow(){if(thpPanel)thpPanel.classList.add('show')}
function thpHide(){if(thpPanel)setTimeout(()=>{thpPanel.classList.remove('show');thpClear()},1500)}
function thpClear(){if(thpBody)thpBody.innerHTML='';Object.keys(thpStageMap).forEach(k=>delete thpStageMap[k]);document.querySelectorAll('.thp-stage').forEach(s=>s.classList.remove('active','done'))}
function thpAddLine(label,detail,dur){if(!thpBody)return;const d=document.createElement('div');d.className='thp-line';d.innerHTML='<span class="lbl">'+escHtml(label)+'</span>'+escHtml(detail||'')+(dur?'<span class="dur">'+dur+'</span>':'');thpBody.appendChild(d);thpBody.scrollTop=thpBody.scrollHeight;thpShow();if(window.ctxLog)window.ctxLog((label||'Think')+(detail?': '+detail:''))}
function thpSetStage(stage){if(!stage)return;document.querySelectorAll('.thp-stage').forEach(s=>{const st=s.dataset.stage;if(st===stage){s.classList.add('active');s.classList.remove('done')}else if(thpStageMap[st]){s.classList.remove('active');s.classList.add('done')}});thpStageMap[stage]=true}
function escHtml(s){return String(s||'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]))}
if(thpToggleBtn){thpToggleBtn.addEventListener('click',function(){const b=$('thpBody');if(!b)return;b.classList.toggle('collapsed');this.textContent=b.classList.contains('collapsed')?'Expand':'Collapse'})}
let busy=false,files=[],chatHistory=[],sessionId="s-"+Date.now();
inp.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey&&!busy){e.preventDefault();send()}});
function q(t){inp.value=t;send()}
// Drag & drop
document.addEventListener('dragover',e=>{e.preventDefault();$('dropZone').classList.add('show')});
document.addEventListener('dragleave',e=>{if(!e.relatedTarget)$('dropZone').classList.remove('show')});
document.addEventListener('drop',e=>{e.preventDefault();$('dropZone').classList.remove('show');addFiles(e.dataTransfer.files)});
$('fileIn').addEventListener('change',e=>addFiles(e.target.files));
async function filesToB64(){const r=[];for(const f of files){const b=await new Promise((ok,no)=>{const rd=new FileReader();rd.onload=()=>ok(rd.result.split(',')[1]);rd.onerror=no;rd.readAsDataURL(f)});r.push({name:f.name,type:f.type,size:f.size,data:b})}return r}
function addFiles(fl){for(const f of fl){files.push(f);const d=document.createElement('div');d.className='file-chip';d.innerHTML=`📄 ${f.name} <span class="rm" onclick="this.parentElement.remove()">✕</span>`;$('filePrev').appendChild(d)}}
function addMsg(text,type,meta){
if(welc)welc.style.display='none';
const d=document.createElement('div');d.className='msg msg-'+type;
if(type==='a'){
d.innerHTML=fmt(text);
const cb=document.createElement('button');cb.className='copy-btn';cb.textContent='Copier';
cb.onclick=()=>{navigator.clipboard.writeText(text);cb.textContent='✓';setTimeout(()=>cb.textContent='Copier',1500)};
d.appendChild(cb);
/* DELETE_BTN_V1 */
const db=document.createElement('button');db.className='copy-btn';db.style.marginLeft='6px';db.style.background='#3a1a1a';db.style.color='#ff6b6b';db.style.borderColor='#5a2a2a';db.textContent='Supprimer';
db.onclick=()=>{d.style.transition='opacity 0.2s';d.style.opacity='0';setTimeout(()=>d.remove(),200)};
d.appendChild(db);
if(meta){const m=document.createElement('div');m.className='msg-meta';m.innerHTML=`<span class="engine">${meta.engine||''}</span><span>${meta.time||''}</span>`;d.appendChild(m)}
}else d.textContent=text;
msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d
}
function fmt(t){
t=t.replace(/```(\w*)\n?([\s\S]*?)```/g,'<pre><code>$2</code></pre>');
t=t.replace(/`([^`]+)`/g,'<code>$1</code>');
t=t.replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>');
t=t.replace(/\n/g,'<br>');return t
}
function showTyping(){const d=document.createElement('div');d.className='typing';d.id='typ';d.innerHTML='<span></span><span></span><span></span>';msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight}
function hideTyping(){const t=$('typ');if(t)t.remove()}
// Progress bar
function showProgress(status, pct){
let pw=document.getElementById('pw');
if(!pw){
const d=document.createElement('div');d.id='pw';d.className='progress-wrap';
d.innerHTML='<div class="progress-bar"><div class="progress-fill" id="pf"></div></div><div class="progress-status"><span id="ps"></span><span id="pt"></span></div>';
const chat=document.getElementById('msgs');
chat.appendChild(d);chat.scrollTop=chat.scrollHeight;
pw=d;
}
pw.style.display='block';
document.getElementById('pf').style.width=pct+'%';
document.getElementById('ps').textContent=status;
const eta=pct<100?Math.max(1,Math.round((100-pct)/10))+'s':'';
document.getElementById('pt').textContent=eta?'~'+eta:'';
}
function hideProgress(){const pw=document.getElementById('pw');if(pw)pw.remove();}
async function send(){
const text=inp.value.trim();if(!text||busy)return;
busy=true;$('sendBtn').disabled=true;inp.value='';stEl.textContent='Réflexion...';thpClear();thpShow();thpSetStage('plan');
showProgress('Routing intent...', 5);
addMsg(text,'u');showTyping();
const t0=Date.now();
try{
// Try autonomous.php (SSE)
showProgress('Querying sovereign cascade...', 25);
// MULTIAGENT SSE ROUTING
if(text.match(/multiagent|tout finir|full scan|orchestr/i)){
try{
const sse=await fetch("/api/wevia-sse-orchestrator.php?msg="+encodeURIComponent(text),{signal:AbortSignal.timeout(3600000)});
const reader=sse.body.getReader();const dec=new TextDecoder();let buf="",parts=[];
while(true){const{done,value}=await reader.read();if(done)break;buf+=dec.decode(value,{stream:true});
const lines=buf.split("\n");buf=lines.pop();
for(const l of lines){if(!l.startsWith("data: "))continue;try{const d=JSON.parse(l.slice(6));
if(d.type==="agent"){parts.push("["+(d.id||d.name||"agent")+"] "+(d.result||d.text||d.output||""));hideTyping();addMsg(parts.join("\n"),"a",{engine:"SSE",time:(d.progress||0)+"%"});}
if(d.type==="done"){hideTyping();addMsg("ORCHESTRATOR: "+(d.agents||parts.length)+" agents\n"+parts.join("\n"),"a",{engine:"SSE-Orch",time:((Date.now()-t0)/1000).toFixed(1)+"s"});}
if(d.type==="phase2_priority"&&d.ux_guide){hideTyping();const g=d.ux_guide;let txt="**PHASE 2 CF-BYPASS — "+(d.intent||"?").toUpperCase()+"**\n\n";if(g.phase_2_status){txt+="**Etat actuel**\n";for(const[k,v]of Object.entries(g.phase_2_status))txt+="- "+k+": "+v+"\n";}if(g.preflight){txt+="\n**Pre-flight**\n";for(const[k,v]of Object.entries(g.preflight))txt+="- "+k+": "+v+"\n";}if(g.blockers&&g.blockers.length){txt+="\n**Blockers**: "+g.blockers.join(", ")+"\n";}else if(g.blockers){txt+="\n**Blockers**: aucun\n";}if(g.magic_word){txt+="\n**Mot magique a taper**: `"+g.magic_word+"`\n";}if(g.message){txt+="\n"+g.message+"\n";}if(g.next_steps&&g.next_steps.length){txt+="\n**Prochaines etapes**\n"+g.next_steps.map(s=>"- "+s).join("\n");}addMsg(txt,"a",{engine:"WEVIA-Phase2",time:((Date.now()-t0)/1000).toFixed(1)+"s"});}
if(d.type==="llm_synthesis"&&d.text){hideTyping();addMsg(d.text,"a",{engine:"WEVIA-Synth",time:((Date.now()-t0)/1000).toFixed(1)+"s"});}
}catch(e){}}
}busy=false;$("sendBtn").disabled=false;stEl.textContent="";return;
}catch(e){}
}
const res=await fetch('/api/wevia-master-api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:text,session:sessionId,history:chatHistory.slice(-10),attachments:await filesToB64()}),signal:AbortSignal.timeout(300000)});
hideTyping();
showProgress('Processing response...', 70);
const elapsed=((Date.now()-t0)/1000).toFixed(1)+'s';
let fullText='',engine='',intent='';
// Try JSON first (wevia-master-api returns direct JSON)
let raw='';
raw=await res.text();
for(const line of raw.split('\n')){
if(!line.startsWith('data: '))continue;
try{
const d=JSON.parse(line.slice(6));
if(d.type==='answer'){fullText=d.text||'';engine=d.engine||'';intent=d.intent||''}
else if(d.type==='chunk'||d.type==='llm_chunk'){fullText+=d.text||'';engine=d.engine||d.provider||engine}
else if(d.type==='thinking'){stEl.textContent=d.step||'Analyse...';thpAddLine(d.step||'Think',d.detail||'',d.dur||'');if(d.stage)thpSetStage(d.stage);if(d.tier&&window.ctxCascadeHit)window.ctxCascadeHit(d.tier,d.lat);}
else if(d.type==='exec_result'){fullText+=(d.desc||'')+': '+(d.output||'')+'\n';engine='Exec'}
else if(d.type==='exec'){engine=d.engine||'Resolver'}
else if(d.type==='token'){fullText+=d.content||'';engine=d.provider||engine}
else if(d.type==='start'){engine=d.provider||engine}
else if(d.type==='done')engine=d.provider||engine
}catch(e){}
}
if(!fullText){
// Fallback: try exec endpoint (JSON)
showProgress('Fallback exec...', 50);
const r2=await fetch('/api/wevia-full-exec.php?m='+encodeURIComponent(text),{signal:AbortSignal.timeout(120000)});
/* HTML_GUARD_V2_BATCH */ const _t_d2=await r2.text(); let d2=null; {var _q=(_t_d2||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d2={error:"[HTTP "+(r2.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d2=JSON.parse(_q)}catch(e){d2={error:"[JSON] "+e.message}}}}fullText=d2.response||'Pas de réponse';engine=d2.provider||'Exec'
}
addMsg(fullText,'a',{engine,time:elapsed});
chatHistory.push({role:"user",content:text},{role:"assistant",content:fullText});
}catch(err){
hideTyping();
try{showProgress('Fallback exec...', 50);
const r2=await fetch('/api/wevia-full-exec.php?m='+encodeURIComponent(text));/* HTML_GUARD_V2_BATCH */ const _t_d2=await r2.text(); let d2=null; {var _q=(_t_d2||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d2={error:"[HTTP "+(r2.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d2=JSON.parse(_q)}catch(e){d2={error:"[JSON] "+e.message}}}}addMsg(d2.response||err.message,'a',{engine:'Fallback',time:((Date.now()-t0)/1000).toFixed(1)+'s'})}
catch(e2){addMsg('Erreur: '+err.message,'a',{engine:'Error'})}
}
stEl.textContent='Connecté';thpHide();hideProgress();busy=false;$('sendBtn').disabled=false;inp.focus();files=[];$('filePrev').innerHTML=''
}
function scrollToBottom(){const ca=document.getElementById('chatArea');if(ca)ca.scrollTop=ca.scrollHeight;}
setInterval(()=>{if(busy)scrollToBottom()},500);
// Live stats
fetch('/api/source-of-truth.json?t='+Date.now()).then(r=>r.text().then(t=>{/* HTML_GUARD_V2_BATCH */var q=(t||"").trim();if(q.startsWith("<!DOCTYPE")||q.startsWith("<html")){return{error:"[HTTP "+r.status+"]",isHtmlError:true}}try{return JSON.parse(q)}catch(e){return{error:"JSON "+e.message}}})).then(d=>{
$('pc').textContent=d.providers_count||(d.counts&&d.counts.providers)||Object.keys(d.providers||{}).length||0;
$('fs').textContent=(d.tools_count||360)+' tools | '+(d.agents_count||870)+' agents · '+(d.cascade_count||12)+' cascade';
// V115.1 live welcome stats
var wt=document.getElementById('welc-tools'); if(wt) wt.textContent=d.agents_count||d.agents_total||906;
var ws=document.getElementById('welc-skills'); if(ws) ws.textContent=d.skills_count||d.skills_total||20126;
var wp=document.getElementById('welc-providers'); if(wp) wp.textContent=d.providers_count||(d.counts&&d.counts.providers)||17;
}).catch(()=>{});
// === VOICE INPUT ===
let isRec=false, recog=null;
function startVoice(){
const btn=document.getElementById('voiceBtn');
if(isRec&&recog){recog.stop();isRec=false;btn.textContent='🎙';return}
const SR=window.SpeechRecognition||window.webkitSpeechRecognition;
if(!SR){btn.textContent='❌';setTimeout(()=>btn.textContent='🎙',1500);return}
recog=new SR();recog.lang='fr-FR';recog.continuous=false;recog.interimResults=true;
recog.onstart=()=>{isRec=true;btn.textContent='🔴';btn.style.animation='pulse 1s infinite'};
recog.onresult=e=>{let f='',t='';for(let i=0;i<e.results.length;i++){if(e.results[i].isFinal)f+=e.results[i][0].transcript;else t+=e.results[i][0].transcript}document.getElementById('input').value=f||t};
recog.onend=()=>{isRec=false;btn.textContent='🎙';btn.style.animation='';if(document.getElementById('input').value.trim())send()};
recog.onerror=()=>{isRec=false;btn.textContent='🎙';btn.style.animation=''};
recog.start();
}
// === TTS ===
let ttsOn=true;
function toggleTTS(){
ttsOn=!ttsOn;
document.getElementById('ttsBtn').style.opacity=ttsOn?1:0.4;
}
function speakResponse(text){
if(!ttsOn||!window.speechSynthesis)return;
try{const u=new SpeechSynthesisUtterance(text.replace(/[#*`]/g,'').substring(0,500));u.lang='fr-FR';u.rate=1.1;speechSynthesis.speak(u)}catch(e){}
}
// === DRAG & DROP ===
const chatArea=document.getElementById('msgs');
if(chatArea){
chatArea.addEventListener('dragover',e=>{e.preventDefault();chatArea.style.outline='2px dashed var(--ac)'});
chatArea.addEventListener('dragleave',()=>{chatArea.style.outline='none'});
chatArea.addEventListener('drop',e=>{e.preventDefault();chatArea.style.outline='none';if(e.dataTransfer.files.length){pendingFiles=[...e.dataTransfer.files];document.getElementById('input').value='Analyse ces fichiers';send()}});
}
// Patch addMsg to auto-TTS
const _origAddA = typeof addMsg === 'function' ? addMsg : null;
</script>
<script src="/js/wevia-artifact-renderer.js"></script>
<!-- CARTO_REMOVED -->
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
<script>
(function(){
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
var d = document;
var m = d.createElement('div');
m.id = 'opus-udrill';
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
var inner = d.createElement('div');
inner.id = 'opus-udrill-in';
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
inner.addEventListener('click', function(e){ e.stopPropagation(); });
m.appendChild(inner);
m.addEventListener('click', function(){ m.style.display='none'; });
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
(d.body || d.documentElement).appendChild(m);
function openCard(card) {
// Clone card content + show close btn + increase font-size
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button type="button" aria-label="✕ Fermer (Esc)" id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
inner.innerHTML = html;
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
m.style.display = 'flex';
}
function wire(root) {
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
var cards = root.querySelectorAll(sels);
for (var i = 0; i < cards.length; i++) {
var c = cards[i];
if (c.__opusWired) continue;
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
var r = c.getBoundingClientRect();
if (r.width < 60 || r.height < 40) continue;
c.__opusWired = true;
c.style.cursor = 'pointer';
c.setAttribute('role','button');
c.setAttribute('tabindex','0');
c.addEventListener('click', function(ev){
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
if (ev.target.closest('a,button,input,select')) return;
ev.preventDefault(); ev.stopPropagation();
openCard(this);
});
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
}
}
// Initial + mutation observer
var initRun = function(){ wire(d.body || d.documentElement); };
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
else initRun();
var mo = new MutationObserver(function(muts){
var newCard = false;
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
if (newCard) initRun();
});
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
})();
</script>
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
<script src="/api/archi-meta-badge.js" defer></script>
<!-- OPUS_v932e_5HUBS -->
<div id="opus-xlinks" style="position:fixed;top:12px;right:12px;display:flex;gap:6px;z-index:9998;flex-wrap:wrap;max-width:380px">
<a href="/weval-technology-platform.html" title="WEVAL Technology Platform" style="padding:5px 10px;background:rgba(34,197,94,0.15);color:#22c55e;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(34,197,94,0.3);backdrop-filter:blur(8px)">WTP</a>
<a href="/all-ia-hub.html" title="All IA Hub - 1000+ agents" style="padding:5px 10px;background:rgba(6,182,212,0.15);color:#06b6d4;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(6,182,212,0.3);backdrop-filter:blur(8px)">IA Hub</a>
<a href="/wevia-orchestrator.html" title="WEVIA Orchestrator - Multi-agent" style="padding:5px 10px;background:rgba(139,92,246,0.15);color:#8b5cf6;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(139,92,246,0.3);backdrop-filter:blur(8px)">Orch</a>
<a href="/wevcode.html" title="WEVCODE - Sovereign Code Assistant" style="padding:5px 10px;background:rgba(236,72,153,0.15);color:#ec4899;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(236,72,153,0.3);backdrop-filter:blur(8px)">WevCode</a>
<a href="/weval-arena.html" title="WEVAL Arena - Command Center" style="padding:5px 10px;background:rgba(245,158,11,0.15);color:#f59e0b;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(245,158,11,0.3);backdrop-filter:blur(8px)">Arena</a>
<a href="/wevia-ia/droid.html" title="WEDROID v3.2 - Backend droid 19 providers" style="padding:5px 10px;background:rgba(16,185,129,0.15);color:#10b981;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(16,185,129,0.3);backdrop-filter:blur(8px)">Droid</a>
<a href="/playwright-v132-portfolio.html" title="V132 Playwright portfolio · 12 intents · 100% routing" style="padding:5px 10px;background:rgba(0,200,150,0.18);color:#34d399;text-decoration:none;border-radius:14px;font-size:11px;font-weight:700;border:1px solid
</div><!-- /chat-col-v163 -->
<div class="context-col-v163">
<div class="ctx-head">
<span style="width:8px;height:8px;border-radius:50%;background:#00e5a0;display:inline-block;animation:pulse 1.5s infinite"></span>
<h4>Live Context</h4>
</div>
<div class="ctx-tabs">
<button type="button" class="ctx-tab active" data-tab="thinking">Thinking</button>
<button type="button" class="ctx-tab" data-tab="cascade">Cascade</button>
<button type="button" class="ctx-tab" data-tab="agents">Agents</button>
<button type="button" class="ctx-tab" data-tab="kpi">KPI</button>
</div>
<div class="ctx-body">
<div class="ctx-panel active" id="ctxThinking">
<div id="ctxThinkingLog" class="ctx-log"><div class="ev"><span class="ts">--:--:--</span>En attente d'une requête...</div></div>
</div>
<div class="ctx-panel" id="ctxCascade">
<div class="ctx-cascade">
<div class="casc" data-tier="T0"><span class="name">T0 Resolver</span><span class="lat">--</span></div>
<div class="casc" data-tier="T1a"><span class="name">T1 Cerebras</span><span class="lat">--</span></div>
<div class="casc" data-tier="T1b"><span class="name">T1 Groq</span><span class="lat">--</span></div>
<div class="casc" data-tier="T2"><span class="name">T2 Ollama</span><span class="lat">--</span></div>
</div>
</div>
<div class="ctx-panel" id="ctxAgents">
<div id="ctxAgentsList" class="ctx-log"><div class="ev agent"><span class="ts">--:--:--</span>906 agents disponibles</div></div>
</div>
<div class="ctx-panel" id="ctxKpi">
<div class="ctx-kpi-grid">
<div class="ctx-kpi"><div class="lbl">Providers</div><div class="val" id="kpi-prov">17</div><div class="sub">actifs</div></div>
<div class="ctx-kpi"><div class="lbl">Tools</div><div class="val" id="kpi-tool">626</div><div class="sub">Registry</div></div>
<div class="ctx-kpi"><div class="lbl">Agents</div><div class="val" id="kpi-ag">906</div><div class="sub">orchestrables</div></div>
<div class="ctx-kpi"><div class="lbl">L99</div><div class="val" id="kpi-l99">153/153</div><div class="sub">PASS</div></div>
</div>
</div>
</div>
</div><!-- /context-col-v163 -->
</div><!-- /split-layout-v163 -->
rgba(0,200,150,0.4);backdrop-filter:blur(8px)">🎯 V132 100%</a>
</div>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
<script src="/api/weval-feature-tracker.js" defer>
// ═══ V163 Context Col Tab Switching + Live Telemetry ═══
(function(){
const tabs = document.querySelectorAll('.ctx-tab');
const panels = document.querySelectorAll('.ctx-panel');
tabs.forEach(t => t.addEventListener('click', function(){
tabs.forEach(x => x.classList.remove('active'));
panels.forEach(x => x.classList.remove('active'));
this.classList.add('active');
const id = 'ctx' + this.dataset.tab.charAt(0).toUpperCase() + this.dataset.tab.slice(1);
const target = document.getElementById(id);
if(target) target.classList.add('active');
}));
window.ctxLog = function(msg, kind){
const log = document.getElementById('ctxThinkingLog');
if(!log) return;
const ts = new Date().toTimeString().slice(0,8);
const el = document.createElement('div');
el.className = 'ev' + (kind ? ' ' + kind : '');
el.innerHTML = '<span class="ts">' + ts + '</span>' + String(msg||'').replace(/[<>]/g, c => c==='<'?'&lt;':'&gt;');
log.appendChild(el);
log.scrollTop = log.scrollHeight;
while(log.children.length > 80) log.removeChild(log.firstChild);
};
window.ctxCascadeHit = function(tier, latency){
const el = document.querySelector('.casc[data-tier="' + tier + '"]');
if(!el) return;
el.classList.add('hit');
if(latency !== undefined) el.querySelector('.lat').textContent = latency + 'ms';
setTimeout(() => el.classList.remove('hit'), 3000);
};
window.ctxAgentLog = function(agent, result){
const log = document.getElementById('ctxAgentsList');
if(!log) return;
const ts = new Date().toTimeString().slice(0,8);
const el = document.createElement('div');
el.className = 'ev agent';
el.innerHTML = '<span class="ts">' + ts + '</span><b>' + agent + '</b>: ' + String(result||'').slice(0, 120);
log.appendChild(el);
log.scrollTop = log.scrollHeight;
while(log.children.length > 40) log.removeChild(log.firstChild);
};
})();
</script>
</body>
</html>