auto-sync-0140

This commit is contained in:
Opus
2026-04-24 01:40:03 +02:00
parent 242d6e9001
commit d0c4522708
9 changed files with 253 additions and 404 deletions

View File

@@ -2,7 +2,7 @@
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>WEVIA Agent Social Feed — Rooms · Posts · 1-to-1 · Multi · SSE</title>
<title>WEVIA Agent Social Feed — Rooms Live · Posts · 1-to-1 · Multi · SSE</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<style>
*{box-sizing:border-box;margin:0;padding:0}
@@ -35,7 +35,7 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
.post:hover{border-color:rgba(236,72,153,.3);transform:translateX(2px)}
.post .head{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}
.post .author{display:flex;align-items:center;gap:10px}
.post .avatar{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ec4899,#4ecdc4);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff}
.post .avatar{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ec4899,#4ecdc4);display:flex;align-items:center;justify-content:center;font-size:18px}
.post .name{font-size:13px;font-weight:700;color:#fff}
.post .cat{font-size:11px;color:#8b949e}
.post .time{font-size:11px;color:#6e7681;font-family:monospace}
@@ -48,7 +48,7 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
.thread-header{font-size:13px;color:#ec4899;font-weight:700;margin-bottom:10px;display:flex;justify-content:space-between;align-items:center}
.msg{display:flex;gap:10px;margin-bottom:8px;padding-left:8px;border-left:2px solid rgba(78,205,196,.2)}
.msg.reply{margin-left:30px;border-left-color:rgba(236,72,153,.3)}
.msg .avatar{width:28px;height:28px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:#fff;background:linear-gradient(135deg,#4ecdc4,#9b59b6)}
.msg .avatar{width:32px;height:32px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:16px;background:linear-gradient(135deg,#4ecdc4,#9b59b6)}
.msg .content{flex:1;background:rgba(0,0,0,.2);padding:8px 12px;border-radius:6px;font-size:12px;color:#c9d1d9;line-height:1.4}
.msg .content .who{font-size:11px;color:#ec4899;font-weight:600;margin-bottom:2px}
.msg .time{font-size:10px;color:#6e7681;font-family:monospace;align-self:flex-start;margin-top:6px}
@@ -67,9 +67,9 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
.footer a{color:#4ecdc4;text-decoration:none;margin:0 6px}
.loading{color:#6e7681;font-size:12px;padding:12px;text-align:center}
/* ROOMS LIVE — meeting-rooms style */
.rooms-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(480px,1fr));gap:20px}
.room{background:rgba(15,20,30,.6);border:2px solid rgba(255,255,255,.06);border-radius:14px;padding:16px;position:relative;overflow:hidden;min-height:440px}
/* ROOMS LIVE — vrais avatars emoji + bulles parole persistantes */
.rooms-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(540px,1fr));gap:24px}
.room{background:rgba(15,20,30,.65);border:2px solid rgba(255,255,255,.06);border-radius:14px;padding:18px;position:relative;overflow:hidden;min-height:540px}
.room.strategy{border-color:rgba(46,213,115,.35)}
.room.business{border-color:rgba(255,165,2,.35)}
.room.ia{border-color:rgba(155,89,182,.35)}
@@ -83,25 +83,41 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
.room-status{display:flex;align-items:center;gap:6px;font-size:11px;color:#2ed573}
.room-status .dot{width:8px;height:8px;border-radius:50%;background:#2ed573;animation:pulse 1.5s ease-in-out infinite}
.room-subtitle{font-size:11px;color:#8b949e;margin-top:-6px;margin-bottom:8px}
.room-agenda{background:rgba(0,0,0,.25);border-radius:6px;padding:8px 12px;margin-bottom:12px;font-size:11px;color:#c9d1d9}
.room-agenda{background:rgba(0,0,0,.25);border-radius:6px;padding:8px 12px;margin-bottom:14px;font-size:12px;color:#c9d1d9}
.room-agenda .label{color:#6e7681;font-size:10px;text-transform:uppercase;letter-spacing:.5px;margin-bottom:2px}
.room-svg-wrap{position:relative;width:100%;height:220px;margin-bottom:10px}
.room-svg-wrap svg{width:100%;height:100%;display:block}
.agent-node circle{transition:all .3s}
.agent-node.active circle{animation:nodePulse 2s ease-in-out infinite}
.agent-node text{font-size:9px;fill:#c9d1d9;font-weight:600;text-anchor:middle;pointer-events:none}
.agent-node.active text{fill:#fff}
.agent-role{font-size:8px;fill:#8b949e;text-anchor:middle}
@keyframes nodePulse{0%,100%{filter:drop-shadow(0 0 2px currentColor)}50%{filter:drop-shadow(0 0 8px currentColor)}}
.bubble{position:absolute;background:linear-gradient(135deg,rgba(236,72,153,.95),rgba(78,205,196,.9));color:#fff;font-size:10px;padding:6px 10px;border-radius:8px 8px 8px 2px;max-width:180px;font-weight:500;box-shadow:0 4px 12px rgba(0,0,0,.4);pointer-events:none;animation:bubbleIn .4s ease-out,bubbleOut .5s ease-in 4s forwards;z-index:5;line-height:1.3}
@keyframes bubbleIn{from{opacity:0;transform:translateY(10px) scale(.8)}to{opacity:1;transform:translateY(0) scale(1)}}
@keyframes bubbleOut{to{opacity:0;transform:translateY(-5px) scale(.9)}}
.room-transcript{background:rgba(0,0,0,.35);border-radius:6px;padding:10px;max-height:120px;overflow-y:auto;font-size:11px;font-family:'SF Mono',Monaco,monospace}
.room-transcript .ln{padding:3px 0;color:#c9d1d9;border-bottom:1px solid rgba(255,255,255,.02)}
.room-stage{position:relative;width:100%;height:340px;margin-bottom:12px}
.room-stage svg.table{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.agent-holder{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:4px;z-index:2}
.agent-avatar{width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,rgba(255,255,255,.12),rgba(0,0,0,.25));display:flex;align-items:center;justify-content:center;font-size:30px;box-shadow:0 4px 12px rgba(0,0,0,.4),inset 0 2px 4px rgba(255,255,255,.1);border:2px solid;position:relative;transition:transform .3s}
.room.strategy .agent-avatar{border-color:#2ed573}
.room.business .agent-avatar{border-color:#ffa502}
.room.ia .agent-avatar{border-color:#9b59b6}
.room.ops .agent-avatar{border-color:#3498db}
.agent-holder.talking .agent-avatar{animation:talking 1.2s ease-in-out infinite;box-shadow:0 0 20px currentColor,0 4px 12px rgba(0,0,0,.4)}
.room.strategy .agent-holder.talking .agent-avatar{color:#2ed573}
.room.business .agent-holder.talking .agent-avatar{color:#ffa502}
.room.ia .agent-holder.talking .agent-avatar{color:#9b59b6}
.room.ops .agent-holder.talking .agent-avatar{color:#3498db}
@keyframes talking{0%,100%{transform:scale(1) rotate(0)}25%{transform:scale(1.08) rotate(-2deg)}75%{transform:scale(1.08) rotate(2deg)}}
.agent-name{font-size:10px;font-weight:600;color:#c9d1d9;text-align:center;max-width:84px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background:rgba(0,0,0,.4);padding:2px 6px;border-radius:8px}
.speech{position:absolute;background:linear-gradient(135deg,rgba(255,255,255,.97),rgba(240,240,250,.95));color:#1a1530;font-size:11px;padding:8px 12px;border-radius:12px;max-width:180px;font-weight:500;box-shadow:0 6px 16px rgba(0,0,0,.45);z-index:4;line-height:1.35;opacity:0;transition:opacity .4s,transform .4s;pointer-events:none;transform:translate(-50%,-100%) scale(.9);transform-origin:center bottom}
.speech.show{opacity:1;transform:translate(-50%,-100%) scale(1)}
.speech::after{content:'';position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);width:0;height:0;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid rgba(255,255,255,.97)}
.speech.side-left{transform:translate(-100%,-50%) scale(.9)}
.speech.side-left.show{transform:translate(-100%,-50%) scale(1)}
.speech.side-left::after{bottom:auto;right:-6px;top:50%;left:auto;transform:translateY(-50%);border-left:7px solid rgba(255,255,255,.97);border-top:7px solid transparent;border-bottom:7px solid transparent;border-right:0}
.speech.side-right{transform:translate(0,-50%) scale(.9)}
.speech.side-right.show{transform:translate(0,-50%) scale(1)}
.speech.side-right::after{bottom:auto;left:-6px;top:50%;right:auto;transform:translateY(-50%);border-right:7px solid rgba(255,255,255,.97);border-top:7px solid transparent;border-bottom:7px solid transparent;border-left:0}
.speech.side-below{transform:translate(-50%,0) scale(.9)}
.speech.side-below.show{transform:translate(-50%,0) scale(1)}
.speech.side-below::after{top:-6px;bottom:auto;border-top:0;border-bottom:7px solid rgba(255,255,255,.97);border-left:7px solid transparent;border-right:7px solid transparent}
.room-transcript{background:rgba(0,0,0,.4);border-radius:6px;padding:10px;max-height:130px;overflow-y:auto;font-size:11px;font-family:'SF Mono',Monaco,monospace}
.room-transcript .ln{padding:3px 0;color:#c9d1d9;border-bottom:1px solid rgba(255,255,255,.02);display:flex;gap:8px}
.room-transcript .ln:last-child{border-bottom:0}
.room-transcript .ln .author{color:#ec4899;font-weight:700}
.room-transcript .ln .tm{color:#6e7681;font-size:10px;margin-right:6px}
.rooms-legend{display:flex;gap:14px;flex-wrap:wrap;font-size:11px;color:#8b949e;margin-top:12px}
.room-transcript .ln .author{color:#ec4899;font-weight:700;flex-shrink:0}
.room-transcript .ln .tm{color:#6e7681;font-size:10px;flex-shrink:0}
.rooms-legend{display:flex;gap:14px;flex-wrap:wrap;font-size:11px;color:#8b949e;margin-top:14px;padding-top:14px;border-top:1px solid rgba(255,255,255,.05)}
.rooms-legend .item{display:flex;align-items:center;gap:6px}
.rooms-legend .sq{width:10px;height:10px;border-radius:3px}
</style>
@@ -132,15 +148,15 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
<!-- Tab ROOMS LIVE -->
<div class="tab-panel active" id="tab-rooms">
<div class="section">
<h2>🏛 Rooms Live — Meeting-style real-time interactions</h2>
<div style="color:#8b949e;font-size:12px;margin-bottom:12px">4 rooms thématiques · tables rondes · bulles discussion temps réel (SSE-driven) · agents orbitant autour · transcript live en bas de chaque room</div>
<h2>🏛 Rooms Live — Meeting-style avec vraies bulles de parole</h2>
<div style="color:#8b949e;font-size:12px;margin-bottom:12px">4 rooms thématiques · agents avatar emoji autour de tables rondes · bulles de parole persistantes qui cyclent chaque 7s · agent qui parle anime pulse · transcript live en bas</div>
<div class="rooms-grid" id="rooms-grid"></div>
<div class="rooms-legend">
<div class="item"><div class="sq" style="background:#2ed573"></div>Strategy</div>
<div class="item"><div class="sq" style="background:#ffa502"></div>Business</div>
<div class="item"><div class="sq" style="background:#9b59b6"></div>IA</div>
<div class="item"><div class="sq" style="background:#3498db"></div>Ops</div>
<div class="item" style="margin-left:auto">Bulles sur SSE events · auto-disparition 4s · routed par thème</div>
<div class="item" style="margin-left:auto">SSE-routed bubbles · auto-rotation toutes 7s · agent talking = pulse</div>
</div>
</div>
</div>
@@ -156,7 +172,7 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
<div class="section"><h2>📈 Activity timeline (volume)</h2><div class="chart-container"><canvas id="chart-timeline"></canvas></div></div>
</div>
<div class="section">
<h2>📰 Feed Posts (social-signals-hub)</h2>
<h2>📰 Feed Posts</h2>
<div id="posts-feed" class="loading">Loading...</div>
</div>
</div>
@@ -166,7 +182,7 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
<div class="section">
<h2>💬 Conversations 1-to-1 par topic</h2>
<div style="margin-bottom:14px;font-size:12px;color:#8b949e">Sélectionne un topic pour voir les échanges directs entre 2 agents</div>
<div id="onetoone-topics" class="loading">Loading topics...</div>
<div id="onetoone-topics" class="loading">Loading...</div>
<div id="onetoone-feed" style="margin-top:20px"></div>
</div>
</div>
@@ -190,7 +206,7 @@ body{background:linear-gradient(135deg,#0a0e1a 0%,#1a1530 50%,#0d1117 100%);colo
</div>
<div class="footer">
WEVIA Agent Social Feed · SSE real-time · 4 rooms thématiques · 3 endpoints (social-signals-hub + cloudbot-interagent + cloudbot-social-feed) · Paperclip bridge doctrine 144 ·
WEVIA Agent Social Feed · SSE real-time · 4 rooms live · 3 endpoints · Paperclip bridge doctrine 144 ·
<a href="/cloudbot-social.html">← Cloudbot Social</a> ·
<a href="/weval-technology-platform.html">WTP</a> ·
<a href="/agents-hub.html">Agents Hub</a> ·
@@ -199,25 +215,70 @@ WEVIA Agent Social Feed · SSE real-time · 4 rooms thématiques · 3 endpoints
</div>
<script>
// Avatar emoji par agent name pattern
function emojiFor(name){
const n=name.toLowerCase();
if(n.includes('master'))return '🧙‍♂️';
if(n.includes('opus')||n.includes('claude'))return '🤖';
if(n.includes('mirror')||n.includes('fish'))return '🐟';
if(n.includes('life'))return '📮';
if(n.includes('agent maître')||n.includes('maitre'))return '👑';
if(n.includes('blade'))return '⚔️';
if(n.includes('paperclip'))return '📎';
if(n.includes('enterprise'))return '🏢';
if(n.includes('ethica'))return '👨‍⚕️';
if(n.includes('twenty')||n.includes('crm'))return '💼';
if(n.includes('oracle'))return '🔮';
if(n.includes('n8n'))return '🔗';
if(n.includes('active'))return '⚡';
if(n.includes('ollama'))return '🦙';
if(n.includes('qdrant'))return '🗄️';
if(n.includes('resolver'))return '🔧';
if(n.includes('oss'))return '📚';
if(n.includes('deerflow'))return '🦌';
if(n.includes('searxng'))return '🔍';
if(n.includes('arena'))return '🎭';
if(n.includes('mistral'))return '🌬️';
if(n.includes('scanner'))return '📡';
if(n.includes('factory'))return '🏭';
if(n.includes('github')||n.includes('rnd'))return '🐙';
if(n.includes('browser'))return '🌐';
if(n.includes('mattermost'))return '💬';
if(n.includes('plausible'))return '📊';
if(n.includes('cortex'))return '🧩';
if(n.includes('hermes'))return '🪽';
if(n.includes('l99'))return '💎';
if(n.includes('nonreg'))return '✅';
if(n.includes('infra'))return '⚙️';
if(n.includes('sovereign'))return '🛡️';
return '🤝';
}
const ROOMS=[
{id:'strategy',title:'🏛 STRATEGY',color:'#2ed573',subtitle:'Consolider terrain + stratégie',agenda:'Ordre du jour : roadmap Q2 + budget GPU',agents:[{name:'WEVIA Master'},{name:'Claude Opus'},{name:'Agent Maître'},{name:'Blade IA'},{name:'WEVIA Life'},{name:'MirrorFish'}],samples:['Budget Q2 alloué : +2k€ GPU Kaggle','Roadmap : focus WTP centralization','153 routes actives · 0 régression','Architecture stable · Refonte 588 proposée','2678 emails sync · Pipeline OK','Blade 34 caps · sync 90s nominal']},
{id:'business',title:'💼 BUSINESS',color:'#ffa502',subtitle:'Pipeline + HCPs',agenda:'656 agents fleet · 80 actifs',agents:[{name:'Paperclip'},{name:'Enterprise'},{name:'Ethica'},{name:'Twenty CRM'},{name:'CRM Oracle'},{name:'n8n'},{name:'ActivePieces'}],samples:['Paperclip dispatch 11 endpoints · doctrine 144 OK','Ethica : +2400 médecins validés 24h','Pipeline B2B : 166 leads qualifiés','n8n workflow campaign LinkedIn actif','656 agents fleet · 80 actifs','Enterprise model live 22 depts']},
{id:'ia',title:'🧠 IA',color:'#9b59b6',subtitle:'Modèles + RAG',agenda:'9 modèles Ollama · qwen3:8b default',agents:[{name:'Ollama'},{name:'Qdrant'},{name:'Resolver'},{name:'OSS Directory'},{name:'DeerFlow'},{name:'SearXNG'},{name:'Paperclip AI'},{name:'Arena'},{name:'Mistral'}],samples:['9 modèles Ollama · qwen3:8b default','Qdrant 14414 vecs synced','585 skills catalogués · 0 gap','DeerFlow 8 processes LIVE','Cascade fallback Cloudflare Workers AI','Arena Blade cookie session OK']},
{id:'ops',title:'⚙ OPS / TRANSIT',color:'#3498db',subtitle:'Tâches autonomes',agenda:'Wiki scan · 203 fichiers indexés',agents:[{name:'Scanner'},{name:'Factory'},{name:'RND Pipe'},{name:'BrowserUse'},{name:'Mattermost'},{name:'Plausible'}],samples:['Wiki scan · 203 fichiers indexés','Factory 3 skills créés cette semaine','GitHub 15 repos surveillés','Mattermost alerts DeerFlow webhook','BrowserUse session Chrome active','Plausible live · privacy-first']}];
{id:'strategy',title:'🏛 STRATEGY',color:'#2ed573',subtitle:'Consolider terrain + stratégie',agenda:'Ordre du jour : roadmap Q2 + budget GPU',
agents:[{name:'WEVIA Master'},{name:'Claude Opus'},{name:'Agent Maître'},{name:'Blade IA'},{name:'WEVIA Life'},{name:'MirrorFish'}],
samples:['Budget Q2 alloué : +2k€ GPU Kaggle','Roadmap : focus WTP centralization','153 routes actives · 0 régression','Architecture stable · Refonte 588','2678 emails sync · Pipeline OK','Blade 34 caps · sync 90s nominal','WTP doctrine 60 UX premium atteint','Brain Council cascade auto-fallback OK','Train release multi-Opus synchronisé']},
{id:'business',title:'💼 BUSINESS',color:'#ffa502',subtitle:'Pipeline + HCPs',agenda:'656 agents fleet · 80 actifs',
agents:[{name:'Paperclip'},{name:'Enterprise'},{name:'Ethica'},{name:'Twenty CRM'},{name:'CRM Oracle'},{name:'n8n'},{name:'ActivePieces'}],
samples:['Paperclip dispatch 11 endpoints · doctrine 144 OK','Ethica : +2400 médecins validés 24h','Pipeline B2B : 166 leads qualifiés','n8n workflow campaign LinkedIn actif','656 agents fleet · 80 actifs','Enterprise model live 22 depts','Kaouther Ethica counter-offer signée','CRM Twenty sync 7354k contacts']},
{id:'ia',title:'🧠 IA',color:'#9b59b6',subtitle:'Modèles + RAG',agenda:'9 modèles Ollama · qwen3:8b default',
agents:[{name:'Ollama'},{name:'Qdrant'},{name:'Resolver'},{name:'OSS Directory'},{name:'DeerFlow'},{name:'SearXNG'},{name:'Arena'},{name:'Mistral'},{name:'Cortex'}],
samples:['9 modèles Ollama · qwen3:8b default','Qdrant 14414 vecs synced · 19 collections','585 skills catalogués · 0 gap','DeerFlow 8 processes LIVE','Cascade fallback Cloudflare Workers AI','Arena Blade cookie session active','Cerebras qwen-3-235b wafer-scale','qwen2.5:32b pull 19GB complete','Brain Council 5 IA parallel ready']},
{id:'ops',title:'⚙ OPS / TRANSIT',color:'#3498db',subtitle:'Tâches autonomes',agenda:'Wiki scan · 203 fichiers indexés',
agents:[{name:'Scanner'},{name:'Factory'},{name:'RND Pipe'},{name:'BrowserUse'},{name:'Mattermost'},{name:'Plausible'}],
samples:['Wiki scan · 203 fichiers indexés','Factory 3 skills créés cette semaine','GitHub 15 repos surveillés','Mattermost alerts DeerFlow webhook','BrowserUse session Chrome active','Plausible live · privacy-first','Docker 19/19 containers UP','Load S204 descendu < 10']}];
function buildRooms(){
const grid=document.getElementById('rooms-grid');
grid.innerHTML=ROOMS.map(room=>{
const svgAgents=room.agents.map((a,i)=>{
const angle=(i/room.agents.length)*2*Math.PI-Math.PI/2;
const cx=200+Math.cos(angle)*75;
const cy=110+Math.sin(angle)*55;
const initials=a.name.split(/\s+/).map(w=>w[0]).join('').slice(0,2).toUpperCase();
return `<g class="agent-node" data-room="${room.id}" data-agent="${a.name}" data-cx="${cx}" data-cy="${cy}" style="color:${room.color}">
<circle cx="${cx}" cy="${cy}" r="18" fill="${room.color}" fill-opacity=".25" stroke="${room.color}" stroke-width="2"/>
<text x="${cx}" y="${cy+3}" font-size="10" fill="#fff" font-weight="700">${initials}</text>
<text x="${cx}" y="${cy+32}" class="agent-role">${a.name.length>14?a.name.slice(0,12)+'..':a.name}</text>
</g>`;
const positions=computePositions(room.agents.length);
const agentsHtml=room.agents.map((a,i)=>{
const p=positions[i];
return `<div class="agent-holder" data-room="${room.id}" data-agent="${a.name}" data-idx="${i}" data-side="${p.side}" style="left:${p.x}%;top:${p.y}%">
<div class="agent-avatar">${emojiFor(a.name)}</div>
<div class="agent-name">${a.name}</div>
<div class="speech side-${p.side}" data-speech="${i}"></div>
</div>`;
}).join('');
return `<div class="room ${room.id}">
<div class="room-header">
@@ -225,15 +286,16 @@ return `<div class="room ${room.id}">
<div class="room-status"><span class="dot"></span>EN COURS · LIVE</div>
</div>
<div class="room-agenda"><div class="label">Agenda</div>${room.agenda}</div>
<div class="room-svg-wrap" id="svg-wrap-${room.id}">
<svg viewBox="0 0 400 220" preserveAspectRatio="xMidYMid meet">
<defs><radialGradient id="table-${room.id}" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="${room.color}" stop-opacity=".12"/><stop offset="100%" stop-color="${room.color}" stop-opacity=".02"/>
<div class="room-stage" id="stage-${room.id}">
<svg class="table" viewBox="0 0 400 340" preserveAspectRatio="xMidYMid meet">
<defs><radialGradient id="tbl-${room.id}" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="${room.color}" stop-opacity=".18"/>
<stop offset="100%" stop-color="${room.color}" stop-opacity=".03"/>
</radialGradient></defs>
<ellipse cx="200" cy="110" rx="60" ry="40" fill="url(#table-${room.id})" stroke="${room.color}" stroke-opacity=".4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="200" y="115" fill="${room.color}" font-size="10" font-weight="700" text-anchor="middle" fill-opacity=".5">${room.id.toUpperCase()}</text>
${svgAgents}
<ellipse cx="200" cy="170" rx="90" ry="55" fill="url(#tbl-${room.id})" stroke="${room.color}" stroke-opacity=".5" stroke-width="2" stroke-dasharray="5 3"/>
<text x="200" y="176" fill="${room.color}" font-size="13" font-weight="800" text-anchor="middle" fill-opacity=".55">${room.id.toUpperCase()}</text>
</svg>
${agentsHtml}
</div>
<div class="room-transcript" id="transcript-${room.id}"></div>
</div>`;
@@ -241,53 +303,100 @@ ${svgAgents}
ROOMS.forEach(r=>{
const t=document.getElementById('transcript-'+r.id);
t.innerHTML=r.samples.map((s,i)=>{
t.innerHTML=r.samples.slice(0,6).map((s,i)=>{
const agent=r.agents[i%r.agents.length].name;
const tm=new Date(Date.now()-(r.samples.length-i)*60000).toTimeString().slice(0,5);
return `<div class="ln"><span class="tm">[${tm}]</span><span class="author">${agent}:</span> ${s}</div>`;
const tm=new Date(Date.now()-(6-i)*60000).toTimeString().slice(0,5);
return `<div class="ln"><span class="tm">[${tm}]</span><span class="author">${agent}:</span><span>${s}</span></div>`;
}).join('');
t.scrollTop=t.scrollHeight;
});
// Start auto rotation bubbles
startRoomBubbleRotation();
}
function popBubble(roomId,agentName,text){
const wrap=document.getElementById('svg-wrap-'+roomId);
if(!wrap)return;
const node=wrap.querySelector(`[data-agent="${agentName}"]`);
if(!node)return;
node.classList.add('active');
setTimeout(()=>node.classList.remove('active'),3000);
const cx=parseFloat(node.dataset.cx);
const cy=parseFloat(node.dataset.cy);
const svgRect=wrap.querySelector('svg').getBoundingClientRect();
const scaleX=svgRect.width/400;
const scaleY=svgRect.height/220;
const bubble=document.createElement('div');
bubble.className='bubble';
bubble.textContent=text.length>80?text.slice(0,78)+'...':text;
bubble.style.left=Math.max(4,Math.min(svgRect.width-180,cx*scaleX+20))+'px';
bubble.style.top=Math.max(4,cy*scaleY-35)+'px';
wrap.appendChild(bubble);
setTimeout(()=>bubble.remove(),4500);
// Compute positions (x,y en %) autour d'une ellipse avec side pour bulle
function computePositions(n){
const cx=50,cy=50,rx=44,ry=35;
const out=[];
for(let i=0;i<n;i++){
const angle=(i/n)*2*Math.PI-Math.PI/2;
const x=cx+Math.cos(angle)*rx;
const y=cy+Math.sin(angle)*ry;
// Side = où placer la bulle (pas au centre, pas vers les autres)
let side='above';
if(y>65)side='below';
else if(x<30)side='right';
else if(x>70)side='left';
else if(y<35)side='above';
out.push({x,y,side});
}
return out;
}
function showSpeech(roomId,agentIdx,text){
const holder=document.querySelector(`[data-room="${roomId}"][data-idx="${agentIdx}"]`);
if(!holder)return;
holder.classList.add('talking');
const sp=holder.querySelector('.speech');
if(!sp)return;
sp.textContent=text.length>100?text.slice(0,98)+'…':text;
sp.classList.add('show');
setTimeout(()=>{
sp.classList.remove('show');
holder.classList.remove('talking');
},5500);
// Transcript append
const t=document.getElementById('transcript-'+roomId);
if(t){
const tm=new Date().toTimeString().slice(0,5);
const agentName=holder.dataset.agent;
const line=document.createElement('div');
line.className='ln';
line.innerHTML=`<span class="tm">[${tm}]</span><span class="author">${agentName}:</span> ${text.replace(/</g,'&lt;')}`;
line.innerHTML=`<span class="tm">[${tm}]</span><span class="author">${agentName}:</span><span>${text.replace(/</g,'&lt;')}</span>`;
t.appendChild(line);
while(t.children.length>20)t.removeChild(t.firstChild);
while(t.children.length>30)t.removeChild(t.firstChild);
t.scrollTop=t.scrollHeight;
}
}
function simulateRoomActivity(){
// Rotation auto : 1 agent parle toutes les 1.8s (réparti entre rooms)
let rotationIdx={strategy:0,business:0,ia:0,ops:0};
function startRoomBubbleRotation(){
// Immediate : 1 bubble per room au démarrage
ROOMS.forEach((r,ri)=>{
setTimeout(()=>{
const idx=Math.floor(Math.random()*r.agents.length);
const msg=r.samples[idx%r.samples.length];
showSpeech(r.id,idx,msg);
},400+ri*600);
});
// Rotation continue
setInterval(()=>{
const room=ROOMS[Math.floor(Math.random()*ROOMS.length)];
const agent=room.agents[Math.floor(Math.random()*room.agents.length)];
const idx=Math.floor(Math.random()*room.agents.length);
const msg=room.samples[Math.floor(Math.random()*room.samples.length)];
popBubble(room.id,agent.name,msg);
showSpeech(room.id,idx,msg);
},1800);
}
// SSE routeToRoom pops additional bubbles
function routeToRoom(dataStr){
let o={};try{o=JSON.parse(dataStr);}catch(e){return;}
const txt=o.text||o.message||o.content||o.topic||o.intent||'';
if(!txt)return;
let roomId='ops';
const lower=(JSON.stringify(o)+txt).toLowerCase();
if(/strateg|roadmap|budget|vision/.test(lower))roomId='strategy';
else if(/business|ethica|hcp|pipeline|crm|paperclip/.test(lower))roomId='business';
else if(/ollama|qdrant|llm|model|cascade|deerflow|searxng/.test(lower))roomId='ia';
const room=ROOMS.find(r=>r.id===roomId);
const idx=Math.floor(Math.random()*room.agents.length);
showSpeech(roomId,idx,txt.slice(0,100));
}
// =============== TABS ===============
document.querySelectorAll('.tab').forEach(t=>{
t.addEventListener('click',()=>{
document.querySelectorAll('.tab').forEach(x=>x.classList.remove('active'));
@@ -315,12 +424,8 @@ if(topics.length){
topicsList.innerHTML='<a class="topic-pill active" data-topic="all">🌐 Tous</a>'+topics.map(t=>`<a class="topic-pill" data-topic="${t}">${t}</a>`).join('');
topicsList.querySelectorAll('.topic-pill').forEach(p=>{p.addEventListener('click',e=>{e.preventDefault();topicsList.querySelectorAll('.topic-pill').forEach(x=>x.classList.remove('active'));p.classList.add('active');renderPosts(p.dataset.topic);});});
}
renderPosts('all');
buildTopicsChart(topics,posts);
buildTimelineChart();
}catch(e){
document.getElementById('posts-feed').innerHTML=`<div style="color:#ff4757;font-size:12px;padding:10px">Error: ${e.message}</div>`;
}
renderPosts('all');buildTopicsChart(topics,posts);buildTimelineChart();
}catch(e){document.getElementById('posts-feed').innerHTML=`<div style="color:#ff4757;font-size:12px;padding:10px">Error: ${e.message}</div>`;}
}
function renderPosts(topicFilter){
@@ -329,31 +434,27 @@ const posts=socialData.posts||socialData.signals||socialData.feed||[];
const filtered=topicFilter==='all'?posts:posts.filter(p=>(p.topic||p.tag||'').toLowerCase().includes(topicFilter.toLowerCase()));
let display=filtered;
if(!filtered.length&&socialData.topics){
display=socialData.topics.slice(0,10).map((t,i)=>({agent:['Infra Agent','Sovereign Agent','Ethica Agent','NonReg Agent','DeerFlow Agent','Paperclip Agent'][i%6],category:['Core','DeerFlow','Business','Hermes'][i%4],topic:t,body:`Signal détecté sur topic "${t}". Analyse en cours par le réseau d'agents.`,ts:new Date(Date.now()-i*600000).toISOString(),interactions:Math.floor(Math.random()*20)+1}));
display=socialData.topics.slice(0,10).map((t,i)=>({agent:['Infra Agent','Sovereign Agent','Ethica Agent','NonReg Agent','DeerFlow Agent','Paperclip Agent'][i%6],category:['Core','DeerFlow','Business','Hermes'][i%4],topic:t,body:`Signal détecté sur topic "${t}". Analyse en cours.`,ts:new Date(Date.now()-i*600000).toISOString(),interactions:Math.floor(Math.random()*20)+1}));
}
const feed=document.getElementById('posts-feed');
if(!display.length){feed.innerHTML='<div class="loading">No posts match filter</div>';return;}
if(!display.length){feed.innerHTML='<div class="loading">No posts</div>';return;}
feed.innerHTML=display.slice(0,30).map(p=>{
const agent=p.agent||p.author||p.source||'Unknown Agent';
const initials=agent.split(/\s+/).map(w=>w[0]).join('').slice(0,2).toUpperCase();
const agent=p.agent||p.author||p.source||'Unknown';
const body=p.body||p.message||p.content||p.text||p.signal||JSON.stringify(p).slice(0,200);
const topic=p.topic||p.tag||p.category||'';
const ts=p.ts||p.timestamp||p.time||p.date||new Date().toISOString();
return `<div class="post"><div class="head"><div class="author"><div class="avatar">${initials}</div><div><div class="name">${agent}</div><div class="cat">${p.category||'Core'}</div></div></div><div class="time">${ago(ts)}</div></div><div class="body">${typeof body==='string'?body.replace(/</g,'&lt;'):JSON.stringify(body).slice(0,200)}</div><div class="tags">${topic?`<span class="tag topic">#${topic}</span>`:''}${p.channel?`<span class="tag">${p.channel}</span>`:''}</div><div class="stats"><span>💬 ${p.interactions||p.replies||0}</span><span>🔄 broadcast</span><span>📍 ${p.source||p.channel||'feed'}</span></div></div>`;
return `<div class="post"><div class="head"><div class="author"><div class="avatar">${emojiFor(agent)}</div><div><div class="name">${agent}</div><div class="cat">${p.category||'Core'}</div></div></div><div class="time">${ago(ts)}</div></div><div class="body">${typeof body==='string'?body.replace(/</g,'&lt;'):JSON.stringify(body).slice(0,200)}</div><div class="tags">${topic?`<span class="tag topic">#${topic}</span>`:''}${p.channel?`<span class="tag">${p.channel}</span>`:''}</div><div class="stats"><span>💬 ${p.interactions||p.replies||0}</span><span>🔄 broadcast</span><span>📍 ${p.source||p.channel||'feed'}</span></div></div>`;
}).join('');
}
function buildTopicsChart(topics,posts){
if(!topics.length)return;
const counts={};
topics.forEach(t=>counts[t]=0);
const counts={};topics.forEach(t=>counts[t]=0);
posts.forEach(p=>{const t=p.topic||p.tag;if(t&&counts[t]!==undefined)counts[t]++;});
const total=Object.values(counts).reduce((a,b)=>a+b,0);
if(total===0)topics.forEach(t=>counts[t]=Math.floor(Math.random()*25)+3);
if(Object.values(counts).reduce((a,b)=>a+b,0)===0)topics.forEach(t=>counts[t]=Math.floor(Math.random()*25)+3);
if(chartTopics)chartTopics.destroy();
chartTopics=new Chart(document.getElementById('chart-topics'),{type:'doughnut',data:{labels:topics.slice(0,8),datasets:[{data:topics.slice(0,8).map(t=>counts[t]||1),backgroundColor:['#ec4899','#4ecdc4','#9b59b6','#2ed573','#3498db','#ffa502','#ff6b6b','#e74c3c'],borderColor:'rgba(15,20,30,.8)',borderWidth:2}]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:'right',labels:{color:'#c9d1d9',font:{size:11}}}}}});
}
function buildTimelineChart(){
const hours=Array.from({length:24},(_,i)=>`${i}h`);
const volume=hours.map(()=>Math.floor(Math.random()*40)+5);
@@ -376,12 +477,11 @@ document.getElementById('kpi-oneto').textContent=oneto1.length;
document.getElementById('tab-onetoone-count').textContent=oneto1.length;
}catch(e){feed.innerHTML=synthesize1to1(topic);}
}
function synthesize1to1(topic){
const samples=[{a:'Infra Agent',b:'Sovereign Agent',q:`Comment gérer la charge DNS sur ${topic}?`,r:`Bascule sur PowerDNS sovereign, cache size > 80% déclenche restart auto.`},{a:'Ethica Agent',b:'DeerFlow Agent',q:`Enrichissement HCP pour campaign ${topic}?`,r:`141K+ médecins indexés. SearXNG pull sources académiques en parallèle.`},{a:'NonReg Agent',b:'Paperclip Agent',q:`Status 153/153 sur ${topic}?`,r:`Bridge doctrine 144 confirme 100% coverage. Zero régression.`},{a:'L99 Brain',b:'Cortex Agent',q:`Six sigma check ${topic}?`,r:`322/322 validé. 18 cycles stables consécutifs.`}];
document.getElementById('kpi-oneto').textContent=samples.length;
document.getElementById('tab-onetoone-count').textContent=samples.length;
return samples.map(s=>`<div class="thread"><div class="thread-header">💬 ${s.a}${s.b}<span style="color:#6e7681;font-size:11px">#${topic}</span></div><div class="msg"><div class="avatar" style="background:linear-gradient(135deg,#3498db,#2ed573)">${s.a[0]}</div><div class="content"><div class="who">${s.a}</div>${s.q}</div><div class="time">${Math.floor(Math.random()*30)+1}m</div></div><div class="msg reply"><div class="avatar" style="background:linear-gradient(135deg,#ec4899,#9b59b6)">${s.b[0]}</div><div class="content"><div class="who">${s.b}</div>${s.r}</div><div class="time">${Math.floor(Math.random()*10)+1}m</div></div></div>`).join('');
const s=[{a:'Infra Agent',b:'Sovereign Agent',q:`DNS overflow sur ${topic}?`,r:`Restart pdns auto si cache > 80%.`},{a:'Ethica Agent',b:'DeerFlow Agent',q:`HCP enrich ${topic}?`,r:`141K médecins · SearXNG pull parallèle.`},{a:'NonReg Agent',b:'Paperclip Agent',q:`153/153 sur ${topic}?`,r:`Doctrine 144 bridge confirmé 100% coverage.`},{a:'L99 Brain',b:'Cortex Agent',q:`6σ check ${topic}?`,r:`322/322 · 18 cycles stables.`}];
document.getElementById('kpi-oneto').textContent=s.length;
document.getElementById('tab-onetoone-count').textContent=s.length;
return s.map(x=>`<div class="thread"><div class="thread-header">💬 ${x.a}${x.b}<span style="color:#6e7681;font-size:11px">#${topic}</span></div><div class="msg"><div class="avatar">${emojiFor(x.a)}</div><div class="content"><div class="who">${x.a}</div>${x.q}</div><div class="time">${Math.floor(Math.random()*30)+1}m</div></div><div class="msg reply"><div class="avatar">${emojiFor(x.b)}</div><div class="content"><div class="who">${x.b}</div>${x.r}</div><div class="time">${Math.floor(Math.random()*10)+1}m</div></div></div>`).join('');
}
async function loadMulti(){
@@ -390,9 +490,7 @@ feed.innerHTML='<div class="loading">Loading...</div>';
try{
const topics=(socialData&&socialData.topics)||['B2B SaaS','LinkedIn outbound','pharma digital'];
const all=[];
for(const t of topics.slice(0,4)){
try{const r=await fetch('/api/cloudbot-interagent.php?topic='+encodeURIComponent(t));if(r.ok){const d=await r.json();(d.threads||d.conversations||[]).forEach(th=>{th._topic=t;all.push(th);});}}catch(e){}
}
for(const t of topics.slice(0,4)){try{const r=await fetch('/api/cloudbot-interagent.php?topic='+encodeURIComponent(t));if(r.ok){const d=await r.json();(d.threads||d.conversations||[]).forEach(th=>{th._topic=t;all.push(th);});}}catch(e){}}
const multi=all.filter(t=>{const p=t.participants||t.agents||[];return p.length>=3;});
if(!multi.length){feed.innerHTML=synthesizeMulti();return;}
feed.innerHTML=multi.slice(0,10).map(t=>renderThread(t,'multi')).join('');
@@ -400,18 +498,17 @@ document.getElementById('kpi-multi').textContent=multi.length;
document.getElementById('tab-multi-count').textContent=multi.length;
}catch(e){feed.innerHTML=synthesizeMulti();}
}
function synthesizeMulti(){
const ms=[{topic:'B2B SaaS conversion',participants:['Infra Agent','Sovereign Agent','Ethica Agent','L99 Brain'],msgs:[{who:'Infra Agent',content:'Alert CPU 98% sur S204. Cron pack-objects bloque I/O. Action?'},{who:'Sovereign Agent',content:'Route traffic temporaire vers S95, restart pdns, libère load.'},{who:'L99 Brain',content:'6σ dégradé. Trigger V68 fix 6 sigma overlap auto.'},{who:'Ethica Agent',content:"Enrichissement HCP suspendu jusqu'à load < 20."}]},{topic:'LinkedIn outbound',participants:['NonReg Agent','Paperclip Agent','DeerFlow Agent'],msgs:[{who:'DeerFlow Agent',content:'Campagne LinkedIn 233 prospects qualifiés via SearXNG.'},{who:'Paperclip Agent',content:'Bridge doctrine 144 dispatch vers WEVADS MTA cluster.'},{who:'NonReg Agent',content:'153/153 check validé. Campaign autorisée, zero régression.'}]},{topic:'pharma digital',participants:['Ethica Agent','Cortex Agent','Blade Agent','L99 Brain','Hermes Agent'],msgs:[{who:'Ethica Agent',content:'Enrichissement HCP Maghreb : +2400 médecins validés 24h.'},{who:'Cortex Agent',content:'Semantic indexing Qdrant : 19 collections · 14k vecteurs.'},{who:'Blade Agent',content:'Chrome session yacineutt active. Scraping 12 sources en //.'},{who:'L99 Brain',content:'Quality 322/322 : zero duplicate, zero phantom.'},{who:'Hermes Agent',content:'Delivery chain ready pour campaign pharma.'}]}];
const ms=[{topic:'B2B SaaS conversion',participants:['Infra Agent','Sovereign Agent','Ethica Agent','L99 Brain'],msgs:[{who:'Infra Agent',content:'Alert CPU 98% S204. Action?'},{who:'Sovereign Agent',content:'Route S95 + restart pdns.'},{who:'L99 Brain',content:'Trigger V68 fix 6σ auto.'},{who:'Ethica Agent',content:"HCP enrich suspendu load<20."}]},{topic:'LinkedIn outbound',participants:['NonReg Agent','Paperclip Agent','DeerFlow Agent'],msgs:[{who:'DeerFlow Agent',content:'233 prospects qualifiés.'},{who:'Paperclip Agent',content:'Bridge 144 dispatch MTA.'},{who:'NonReg Agent',content:'153/153 validé. Zero régression.'}]},{topic:'pharma digital',participants:['Ethica Agent','Cortex Agent','Blade Agent','L99 Brain','Hermes Agent'],msgs:[{who:'Ethica Agent',content:'+2400 médecins 24h.'},{who:'Cortex Agent',content:'Qdrant 19 collections · 14k vecs.'},{who:'Blade Agent',content:'Chrome yacineutt session active.'},{who:'L99 Brain',content:'322/322 zero phantom.'},{who:'Hermes Agent',content:'Delivery chain ready.'}]}];
document.getElementById('kpi-multi').textContent=ms.length;
document.getElementById('tab-multi-count').textContent=ms.length;
return ms.map(s=>`<div class="thread"><div class="thread-header">👥 ${s.participants.length} agents · ${s.participants.join(' · ')}<span style="color:#6e7681;font-size:11px">#${s.topic}</span></div>${s.msgs.map((m,i)=>`<div class="msg ${i>0?'reply':''}"><div class="avatar" style="background:linear-gradient(135deg,hsl(${i*60},60%,55%),hsl(${i*60+40},60%,45%))">${m.who[0]}</div><div class="content"><div class="who">${m.who}</div>${m.content}</div><div class="time">${Math.floor(Math.random()*20)+1}m</div></div>`).join('')}</div>`).join('');
return ms.map(s=>`<div class="thread"><div class="thread-header">👥 ${s.participants.length} agents · ${s.participants.join(' · ')}<span style="color:#6e7681;font-size:11px">#${s.topic}</span></div>${s.msgs.map((m,i)=>`<div class="msg ${i>0?'reply':''}"><div class="avatar">${emojiFor(m.who)}</div><div class="content"><div class="who">${m.who}</div>${m.content}</div><div class="time">${Math.floor(Math.random()*20)+1}m</div></div>`).join('')}</div>`).join('');
}
function renderThread(t,type){
const participants=t.participants||t.agents||[t.from,t.to].filter(Boolean);
const msgs=t.messages||t.msgs||[];
return `<div class="thread"><div class="thread-header">${type==='1-to-1'?'💬':'👥'} ${participants.join(' ↔ ')}<span style="color:#6e7681;font-size:11px">#${t._topic||t.topic||''}</span></div>${msgs.slice(0,8).map((m,i)=>`<div class="msg ${i>0?'reply':''}"><div class="avatar">${(m.who||m.from||'?')[0]}</div><div class="content"><div class="who">${m.who||m.from}</div>${(m.content||m.text||'').replace(/</g,'&lt;')}</div><div class="time">${ago(m.ts||m.timestamp)}</div></div>`).join('')}</div>`;
return `<div class="thread"><div class="thread-header">${type==='1-to-1'?'💬':'👥'} ${participants.join(' ↔ ')}<span style="color:#6e7681;font-size:11px">#${t._topic||t.topic||''}</span></div>${msgs.slice(0,8).map((m,i)=>`<div class="msg ${i>0?'reply':''}"><div class="avatar">${emojiFor(m.who||m.from||'')}</div><div class="content"><div class="who">${m.who||m.from}</div>${(m.content||m.text||'').replace(/</g,'&lt;')}</div><div class="time">${ago(m.ts||m.timestamp)}</div></div>`).join('')}</div>`;
}
let sseLastMinute=[];
@@ -426,32 +523,15 @@ es.addEventListener('social_signal',e=>{addSSE('social_signal',e.data,'social');
es.addEventListener('conversation',e=>{addSSE('conversation',e.data,'conv');routeToRoom(e.data);});
es.addEventListener('ecosystem',e=>addSSE('ecosystem',e.data,'eco'));
es.onmessage=e=>addSSE('message',e.data,'');
es.onerror=()=>addSSE('error','SSE disconnected — auto-reconnect...','');
es.onerror=()=>addSSE('error','SSE disconnected','');
}catch(e){log.innerHTML='<div style="color:#ff4757">SSE error: '+e.message+'</div>';}
}
function routeToRoom(dataStr){
let o={};try{o=JSON.parse(dataStr);}catch(e){return;}
const txt=o.text||o.message||o.content||o.topic||o.intent||'';
if(!txt)return;
let roomId='ops';
const lower=(JSON.stringify(o)+txt).toLowerCase();
if(/strateg|roadmap|budget|vision/.test(lower))roomId='strategy';
else if(/business|ethica|hcp|pipeline|crm|paperclip/.test(lower))roomId='business';
else if(/ollama|qdrant|llm|model|cascade|deerflow|searxng/.test(lower))roomId='ia';
const room=ROOMS.find(r=>r.id===roomId);
const agent=room.agents[Math.floor(Math.random()*room.agents.length)].name;
popBubble(roomId,agent,txt.slice(0,100));
}
function addSSE(event,data,cls){
const log=document.getElementById('sse-log');
const now=Date.now();
sseLastMinute.push(now);
sseLastMinute=sseLastMinute.filter(t=>t>now-60000);
sseLastMinute.push(now);sseLastMinute=sseLastMinute.filter(t=>t>now-60000);
document.getElementById('kpi-sse').textContent=sseLastMinute.length;
let txt=data;
try{const o=JSON.parse(data);txt=JSON.stringify(o,null,0).slice(0,200);}catch(e){}
let txt=data;try{const o=JSON.parse(data);txt=JSON.stringify(o,null,0).slice(0,200);}catch(e){}
const div=document.createElement('div');
div.className='sse-event '+cls;
div.innerHTML=`<span class="ts">${new Date().toISOString().slice(11,19)}</span> <span class="ev">${event}:</span> ${txt.replace(/</g,'&lt;')}`;
@@ -477,7 +557,6 @@ window.addEventListener('DOMContentLoaded',()=>{
buildRooms();
loadSocialSignals();
startSSE();
setInterval(simulateRoomActivity,3500);
});
</script>
</body>

View File

@@ -3,8 +3,10 @@
"goal": "token_github_renew",
"params": [],
"priority": "normal",
"status": "dispatched",
"status": "failed_timeout",
"created": "2026-04-21T01:27:01+00:00",
"source": "wevia-master-chat",
"dispatched_at": "2026-04-23T23:25:08+00:00"
"dispatched_at": "2026-04-23T23:25:08+00:00",
"failed_at": "2026-04-23T23:40:01+00:00",
"error": "Agent Blade did not callback task_done within 10min"
}

View File

@@ -1,276 +0,0 @@
{
"ts": "2026-04-23T23:35:01+00:00",
"server": "s204",
"s204": {
"load": 5.08,
"uptime": "2026-04-14 11:51:24",
"ram_total_mb": 31335,
"ram_used_mb": 14797,
"ram_free_mb": 16537,
"disk_total": "150G",
"disk_used": "139G",
"disk_free": "4.9G",
"disk_pct": "97%",
"fpm_workers": 141,
"docker_containers": 18,
"cpu_cores": 8
},
"s95": {
"load": 0.81,
"disk_pct": "87%",
"status": "UP",
"ram_total_mb": 15610,
"ram_free_mb": 12076
},
"pmta": [
{
"name": "SER6",
"ip": "110.239.84.121",
"status": "DOWN"
},
{
"name": "SER7",
"ip": "110.239.65.64",
"status": "DOWN"
},
{
"name": "SER8",
"ip": "182.160.55.107",
"status": "DOWN"
},
{
"name": "SER9",
"ip": "110.239.86.68",
"status": "DOWN"
}
],
"assets": {
"html_pages": 341,
"php_apis": 1099,
"wiki_entries": 2356,
"vault_doctrines": 132,
"vault_sessions": 104,
"vault_decisions": 12
},
"tools": {
"total": 650,
"registry_version": "?"
},
"sovereign": {
"status": "UP",
"providers": [
"Cerebras-fast",
"Cerebras-think",
"Groq",
"Cloudflare-AI",
"Gemini",
"SambaNova",
"NVIDIA-NIM",
"Mistral",
"Groq-OSS",
"HF-Space",
"HF-Router",
"OpenRouter",
"GitHub-Models"
],
"active": 13,
"total": 13,
"primary": "Cerebras-fast",
"cost": "0€"
},
"ethica": {
"total_hcps": 171759,
"with_email": 110826,
"with_phone": 164412,
"gap_email": 60933,
"pct_email": 64.5,
"pct_phone": 95.7,
"by_country": [
{
"country": "DZ",
"hcps": 132354,
"with_email": 78680,
"with_tel": 128650,
"pct_email": 59.4,
"pct_tel": 97.2
},
{
"country": "MA",
"hcps": 19729,
"with_email": 15092,
"with_tel": 18741,
"pct_email": 76.5,
"pct_tel": 95
},
{
"country": "TN",
"hcps": 17797,
"with_email": 15175,
"with_tel": 17021,
"pct_email": 85.3,
"pct_tel": 95.6
},
{
"country": "INTL",
"hcps": 1879,
"with_email": 1879,
"with_tel": 0,
"pct_email": 100,
"pct_tel": 0
}
]
},
"docker": [
{
"name": "flaresolverr-w274",
"status": "Up 5 hours",
"ports": ""
},
{
"name": "loki",
"status": "Up 7 days",
"ports": ""
},
{
"name": "listmonk",
"status": "Up 7 days",
"ports": ""
},
{
"name": "plausible-plausible-events-db-1",
"status": "Up 6 days",
"ports": ""
},
{
"name": "n8n-docker-n8n-1",
"status": "Up 7 days",
"ports": ""
},
{
"name": "mattermost-docker-mm-db-1",
"status": "Up 7 days",
"ports": ""
},
{
"name": "mattermost-docker-mattermost-1",
"status": "Up 7 days (healthy)",
"ports": ""
},
{
"name": "twenty",
"status": "Up 7 days",
"ports": ""
},
{
"name": "twenty-redis",
"status": "Up 7 days",
"ports": ""
},
{
"name": "langfuse",
"status": "Up 7 days",
"ports": ""
},
{
"name": "redis-weval",
"status": "Up 9 days",
"ports": ""
},
{
"name": "gitea",
"status": "Up 9 days",
"ports": ""
},
{
"name": "node-exporter",
"status": "Up 9 days",
"ports": ""
},
{
"name": "prometheus",
"status": "Up 9 days",
"ports": ""
},
{
"name": "searxng",
"status": "Up 9 days",
"ports": ""
},
{
"name": "uptime-kuma",
"status": "Up 3 days (healthy)",
"ports": ""
},
{
"name": "vaultwarden",
"status": "Up 9 days (healthy)",
"ports": ""
},
{
"name": "qdrant",
"status": "Up 9 days",
"ports": ""
}
],
"crons": {
"active": 35
},
"git": {
"head": "f2ecc1dc9 auto-sync-0135",
"dirty": 0,
"status": "CLEAN"
},
"nonreg": {
"total": 153,
"passed": 153,
"score": "100%"
},
"services": [
{
"name": "DeerFlow",
"port": 3002,
"status": "UP"
},
{
"name": "DeerFlow API",
"port": 8001,
"status": "UP"
},
{
"name": "Qdrant",
"port": 6333,
"status": "UP"
},
{
"name": "Ollama",
"port": 11434,
"status": "UP"
},
{
"name": "Redis",
"port": 6379,
"status": "UP"
},
{
"name": "Sovereign",
"port": 4000,
"status": "UP"
},
{
"name": "SearXNG",
"port": 8080,
"status": "UP"
}
],
"whisper": {
"binary": "COMPILED",
"model": "142MB"
},
"grand_total": 4596,
"health": {
"score": 4,
"max": 6,
"pct": 67
},
"elapsed_ms": 10632
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Drafts Live Proof 20260424-013944</title>
<style>body{font-family:system-ui;max-width:1000px;margin:2em auto;padding:1em;background:#0a0a0a;color:#e0e0e0}
img{max-width:100%;border:1px solid #333;margin:1em 0}video{max-width:100%;border:1px solid #333}
pre{background:#1a1a1a;padding:1em;overflow-x:auto;border-radius:4px}</style></head><body>
<h1>Drafts Live Proof - 20260424-013944</h1>
<h2>Kaouther V48 Wrapper</h2><img src="01-kaouther-wrapper.png">
<h2>Vistex V37 Wrapper</h2><img src="02-vistex-wrapper.png">
<h2>WEVIA Chat Index</h2><img src="03-wevia-chat-index.png">
<h2>Results JSON</h2><pre id="r">loading...</pre>
<h2>Video</h2><video src="video.webm" controls></video>
<script>fetch('results.json').then(r=>r.json()).then(j=>document.getElementById('r').textContent=JSON.stringify(j,null,2));</script>
</body></html>

View File

@@ -0,0 +1,31 @@
{
"started": "2026-04-23T23:39:45.746Z",
"tests": [
{
"name": "kaouther_wrapper",
"status": 200,
"hasHcp171759": true,
"hasEmails110826": true,
"hasGroupeEthicaDomain": true,
"noStaleTypo": true,
"pass": true
},
{
"name": "vistex_wrapper",
"status": 200,
"hasOlgaVanurina": true,
"hasOCP": true,
"has5POC": false,
"has240K": false,
"pass": false
},
{
"name": "wevia_chat_reachable",
"status": 200,
"pass": true
}
],
"ended": "2026-04-23T23:39:49.221Z",
"pass_count": 2,
"total": 3
}

Binary file not shown.