Files
html/claw-chat.html
Opus 6fbe5081ff
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-sync-0305
2026-04-24 03:05:04 +02:00

318 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. 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>WEVAL Claw Code Chat</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#0a0f1a;--card:#111827;--border:#1e293b;--text:#e2e8f0;--muted:#64748b;--accent:#22d3ee;--green:#22c55e;--user:#1e40af;--bot:#1e293b}
body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;height:100vh;display:flex;flex-direction:column}
.hdr{background:var(--card);border-bottom:1px solid var(--border);padding:10px 16px;display:flex;align-items:center;gap:10px}
.hdr h1{font-size:15px;font-weight:700;background:linear-gradient(90deg,var(--accent),#a78bfa);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hdr .b{font-size:9px;padding:2px 7px;border-radius:6px;font-weight:600}
.hdr .live{background:#22c55e20;color:var(--green)}.hdr .ct{background:#a78bfa20;color:#a78bfa}
.hdr .right{margin-left:auto;font-size:10px;color:var(--muted)}
.chips{display:flex;gap:5px;flex-wrap:wrap;padding:6px 16px;background:#0d1117;border-bottom:1px solid var(--border)}
.chip{font-size:10px;padding:3px 9px;border-radius:12px;border:1px solid var(--border);color:var(--muted);cursor:pointer;transition:.2s;white-space:nowrap}
.chip:hover{border-color:var(--accent);color:var(--accent);background:#22d3ee10}
.chip.cat-infra{border-color:#f59e0b30}.chip.cat-ai{border-color:#a78bfa30}.chip.cat-sec{border-color:#ef444430}.chip.cat-data{border-color:#22c55e30}
.msgs{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px}
.msg{max-width:85%;padding:10px 14px;border-radius:14px;font-size:13px;line-height:1.65;animation:fadeIn .3s}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.msg.u{background:var(--user);color:#fff;align-self:flex-end;border-bottom-right-radius:4px}
.msg.b{background:var(--bot);align-self:flex-start;border-bottom-left-radius:4px}
.msg .prov{font-size:9px;color:var(--accent);margin-bottom:3px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}
.msg pre{background:#080c14;padding:8px 10px;border-radius:8px;overflow-x:auto;margin:6px 0;font-size:11px;font-family:'JetBrains Mono',monospace;border:1px solid #1e293b}
.msg code{font-family:'JetBrains Mono',monospace;font-size:11px;background:#1e293b;padding:1px 4px;border-radius:3px}
.msg pre code{background:none;padding:0}
.msg strong{color:var(--accent)}
.msg ul,.msg ol{margin:4px 0 4px 18px}
.msg li{margin:2px 0}
.input-area{background:var(--card);border-top:1px solid var(--border);padding:10px 16px;display:flex;gap:8px;align-items:end}
.input-area textarea{flex:1;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:12px;padding:10px 14px;font-size:13px;resize:none;outline:none;min-height:42px;max-height:140px;font-family:inherit;transition:.2s}
.input-area textarea:focus{border-color:var(--accent);box-shadow:0 0 0 2px #22d3ee20}
.input-area textarea::placeholder{color:var(--muted)}
.btn{background:var(--accent);color:var(--bg);border:none;border-radius:10px;padding:10px 16px;font-weight:700;cursor:pointer;font-size:13px;transition:.2s;min-width:42px;display:flex;align-items:center;justify-content:center}
.btn:hover{background:#06b6d4;transform:scale(1.02)}.btn:disabled{opacity:.4;cursor:not-allowed;transform:none}
.btn svg{width:18px;height:18px;fill:currentColor}
.welcome{text-align:center;color:var(--muted);margin:auto;max-width:440px}
.welcome h2{color:var(--accent);font-size:18px;margin-bottom:6px}
.welcome p{font-size:12px;line-height:1.6}
.typing{color:var(--accent);font-size:11px;padding:6px 14px;display:flex;align-items:center;gap:6px}
.typing .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);animation:pulse .8s infinite alternate}
.typing .dot:nth-child(2){animation-delay:.2s}.typing .dot:nth-child(3){animation-delay:.4s}
@keyframes pulse{from{opacity:.3}to{opacity:1}}
</style>
</head>
<body>
<div class="hdr">
<h1>WEVAL Claw Code</h1>
<span class="b live">97 skills</span>
<span class="b ct">6 produits</span>
<span class="right">Groq &middot; Cerebras &middot; Gemini &middot; Ollama</span>
</div>
<div class="chips" id="chips">
<span class="chip cat-infra" onclick="q('Diagnostic complet WEDROID S204 et S95')">WEDROID</span>
<span class="chip cat-ai" onclick="q('Blade IA agent loop et Sentinel')">BLADE</span>
<span class="chip cat-ai" onclick="q('WEVIA PUBLIC Centre Commande 71 modules')">WEVIA</span>
<span class="chip cat-ai" onclick="q('WEVAL Manager consensus multi-provider')">MANAGER</span>
<span class="chip cat-ai" onclick="q('WEVCODE assistant code souverain 4 modes')">WEVCODE</span>
<span class="chip cat-data" onclick="q('WEVIA Life sync documents et RAG')">LIFE</span>
<span class="chip cat-data" onclick="q('Ethica HCP Maghreb stats enrichissement')">ETHICA</span>
<span class="chip cat-sec" onclick="q('NonReg 153 tests status complet')">NONREG</span>
<span class="chip cat-infra" onclick="q('Infra Docker S204 disk containers')">INFRA</span>
<span class="chip cat-ai" onclick="q('DeerFlow skills recherche web')">DEERFLOW</span>
<span class="chip cat-sec" onclick="q('Nuclei scan vulnerabilites sécurité')">NUCLEI</span>
<span class="chip cat-ai" onclick="q('Paperclip 150 agents orchestration')">PAPERCLIP</span>
<span class="chip cat-ai" onclick="q('OpenClaw Ollama modeles souverains')">OPENCLAW</span>
<span class="chip cat-data" onclick="q('B2B leads scraping LinkedIn prospects')">B2B</span>
<span class="chip cat-infra" onclick="q('Email MTA PMTA KumoMTA delivrabilite')">EMAIL</span>
<span class="chip cat-sec" onclick="q('L99 tests sécurité layers complet')">L99</span>
<span class="chip cat-data" onclick="q('Qdrant RAG embeddings knowledge base')">QDRANT</span>
<span class="chip cat-infra" onclick="q('Providers IA chaine Groq Cerebras Gemini')">PROVIDERS</span>
</div>
<div class="msgs" id="msgs">
<div class="welcome">
<h2>Claw Code Chat</h2>
<p>97 skills souverains &middot; 6 produits WEVAL<br>Tape ta question &mdash; le routeur intelligent choisit le bon agent.</p>
</div>
</div>
<div class="input-area">
<textarea id="in" placeholder="Pose ta question ici..." rows="1" autofocus></textarea>
<button class="btn" id="btn" onclick="go()"><svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg></button>
</div>
<script>
const API='/api/wevia-json-api.php',M=document.getElementById('msgs'),I=document.getElementById('in'),B=document.getElementById('btn');
I.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();go()}});
I.addEventListener('input',()=>{I.style.height='auto';I.style.height=Math.min(I.scrollHeight,140)+'px'});
function q(t){I.value=t;go()}
async function go(){
const t=I.value.trim();if(!t||B.disabled)return;
I.value='';I.style.height='auto';
const w=M.querySelector('.welcome');if(w)w.remove();
M.innerHTML+=`<div class="msg u">${esc(t)}</div>`;
M.innerHTML+=`<div class="typing" id="ty"><div class="dot"></div><div class="dot"></div><div class="dot"></div><span style="margin-left:4px">Routage intelligent...</span></div>`;
M.scrollTop=1e6;B.disabled=true;
try{
const r=await fetch(API,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:t,mode:'fast'})});
const d=await r.json();
document.getElementById('ty')?.remove();
M.innerHTML+=`<div class="msg b"><div class="prov">${esc(d.provider||'WEVIA')}</div>${fmt(d.response||d.error||'...')}</div>`;
}catch(e){
document.getElementById('ty')?.remove();
M.innerHTML+=`<div class="msg b" style="border-left:2px solid #ef4444"><div class="prov">ERREUR</div>${esc(e.message)}</div>`;
}
B.disabled=false;M.scrollTop=1e6;I.focus();
}
function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}
function fmt(s){
s=esc(s);
s=s.replace(/```(\w*)\n([\s\S]*?)```/g,'<pre><code>$2</code></pre>');
s=s.replace(/`([^`]+)`/g,'<code>$1</code>');
s=s.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>');
s=s.replace(/^- (.+)/gm,'<li>$1</li>');
s=s.replace(/(<li>.*<\/li>)/gs,'<ul>$1</ul>');
s=s.replace(/\n/g,'<br>');
return s;
}
</script>
<!-- === 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 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/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><script src="/wtp-unified-dock.js" defer></script>
<script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
<!-- Opus v17 · Claude Pattern SSE (auto-injected) -->
<style id="opus-pattern-style">
#opus-pattern-badge{position:fixed;bottom:20px;right:20px;z-index:99990;
background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff;
padding:10px 16px;border-radius:20px;font:700 0.78rem -apple-system,sans-serif;
cursor:pointer;box-shadow:0 4px 16px rgba(0,0,0,0.35);transition:all 0.2s;
display:flex;align-items:center;gap:6px}
#opus-pattern-badge:hover{transform:translateY(-2px);box-shadow:0 6px 20px rgba(6,182,212,0.4)}
#opus-pattern-modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.8);
z-index:99991;align-items:center;justify-content:center;padding:20px}
#opus-pattern-modal.show{display:flex}
#opus-pattern-box{background:#0b0d15;color:#e2e8f0;border:1px solid rgba(6,182,212,0.3);
border-radius:14px;padding:22px;max-width:820px;width:100%;max-height:85vh;overflow:auto;
font:-apple-system,sans-serif}
#opus-pattern-box h3{font:800 1.2rem;margin-bottom:12px;
background:linear-gradient(135deg,#06b6d4,#ec4899);
-webkit-background-clip:text;-webkit-text-fill-color:transparent}
#opus-pattern-input{width:100%;background:#1a1f3a;color:#fff;border:1px solid rgba(100,116,139,0.3);
border-radius:8px;padding:10px;margin-bottom:10px;font:0.9rem -apple-system}
#opus-pattern-run{background:linear-gradient(135deg,#10b981,#06b6d4);color:#fff;border:0;
padding:10px 20px;border-radius:8px;font:700 0.85rem;cursor:pointer;margin-bottom:14px}
.phase-card{background:rgba(15,23,42,0.8);border:1px solid rgba(100,116,139,0.2);
border-left:3px solid #06b6d4;border-radius:8px;padding:10px 14px;margin-bottom:8px;
font-size:0.82rem}
.phase-card.done{border-left-color:#22c55e}
.phase-card.active{border-left-color:#f59e0b;animation:pulse 1.2s ease infinite}
.phase-name{font-weight:800;color:#06b6d4;margin-bottom:4px;font-size:0.78rem;text-transform:uppercase;letter-spacing:1px}
.phase-data{font-size:0.72rem;color:#94a3b8;font-family:ui-monospace,monospace}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.6}}
#opus-pattern-close{position:absolute;top:14px;right:20px;background:0;border:0;color:#94a3b8;
font-size:1.6rem;cursor:pointer}
/* === WEVIA Gemini Rolling v2 VISIBLE Enrichment (wave 306 batch) === */
.kpi,[class*="card"],[class*="panel"],[class*="room"],.stat-card,.metric-card,.hub-card,.widget,.stat,.box{position:relative!important}
.kpi,[class*="card"],.stat-card,.metric-card,.hub-card{animation:geV2Entrance .8s cubic-bezier(.34,1.56,.64,1) backwards}
.kpi:nth-child(1),[class*="card"]:nth-child(1){animation-delay:0s}
.kpi:nth-child(2),[class*="card"]:nth-child(2){animation-delay:.09s}
.kpi:nth-child(3),[class*="card"]:nth-child(3){animation-delay:.18s}
.kpi:nth-child(4),[class*="card"]:nth-child(4){animation-delay:.27s}
.kpi:nth-child(5),[class*="card"]:nth-child(5){animation-delay:.36s}
.kpi:nth-child(6),[class*="card"]:nth-child(6){animation-delay:.45s}
@keyframes geV2Entrance{from{opacity:0;transform:translateY(24px) scale(.94)}to{opacity:1;transform:translateY(0) scale(1)}}
.kpi,[class*="card"],.stat-card,.metric-card,.hub-card,.widget{border:1px solid transparent!important;box-shadow:0 0 0 1px rgba(236,72,153,.15),0 4px 16px rgba(0,0,0,.25)!important;transition:box-shadow .4s,transform .3s cubic-bezier(.34,1.56,.64,1),filter .3s!important}
.kpi:hover,[class*="card"]:hover,.stat-card:hover,.metric-card:hover,.hub-card:hover{transform:translateY(-6px) scale(1.03)!important;filter:brightness(1.2)!important;box-shadow:0 0 0 2px rgba(236,72,153,.6),0 12px 32px rgba(236,72,153,.25),0 0 24px rgba(78,205,196,.2)!important}
.kpi::before,[class*="card"]::before,.stat-card::before,.metric-card::before,.hub-card::before{content:"";position:absolute;top:12px;right:12px;width:10px;height:10px;border-radius:50%;background:radial-gradient(circle,#2ed573,#1a9a4e);box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5);animation:geV2Pulse 1.6s ease-out infinite;z-index:100;pointer-events:none}
@keyframes geV2Pulse{0%{transform:scale(1);box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5)}50%{transform:scale(1.4);box-shadow:0 0 20px #2ed573,0 0 40px rgba(46,213,115,.8)}100%{transform:scale(1);box-shadow:0 0 12px #2ed573,0 0 24px rgba(46,213,115,.5)}}
body::after{content:"";position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at 70% 30%,transparent 40%,rgba(236,72,153,.06) 100%),radial-gradient(ellipse at 30% 70%,transparent 40%,rgba(78,205,196,.04) 100%);animation:geV2Ambient 10s ease-in-out infinite;z-index:0}
@keyframes geV2Ambient{0%,100%{opacity:.5}50%{opacity:1}}
h1,.header-title,.main-title,.hub-title,.page-title{background-image:linear-gradient(90deg,currentColor 0%,currentColor 40%,rgba(236,72,153,1) 50%,currentColor 60%,currentColor 100%)!important;background-size:200% auto!important;-webkit-background-clip:text!important;background-clip:text!important;-webkit-text-fill-color:transparent!important;animation:geV2Shimmer 5s linear infinite!important}
@keyframes geV2Shimmer{0%{background-position:200% center}100%{background-position:-200% center}}
/* Doctrine zero chevauchement - hide common offenders */
.opus-x-btn,.toggle-top-right-btn,.fab-corner{display:none!important}
/* === end WEVIA Gemini Rolling v2 batch === */
</style>
<div id="opus-pattern-badge" onclick="window.__opusPatternOpen()">
<span>🧠</span><span>Claude Pattern</span>
</div>
<div id="opus-pattern-modal" onclick="if(event.target.id==='opus-pattern-modal')window.__opusPatternClose()">
<div id="opus-pattern-box">
<button id="opus-pattern-close" onclick="window.__opusPatternClose()">×</button>
<h3>🧠 Claude Pattern · 7 phases REAL (SSE live)</h3>
<p style="font-size:0.82rem;color:#94a3b8;margin-bottom:12px">Backend: <b id="opus-pattern-bot">claw-chat</b> · anti-hallucination · langue naturelle</p>
<input id="opus-pattern-input" placeholder="Posez une question (FR ou EN)..." value="bonjour quel est le statut" />
<button id="opus-pattern-run" onclick="window.__opusPatternRun()">▶ Lancer (SSE stream)</button>
<div id="opus-pattern-output"></div>
</div>
</div>
<script>
(function(){
const BOT = 'claw-chat';
window.__opusPatternOpen = () => document.getElementById('opus-pattern-modal').classList.add('show');
window.__opusPatternClose = () => document.getElementById('opus-pattern-modal').classList.remove('show');
window.__opusPatternRun = () => {
const msg = document.getElementById('opus-pattern-input').value.trim();
if (!msg) return;
const out = document.getElementById('opus-pattern-output');
out.innerHTML = '';
const OPUS_SESSION_KEY = 'opus_chatbot_session_' + BOT;
let sess = localStorage.getItem(OPUS_SESSION_KEY);
if (!sess) {
sess = 'opus-' + BOT + '-' + Date.now().toString(36) + '-' + Math.random().toString(36).substr(2, 6);
localStorage.setItem(OPUS_SESSION_KEY, sess);
}
// CF_BYPASS_V23 · direct 127.0.0.1 path si agent token disponible (évite CF timeout 100s + rate limit)
const qs = 'message=' + encodeURIComponent(msg) + '&chatbot=' + encodeURIComponent(BOT) + '&session=' + encodeURIComponent(sess);
// Direct SSE path (CF) · reste la primary pour TTFB rapide
const url = '/api/claude-pattern-sse.php?' + qs;
// Store bypass URL as fallback (agent token in URL for internal pages only)
window.__opusBypassUrl = '/api/cf-bypass-helper.php?target=' + encodeURIComponent('/api/claude-pattern-sse.php?' + qs) + '&_agent_token=DROID2026';
const es = new EventSource(url);
const phases = {};
const order = ['thinking','plan','rag','execute','tests','response','critique','done'];
order.forEach(p => {
const card = document.createElement('div');
card.className = 'phase-card';
card.id = 'phase-' + p;
card.innerHTML = '<div class="phase-name">' + p.toUpperCase() + '</div><div class="phase-data">⏳ waiting...</div>';
out.appendChild(card);
});
order.forEach(evName => {
es.addEventListener(evName, (e) => {
const data = JSON.parse(e.data);
const card = document.getElementById('phase-' + evName);
if (card) {
card.classList.add('done');
card.classList.remove('active');
let txt;
if (evName === 'response' && data.text) {
txt = '<div style="background:rgba(6,182,212,0.1);padding:10px;border-radius:6px;margin-top:6px;color:#e2e8f0;font-size:0.82rem">' + (data.text.substring(0, 600)) + (data.text.length > 600 ? '...' : '') + '</div>';
} else if (evName === 'tests') {
txt = '<div>' + data.passed + '/' + data.total + ' tests ✓</div>';
} else if (evName === 'critique') {
txt = '<div>Quality: <b style="color:' + (data.quality === 'EXCELLENT' ? '#22c55e' : (data.quality === 'OK' ? '#f59e0b' : '#ef4444')) + '">' + data.quality + '</b> (' + (data.quality_score * 5).toFixed(0) + '/5)</div>';
} else {
txt = JSON.stringify(data).substring(0, 300);
}
card.querySelector('.phase-data').innerHTML = txt;
}
if (evName === 'done') es.close();
});
});
es.addEventListener('error', () => es.close());
};
})();
</script>
</body>
</html>