Files
html/tasks-live-opus5.html.gold-v5-source-patch
2026-04-19 22:50:03 +02:00

284 lines
15 KiB
Plaintext

<!DOCTYPE html>
<html lang="fr"><head>
<meta charset="UTF-8"><title>WEVAL Tasks Live Opus5</title>
<style>
body{font-family:-apple-system,system-ui,sans-serif;background:#0a0e27;color:#e4e8f7;margin:0;padding:0;line-height:1.5}
.container{max-width:1400px;margin:0 auto;padding:24px}
h1{color:#6ba3ff;border-bottom:2px solid #1e3a8a;padding-bottom:8px;margin-top:0;font-size:22px;font-weight:500}
h2{color:#c084fc;margin-top:20px;font-size:18px;font-weight:500}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;margin-top:16px}
.card{background:#141933;border:1px solid #263161;border-radius:10px;padding:16px}
.metric{font-size:26px;font-weight:500;margin:4px 0;color:#e4e8f7}
.metric-label{font-size:12px;color:#9ca8d3;text-transform:uppercase;letter-spacing:0.5px}
.status-ok{color:#10b981}.status-warn{color:#fbbf24}.status-bad{color:#ef4444}
.events{background:#0f1529;border:1px solid #263161;border-radius:10px;padding:16px;margin-top:20px;max-height:400px;overflow-y:auto}
.event-row{display:grid;grid-template-columns:75px 1fr 130px 70px;gap:10px;padding:8px 0;border-bottom:1px solid #1e2a4a;font-size:13px;align-items:center}
.event-row:last-child{border-bottom:none}
.event-time{color:#6b7a9e;font-family:SF Mono,monospace;font-size:11px}
.event-intent{color:#fbbf24;font-weight:500}
.event-prov{color:#9ca8d3;font-size:11px}
.event-ms{text-align:right;color:#9ca8d3;font-variant-numeric:tabular-nums}
.badge{display:inline-block;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:0.5px}
.badge-live{background:rgba(16,185,129,0.2);color:#10b981}
.badge-dead{background:rgba(239,68,68,0.2);color:#ef4444}
.trigger-btn{background:#1e3a8a;color:#e4e8f7;border:1px solid #2a4db5;padding:6px 12px;border-radius:6px;cursor:pointer;font-size:12px;margin:3px;transition:all 0.15s}
.trigger-btn:hover{background:#2a4db5;border-color:#3b5dcc}
.reply{background:#0a1224;padding:12px;border-radius:6px;margin-top:10px;font-family:SF Mono,monospace;font-size:12px;color:#d1d5db;max-height:200px;overflow-y:auto;white-space:pre-wrap}
</style>
</head><body>
<div class="container">
<h1>Tasks Live Opus5 Dispatch-Proxy Monitor</h1>
<p style="color:#9ca8d3;font-size:13px">Connected to /api/opus5-task-log.php auto-refresh 5s streaming ready</p>
<div class="grid">
<div class="card"><div class="metric-label">Events tracked</div><div class="metric" id="m-total"></div></div>
<div class="card"><div class="metric-label">Dispatches</div><div class="metric" id="m-dispatch"></div></div>
<div class="card"><div class="metric-label">Proxy (master-api)</div><div class="metric" id="m-proxy"></div></div>
<div class="card"><div class="metric-label">Avg latency</div><div class="metric" id="m-lat"></div></div>
<div class="card"><div class="metric-label">Ethica HCPs</div><div class="metric" id="m-ethica">156 714</div></div>
<div class="card"><div class="metric-label">NR status</div><div class="metric status-ok" id="m-nr">153/153</div></div>
<div class="card"><div class="metric-label">L99 status</div><div class="metric status-ok" id="m-l99">304/304</div></div>
<div class="card"><div class="metric-label">Blade</div><div class="metric" id="m-blade"><span class="badge" id="blade-status-live" style="background:#064e3b;color:#86efac">checking...</span></div></div>
</div>
<h2>Quick triggers (one-click test)</h2>
<div style="margin-top:10px">
<button class="trigger-btn" onclick="trigger('sovereign status')">sovereign status</button>
<button class="trigger-btn" onclick="trigger('ethica live')">ethica live</button>
<button class="trigger-btn" onclick="trigger('s95 load')">s95 load</button>
<button class="trigger-btn" onclick="trigger('blade wake')">blade wake</button>
<button class="trigger-btn" onclick="trigger('p0 status')">p0 status</button>
<button class="trigger-btn" onclick="trigger('crm stats live')">crm stats</button>
<button class="trigger-btn" onclick="trigger('task log')">task log</button>
<button class="trigger-btn" onclick="trigger('combien de fichiers')">count 11435</button>
</div>
<div class="reply" id="reply" style="display:none"></div>
<h2>Recent events (live)</h2>
<div class="events" id="events"></div>
</div>
<script>
async function trigger(msg){
const reply=document.getElementById('reply');reply.style.display='block';reply.textContent='Loading: '+msg;
try{
const r=await fetch('/api/wevia-master-dispatch.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg,session:'tasks-ui'})});
const d=await r.json();
reply.textContent='['+d.provider+'] intent='+(d.intent||d.tool||'?')+' ms='+d.ms+'\n\n'+(d.response||d.content||d.output||JSON.stringify(d,null,2)).substring(0,2000);
setTimeout(load,500);
}catch(e){reply.textContent='Error: '+e.message}
}
async function load(){
try{
const r=await fetch('/api/opus5-task-log.php?limit=25');
const d=await r.json();
const events=d.events||[];
const stats=d.stats||{};
document.getElementById('m-total').textContent=(stats.total_lines||0).toLocaleString();
document.getElementById('m-dispatch').textContent=events.filter(e=>(e.provider||'').includes('dispatch-proxy')).length;
document.getElementById('m-proxy').textContent=events.filter(e=>e.type==='proxy').length;
const lats=events.map(e=>e.ms).filter(m=>typeof m==='number');
document.getElementById('m-lat').textContent=lats.length?Math.round(lats.reduce((a,b)=>a+b,0)/lats.length)+'ms':'';
const ev=document.getElementById('events');ev.innerHTML='';
events.slice(0,20).forEach(e=>{
const r=document.createElement('div');r.className='event-row';
const time=(e.ts||'').slice(11,19);
const intent=e.intent||'?';
const prov=(e.provider||'').replace('opus5-','').replace('opus-','');
const ms=e.ms?e.ms+'ms':'';
r.innerHTML='<span class="event-time">'+time+'</span><span class="event-intent">'+intent+'</span><span class="event-prov">'+prov+'</span><span class="event-ms">'+ms+'</span>';
ev.appendChild(r);
});
if(events.length===0){ev.innerHTML='<div style="color:#9ca8d3;padding:8px">No events yet. Click a trigger above.</div>';}
}catch(e){console.error(e)}
}
load();setInterval(load,5000);
</script>
<!-- V8.5 CANONICAL STATS LOADER (doctrine 14 additif 19avr Opus) -->
<script>
(function(){
if (window.__opus5_canonical) return; window.__opus5_canonical = true;
async function updateCanonical(){
// NR + L99 from canonical APIs (source of truth)
try {
const nr = await fetch('/api/nonreg-api.php?cat=all', {cache:'no-store'}).then(r=>r.json());
const nrEl = document.getElementById('m-nr');
if (nrEl && nr.pass !== undefined) nrEl.textContent = nr.pass + '/' + nr.total;
} catch(e) {}
try {
const l99 = await fetch('/api/l99-api.php?action=stats', {cache:'no-store'}).then(r=>r.json());
const l99El = document.getElementById('m-l99');
if (l99El && l99.pass !== undefined) l99El.textContent = l99.pass + '/' + l99.total;
} catch(e) {}
// Ethica HCPs (use visual-management-live for total, fallback ethica-stats)
try {
const vm = await fetch('/api/visual-management-live.php', {cache:'no-store'}).then(r=>r.json());
const eEl = document.getElementById('m-ethica');
if (eEl) {
const total = (vm && vm.ethica && vm.ethica.total) || (vm && vm.hcps_total) || (vm && vm.ethica_total);
if (total) eEl.textContent = total.toLocaleString('fr-FR');
}
} catch(e) {
try {
const es = await fetch('/api/ethica-stats.php', {cache:'no-store'}).then(r=>r.json());
const eEl = document.getElementById('m-ethica');
if (eEl && es.total) eEl.textContent = es.total.toLocaleString('fr-FR');
} catch(e2){}
}
// Blade status
try {
const b = await fetch('/api/blade-status-public.php', {cache:'no-store'}).then(r=>r.json());
const bEl = document.getElementById('m-blade');
if (bEl && b) {
const lastHb = b.last_hb || b.last_heartbeat || b.lastHeartbeat;
const online = b.online === true || b.status === 'online';
if (online) {
bEl.innerHTML = '<span class="badge" style="background:rgba(16,185,129,0.15);color:#10b981;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:700">ONLINE</span>';
} else if (lastHb) {
const age = Math.floor((Date.now() - new Date(lastHb).getTime()) / 3600000);
bEl.innerHTML = '<span class="badge" style="background:rgba(239,68,68,0.15);color:#ef4444;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:700">DEAD ' + age + 'h</span>';
}
}
} catch(e) {}
}
// Run immediately + every 5s
updateCanonical();
setInterval(updateCanonical, 5000);
})();
</script>
<!-- /V8.5 CANONICAL STATS LOADER -->
<!-- === 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>
async function loadBladeStatus() {
try {
const r = await fetch('/api/blade-heartbeat.json', {cache:'no-store'});
const d = await r.json();
const el = document.getElementById('blade-status-live');
if (!el) return;
const ageMin = Math.floor((Date.now()/1000 - (d.last_heartbeat_ts_epoch||0)) / 60);
const ageH = (ageMin/60).toFixed(1);
if (ageMin < 30) { el.style.background='#064e3b'; el.style.color='#86efac'; el.textContent='ALIVE '+ageMin+'m'; }
else if (ageMin < 120) { el.style.background='#78350f'; el.style.color='#fcd34d'; el.textContent='STALE '+ageH+'h'; }
else { el.style.background='#7f1d1d'; el.style.color='#fca5a5'; el.textContent='DEAD '+ageH+'h'; }
} catch(e) {}
}
loadBladeStatus(); setInterval(loadBladeStatus, 30000);
</script>
<!-- === OPUS HONEST NR/L99 OVERLAY v1 19avr - append-only doctrine #14 === -->
<script>
(function(){
if (window.__opusHonestOverlay) return; window.__opusHonestOverlay = true;
async function updateHonestValues(){
try {
const r = await fetch('/api/l99-honest.php', {cache:'no-store'});
const d = await r.json();
if (!d.ok) return;
// Find any element showing "153/153" or "304/304" and ADD a secondary live value next to it
const bodyText = document.body.innerHTML;
// Replace static "153/153" inline with live real value
const realNR = `${d.combined.pass}/${d.combined.total}`;
const realSigma = d.sigma;
document.querySelectorAll('*').forEach(el => {
if (el.children.length === 0 && el.textContent) {
if (el.textContent.trim() === '153/153' || el.textContent.trim() === 'NR status 153/153') {
el.setAttribute('data-original', el.textContent);
el.innerHTML = `<span style="color:#14b8a6">${realNR}</span> <sup style="color:#94a3b8;font-size:0.7em">(was 153/153)</sup>`;
}
if (el.textContent.trim() === '304/304' || el.textContent.trim() === 'L99 status 304/304') {
el.setAttribute('data-original', el.textContent);
el.innerHTML = `<span style="color:#14b8a6">${realNR}</span> <sup style="color:#94a3b8;font-size:0.7em">(was 304/304 hardcoded)</sup>`;
}
}
});
// Add a banner showing the honest status at top of body if not already
if (!document.getElementById('opus-honest-banner')) {
const banner = document.createElement('div');
banner.id = 'opus-honest-banner';
banner.style.cssText = 'position:fixed;top:0;left:0;right:0;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 14px;font:11px/1.4 Inter,system-ui,sans-serif;font-weight:700;text-align:center;z-index:99994;box-shadow:0 2px 8px rgba(0,0,0,0.3)';
banner.innerHTML = `📊 HONEST NonReg live: ${realNR} (${realSigma}) · master 72/72 + opus 129/129 = ${d.combined.total} real tests · doctrine #4`;
document.body.appendChild(banner);
}
} catch(e){console.error('L99-honest fetch error:', e);}
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
else updateHonestValues();
setInterval(updateHonestValues, 60000);
})();
</script>
<!-- === OPUS HONEST END === -->
</body></html>