Files
html/agents-fleet.html
2026-04-19 22:40:02 +02:00

391 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WEVAL Agents Fleet</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Outfit:wght@300;500;700;900&display=swap" rel="stylesheet">
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap');
:root {
--bg: #06080f;
--card: #0c1020;
--border: #1a2040;
--text: #c8d0e0;
--dim: #5a6580;
--green: #22c55e;
--red: #ef4444;
--blue: #3b82f6;
--purple: #a855f7;
--amber: #f59e0b;
--cyan: #06b6d4;
--pink: #ec4899;
--lime: #84cc16;
}
* { margin:0; padding:0; box-sizing:border-box; }
body { background:var(--bg); color:var(--text); font-family:'Outfit',sans-serif; min-height:100vh; overflow-x:hidden; }
.noise { position:fixed; inset:0; opacity:.03; pointer-events:none; background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
header {
padding:40px 40px 20px;
display:flex; justify-content:space-between; align-items:flex-end;
border-bottom:1px solid var(--border);
}
h1 { font-size:2.8rem; font-weight:900; letter-spacing:-2px; line-height:1; }
h1 span { background:linear-gradient(135deg,var(--cyan),var(--purple)); -webkit-background-clip:text; -webkit-text-fill-color:transparent; }
.stats { display:flex; gap:24px; }
.stat { text-align:center; }
.stat-num { font-family:'JetBrains Mono',monospace; font-size:2rem; font-weight:700; }
.stat-label { font-size:.7rem; text-transform:uppercase; letter-spacing:2px; color:var(--dim); }
.type-filter { display:flex; gap:8px; padding:20px 40px; flex-wrap:wrap; }
.type-btn { background:var(--card); border:1px solid var(--border); color:var(--dim); padding:6px 16px; border-radius:20px; cursor:pointer; font-size:.8rem; font-family:'Outfit',sans-serif; transition:.2s; }
.type-btn:hover, .type-btn.active { border-color:var(--cyan); color:var(--cyan); background:#0a1530; }
.grid {
display:grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap:16px;
padding:20px 40px 60px;
}
.agent-card {
background:var(--card);
border:1px solid var(--border);
border-radius:16px;
padding:20px;
position:relative;
overflow:hidden;
transition: transform .25s, border-color .3s, box-shadow .3s;
cursor:default;
animation: fadeUp .5s ease both;
}
.agent-card:hover {
transform:translateY(-4px);
border-color:var(--cyan);
box-shadow:0 8px 32px rgba(6,182,212,.12);
}
@keyframes fadeUp {
from { opacity:0; transform:translateY(20px); }
to { opacity:1; transform:translateY(0); }
}
.agent-avatar {
width:56px; height:56px;
border-radius:14px;
display:flex; align-items:center; justify-content:center;
font-size:1.6rem;
margin-bottom:12px;
position:relative;
}
.agent-avatar::after {
content:'';
position:absolute;
bottom:-2px; right:-2px;
width:14px; height:14px;
border-radius:50%;
border:2px solid var(--card);
}
.agent-card[data-status="active"] .agent-avatar::after { background:var(--green); }
.agent-card[data-status="down"] .agent-avatar::after { background:var(--red); }
.agent-card[data-status="offline"] .agent-avatar::after { background:var(--amber); }
.agent-name { font-weight:700; font-size:1rem; margin-bottom:4px; color:#fff; }
.agent-type {
display:inline-block;
font-size:.65rem;
text-transform:uppercase;
letter-spacing:1.5px;
padding:2px 8px;
border-radius:6px;
margin-bottom:8px;
font-weight:500;
}
.agent-desc { font-size:.82rem; color:var(--dim); line-height:1.4; margin-bottom:10px; min-height:40px; }
.agent-produces { font-family:'JetBrains Mono',monospace; font-size:.7rem; color:var(--cyan); opacity:.7; }
.type-cognitive .agent-avatar { background:linear-gradient(135deg,#1e3a5f,#0d1b2a); }
.type-cognitive .agent-type { background:#1e3a5f33; color:var(--blue); }
.type-autonomous .agent-avatar { background:linear-gradient(135deg,#4a1942,#1a0a18); }
.type-autonomous .agent-type { background:#4a194233; color:var(--purple); }
.type-mode .agent-avatar { background:linear-gradient(135deg,#1a3a1a,#0a180a); }
.type-mode .agent-type { background:#1a3a1a33; color:var(--lime); }
.type-backend .agent-avatar { background:linear-gradient(135deg,#3a2a1a,#1a1508); }
.type-backend .agent-type { background:#3a2a1a33; color:var(--amber); }
.type-research .agent-avatar { background:linear-gradient(135deg,#1a2a3a,#081520); }
.type-research .agent-type { background:#1a2a3a33; color:var(--cyan); }
.type-creative .agent-avatar { background:linear-gradient(135deg,#3a1a2a,#200a18); }
.type-creative .agent-type { background:#3a1a2a33; color:var(--pink); }
.type-monitor .agent-avatar, .type-security .agent-avatar { background:linear-gradient(135deg,#2a2a1a,#18180a); }
.type-monitor .agent-type, .type-security .agent-type { background:#2a2a1a33; color:var(--amber); }
.type-desktop .agent-avatar { background:linear-gradient(135deg,#1a2a2a,#0a1818); }
.type-desktop .agent-type { background:#1a2a2a33; color:var(--cyan); }
.type-scraper .agent-avatar { background:linear-gradient(135deg,#2a1a2a,#180a18); }
.type-scraper .agent-type { background:#2a1a2a33; color:var(--pink); }
.pulse { animation:pulse 2s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:.7} 50%{opacity:1} }
footer { text-align:center; padding:20px; color:var(--dim); font-size:.75rem; border-top:1px solid var(--border); }
footer a { color:var(--cyan); text-decoration:none; }
.loading { text-align:center; padding:80px; color:var(--dim); font-size:1.2rem; }
</style>
<link rel="stylesheet" href="/css/weval-premium.css">
</head><!--archi-->
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
<a href="/wevia-meeting-rooms.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Rooms</a>
<a href="/enterprise-model.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Enterprise</a>
<a href="/value-stream.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">VSM</a>
<a href="/value-chain.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Chain</a>
<a href="/toolhub.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Tools</a>
<a href="/wiki.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Wiki</a>
<a href="/agents-ia.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Pyramid</a>
<a href="/director-chat.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Chat</a>
<a href="/l99-brain.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">L99</a>
</div><div id="live-stats" ondblclick="this.remove()" style="position:fixed;top:0;left:0;right:0;z-index:9999;display:flex;justify-content:center;gap:12px;padding:4px 8px;background:linear-gradient(135deg,#1e293b,#0f172a);font-family:sans-serif"><div style="color:#4ade80;font:700 10px sans-serif"><body>#9889; <span id="ls-ag">669</span> Agents</div><div style="color:#60a5fa;font:700 10px sans-serif"><body>#127970; <span id="ls-dp">22</span> Depts</div><div style="color:#fbbf24;font:700 10px sans-serif"><body>#128051; 20 Docker</div><div style="color:#a78bfa;font:700 10px sans-serif"><body>#129302; 10 Ollama</div><div style="color:#f87171;font:700 10px sans-serif"><body>#128200; <span id="ls-nr">153/153</span></div><div style="color:#34d399;font:700 10px sans-serif"><body>#128274; SSO OK</div><div style="width:6px;height:6px;border-radius:50%;background:#4ade80;animation:lp 2s infinite;align-self:center"></div></div><style>@keyframes lp{0%,100%{opacity:1}50%{opacity:.3}}</style>
<div class="noise"></div>
<header>
<div>
<h1><span>WEVAL</span> Agents Fleet</h1>
<p style="color:var(--dim);margin-top:6px;font-size:.9rem">Intelligence souveraine — 0 dépendance cloud US</p>
</div>
<div class="stats">
<div class="stat"><div class="stat-num" id="s-total"></div><div class="stat-label">Agents</div></div>
<div class="stat"><div class="stat-num" style="color:var(--green)" id="s-active"></div><div class="stat-label">Actifs</div></div>
<div class="stat"><div class="stat-num" style="color:var(--purple)" id="s-types"></div><div class="stat-label">Types</div></div>
</div>
</header>
<div class="type-filter" id="filters"></div>
<div class="grid" id="grid"><div class="loading pulse">Chargement des agents...</div></div>
<footer>
WEVAL Consulting — <a href="/">weval-consulting.com</a> — Casablanca | Paris | NYC — Powered by WEVIA Sovereign AI
</footer>
<script>
const AVATARS = {
'analyst':'🔍','architect':'🏗️','code-reviewer':'👁️','code-simplifier':'✂️',
'critic':'⚖️','debugger':'🐛','designer':'🎨','document-specialist':'📝',
'executor':'⚡','explore':'🧭','git-master':'🌿','planner':'📋',
'qa-tester':'🧪','scientist':'🔬','security-reviewer':'🛡️','test-engineer':'🧰',
'tracer':'🔦','verifier':'✅','writer':'✍️',
'CEO':'👔','WEDROID':'🤖','DeerFlow':'🦌','MiroFish':'🐟',
'/sc:brainstorming':'💡','/sc:business_panel':'📊','/sc:deep_research':'🔬',
'/sc:introspection':'🧠','/sc:orchestration':'🎯','/sc:task_management':'📋',
'/sc:token_efficiency':'⚡',
'Watchdog':'🐕','Guardian':'🛡️','Blade Sentinel':'💻','Ethica Scraper':'💊'
};
const PRODUCES = {
'analyst':'→ Analyse requirements, specs',
'architect':'→ Architecture, diagrammes, decisions',
'code-reviewer':'→ Code reviews, severity ratings',
'code-simplifier':'→ Code refactoré, simplifié',
'critic':'→ Plans validés, risques identifiés',
'debugger':'→ Bugs tracés, root cause, fix',
'designer':'→ UI/UX, mockups, wireframes',
'document-specialist':'→ Docs techniques, README',
'executor':'→ Scripts exécutés, déploiements',
'explore':'→ Exploration, R&D, prototypes',
'git-master':'→ Branches, merges, releases',
'planner':'→ Roadmaps, sprints, milestones',
'qa-tester':'→ Tests E2E, couverture, rapports',
'scientist':'→ Recherche, benchmarks, données',
'security-reviewer':'→ Audits OWASP, vulnérabilités',
'test-engineer':'→ Suites de tests, CI/CD',
'tracer':'→ Logs tracés, chaîne de debug',
'verifier':'→ Validation, conformité, checks',
'writer':'→ Articles, content, copywriting',
'CEO':'→ Stratégie, décisions, hiring (autonome)',
'WEDROID':'→ Diagnostic serveur, DB, fix auto',
'DeerFlow':'→ Recherche deep, synthèse multi-source',
'MiroFish':'→ Contenu créatif, brainstorm',
'/sc:brainstorming':'→ Idées générées, évaluation',
'/sc:business_panel':'→ Analyses business, KPIs',
'/sc:deep_research':'→ Recherche approfondie',
'/sc:introspection':'→ Méta-analyse, réflexion',
'/sc:orchestration':'→ Coordination multi-agent',
'/sc:task_management':'→ Tasks, deadlines, suivi',
'/sc:token_efficiency':'→ Réponses ultra-concises',
'Watchdog':'→ Auto-restart services, alertes TG',
'Guardian':'→ Protection fichiers, chattr +i',
'Blade Sentinel':'→ Tâches desktop, PowerShell',
'Ethica Scraper':'→ 131K+ HCPs enrichis MA/TN/DZ'
};
let allAgents = [];
let activeFilter = 'all';
async function load() {
try {
const r = await fetch('/api/agents-status.php');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
allAgents = d.agents || [];
document.getElementById('s-total').textContent = d.total;
document.getElementById('s-active').textContent = d.active;
const types = [...new Set(allAgents.map(a=>a.type))];
document.getElementById('s-types').textContent = types.length;
// Build filters
const fhtml = [`<button class="type-btn active" onclick="filter('all')">Tous (${d.total})</button>`];
const typeCounts = {};
allAgents.forEach(a => { typeCounts[a.type] = (typeCounts[a.type]||0)+1; });
Object.entries(typeCounts).sort((a,b)=>b[1]-a[1]).forEach(([t,c]) => {
fhtml.push(`<button class="type-btn" onclick="filter('${t}')">${t} (${c})</button>`);
});
document.getElementById('filters').innerHTML = fhtml.join('');
render(allAgents);
} catch(e) {
document.getElementById('grid').innerHTML = '<div class="loading">Erreur chargement</div>';
}
}
function filter(type) {
activeFilter = type;
document.querySelectorAll('.type-btn').forEach(b => b.classList.remove('active'));
event.target.classList.add('active');
const filtered = type === 'all' ? allAgents : allAgents.filter(a => a.type === type);
render(filtered);
}
function render(agents) {
const grid = document.getElementById('grid');
grid.innerHTML = agents.map((a, i) => `
<div class="agent-card type-${a.type}" data-status="${a.status}" style="animation-delay:${i*40}ms">
<div class="agent-avatar">${AVATARS[a.name] || '🤖'}</div>
<div class="agent-name">${a.name}</div>
<div class="agent-type">${a.type}${a.source ? ' · '+a.source : ''}</div>
<div class="agent-desc">${a.desc || ''}</div>
<div class="agent-produces">${PRODUCES[a.name] || '→ Processing...'}</div>
</div>
`).join('');
}
load();
setInterval(load, 30000);
</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 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 === -->
<!-- === 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;
const realNR = `${d.combined.pass}/${d.combined.total}`;
const realSigma = d.sigma;
// Find elements showing the myth values
const mythRegex = /(153\/153|304\/304|NR status 153\/153|L99 status 304\/304|NR 153\/153|L99 304\/304)/g;
// Walk text nodes
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
const toReplace = [];
let node;
while (node = walker.nextNode()) {
if (node.nodeValue && mythRegex.test(node.nodeValue)) toReplace.push(node);
}
toReplace.forEach(textNode => {
const parent = textNode.parentNode;
if (!parent || parent.hasAttribute('data-opus-honest-applied')) return;
const newText = textNode.nodeValue.replace(/153\/153/g, realNR).replace(/304\/304/g, realNR);
textNode.nodeValue = newText;
parent.setAttribute('data-opus-honest-applied', '1');
});
// Add a small badge bottom-right showing honest live status
if (!document.getElementById('opus-honest-badge')) {
const b = document.createElement('div');
b.id = 'opus-honest-badge';
b.style.cssText = 'position:fixed;bottom:12px;right:12px;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 12px;font:10px/1.3 Inter,system-ui,sans-serif;font-weight:700;border-radius:8px;z-index:99993;box-shadow:0 4px 12px rgba(0,0,0,0.3);cursor:pointer;max-width:280px';
b.title = 'Cliquer pour détails';
b.innerHTML = `✓ NR ${realNR} · ${realSigma} live`;
b.onclick = () => {
alert(`HONEST NonReg (doctrine #4):\n\nmaster: ${d.master.pass}/${d.master.total}\nopus: ${d.opus.pass}/${d.opus.total}\ncombined: ${realNR}\nsigma: ${realSigma}\n\n${d.myth_153}\n${d.myth_304}`);
};
document.body.appendChild(b);
}
} catch(e){console.error('L99-honest fetch error:', e);}
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
else updateHonestValues();
setInterval(updateHonestValues, 90000);
})();
</script>
<!-- === OPUS HONEST END === -->
</body>
</html>