feat(SSOT): v2.json source unique avatars (745 agents) + force span emoji agents-archi + refonte avatar-picker + meeting-rooms->v2
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled

This commit is contained in:
opus
2026-04-21 00:11:41 +02:00
parent b13f90aaf5
commit c1f034cc89
2 changed files with 91 additions and 203 deletions

View File

@@ -1,227 +1,115 @@
<!DOCTYPE html>
<html lang="fr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVIA — Agent Avatar Picker</title>
<title>WEVIA — Agent Avatar Picker (SSOT)</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700;900&family=Nunito:wght@600;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#050a18;color:#e2e8f0;font-family:Nunito,sans-serif}
.hdr{background:linear-gradient(135deg,#0f1629,#1a2035);padding:14px 20px;border-bottom:1px solid rgba(6,182,212,.2);position:sticky;top:0;z-index:50;display:flex;justify-content:space-between;align-items:center}
body{background:#050a18;color:#e2e8f0;font-family:Nunito,sans-serif;min-height:100vh}
.hdr{background:linear-gradient(135deg,#0f1629,#1a2035);padding:14px 20px;border-bottom:1px solid rgba(6,182,212,.2);position:sticky;top:0;z-index:50;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px}
.hdr h1{font:900 15px Orbitron;color:#06b6d4;letter-spacing:1px}
.nav{display:flex;gap:8px;font-size:11px}
.nav{display:flex;gap:8px;font-size:11px;flex-wrap:wrap}
.nav a{color:#94a3b8;text-decoration:none;padding:4px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.08)}
.nav a:hover,.nav a.ac{color:#06b6d4;border-color:#06b6d4}
.filters{padding:10px 20px;display:flex;gap:6px;border-bottom:1px solid rgba(255,255,255,.04)}
.fb{padding:4px 14px;border-radius:6px;border:1px solid rgba(255,255,255,.1);background:none;color:#94a3b8;font:700 10px Nunito;cursor:pointer;letter-spacing:1px}
.nav a:hover{color:#06b6d4;border-color:#06b6d4}
.bar{padding:10px 20px;background:#0a0f1e;border-bottom:1px solid rgba(255,255,255,.04);display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.fb{padding:5px 14px;border-radius:6px;border:1px solid rgba(255,255,255,.1);background:none;color:#94a3b8;font:700 10px Nunito;cursor:pointer;letter-spacing:1px;transition:.15s}
.fb.ac{border-color:#06b6d4;background:rgba(6,182,212,.12);color:#06b6d4}
.grid{padding:16px;display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:12px}
.card{background:#0f1629;border:1px solid rgba(255,255,255,.06);border-radius:10px;padding:14px}
.card.pk{border-color:#ffd700;box-shadow:0 0 12px rgba(255,215,0,.08)}
.ch{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.ch img{width:40px;height:40px;border-radius:8px;border:2px solid rgba(255,255,255,.1)}
.ch .nm{font-weight:800;font-size:13px}
.ch .rl{font-size:9px;color:#64748b}
.ch .pk-lbl{margin-left:auto;font-size:9px;color:#ffd700;background:rgba(255,215,0,.1);padding:2px 8px;border-radius:4px}
.opts{display:flex;gap:5px;flex-wrap:wrap}
.opt{display:flex;flex-direction:column;align-items:center;gap:2px;padding:4px;border-radius:8px;border:2px solid transparent;background:rgba(255,255,255,.02);cursor:pointer;width:68px;transition:.15s}
.opt:hover{background:rgba(255,255,255,.06);transform:scale(1.06)}
.opt.sel{border-color:#ffd700;background:rgba(255,215,0,.06)}
.opt img{width:50px;height:50px;border-radius:6px;background:#1a2035}
.opt span{font-size:7px;color:#94a3b8;text-align:center;line-height:1.1}
.bar{padding:8px 20px;background:#0a0f1e;border-bottom:1px solid rgba(255,215,0,.15);font-size:10px;color:#94a3b8;display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.tag{display:inline-flex;align-items:center;gap:3px;background:rgba(255,215,0,.08);border:1px solid rgba(255,215,0,.2);border-radius:5px;padding:2px 6px;font-size:9px;color:#ffd700}
.tag img{width:14px;height:14px;border-radius:3px}
.copy{padding:8px 20px;border:none;border-radius:8px;background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff;font:700 12px Nunito;cursor:pointer}
.search{flex:1;min-width:200px;padding:6px 12px;border-radius:6px;border:1px solid rgba(255,255,255,.1);background:rgba(0,0,0,.3);color:#e2e8f0;font:600 11px Nunito;outline:none}
.stats{font-size:10px;color:#64748b}
.stats b{color:#06b6d4}
.grid{padding:16px;display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
.card{background:#0f1629;border:1.5px solid rgba(255,255,255,.06);border-radius:12px;padding:14px;display:flex;flex-direction:column;align-items:center;gap:8px;transition:.15s;cursor:pointer}
.card:hover{transform:translateY(-2px);border-color:#06b6d4;box-shadow:0 4px 16px rgba(6,182,212,.15)}
.card.master{border-color:rgba(255,215,0,.5);background:linear-gradient(135deg,#1a1410,#0f1629)}
.card.human{border-color:rgba(74,222,128,.3)}
.card.tool{border-color:rgba(139,92,246,.3)}
.card.gap{box-shadow:0 0 14px rgba(34,211,238,.15);border-color:#22d3ee}
.av{width:72px;height:72px;display:flex;align-items:center;justify-content:center;font-size:42px;line-height:1;border-radius:50%;background:rgba(255,255,255,.05);border:2.5px solid;flex-shrink:0;overflow:hidden}
.card.master .av{border-color:rgba(255,215,0,.65);background:rgba(255,215,0,.08);width:84px;height:84px;font-size:50px}
.card.human .av{border-color:rgba(74,222,128,.5);background:rgba(74,222,128,.06)}
.card.tool .av{border-color:rgba(139,92,246,.5);background:rgba(139,92,246,.08)}
.nm{font-weight:800;font-size:12px;text-align:center;color:#e2e8f0;line-height:1.2;max-width:160px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.meta{display:flex;gap:4px;align-items:center;font-size:9px;color:#64748b;flex-wrap:wrap;justify-content:center}
.tag{padding:1px 6px;border-radius:3px;background:rgba(255,255,255,.06);font-weight:700;letter-spacing:.5px;text-transform:uppercase}
.tag.gap{background:rgba(34,211,238,.15);color:#22d3ee}
.tag.role{background:rgba(255,255,255,.04);color:#94a3b8}
.empty{text-align:center;padding:40px;color:#64748b;font-size:12px}
</style></head><body>
<div class="hdr">
<h1>🎨 AGENT AVATAR PICKER</h1>
<h1>🎨 AGENT AVATAR PICKER · SSOT v2.json</h1>
<div class="nav">
<a href="/agents-archi.html">← Architecture 3D</a>
<a href="/wevia-meeting-rooms.html">Meeting Rooms</a>
<a href="/enterprise-model.html">Enterprise</a>
<a href="/agents-fleet.html">Fleet</a>
</div>
</div>
<div class="filters" id="F"></div>
<div class="bar" id="B" style="display:none"></div>
<div class="grid" id="G"></div>
<div class="bar">
<button class="fb ac" data-f="all">ALL</button>
<button class="fb" data-f="master">MASTER</button>
<button class="fb" data-f="human">HUMAN</button>
<button class="fb" data-f="tool">TOOL</button>
<button class="fb" data-f="gap">GAP ONLY</button>
<input class="search" id="srch" placeholder="🔍 Search agent...">
<div class="stats" id="stats">Loading...</div>
</div>
<div class="grid" id="G"><div class="empty">Loading SSOT (agent-avatars-v2.json)...</div></div>
<script>
var A=[
{n:"WEVIA Master",t:"STRATÉGIE",y:"robot",c:"#06b6d4",r:"Head of AI — Orchestrateur Suprême"},
{n:"Director",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Cerveau autonome"},
{n:"Master Router",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"46 routes · 14 providers"},
{n:"Consensus",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Vote multi-provider"},
{n:"Dispatcher",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Moteur de routes"},
{n:"MiroFish",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"WePredict auto-guérison"},
{n:"Blade",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Agent desktop Razer"},
{n:"DeerFlow",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Deep research 12+ sources"},
{n:"AutoFix",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Docker heal 16 containers"},
{n:"Fiability",t:"DIRECTION",y:"robot",c:"#8b5cf6",r:"Santé 24 URLs"},
{n:"DevOps",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"CI/CD · 4 serveurs"},
{n:"Ethica",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"HCP Pharma · 141K+ contacts"},
{n:"Security",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"CVE+SSL+Nuclei"},
{n:"Monitor",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"Uptime 24/7"},
{n:"NonReg",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"Régression 151/153"},
{n:"WEVCODE",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"Code IA · 4 modes"},
{n:"L99 Pilot",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"Qualité Lean 6σ"},
{n:"Scraper",t:"TACTIQUE",y:"robot",c:"#f59e0b",r:"DabaDoc MA+TN+DZ"},
{n:"ArchScan",t:"TACTIQUE",y:"robot",c:"#f59e0b",r:"Topologie 52 nœuds"},
{n:"CrowdSec",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"IDS/IPS"},
{n:"Fail2Ban",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"SSH protect"},
{n:"Registry",t:"TACTIQUE",y:"human",c:"#f59e0b",r:"Registre 626 pages"},
{n:"Ollama",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"LLM LOCAL souverain"},
{n:"Groq",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"<200ms Llama-3.3"},
{n:"Cerebras",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"Qwen-3 235B"},
{n:"SambaNova",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"Meta-Llama"},
{n:"Paperclip",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"Fleet 669 agents"},
{n:"Sentinel",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"Relais S95"},
{n:"Docker",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"16 containers"},
{n:"PMTA",t:"EXÉCUTION",y:"robot",c:"#ef4444",r:"MTA sacré port 25"}
];
let DATA = {};
let activeFilter = 'all';
let activeSearch = '';
function opts(a){
var s=encodeURIComponent(a.n);
if(a.y==="robot") return [
{u:"https://robohash.org/"+s+"?set=set1&size=150x150",l:"Robot"},
{u:"https://robohash.org/"+s+"-v2?set=set1&size=150x150",l:"Robot V2"},
{u:"https://robohash.org/"+s+"-v3?set=set1&size=150x150",l:"Robot V3"},
{u:"https://robohash.org/"+s+"?set=set2&size=150x150",l:"Monster"},
{u:"https://robohash.org/"+s+"?set=set3&size=150x150",l:"Head"},
{u:"https://robohash.org/"+s+"?set=set4&size=150x150",l:"Cat"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name="+s,l:"Bottts"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name="+s,l:"Emoji"}
];
return [
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name="+s,l:"Adventurer"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name="+s+"-v2",l:"Advent. V2"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name="+s+"-v3",l:"Advent. V3"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=avataaars/svg?seed="+s,l:"Avataaars"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=big-smile/svg?seed="+s,l:"Big Smile"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=lorelei/svg?seed="+s,l:"Lorelei"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=notionists/svg?seed="+s,l:"Notionists"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=open-peeps/svg?seed="+s,l:"Open Peeps"},
{u:"https://ui-avatars.com/api/?background=random&color=fff&size=64&name=pixel-art/svg?seed="+s,l:"Pixel Art"},
{u:"https://robohash.org/"+s+"?set=set5&size=150x150",l:"RH Human"}
];
async function load(){
try {
const r = await fetch('/api/agent-avatars-v2.json?t=' + Date.now());
DATA = await r.json();
render();
} catch(e) {
document.getElementById('G').innerHTML = '<div class="empty">ERR loading SSOT: ' + e.message + '</div>';
}
}
var P={},CF="ALL";
function render(){
var fl=A;if(CF!=="ALL")fl=A.filter(function(a){return a.t===CF});
var fh="";["ALL","STRATÉGIE","DIRECTION","TACTIQUE","EXÉCUTION"].forEach(function(t){
fh+='<button class="fb'+(CF===t?" ac":"")+'" onclick="CF=\''+t+'\';render()">'+t+'</button>';
});
document.getElementById("F").innerHTML=fh;
var n=Object.keys(P).length;
if(n>0){
var bh='<b style="color:#ffd700">'+n+' choix</b> ';
for(var k in P){bh+='<span class="tag"><img src="'+P[k].u+'">'+k+' ('+P[k].l+')</span> ';}
bh+=' <button class="copy" onclick="doCopy()">📋 Copier</button>';
document.getElementById("B").style.display="flex";
document.getElementById("B").innerHTML=bh;
}else{document.getElementById("B").style.display="none";}
var gh="";
fl.forEach(function(a){
var o=opts(a);var pk=P[a.n];
gh+='<div class="card'+(pk?" pk":"")+'"><div class="ch">';
if(pk)gh+='<img src="'+pk.u+'">';
gh+='<div><div class="nm" style="color:'+a.c+'">'+a.n+'</div><div class="rl">'+a.r+'</div></div>';
if(pk)gh+='<span class="pk-lbl">✓ '+pk.l+'</span>';
gh+='</div><div class="opts">';
o.forEach(function(op){
var sel=pk&&pk.u===op.u;
gh+='<div class="opt'+(sel?" sel":"")+'" onclick="pick(\''+a.n.replace(/'/g,"\\'")+'\',\''+op.u.replace(/'/g,"\\'")+'\',\''+op.l+'\')">';
gh+='<img src="'+op.u+'" loading="lazy" onerror="this.style.opacity=0.2"><span>'+op.l+'</span></div>';
});
gh+='</div></div>';
});
document.getElementById("G").innerHTML=gh;
}
function pick(n,u,l){if(P[n]&&P[n].u===u)delete P[n];else P[n]={u:u,l:l};render();}
function doCopy(){
var t="";for(var k in P)t+=k+": "+P[k].l+" → "+P[k].u+"\n";
if(navigator.clipboard)navigator.clipboard.writeText(t);
alert(Object.keys(P).length+" choix copiés !\n\n"+t);
}
render();
</script>
<script>
// WAVE 165 — avatar-picker: fix broken dicebear.com images
window.__avatar_fix_v165=true;
document.addEventListener("DOMContentLoaded",function(){
const placeholder='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiBmaWxsPSIjMWUyOTNiIi8+PHRleHQgeD0iMzIiIHk9IjM4IiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgZm9udC1zaXplPSIyNCIgZmlsbD0iIzA2YjZkNCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QTwvdGV4dD48L3N2Zz4=';
Array.from(document.querySelectorAll("img")).forEach(img=>{
img.addEventListener("error",function(){this.onerror=null;this.src=placeholder;},false);
// Preemptively check
if(img.src.indexOf("dicebear.com")>-1){
const orig=img.src;
img.onerror=function(){this.src=placeholder;};
}
const G = document.getElementById('G');
const entries = Object.entries(DATA);
const filtered = entries.filter(([n, a]) => {
if (activeSearch && !n.toLowerCase().includes(activeSearch)) return false;
if (activeFilter === 'all') return true;
if (activeFilter === 'gap') return a.isGap;
return a.persona === activeFilter;
});
if (!filtered.length) {
G.innerHTML = '<div class="empty">No agent matches</div>';
document.getElementById('stats').innerHTML = '<b>0</b> / ' + entries.length;
return;
}
G.innerHTML = filtered.map(([n, a]) => {
const cls = ['card', a.persona || 'human'];
if (a.isGap) cls.push('gap');
const safeN = n.replace(/[<>"']/g, c => ({'<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c]);
return `<div class="${cls.join(' ')}" title="${safeN}">
<div class="av">${a.emoji || '👤'}</div>
<div class="nm">${safeN}</div>
<div class="meta">
${a.isGap ? '<span class="tag gap">GAP</span>' : ''}
${a.role ? '<span class="tag role">' + a.role + '</span>' : ''}
</div>
</div>`;
}).join('');
document.getElementById('stats').innerHTML = '<b>' + filtered.length + '</b> / ' + entries.length + ' agents';
}
document.querySelectorAll('.fb').forEach(b => b.onclick = () => {
document.querySelectorAll('.fb').forEach(x => x.classList.remove('ac'));
b.classList.add('ac');
activeFilter = b.dataset.f;
render();
});
document.getElementById('srch').oninput = e => { activeSearch = e.target.value.toLowerCase().trim(); render(); };
load();
</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 === -->
</body></html>

View File

@@ -638,7 +638,7 @@ var _hist=[];function addHist(msg){_hist.unshift({t:new Date().toLocaleTimeStrin
(function() {
if (window.__WEVAL_AVATAR_V75) return;
window.__WEVAL_AVATAR_V75 = true;
const REG_URL = '/api/agent-avatars-v75.json';
const REG_URL = '/api/agent-avatars-v2.json';
const SVG_EP = '/api/agent-avatar-svg.php';
function emojiSVGUrl(name, emoji) {
return SVG_EP + '?n=' + encodeURIComponent(name) + '&e=' + encodeURIComponent(emoji);