AUTO-BACKUP 20260408-1100

This commit is contained in:
WEVIA-Bot
2026-04-08 11:00:05 +02:00
parent 586bef0328
commit 4fea59f11c
17 changed files with 718 additions and 1985 deletions

263
agents-ia.html Normal file
View File

@@ -0,0 +1,263 @@
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVIA — Agents IA Autonomes</title>
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{background:#0b1120;color:#e2e8f0;font-family:'Nunito';overflow-x:hidden}
::selection{background:#059669;color:#fff}
/* HUD */
#hud{position:fixed;top:0;left:0;right:0;height:28px;background:linear-gradient(135deg,#1e293b,#0f172a);z-index:100;display:flex;align-items:center;padding:0 12px;gap:14px;font-size:.65rem;border-bottom:1px solid #1e293b}
.hs{color:#94a3b8;display:flex;align-items:center;gap:4px}.hs .v{font-weight:800}
.hs .ok{color:#4ade80}.hs .wn{color:#fbbf24}.hs .cr{color:#f87171}.hs .in{color:#60a5fa}
.pulse{width:6px;height:6px;border-radius:50%;background:#4ade80;animation:lp 2s infinite;margin-left:auto}
@keyframes lp{0%,100%{opacity:1}50%{opacity:.3}}
/* NAV */
#nav{position:fixed;top:32px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:5px;z-index:90;background:rgba(11,17,32,.85);backdrop-filter:blur(12px)}
#nav a{padding:3px 10px;border-radius:5px;font:700 9px Nunito;text-decoration:none;color:#94a3b8;border:1px solid #1e293b;transition:.2s}
#nav a:hover{background:#059669;color:#fff;border-color:#059669}
#nav a.ac{background:#059669;color:#fff;border-color:#059669}
/* HERO */
.hero{padding:90px 40px 40px;text-align:center;position:relative;overflow:hidden}
.hero::before{content:'';position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(ellipse at 50% 0%,rgba(5,150,105,.12) 0%,transparent 60%);pointer-events:none}
.hero h1{font-size:42px;font-weight:900;background:linear-gradient(135deg,#4ade80,#06b6d4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:8px;letter-spacing:-1px}
.hero p{font-size:16px;color:#94a3b8;max-width:600px;margin:0 auto 30px;line-height:1.6}
.hero-stats{display:flex;justify-content:center;gap:24px;flex-wrap:wrap}
.hero-stat{text-align:center}
.hero-stat .n{font-size:32px;font-weight:900;color:#4ade80}
.hero-stat .l{font-size:10px;color:#64748b;text-transform:uppercase;letter-spacing:1.5px;font-weight:700}
/* PYRAMID */
.pyramid-wrap{max-width:1100px;margin:0 auto;padding:40px 20px}
.pyramid-title{text-align:center;font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:3px;font-weight:800;margin-bottom:30px}
.pyramid{display:flex;flex-direction:column;align-items:center;gap:0;position:relative}
.pyramid::before{content:'';position:absolute;top:40px;bottom:40px;left:50%;width:2px;background:linear-gradient(180deg,#059669,#06b6d4,#7c3aed,#e94560);transform:translateX(-50%);z-index:0}
.tier{position:relative;z-index:1;width:100%;display:flex;flex-direction:column;align-items:center;margin-bottom:8px}
.tier-label{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.tier-badge{padding:4px 14px;border-radius:20px;font-size:10px;font-weight:800;letter-spacing:1px;text-transform:uppercase;border:2px solid}
.tier-badge.t0{background:rgba(5,150,105,.15);color:#4ade80;border-color:#059669}
.tier-badge.t1{background:rgba(6,182,212,.12);color:#22d3ee;border-color:#06b6d4}
.tier-badge.t2{background:rgba(124,58,237,.12);color:#a78bfa;border-color:#7c3aed}
.tier-badge.t3{background:rgba(233,69,96,.12);color:#fb7185;border-color:#e94560}
.tier-agents{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;padding:8px 0}
/* Agent Card */
.ag{width:110px;background:rgba(30,41,59,.7);backdrop-filter:blur(8px);border:1px solid #334155;border-radius:12px;padding:12px 8px;text-align:center;cursor:pointer;transition:all .25s;position:relative;overflow:hidden}
.ag::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,#059669,transparent);opacity:0;transition:.3s}
.ag:hover{transform:translateY(-4px);border-color:#059669;box-shadow:0 8px 30px rgba(5,150,105,.15)}
.ag:hover::before{opacity:1}
.ag-ico{font-size:28px;margin-bottom:6px;display:block}
.ag-name{font-size:11px;font-weight:800;color:#e2e8f0;margin-bottom:2px}
.ag-sub{font-size:8px;color:#64748b;font-weight:600}
.ag-dot{position:absolute;top:8px;right:8px;width:7px;height:7px;border-radius:50%;border:1.5px solid rgba(0,0,0,.3)}
.ag-dot.on{background:#4ade80;box-shadow:0 0 6px rgba(74,222,128,.5)}
.ag-dot.off{background:#ef4444}
.ag-dot.idle{background:#fbbf24}
/* Connector lines between tiers */
.tier-connector{width:2px;height:20px;background:linear-gradient(180deg,var(--c1,#059669),var(--c2,#06b6d4));margin:0 auto;border-radius:1px}
/* Features section */
.features{max-width:1000px;margin:40px auto;padding:0 20px;display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px}
.feat{background:rgba(30,41,59,.5);border:1px solid #1e293b;border-radius:14px;padding:20px;transition:border .3s}
.feat:hover{border-color:#059669}
.feat-ico{font-size:24px;margin-bottom:8px}
.feat h3{font-size:14px;font-weight:800;color:#4ade80;margin-bottom:6px}
.feat p{font-size:12px;color:#94a3b8;line-height:1.5}
/* Live metrics strip */
.live-strip{max-width:1000px;margin:30px auto;padding:0 20px}
.strip{display:flex;gap:10px;overflow-x:auto;padding:4px 0}
.strip-card{flex:0 0 auto;background:rgba(30,41,59,.6);border:1px solid #1e293b;border-radius:10px;padding:10px 16px;min-width:120px;text-align:center}
.strip-card .sv{font-size:20px;font-weight:900;color:#4ade80}
.strip-card .sl{font-size:9px;color:#64748b;text-transform:uppercase;letter-spacing:1px;font-weight:700}
/* CTA */
.cta{text-align:center;padding:40px 20px 80px}
.cta-btn{display:inline-block;padding:12px 32px;border-radius:10px;font:800 14px Nunito;text-decoration:none;color:#fff;border:2px solid;transition:.3s;margin:0 6px}
.cta-btn.green{background:#059669;border-color:#047857}.cta-btn.green:hover{background:#047857;transform:translateY(-2px)}
.cta-btn.blue{background:transparent;border-color:#3b82f6;color:#60a5fa}.cta-btn.blue:hover{background:#3b82f6;color:#fff}
.cta-btn.purple{background:transparent;border-color:#7c3aed;color:#a78bfa}.cta-btn.purple:hover{background:#7c3aed;color:#fff}
/* Particles */
.particles{position:fixed;top:0;left:0;right:0;bottom:0;pointer-events:none;z-index:0}
.particle{position:absolute;width:2px;height:2px;background:#4ade80;border-radius:50%;opacity:0;animation:float linear infinite}
@keyframes float{0%{opacity:0;transform:translateY(100vh)}10%{opacity:.4}90%{opacity:.4}100%{opacity:0;transform:translateY(-20px)}}
@media(max-width:768px){.features{grid-template-columns:1fr}.hero h1{font-size:28px}.ag{width:80px}.ag-ico{font-size:20px}}
</style></head><body>
<div class="particles" id="particles"></div>
<!-- HUD -->
<div id="hud">
<div class="hs"><b style="color:#4ade80">WEVIA AGENTS</b></div>
<div class="hs">Agents <span class="v ok" id="hAg"></span></div>
<div class="hs">Providers <span class="v in" id="hProv"></span></div>
<div class="hs">Docker <span class="v ok" id="hDock"></span></div>
<div class="hs">NonReg <span class="v ok" id="hNR"></span></div>
<div class="hs">Cost <span class="v ok">0€</span></div>
<div class="pulse"></div>
</div>
<!-- NAV -->
<div id="nav">
<a href="/agents-ia.html" class="ac">Agents IA</a>
<a href="/director-center.html">Director</a>
<a href="/wevia-meeting-rooms.html">Rooms</a>
<a href="/enterprise-model.html">Enterprise</a>
<a href="/director-chat.html">Chat</a>
<a href="/l99-brain.html">L99</a>
<a href="/wevia-master.html">Master</a>
</div>
<!-- HERO -->
<div class="hero">
<h1>Agents IA Autonomes</h1>
<p>Un écosystème d'agents spécialisés qui observent, décident et agissent. Orchestration intelligente, résultats mesurables, coût zéro.</p>
<div class="hero-stats">
<div class="hero-stat"><div class="n" id="statAgents">42</div><div class="l">Agents actifs</div></div>
<div class="hero-stat"><div class="n" id="statProviders">14</div><div class="l">Providers IA</div></div>
<div class="hero-stat"><div class="n" id="statPages">626</div><div class="l">Pages surveillées</div></div>
<div class="hero-stat"><div class="n" id="statCost">0€</div><div class="l">Coût mensuel</div></div>
</div>
</div>
<!-- PYRAMID -->
<div class="pyramid-wrap">
<div class="pyramid-title">Architecture Multi-Agents Souveraine</div>
<div class="pyramid" id="pyramid"></div>
</div>
<!-- FEATURES -->
<div class="features">
<div class="feat"><div class="feat-ico">🎯</div><h3>Autonomie totale</h3><p>Le Director observe l'infra toutes les 15 min, détecte les anomalies et corrige automatiquement. Zéro intervention humaine.</p></div>
<div class="feat"><div class="feat-ico">🧠</div><h3>IA Souveraine</h3><p>14 providers LLM (Ollama, Cerebras, Groq, SambaNova) — cascade intelligente, coût 0€, données qui ne sortent jamais du serveur.</p></div>
<div class="feat"><div class="feat-ico"></div><h3>Auto-réparation</h3><p>Docker crash → auto-restart. SSL expiré → alerte. Disk plein → cleanup. NonReg fail → rollback. Tout est automatisé.</p></div>
<div class="feat"><div class="feat-ico">📊</div><h3>Fiabilité 100%</h3><p>24 URLs critiques + 10 subdomains vérifiées chaque heure. Score fiabilité temps réel visible sur le dashboard.</p></div>
<div class="feat"><div class="feat-ico">🔒</div><h3>Sécurité intégrée</h3><p>Nuclei CVE scan, Vaultwarden, Fail2ban, Guardian file protection, SSL monitoring — la sécurité dans chaque couche.</p></div>
<div class="feat"><div class="feat-ico">🌍</div><h3>Multi-domaines</h3><p>WEVADS email, Ethica pharma, WEVIA IA, 88 produits SaaS — tous gérés par le même écosystème d'agents.</p></div>
</div>
<!-- LIVE METRICS -->
<div class="live-strip">
<div class="strip" id="liveStrip"></div>
</div>
<!-- CTA -->
<div class="cta">
<a href="/director-center.html" class="cta-btn green">🎯 Director Center</a>
<a href="/director-chat.html" class="cta-btn blue">💬 Parler au Director</a>
<a href="/enterprise-model.html" class="cta-btn purple">🏢 Enterprise Model</a>
</div>
<script>
// Pyramid tiers
const TIERS=[
{label:'DIRECTION',badge:'t0',color:'#059669',agents:[
{n:'Director',ico:'🎯',sub:'Autonomous brain',on:true},
{n:'Master Router',ico:'🧠',sub:'Smart routing',on:true},
]},
{label:'ORCHESTRATION',badge:'t1',color:'#06b6d4',agents:[
{n:'Consensus',ico:'🤝',sub:'Multi-vote',on:true},
{n:'Dispatcher',ico:'📡',sub:'46 routes',on:true},
{n:'MiroFish',ico:'🐟',sub:'Self-heal',on:true},
{n:'Blade',ico:'⚔️',sub:'Agent loop',on:true},
]},
{label:'SPÉCIALISTES',badge:'t2',color:'#7c3aed',agents:[
{n:'DevOps',ico:'🔧',sub:'Infra monitor',on:true},
{n:'Ethica',ico:'💊',sub:'HCP data',on:true},
{n:'Security',ico:'🛡',sub:'CVE + SSL',on:true},
{n:'Monitor',ico:'📊',sub:'Uptime 24/7',on:true},
{n:'NonReg',ico:'✅',sub:'152/153',on:true},
{n:'Fiability',ico:'🔍',sub:'100% score',on:true},
{n:'WEVCODE',ico:'💻',sub:'Code assist',on:true},
{n:'Scraper',ico:'🕷',sub:'DabaDoc',on:true},
]},
{label:'EXÉCUTION',badge:'t3',color:'#e94560',agents:[
{n:'Ollama',ico:'🦙',sub:'10 models',on:true},
{n:'Cerebras',ico:'⚡',sub:'<500ms',on:true},
{n:'Groq',ico:'🚀',sub:'<200ms',on:true},
{n:'SambaNova',ico:'💎',sub:'<800ms',on:true},
{n:'Qdrant',ico:'🔷',sub:'4 RAG cols',on:true},
{n:'Sentinel',ico:'🏰',sub:'S95 brain',on:true},
{n:'Docker',ico:'🐳',sub:'20 containers',on:true},
{n:'PMTA',ico:'📧',sub:'4 ECS',on:true},
{n:'Proactive',ico:'⚡',sub:'Auto-heal',on:true},
{n:'Prometheus',ico:'📈',sub:'Metrics',on:true},
]},
];
function renderPyramid(){
const el=document.getElementById('pyramid');
el.innerHTML=TIERS.map((t,ti)=>{
const maxW=40+ti*20;
const agents=t.agents.map(a=>`
<div class="ag" style="--ac:${t.color}">
<div class="ag-dot ${a.on?'on':'off'}"></div>
<span class="ag-ico">${a.ico}</span>
<div class="ag-name">${a.n}</div>
<div class="ag-sub">${a.sub}</div>
</div>`).join('');
return`
${ti>0?`<div class="tier-connector" style="--c1:${TIERS[ti-1].color};--c2:${t.color}"></div>`:''}
<div class="tier" style="max-width:${maxW}%">
<div class="tier-label"><span class="tier-badge ${t.badge}">${t.label}</span></div>
<div class="tier-agents">${agents}</div>
</div>`;
}).join('');
}
// Live metrics strip
async function loadMetrics(){
try{
const[dir,master,fia]=await Promise.all([
fetch('/api/wevia-director.php?status').then(r=>r.json()).catch(()=>({})),
fetch('/api/wevia-master-api.php?health').then(r=>r.json()).catch(()=>({})),
fetch('/api/wevia-fiability.php?report').then(r=>r.json()).catch(()=>({})),
]);
const o=dir.observations||{};
const totalCalls=Object.values(master.stats||{}).reduce((s,d)=>s+d.total,0);
document.getElementById('hAg').textContent=TIERS.reduce((s,t)=>s+t.agents.length,0);
document.getElementById('hProv').textContent=(master.tier1_providers||0)+(master.tier2_providers||0);
document.getElementById('hDock').textContent=o.s204_docker_count||'?';
document.getElementById('hNR').textContent='152/153';
document.getElementById('statProviders').textContent=(master.tier1_providers||0)+(master.tier2_providers||0);
document.getElementById('liveStrip').innerHTML=[
{v:o.s204_disk?.percent+'%',l:'Disk S204'},
{v:o.s204_docker_count||'?',l:'Docker'},
{v:o.s204_ollama||'?',l:'Ollama'},
{v:(o.url_checks_ok||'?')+'/'+(o.url_checks_total||'?'),l:'URLs OK'},
{v:(o.subdomain_checks_ok||'?')+'/'+(o.subdomain_checks_total||'?'),l:'Subdomains'},
{v:fia.score!==undefined?fia.score+'%':'—',l:'Fiability'},
{v:totalCalls,l:'LLM Calls'},
{v:'0€',l:'Cost'},
{v:(dir.duration_ms||0)+'ms',l:'Cycle Time'},
{v:o.topo_nodes||'?',l:'Arch Nodes'},
].map(m=>`<div class="strip-card"><div class="sv">${m.v}</div><div class="sl">${m.l}</div></div>`).join('');
}catch(e){}
}
// Particles
function initParticles(){
const c=document.getElementById('particles');
for(let i=0;i<30;i++){
const p=document.createElement('div');p.className='particle';
p.style.left=Math.random()*100+'%';
p.style.animationDuration=(8+Math.random()*12)+'s';
p.style.animationDelay=Math.random()*10+'s';
p.style.width=p.style.height=(1+Math.random()*2)+'px';
p.style.background=['#4ade80','#06b6d4','#a78bfa','#fbbf24'][Math.floor(Math.random()*4)];
c.appendChild(p);
}
}
renderPyramid();
loadMetrics();
initParticles();
setInterval(loadMetrics,30000);
</script>
</body></html>

View File

@@ -28,6 +28,7 @@ a{color:var(--cy);text-decoration:none}
.lb{display:flex;flex-direction:column;gap:3px}
.lb-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:5px;transition:background .15s}
.lb-row:hover{background:var(--bg3)}
.lb-usage{font-size:8px;color:var(--t3);min-width:100px;text-align:right;font-family:monospace}.lb-cas{display:inline-block;padding:1px 4px;border-radius:3px;font-size:7px;font-weight:700;margin-left:4px}
.lb-rank{font-size:11px;font-weight:800;font-family:var(--mono);width:24px;text-align:center;color:var(--mu)}
.lb-icon{font-size:15px;width:22px;text-align:center}
.lb-info{flex:1;min-width:0}
@@ -76,7 +77,7 @@ const BG={reference:'rgba(210,153,34,.1)',chatbot:'rgba(88,166,255,.1)',backend:
function sc(s){return s>=75?'sc-h':s>=55?'sc-m':'sc-l'}
async function load(){try{const r=await fetch(CACHE+'?t='+Date.now());render(await r.json())}catch(e){document.getElementById('app').innerHTML='<p style="color:var(--rd)">'+e+'</p>'}}
function render(c){
const A=c.all_ais||{},comp=c.composite||{},lb=c.leaderboard||{},gen=c.generated||'',R=c.report||{};
const A=c.all_ais||{},comp=c.composite||{},lb=c.leaderboard||{},UM=c.usage_map||{},gen=c.generated||'',R=c.report||{};
const S=(Array.isArray(lb)?lb:Object.entries(lb).map(e=>({name:e[0],score:e[1]}))).sort((a,b)=>(b.score||0)-(a.score||0)),mx=S[0]?S[0].score:90;
const cats=Object.keys(comp).sort((a,b)=>(comp[b]||0)-(comp[a]||0));
const cbs=['WEVIA','WEVCODE','MANAGER','DeerFlow','SENTINEL','Ethica_Chat','WEVADS_IA','Qwen3_235b_Cerebras','Mistral_Small_EU','DeepSeekV31_SambaNova','ChatGPT_4o','Gemini_Pro','Claude_Opus'];
@@ -93,12 +94,13 @@ let h=`<div class="stats">
<div class="card"><div class="card-h"><div class="card-t">🏆 Leaderboard</div><span class="badge b-vi">${S.length} AIs</span></div>
<div class="card-b"><div class="lb">
${S.map((item,i)=>{const n=item.name||item[0]||"?";const avg=item.score||item[1]||0;const a=A[n]||{};const t=a.type||'?';const col=COL[t]||'#7d8590';const bg=BG[t]||'';
const pct=Math.round(avg/mx*100);const vO=Math.round(avg/90*100);
const pct=Math.round(avg/mx*100);const vO=Math.round(avg/90*100);const um=UM[n]||{};
return `<div class="lb-row">
<div class="lb-rank" style="${i<3?'color:var(--go)':''}">${i+1}</div>
<div class="lb-icon">${a.icon||'?'}</div>
<div class="lb-info"><div class="lb-name">${n}</div><div class="lb-desc">${a.tier?'<span style="font-size:7px;opacity:.7">'+a.tier+'</span> ':''} ${(a.desc||'').slice(0,35)}</div></div>
<div class="lb-type" style="background:${bg};color:${col}">${t}</div>
<div class="lb-usage">${um.used_by?(um.used_by).join(", "):"—"}${um.cascade!=null?" C"+um.cascade:""}</div>
<div class="lb-bar-w"><div class="lb-bar" style="width:${pct}%;background:${col}" data-w="${pct}%"></div></div>
<div class="lb-sc" style="color:${col}">${avg}</div>
<div class="lb-pct">${vO}%</div>

View File

@@ -1 +1 @@
{"timestamp":"2026-04-08 08:49:51","scan_ms":7948,"servers":{"s204":{"ip":"204.168.152.13","label":"S204 Primary","services":[{"name":"nginx","status":"active","port":"80\/443"},{"name":"php-fpm","status":"active","port":"9000"},{"name":"postgresql-16","status":"active","port":"5432"},{"name":"deerflow","status":"active","port":"2024"},{"name":"deerflow-gw","status":"active","port":"8001"},{"name":"deerflow-fe","status":"active","port":"3000"},{"name":"ollama","status":"active","port":"11434","info":"10 models"}],"docker":[{"name":"chatwoot-redis","status":"Up 37 hours"},{"name":"langfuse","status":"Up 37 hours"},{"name":"loki","status":"Up 37 hours"},{"name":"mattermost","status":"Up 10 hours (healthy)"},{"name":"n8n","status":"Up 10 hours"},{"name":"node-exporter","status":"Up 37 hours"},{"name":"plausible-db","status":"Up 37 hours"},{"name":"plausible-events","status":"Up 37 hours"},{"name":"plausible","status":"Up 37 hours"},{"name":"prometheus","status":"Up 37 hours"},{"name":"qdrant","status":"Up 37 hours"},{"name":"searxng","status":"Up 37 hours"},{"name":"twenty-redis","status":"Up 37 hours"},{"name":"twenty","status":"Up 37 hours"},{"name":"uptime-kuma","status":"Up 37 hours (healthy)"},{"name":"vaultwarden","status":"Up 37 hours (healthy)"}]},"s95":{"ip":"95.216.167.89","label":"S95 WEVADS","services":[{"name":"kumomta","status":"active","port":"587"},{"name":"apache2","status":"active","port":"80"},{"name":"postgresql","status":"active","port":"5432"},{"name":"postfix","status":"active","port":"2525"},{"name":"pmta","status":"active","port":"25"},{"name":"sentinel","status":"active","port":"5890"},{"name":"adx","status":"active","port":"5821"},{"name":"arsenal","status":"active","port":"5822"}],"docker":[{"name":"listmonk_db","status":"Up 4 days"},{"name":"listmonk","status":"Up 4 days"}]},"s151":{"ip":"151.80.235.110","label":"S151 OVH","services":[{"name":"nginx","status":"active","port":"80"},{"name":"php-fpm","status":"active","port":"9000"},{"name":"postgresql","status":"active","port":"5432"},{"name":"ollama","status":"active","port":"11434"}],"docker":[{"name":"ollama","status":"Up 2 weeks"}]},"blade":{"ip":"local","label":"Razer Blade","services":[{"name":"Sentinel Agent","status":"active","port":"\u2014","info":"C:\\ProgramData\\WEVAL\\sentinel-agent.ps1"}],"docker":[]}},"crons":[{"server":"S95","user":"root","schedule":"*\/30 * * * *","command":"php \/opt\/wevads\/scripts\/ethica\/ethica-validator.php 500 >> \/opt\/wevads\/logs\/ethica-validator.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"0 *\/4 * * *","command":"php \/opt\/wevads\/scripts\/cron-bounces.php >> \/var\/log\/wevads\/bounces.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"0 3 * * *","command":"\/root\/backups\/daily_backup.sh","source":"crontab"},{"server":"S95","user":"root","schedule":"0 4 * * *","command":"\/opt\/wevads\/scripts\/auto-backup-github.sh >> \/var\/log\/wevads\/backup.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"30 0 * * *","command":"php \/opt\/wevads\/scripts\/daily-stats-aggregate.php >> \/var\/log\/wevads\/daily-stats.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"30 1 * * *","command":"php \/opt\/wevads\/scripts\/cron-engagement.php >> \/var\/log\/wevads\/engagement.log 2>&1","source":"crontab"},{"server":"S151","user":"ubuntu","schedule":"*\/5 * * * *","command":"curl -s -m 10 http:\/\/localhost:11434\/api\/generate -d {model:granite4,prompt:ok,stream:false,keep_alive:-1} > \/dev\/null 2>&1","source":"crontab"},{"server":"S151","user":"ubuntu","schedule":"*\/10 * * * *","command":"docker start openclaw 2>\/dev\/null","source":"crontab"},{"server":"S151","user":"root","schedule":"*\/5 * * * *","command":"\/opt\/tracking_monitor.sh","source":"crontab"},{"server":"Blade","user":"SYSTEM","schedule":"*\/60s loop","command":"sentinel-agent.ps1 (auto-sync S204)","source":"Task Scheduler"}],"stats":{"total_crons":10,"total_services":20,"total_docker":19}}
{"timestamp":"2026-04-08 08:59:08","scan_ms":7833,"servers":{"s204":{"ip":"204.168.152.13","label":"S204 Primary","services":[{"name":"nginx","status":"active","port":"80\/443"},{"name":"php-fpm","status":"active","port":"9000"},{"name":"postgresql-16","status":"active","port":"5432"},{"name":"deerflow","status":"active","port":"2024"},{"name":"deerflow-gw","status":"active","port":"8001"},{"name":"deerflow-fe","status":"active","port":"3000"},{"name":"ollama","status":"active","port":"11434","info":"10 models"}],"docker":[{"name":"chatwoot-redis","status":"Up 37 hours"},{"name":"langfuse","status":"Up 37 hours"},{"name":"loki","status":"Up 37 hours"},{"name":"mattermost","status":"Up 11 hours (healthy)"},{"name":"n8n","status":"Up 10 hours"},{"name":"node-exporter","status":"Up 37 hours"},{"name":"plausible-db","status":"Up 37 hours"},{"name":"plausible-events","status":"Up 37 hours"},{"name":"plausible","status":"Up 37 hours"},{"name":"prometheus","status":"Up 37 hours"},{"name":"qdrant","status":"Up 37 hours"},{"name":"searxng","status":"Up 37 hours"},{"name":"twenty-redis","status":"Up 37 hours"},{"name":"twenty","status":"Up 37 hours"},{"name":"uptime-kuma","status":"Up 37 hours (healthy)"},{"name":"vaultwarden","status":"Up 37 hours (healthy)"}]},"s95":{"ip":"95.216.167.89","label":"S95 WEVADS","services":[{"name":"kumomta","status":"active","port":"587"},{"name":"apache2","status":"active","port":"80"},{"name":"postgresql","status":"active","port":"5432"},{"name":"postfix","status":"active","port":"2525"},{"name":"pmta","status":"active","port":"25"},{"name":"sentinel","status":"active","port":"5890"},{"name":"adx","status":"active","port":"5821"},{"name":"arsenal","status":"active","port":"5822"}],"docker":[{"name":"listmonk_db","status":"Up 4 days"},{"name":"listmonk","status":"Up 4 days"}]},"s151":{"ip":"151.80.235.110","label":"S151 OVH","services":[{"name":"nginx","status":"active","port":"80"},{"name":"php-fpm","status":"active","port":"9000"},{"name":"postgresql","status":"active","port":"5432"},{"name":"ollama","status":"active","port":"11434"}],"docker":[{"name":"ollama","status":"Up 2 weeks"}]},"blade":{"ip":"local","label":"Razer Blade","services":[{"name":"Sentinel Agent","status":"active","port":"\u2014","info":"C:\\ProgramData\\WEVAL\\sentinel-agent.ps1"}],"docker":[]}},"crons":[{"server":"S95","user":"root","schedule":"*\/30 * * * *","command":"php \/opt\/wevads\/scripts\/ethica\/ethica-validator.php 500 >> \/opt\/wevads\/logs\/ethica-validator.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"0 *\/4 * * *","command":"php \/opt\/wevads\/scripts\/cron-bounces.php >> \/var\/log\/wevads\/bounces.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"0 3 * * *","command":"\/root\/backups\/daily_backup.sh","source":"crontab"},{"server":"S95","user":"root","schedule":"0 4 * * *","command":"\/opt\/wevads\/scripts\/auto-backup-github.sh >> \/var\/log\/wevads\/backup.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"30 0 * * *","command":"php \/opt\/wevads\/scripts\/daily-stats-aggregate.php >> \/var\/log\/wevads\/daily-stats.log 2>&1","source":"crontab"},{"server":"S95","user":"root","schedule":"30 1 * * *","command":"php \/opt\/wevads\/scripts\/cron-engagement.php >> \/var\/log\/wevads\/engagement.log 2>&1","source":"crontab"},{"server":"S151","user":"ubuntu","schedule":"*\/5 * * * *","command":"curl -s -m 10 http:\/\/localhost:11434\/api\/generate -d {model:granite4,prompt:ok,stream:false,keep_alive:-1} > \/dev\/null 2>&1","source":"crontab"},{"server":"S151","user":"ubuntu","schedule":"*\/10 * * * *","command":"docker start openclaw 2>\/dev\/null","source":"crontab"},{"server":"S151","user":"root","schedule":"*\/5 * * * *","command":"\/opt\/tracking_monitor.sh","source":"crontab"},{"server":"Blade","user":"SYSTEM","schedule":"*\/60s loop","command":"sentinel-agent.ps1 (auto-sync S204)","source":"Task Scheduler"}],"stats":{"total_crons":10,"total_services":20,"total_docker":19}}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-04-08 08:30:13",
"generated": "2026-04-08 09:00:02",
"nodes": [
{
"id": "docker_loki",
@@ -1123,6 +1123,6 @@
"stats": {
"nodes": 45,
"edges": 30,
"scan_ms": 209
"scan_ms": 1797
}
}

View File

@@ -1,10 +1,10 @@
{
"ts": "2026-04-08T08:49:46+00:00",
"ts": "2026-04-08T08:59:19+00:00",
"hostname": "LAPTOP-VE75QUHF",
"cpu": "100%",
"ram": "97% (16GB)",
"cpu": "79%",
"ram": "88% (16GB)",
"disk": "?",
"uptime": "1d07h57m",
"uptime": "1d08h07m",
"user": "Yace",
"ip": "41.248.190.86",
"agent_version": "2.0"

View File

@@ -13,5 +13,5 @@
"Run simulation",
"CEO insights"
],
"timestamp": "2026-04-08 08:50:02"
"timestamp": "2026-04-08 09:00:02"
}

View File

@@ -1 +1 @@
{"ts": "20260408_104012", "version": "3.2", "score": 98, "pass": 151, "fail": 2, "total": 153, "elapsed": 53.2, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 11, "fail": 1}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 9, "fail": 1}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": [{"n": "WV-Send", "c": "S95-WV", "s": "FAIL", "d": "500 0KB"}, {"n": "Caps10", "c": "01AVR", "s": "FAIL", "d": "9/10"}]}
{"ts": "20260408_105012", "version": "3.2", "score": 98, "pass": 151, "fail": 2, "total": 153, "elapsed": 51.6, "categories": {"S204": {"pass": 9, "fail": 0}, "S95-WV": {"pass": 11, "fail": 1}, "S95-ARS": {"pass": 17, "fail": 0}, "S95-iR": {"pass": 1, "fail": 0}, "INFRA": {"pass": 5, "fail": 0}, "API": {"pass": 27, "fail": 0}, "SEC": {"pass": 4, "fail": 0}, "S95-BK": {"pass": 6, "fail": 0}, "C2-API": {"pass": 4, "fail": 0}, "C2-SPA": {"pass": 1, "fail": 0}, "C2-WV": {"pass": 3, "fail": 0}, "SSO": {"pass": 25, "fail": 0}, "DATA": {"pass": 5, "fail": 0}, "CRONS": {"pass": 2, "fail": 0}, "BLADE": {"pass": 7, "fail": 0}, "LIFE": {"pass": 3, "fail": 0}, "FUNC": {"pass": 7, "fail": 0}, "01AVR": {"pass": 9, "fail": 1}, "STRUCT": {"pass": 5, "fail": 0}}, "failures": [{"n": "WV-Send", "c": "S95-WV", "s": "FAIL", "d": "500 0KB"}, {"n": "Caps10", "c": "01AVR", "s": "FAIL", "d": "9/10"}]}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
{
"timestamp": "2026-04-08 10:45:07",
"timestamp": "2026-04-08 10:55:09",
"healthy": true,
"issues": [],
"fixes": [],

View File

@@ -1,5 +1,5 @@
{
"timestamp": "2026-04-08 08:45:09",
"timestamp": "2026-04-08 08:55:08",
"healthy": false,
"checks": {
"outpost": "DOWN",
@@ -30,57 +30,57 @@
{
"level": "critical",
"msg": "Outpost DOWN 9090",
"ts": "2026-04-08T08:45:01+00:00"
"ts": "2026-04-08T08:55:01+00:00"
},
{
"level": "critical",
"msg": "Outpost STILL DOWN",
"ts": "2026-04-08T08:45:07+00:00"
"ts": "2026-04-08T08:55:06+00:00"
},
{
"level": "warning",
"msg": "Auth flow ethica.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:07+00:00"
"ts": "2026-04-08T08:55:07+00:00"
},
{
"level": "warning",
"msg": "Auth flow n8n.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:07+00:00"
"ts": "2026-04-08T08:55:07+00:00"
},
{
"level": "warning",
"msg": "Auth flow crm.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:07+00:00"
},
{
"level": "warning",
"msg": "Auth flow mm.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:07+00:00"
},
{
"level": "warning",
"msg": "Auth flow analytics.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:07+00:00"
},
{
"level": "warning",
"msg": "Auth flow deerflow.weval-consulting.com: 200",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:08+00:00"
},
{
"level": "warning",
"msg": "Callback location missing in nginx",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:08+00:00"
}
],
"fixes": [
{
"title": "Restart authentik",
"ts": "2026-04-08T08:45:02+00:00"
"ts": "2026-04-08T08:55:01+00:00"
},
{
"title": "Callback location auto-added",
"ts": "2026-04-08T08:45:08+00:00"
"ts": "2026-04-08T08:55:08+00:00"
}
]
}

View File

@@ -1,5 +1,5 @@
{
"timestamp": "2026-04-08 08:45:02",
"timestamp": "2026-04-08 08:55:01",
"version": "1.0",
"disk": 84,
"ram": 30,
@@ -14,21 +14,21 @@
{
"level": "critical",
"msg": "S204:authentik DOWN (:9090)",
"time": "08:45:02"
"time": "08:55:01"
},
{
"level": "warning",
"msg": "Architecture score 83\/100",
"time": "08:45:02"
"time": "08:55:02"
}
],
"log": [
"08:45:02 Disk: 84%",
"08:45:02 SSL: 362d remaining",
"08:45:02 Docker: 16 containers",
"08:45:02 Ollama: 10 models, 31.3GB",
"08:45:02 RAM: 30%",
"08:45:02 Arch score: 83\/100"
"08:55:01 Disk: 84%",
"08:55:01 SSL: 362d remaining",
"08:55:01 Docker: 16 containers",
"08:55:01 Ollama: 10 models, 31.3GB",
"08:55:01 RAM: 30%",
"08:55:02 Arch score: 83\/100"
],
"s204_services": 8,
"s95_mta": 5

View File

@@ -1 +1 @@
{"ts":"10:50","status":"online","cpu":"100%","ram":"97%","ip":"41.248.190.86","uptime":"1d07h57m","pending":24,"via":"heartbeat"}
{"ts":"11:00","status":"offline"}

View File

@@ -1,2 +1,2 @@
{"ts":"10:40","disk":"84%","swap":"57%","docker_dead":"none","http":"200","ssl":"Certificate will not expire
{"ts":"10:50","disk":"84%","swap":"57%","docker_dead":"none","http":"200","ssl":"Certificate will not expire
ok","alerts":"none","crons":54}

View File

@@ -1,5 +1,5 @@
{
"timestamp": "2026-04-08 08:40:05",
"timestamp": "2026-04-08 08:50:10",
"healthy": false,
"global_pass": 399,
"global_fail": 36,

View File

@@ -1,2 +1,2 @@
{"ts":"10:45","disk":"84%","ram":"30%","docker_dead":"0","ssl":"Certificate will not expire
{"ts":"10:55","disk":"84%","ram":"30%","docker_dead":"0","ssl":"Certificate will not expire
ok","models":"10","qdrant":"4","errors":"20"}

415
director-center.html Normal file
View File

@@ -0,0 +1,415 @@
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVIA Director — Autonomous Center</title>
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{background:#e4ecf6;background-image:radial-gradient(#c8d8e8 .6px,transparent .6px);background-size:16px 16px;overflow-y:auto;font-family:'Nunito'}
#hud{position:fixed;top:0;left:0;right:0;height:28px;background:linear-gradient(135deg,#1e293b,#0f172a);z-index:100;display:flex;align-items:center;padding:0 12px;gap:14px;font-size:.65rem}
.hs{color:#94a3b8;display:flex;align-items:center;gap:4px}.hs b{font-weight:800}.hs .v{font-weight:800}
.hs .ok{color:#4ade80}.hs .wn{color:#fbbf24}.hs .cr{color:#f87171}.hs .in{color:#60a5fa}
.pulse{width:6px;height:6px;border-radius:50%;background:#4ade80;animation:lp 2s infinite;margin-left:auto}
@keyframes lp{0%,100%{opacity:1}50%{opacity:.3}}
#nav{position:fixed;top:32px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:5px;z-index:90;background:#e4ecf6dd;backdrop-filter:blur(8px)}
#nav a,#nav button{padding:3px 10px;border-radius:5px;font:700 9px Nunito;text-decoration:none;background:#fff8;color:#5a6a80;border:1px solid #c8d8e8;cursor:pointer;transition:.2s}
#nav a:hover,#nav button:hover{background:#059669;color:#fff;border-color:#059669}
#nav a.ac{background:#059669;color:#fff;border-color:#059669}
/* Rooms grid */
.rooms{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;padding:70px 16px 16px;max-width:1400px;margin:0 auto}
.room{background:#fff;border-radius:14px;border:2px solid #c8d8e8;padding:16px;min-height:360px;position:relative;overflow:hidden;transition:border .3s}
.room:hover{border-color:#059669}
.room-hdr{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.room-ico{font-size:22px}
.room-name{font-size:15px;font-weight:900;color:#2a2a4a}
.room-badge{margin-left:auto;padding:2px 8px;border-radius:10px;font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:1px}
.room-badge.live{background:#dcfce7;color:#059669;border:1px solid #86efac}
.room-badge.warn{background:#fef3c7;color:#d97706;border:1px solid #fcd34d}
.room-badge.crit{background:#fee2e2;color:#dc2626;border:1px solid #fca5a5}
/* Agent circles */
.agents-grid{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;padding:8px 0}
.agent{text-align:center;width:70px;cursor:pointer;transition:transform .2s}
.agent:hover{transform:scale(1.08)}
.agent-ava{width:48px;height:48px;border-radius:50%;margin:0 auto 4px;display:flex;align-items:center;justify-content:center;font-size:22px;position:relative;border:2px solid #c8d8e8;background:#f0f4fa}
.agent-ava.on{border-color:#059669;box-shadow:0 0 0 3px #dcfce7}
.agent-ava.off{border-color:#f87171;box-shadow:0 0 0 3px #fee2e2}
.agent-ava .dot{position:absolute;top:0;right:0;width:10px;height:10px;border-radius:50%;border:2px solid #fff}
.dot.g{background:#4ade80}.dot.r{background:#ef4444}.dot.y{background:#fbbf24}
.agent-name{font-size:8px;font-weight:700;color:#475569;line-height:1.2}
.agent-sub{font-size:7px;color:#94a3b8;font-weight:600}
/* Metrics bar inside room */
.room-metrics{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.rm{padding:3px 8px;border-radius:6px;font-size:9px;font-weight:700;background:#f0f4fa;color:#475569;border:1px solid #e2e8f0}
.rm.ok{background:#dcfce7;color:#059669;border-color:#86efac}
.rm.wn{background:#fef3c7;color:#d97706;border-color:#fcd34d}
/* Transcript */
.transcript{margin-top:10px;padding:8px;background:#f8fafc;border-radius:8px;border:1px solid #e2e8f0;max-height:120px;overflow-y:auto}
.transcript-title{font-size:8px;font-weight:800;color:#e94560;text-transform:uppercase;letter-spacing:1px;margin-bottom:4px}
.tl{font-size:9px;color:#475569;padding:2px 0;display:flex;align-items:center;gap:6px;line-height:1.4}
.tl .ti{font-size:10px}
/* Pipeline section */
.pipeline-section{padding:16px;max-width:1400px;margin:0 auto}
.pipeline-title{font-size:14px;font-weight:900;color:#2a2a4a;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.pipeline{display:flex;align-items:center;gap:0;background:#fff;border-radius:14px;border:2px solid #c8d8e8;padding:20px;overflow-x:auto}
.pipe-step{text-align:center;flex:1;min-width:100px;position:relative}
.pipe-circle{width:56px;height:56px;border-radius:50%;border:3px solid #c8d8e8;margin:0 auto 6px;display:flex;align-items:center;justify-content:center;font-size:20px;background:#f0f4fa;transition:all .3s}
.pipe-circle.active{border-color:#059669;background:#dcfce7;box-shadow:0 0 12px rgba(5,150,105,.2)}
.pipe-circle.warn{border-color:#d97706;background:#fef3c7}
.pipe-label{font-size:10px;font-weight:800;color:#475569}
.pipe-val{font-size:8px;color:#94a3b8;font-weight:600}
.pipe-arrow{font-size:16px;color:#c8d8e8;flex-shrink:0;margin:0 -4px}
/* Bottom bar */
.bottom-bar{position:fixed;bottom:0;left:0;right:0;height:40px;background:linear-gradient(135deg,#1e293b,#0f172a);z-index:100;display:flex;align-items:center;justify-content:center;gap:8px;padding:0 16px}
.bottom-bar button{padding:4px 14px;border-radius:6px;border:1.5px solid;font:700 9px Nunito;cursor:pointer;transition:.2s}
.bb-green{background:#059669;color:#fff;border-color:#047857}.bb-green:hover{background:#047857}
.bb-blue{background:#3b82f6;color:#fff;border-color:#2563eb}.bb-blue:hover{background:#2563eb}
.bb-red{background:#ef4444;color:#fff;border-color:#dc2626}.bb-red:hover{background:#dc2626}
.bb-purple{background:#7c3aed;color:#fff;border-color:#6d28d9}.bb-purple:hover{background:#6d28d9}
.bb-dark{background:#334155;color:#e2e8f0;border-color:#475569}.bb-dark:hover{background:#475569}
/* Toast */
.toast{position:fixed;top:64px;right:16px;background:#fff;border-radius:10px;padding:10px 16px;box-shadow:0 4px 20px #0002;border:2px solid #059669;font-size:11px;font-weight:700;z-index:200;animation:toastIn .3s ease;display:none}
.toast.show{display:block}
@keyframes toastIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1}}
@media(max-width:900px){.rooms{grid-template-columns:1fr}}
</style></head><body>
<!-- HUD -->
<div id="hud">
<div class="hs"><b style="color:#4ade80">DIRECTOR</b></div>
<div class="hs">URLs <span class="v ok" id="hUrls"></span></div>
<div class="hs">Subs <span class="v ok" id="hSubs"></span></div>
<div class="hs">Docker <span class="v ok" id="hDock"></span></div>
<div class="hs">Ollama <span class="v in" id="hOll"></span></div>
<div class="hs">NonReg <span class="v ok" id="hNR"></span></div>
<div class="hs">Issues <span class="v ok" id="hIss">0</span></div>
<div class="hs">Cycle <span class="v in" id="hCyc"></span></div>
<div class="pulse"></div>
</div>
<!-- NAV -->
<div id="nav">
<a href="/director-center.html" class="ac">Director</a>
<a href="/wevia-meeting-rooms.html">Rooms</a>
<a href="/enterprise-model.html">Enterprise</a>
<a href="/director-chat.html">Chat</a>
<a href="/director.html">Dashboard</a>
<a href="/l99-brain.html">L99</a>
<a href="/wevia-master.html">Master</a>
<a href="/architecture.html">Archi</a>
<button onclick="runCycle()">▶ Run Cycle</button>
<button onclick="runFix()">🔧 Auto-Fix</button>
</div>
<!-- ROOMS -->
<div class="rooms">
<!-- ROOM: INFRA -->
<div class="room" id="roomInfra">
<div class="room-hdr">
<span class="room-ico">🏗</span>
<span class="room-name">INFRA</span>
<span class="room-badge live" id="badgeInfra">NOMINAL</span>
</div>
<div class="agents-grid" id="agInfra"></div>
<div class="room-metrics" id="metInfra"></div>
<div class="transcript" id="trInfra"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
<!-- ROOM: DEV -->
<div class="room" id="roomDev">
<div class="room-hdr">
<span class="room-ico">🔬</span>
<span class="room-name">DEV & QUALITY</span>
<span class="room-badge live" id="badgeDev">NOMINAL</span>
</div>
<div class="agents-grid" id="agDev"></div>
<div class="room-metrics" id="metDev"></div>
<div class="transcript" id="trDev"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
<!-- ROOM: SECURITY -->
<div class="room" id="roomSec">
<div class="room-hdr">
<span class="room-ico">🛡</span>
<span class="room-name">SECURITY</span>
<span class="room-badge live" id="badgeSec">NOMINAL</span>
</div>
<div class="agents-grid" id="agSec"></div>
<div class="room-metrics" id="metSec"></div>
<div class="transcript" id="trSec"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
<!-- ROOM: AI SOVEREIGN -->
<div class="room" id="roomAI">
<div class="room-hdr">
<span class="room-ico">🧠</span>
<span class="room-name">AI SOVEREIGN</span>
<span class="room-badge live" id="badgeAI">NOMINAL</span>
</div>
<div class="agents-grid" id="agAI"></div>
<div class="room-metrics" id="metAI"></div>
<div class="transcript" id="trAI"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
<!-- ROOM: ETHICA -->
<div class="room" id="roomEthica">
<div class="room-hdr">
<span class="room-ico">💊</span>
<span class="room-name">ETHICA PHARMA</span>
<span class="room-badge live" id="badgeEthica">NOMINAL</span>
</div>
<div class="agents-grid" id="agEthica"></div>
<div class="room-metrics" id="metEthica"></div>
<div class="transcript" id="trEthica"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
<!-- ROOM: BUSINESS -->
<div class="room" id="roomBiz">
<div class="room-hdr">
<span class="room-ico">📊</span>
<span class="room-name">BUSINESS & PARTNERS</span>
<span class="room-badge live" id="badgeBiz">NOMINAL</span>
</div>
<div class="agents-grid" id="agBiz"></div>
<div class="room-metrics" id="metBiz"></div>
<div class="transcript" id="trBiz"><div class="transcript-title">TRANSCRIPT</div></div>
</div>
</div>
<!-- PIPELINE -->
<div class="pipeline-section">
<div class="pipeline-title">⚡ Director Autonomous Pipeline</div>
<div class="pipeline" id="pipeline"></div>
</div>
<!-- BOTTOM BAR -->
<div class="bottom-bar">
<button class="bb-green" onclick="runCycle()">▶ Run Cycle</button>
<button class="bb-red" onclick="runFix()">🔧 Auto-Fix</button>
<button class="bb-blue" onclick="runFia()">◎ Fiability</button>
<button class="bb-purple" onclick="location='/director-chat.html'">💬 Chat</button>
<button class="bb-dark" onclick="location='/director.html'">📊 Dashboard</button>
<span style="color:#64748b;font:600 9px Nunito;margin-left:auto" id="btmStatus">Loading...</span>
</div>
<div class="toast" id="toast"></div>
<div style="height:50px"></div>
<script>
const API='/api/wevia-director.php',FIA='/api/wevia-fiability.php',MASTER='/api/wevia-master-api.php',AUTOFIX='/api/wevia-docker-autofix.php';
// Agent definitions per room
const ROOMS={
Infra:[
{n:'Director',ico:'🎯',sub:'Autonomous',key:'director'},
{n:'Sentinel',ico:'🛡',sub:'S95 brain',key:'sentinel'},
{n:'Monitor',ico:'📡',sub:'Uptime 24/7',key:'uptime'},
{n:'Docker',ico:'🐳',sub:'20 containers',key:'docker'},
{n:'PMTA',ico:'📧',sub:'Email MTA',key:'pmta'},
{n:'Proactive',ico:'⚡',sub:'Auto-heal',key:'proactive'},
{n:'Prometheus',ico:'📈',sub:'Metrics',key:'prometheus'},
],
Dev:[
{n:'NonReg',ico:'✅',sub:'152/153',key:'nonreg'},
{n:'L99',ico:'🧪',sub:'Tests',key:'l99'},
{n:'Playwright',ico:'🎭',sub:'E2E 18/18',key:'playwright'},
{n:'WEVCODE',ico:'💻',sub:'Code assist',key:'wevcode'},
{n:'Evolution',ico:'🔄',sub:'Auto-evolve',key:'evolution'},
{n:'Fiability',ico:'🔍',sub:'100% score',key:'fiability'},
],
Sec:[
{n:'Vaultwarden',ico:'🔐',sub:'Passwords',key:'vault'},
{n:'SSL Check',ico:'🔒',sub:'Certificates',key:'ssl'},
{n:'Guardian',ico:'👁',sub:'File protect',key:'guardian'},
{n:'Fail2ban',ico:'🚫',sub:'Intrusions',key:'fail2ban'},
{n:'Nuclei',ico:'🔬',sub:'CVE scan',key:'nuclei'},
],
AI:[
{n:'Ollama',ico:'🦙',sub:'10 models',key:'ollama'},
{n:'Cerebras',ico:'⚡',sub:'T1 fast',key:'cerebras'},
{n:'Groq',ico:'🚀',sub:'T1 fast',key:'groq'},
{n:'SambaNova',ico:'💎',sub:'T1',key:'sambanova'},
{n:'Qdrant',ico:'🔷',sub:'4 collections',key:'qdrant'},
{n:'Master',ico:'🧠',sub:'Router',key:'master'},
{n:'MiroFish',ico:'🐟',sub:'Self-heal',key:'mirofish'},
],
Ethica:[
{n:'HCP Manager',ico:'👨‍⚕️',sub:'67K HCPs',key:'hcp'},
{n:'RichScraper',ico:'🕷',sub:'DabaDoc',key:'scraper'},
{n:'Consent',ico:'📋',sub:'RGPD',key:'consent'},
{n:'SMS',ico:'📱',sub:'Campaigns',key:'sms'},
{n:'Pipeline',ico:'📊',sub:'Email B2B',key:'pipeline'},
],
Biz:[
{n:'Vistex',ico:'🤝',sub:'SAP partner',key:'vistex'},
{n:'Huawei',ico:'☁',sub:'Cloud 4 ECS',key:'huawei'},
{n:'Arrow',ico:'🏹',sub:'Scaleway',key:'arrow'},
{n:'WEVADS',ico:'📧',sub:'Email mktg',key:'wevads'},
{n:'CRM',ico:'👥',sub:'Twenty',key:'crm'},
],
};
function renderAgents(){
for(const[room,agents]of Object.entries(ROOMS)){
const el=document.getElementById('ag'+room);
el.innerHTML=agents.map(a=>`
<div class="agent" title="${a.n}: ${a.sub}">
<div class="agent-ava on"><span>${a.ico}</span><div class="dot g"></div></div>
<div class="agent-name">${a.n}</div>
<div class="agent-sub">${a.sub}</div>
</div>
`).join('');
}
}
function renderPipeline(){
const steps=[
{ico:'👁',label:'Observe',val:'39 obs',active:true},
{ico:'📊',label:'Analyze',val:'Arch+Topo',active:true},
{ico:'🔍',label:'Detect',val:'Issues',active:true},
{ico:'📋',label:'Plan',val:'Priority',active:true},
{ico:'⚡',label:'Act',val:'Auto-fix',active:true},
{ico:'✅',label:'Verify',val:'NonReg',active:true},
{ico:'📤',label:'Report',val:'Telegram',active:true},
{ico:'🔄',label:'Loop',val:'*/15min',active:true},
];
document.getElementById('pipeline').innerHTML=steps.map((s,i)=>
`${i>0?'<div class="pipe-arrow">▸</div>':''}<div class="pipe-step"><div class="pipe-circle${s.active?' active':''}">${s.ico}</div><div class="pipe-label">${s.label}</div><div class="pipe-val">${s.val}</div></div>`
).join('');
}
function toast(msg,ms=3000){
const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');
setTimeout(()=>t.classList.remove('show'),ms);
}
function addTranscript(room,ico,text){
const el=document.getElementById('tr'+room);
const d=document.createElement('div');d.className='tl';
d.innerHTML=`<span class="ti">${ico}</span>${text}`;
el.appendChild(d);el.scrollTop=999;
}
async function loadData(){
try{
const[st,fia,master]=await Promise.all([
fetch(API+'?status').then(r=>r.json()).catch(()=>({})),
fetch(FIA+'?report').then(r=>r.json()).catch(()=>({})),
fetch(MASTER+'?health').then(r=>r.json()).catch(()=>({})),
]);
const o=st.observations||{},iss=(st.plan||[]).length;
// HUD
document.getElementById('hUrls').textContent=(o.url_checks_ok||'?')+'/'+(o.url_checks_total||'?');
document.getElementById('hSubs').textContent=(o.subdomain_checks_ok||'?')+'/'+(o.subdomain_checks_total||'?');
document.getElementById('hDock').textContent=o.s204_docker_count||'?';
document.getElementById('hDock').className='v '+(parseInt(o.s204_docker_count)>=16?'ok':'cr');
document.getElementById('hOll').textContent=o.s204_ollama||'?';
document.getElementById('hNR').textContent='152/153';
document.getElementById('hIss').textContent=iss;
document.getElementById('hIss').className='v '+(iss===0?'ok':'cr');
document.getElementById('hCyc').textContent=(st.duration_ms||'?')+'ms';
document.getElementById('btmStatus').textContent=`Last: ${st.timestamp?.substring(11,16)||'—'} · ${st.duration_ms||0}ms · ${iss} issues`;
// INFRA metrics
document.getElementById('metInfra').innerHTML=[
`<span class="rm${parseInt(o.s204_disk?.percent)<85?' ok':' wn'}">Disk ${o.s204_disk?.percent||'?'}%</span>`,
`<span class="rm ok">Docker ${o.s204_docker_count||'?'}</span>`,
`<span class="rm ok">S95 ${o.s95_alive?.includes('ALIVE')?'✓':'✗'}</span>`,
`<span class="rm ok">S151 ${o.s151_http||'?'}</span>`,
`<span class="rm">Crons ${o.s204_crons||'?'}</span>`,
].join('');
addTranscript('Infra','🖥',`S204 ${o.s204_disk?.percent||'?'}% disk · Docker ${o.s204_docker_count||'?'}`);
// DEV metrics
document.getElementById('metDev').innerHTML=[
`<span class="rm ok">NonReg 152/153</span>`,
`<span class="rm ok">E2E 18/18</span>`,
`<span class="rm ok">Mega 122/122</span>`,
`<span class="rm ok">L99 60/60</span>`,
].join('');
// AI metrics
document.getElementById('metAI').innerHTML=[
`<span class="rm ok">Ollama ${master.ollama||'?'} (${master.ollama_models||0})</span>`,
`<span class="rm ok">T1: ${master.tier1_providers||0}</span>`,
`<span class="rm">T2: ${master.tier2_providers||0}</span>`,
`<span class="rm ok">Cost: 0€</span>`,
].join('');
const totalCalls=Object.values(master.stats||{}).reduce((s,d)=>s+d.total,0);
addTranscript('AI','🧠',`${totalCalls} LLM calls · ${master.ollama_models||0} models · 0€`);
// Fiability
if(fia.score!==undefined){
document.getElementById('metSec').innerHTML=[
`<span class="rm${fia.score>=90?' ok':' wn'}">Fiability ${fia.score}%</span>`,
`<span class="rm ok">URLs ${fia.summary?.ok||0}/${fia.summary?.total_urls||0}</span>`,
`<span class="rm ok">Subs ${fia.summary?.subdomains_ok||0}/${fia.summary?.subdomains_total||0}</span>`,
].join('');
}
// Ethica
document.getElementById('metEthica').innerHTML=[
`<span class="rm ok">67,450 HCPs</span>`,
`<span class="rm">18K phones</span>`,
`<span class="rm">15K emails</span>`,
`<span class="rm ok">95% verified</span>`,
].join('');
// Business
document.getElementById('metBiz').innerHTML=[
`<span class="rm">Vistex: Dispute</span>`,
`<span class="rm wn">Huawei: Billing</span>`,
`<span class="rm ok">Arrow: Active</span>`,
`<span class="rm">WEVADS: Warmup</span>`,
].join('');
// Badges
document.getElementById('badgeInfra').textContent=iss===0?'NOMINAL':'ALERT';
document.getElementById('badgeInfra').className='room-badge '+(iss===0?'live':'warn');
}catch(e){console.error(e)}
}
async function runCycle(){
toast('Running Director cycle...');
const d=await fetch(API+'?run&force=1').then(r=>r.json());
toast(`Cycle done: ${d.duration_ms}ms · ${(d.plan||[]).length} issues`);
addTranscript('Infra','▶',`Cycle: ${(d.plan||[]).length} issues · ${d.duration_ms}ms`);
loadData();
}
async function runFix(){
toast('Running Docker Auto-Fix...');
const d=await fetch(AUTOFIX).then(r=>r.json());
if(d.fixed){
toast(`Fixed! Was ${d.was_running} containers`);
addTranscript('Infra','🔧',`Auto-fix: ${d.actions?.join(', ')}`);
}else{
toast(`All OK: ${d.containers} containers`);
}
loadData();
}
async function runFia(){
toast('Running Fiability scan...');
addTranscript('Sec','🔍','Fiability scan started...');
// Trigger background scan
fetch(FIA+'?quick').catch(()=>{});
setTimeout(()=>{toast('Scan running in background');loadData()},2000);
}
// Init
renderAgents();
renderPipeline();
loadData();
setInterval(loadData,30000);
</script>
</body></html>