984 lines
50 KiB
HTML
984 lines
50 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>WEVIA Cloudbot Social v2 - Live Network</title>
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root{
|
|
--bg:#070a15;--bg2:#0d1220;--card:#121829;--card-h:#1a2138;--bd:rgba(130,150,210,.1);--bd2:rgba(130,150,210,.18);
|
|
--ac:#8b5cf6;--a2:#06d6ba;--wn:#fbbf24;--er:#ef4444;--ok:#10b981;--inf:#3b82f6;--pk:#ec4899;
|
|
--fg:#f1f5f9;--dm:#64748b;--mg:#94a3b8;--hg:#cbd5e1;
|
|
--grad:linear-gradient(135deg,#8b5cf6 0%,#06d6ba 100%);
|
|
--grad2:linear-gradient(135deg,#ec4899 0%,#8b5cf6 50%,#06d6ba 100%);
|
|
--gradInfo:linear-gradient(135deg,#3b82f6 0%,#8b5cf6 100%);
|
|
--shadow-sm:0 2px 8px rgba(139,92,246,.08);
|
|
--shadow-md:0 8px 32px rgba(139,92,246,.12);
|
|
--shadow-lg:0 20px 60px rgba(139,92,246,.2);
|
|
--glow:0 0 40px rgba(139,92,246,.4);
|
|
}
|
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
html,body{background:var(--bg);color:var(--fg);font-family:'Inter',-apple-system,Segoe UI,sans-serif;min-height:100vh;overflow-x:hidden}
|
|
|
|
/* Animated bg */
|
|
body::before{content:"";position:fixed;inset:0;background:
|
|
radial-gradient(ellipse at 20% 0%,rgba(139,92,246,.15),transparent 50%),
|
|
radial-gradient(ellipse at 80% 100%,rgba(6,214,186,.08),transparent 50%),
|
|
radial-gradient(ellipse at 50% 50%,rgba(236,72,153,.05),transparent 60%);
|
|
z-index:-1;pointer-events:none;animation:bgMove 20s ease-in-out infinite alternate}
|
|
@keyframes bgMove{0%{transform:scale(1)}100%{transform:scale(1.1) rotate(1deg)}}
|
|
|
|
header{padding:20px 32px;border-bottom:1px solid var(--bd);display:flex;align-items:center;justify-content:space-between;gap:20px;position:sticky;top:0;z-index:100;backdrop-filter:blur(24px) saturate(180%);background:rgba(7,10,21,.75);flex-wrap:wrap}
|
|
.brand{display:flex;align-items:center;gap:14px}
|
|
.logo{width:44px;height:44px;border-radius:12px;background:var(--grad2);display:flex;align-items:center;justify-content:center;font-size:22px;box-shadow:var(--shadow-md);position:relative;overflow:hidden}
|
|
.logo::after{content:"";position:absolute;inset:0;background:linear-gradient(45deg,transparent 30%,rgba(255,255,255,.3) 50%,transparent 70%);animation:shimmer 3s infinite}
|
|
@keyframes shimmer{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
|
|
h1{font-size:24px;font-weight:900;background:var(--grad2);-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:-.6px;line-height:1}
|
|
.sub{font-size:11px;color:var(--mg);margin-top:4px;display:flex;align-items:center;gap:10px}
|
|
.pulse-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--ok);animation:pulse 2s infinite;box-shadow:0 0 8px var(--ok)}
|
|
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.3)}}
|
|
|
|
.nav{display:flex;gap:6px;flex-wrap:wrap}
|
|
.btn{padding:9px 14px;border-radius:10px;background:var(--card);border:1px solid var(--bd2);color:var(--fg);font-size:12px;font-weight:600;cursor:pointer;text-decoration:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
|
|
.btn:hover{background:var(--card-h);border-color:var(--ac);transform:translateY(-1px);box-shadow:var(--shadow-sm)}
|
|
.btn-primary{background:var(--grad);border:none;color:#fff;font-weight:700}
|
|
.btn-primary:hover{box-shadow:var(--glow)}
|
|
|
|
/* Hero stats */
|
|
.hero{max-width:1500px;margin:24px auto 0;padding:0 24px}
|
|
.hero-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:24px}
|
|
.stat-card{background:var(--card);border:1px solid var(--bd2);border-radius:16px;padding:18px;position:relative;overflow:hidden;transition:all .3s}
|
|
.stat-card:hover{transform:translateY(-3px);border-color:var(--ac);box-shadow:var(--shadow-md)}
|
|
.stat-card::before{content:"";position:absolute;top:-50%;right:-30%;width:200px;height:200px;border-radius:50%;opacity:.08;filter:blur(40px)}
|
|
.stat-card.c1::before{background:var(--ac)}
|
|
.stat-card.c2::before{background:var(--a2)}
|
|
.stat-card.c3::before{background:var(--wn)}
|
|
.stat-card.c4::before{background:var(--pk)}
|
|
.stat-card.c5::before{background:var(--inf)}
|
|
.stat-card.c6::before{background:var(--ok)}
|
|
.stat-val{font-size:32px;font-weight:900;line-height:1;letter-spacing:-1px}
|
|
.stat-val.g1{background:var(--grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-val.g2{background:linear-gradient(135deg,#06d6ba,#3b82f6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-val.g3{background:linear-gradient(135deg,#fbbf24,#ec4899);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-val.g4{background:linear-gradient(135deg,#ec4899,#8b5cf6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-val.g5{background:linear-gradient(135deg,#3b82f6,#06d6ba);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-val.g6{background:linear-gradient(135deg,#10b981,#06d6ba);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-lbl{font-size:10px;text-transform:uppercase;letter-spacing:2px;color:var(--mg);margin-top:8px;font-weight:700}
|
|
.stat-extra{font-size:11px;color:var(--hg);margin-top:6px;display:flex;align-items:center;gap:5px}
|
|
.stat-icon{width:30px;height:30px;border-radius:8px;background:rgba(139,92,246,.15);display:flex;align-items:center;justify-content:center;font-size:16px;margin-bottom:12px}
|
|
.up{color:var(--ok)} .dn{color:var(--er)}
|
|
|
|
/* Main grid */
|
|
main{max-width:1500px;margin:0 auto;padding:0 24px 40px;display:grid;grid-template-columns:260px 1fr 320px;gap:20px}
|
|
@media(max-width:1200px){main{grid-template-columns:220px 1fr;padding:0 16px 24px}.activity{display:none}}
|
|
@media(max-width:768px){main{grid-template-columns:1fr;padding:0 12px 24px}.sidebar{display:none}}
|
|
|
|
/* Sidebar cats */
|
|
.sidebar{position:sticky;top:110px;height:calc(100vh - 130px);overflow-y:auto;scrollbar-width:thin}
|
|
.sidebar::-webkit-scrollbar{width:4px}
|
|
.sidebar::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:2px}
|
|
.panel{background:var(--card);border:1px solid var(--bd2);border-radius:14px;padding:16px;margin-bottom:14px;backdrop-filter:blur(10px)}
|
|
.panel-h{font-size:10px;text-transform:uppercase;letter-spacing:1.6px;color:var(--mg);margin-bottom:14px;font-weight:800;display:flex;align-items:center;gap:8px}
|
|
.cat-list{display:flex;flex-direction:column;gap:4px}
|
|
.cat-item{padding:9px 12px;border-radius:9px;cursor:pointer;display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:600;transition:all .15s;border:1px solid transparent}
|
|
.cat-item:hover{background:var(--card-h);border-color:var(--bd2)}
|
|
.cat-item.active{background:rgba(139,92,246,.12);color:var(--ac);border-color:rgba(139,92,246,.3)}
|
|
.cat-count{background:rgba(130,150,210,.08);padding:2px 8px;border-radius:10px;font-size:10px;color:var(--hg);font-weight:700;font-family:'JetBrains Mono',monospace}
|
|
.cat-item.active .cat-count{background:var(--ac);color:#fff}
|
|
|
|
/* Feed */
|
|
.feed{min-height:calc(100vh - 130px)}
|
|
.filter-bar{background:var(--card);border:1px solid var(--bd2);border-radius:14px;padding:14px;margin-bottom:18px;display:flex;gap:10px;align-items:center;flex-wrap:wrap;box-shadow:var(--shadow-sm)}
|
|
.search-wrap{flex:1;position:relative;min-width:240px}
|
|
.search-wrap::before{content:"🔍";position:absolute;left:14px;top:50%;transform:translateY(-50%);opacity:.5}
|
|
.search{width:100%;background:var(--bg2);border:1px solid var(--bd2);padding:10px 14px 10px 40px;border-radius:10px;color:var(--fg);font-size:13px;font-family:inherit;transition:all .2s}
|
|
.search:focus{outline:none;border-color:var(--ac);box-shadow:0 0 0 3px rgba(139,92,246,.15)}
|
|
.chip{padding:6px 12px;border-radius:8px;background:var(--bg2);border:1px solid var(--bd2);font-size:11px;cursor:pointer;color:var(--mg);font-weight:600;transition:all .15s;display:inline-flex;align-items:center;gap:5px}
|
|
.chip:hover{color:var(--fg);border-color:var(--ac)}
|
|
.chip.on{background:var(--grad);color:#fff;border-color:transparent}
|
|
|
|
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
|
|
.agent-card{background:var(--card);border:1px solid var(--bd2);border-radius:14px;padding:18px;cursor:pointer;transition:all .25s;position:relative;overflow:hidden}
|
|
.agent-card::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--cat-color,var(--ac));opacity:.6;transition:opacity .2s}
|
|
.agent-card::after{content:"";position:absolute;top:-30%;right:-30%;width:180px;height:180px;border-radius:50%;background:var(--cat-color,var(--ac));opacity:0;filter:blur(50px);transition:opacity .4s}
|
|
.agent-card:hover{transform:translateY(-4px);border-color:var(--cat-color,var(--ac));box-shadow:var(--shadow-md)}
|
|
.agent-card:hover::before{opacity:1}
|
|
.agent-card:hover::after{opacity:.15}
|
|
.agent-card>*{position:relative;z-index:1}
|
|
|
|
.agent-head{display:flex;align-items:flex-start;gap:12px;margin-bottom:12px}
|
|
.agent-avatar{width:46px;height:46px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;box-shadow:var(--shadow-sm);position:relative;background:var(--cat-color,var(--ac))}
|
|
.agent-avatar::after{content:"";position:absolute;inset:0;border-radius:12px;border:2px solid rgba(255,255,255,.1)}
|
|
.agent-name{font-size:15px;font-weight:800;color:var(--fg);margin-bottom:3px;letter-spacing:-.3px}
|
|
.agent-cat-lbl{font-size:10px;color:var(--mg);text-transform:uppercase;letter-spacing:.8px;font-weight:700;display:flex;align-items:center;gap:5px}
|
|
.agent-desc{font-size:12px;color:var(--hg);line-height:1.6;margin:8px 0 14px;min-height:38px}
|
|
|
|
.agent-metrics{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}
|
|
.metric-tag{font-size:9.5px;padding:3px 7px;background:var(--bg2);border-radius:5px;color:var(--mg);font-weight:600;font-family:'JetBrains Mono',monospace;border:1px solid var(--bd)}
|
|
|
|
.agent-status{display:flex;align-items:center;gap:6px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--ok)}
|
|
.agent-status.idle{color:var(--dm)}
|
|
.agent-status .status-dot{width:7px;height:7px;border-radius:50%;background:currentColor;animation:pulse 2s infinite;box-shadow:0 0 8px currentColor}
|
|
.agent-status.idle .status-dot{animation:none}
|
|
|
|
.agent-actions{display:flex;gap:6px;margin-top:14px;padding-top:14px;border-top:1px solid var(--bd)}
|
|
.act-btn{flex:1;padding:8px 10px;background:var(--bg2);border:1px solid var(--bd2);border-radius:8px;font-size:11px;color:var(--mg);cursor:pointer;transition:all .15s;text-align:center;font-weight:600;display:inline-flex;align-items:center;justify-content:center;gap:5px}
|
|
.act-btn:hover{background:var(--card-h);color:var(--ac);border-color:var(--ac);transform:scale(1.02)}
|
|
.act-btn.primary{background:var(--grad);color:#fff;border-color:transparent}
|
|
.act-btn.primary:hover{box-shadow:var(--glow)}
|
|
|
|
/* Activity right */
|
|
.activity{position:sticky;top:110px;height:calc(100vh - 130px);overflow-y:auto;scrollbar-width:thin}
|
|
.activity::-webkit-scrollbar{width:4px}
|
|
.activity::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:2px}
|
|
|
|
.live-feed{max-height:360px;overflow-y:auto}
|
|
.live-item{padding:10px 12px;background:var(--bg2);border-radius:10px;margin-bottom:8px;border-left:3px solid var(--ac);font-size:11px;transition:all .2s;position:relative}
|
|
.live-item:hover{background:var(--card-h);transform:translateX(2px)}
|
|
.live-item-head{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:4px}
|
|
.live-item-msg{color:var(--fg);font-weight:500;line-height:1.45}
|
|
.live-item-meta{font-size:9px;color:var(--dm);margin-top:6px;display:flex;align-items:center;gap:6px}
|
|
|
|
.infra-list{display:grid;grid-template-columns:1fr 1fr;gap:6px}
|
|
.infra-item{background:var(--bg2);padding:8px 10px;border-radius:8px;font-size:11px;font-weight:600;display:flex;justify-content:space-between;align-items:center}
|
|
.infra-item.ok{border-left:3px solid var(--ok)}
|
|
.infra-item.down{border-left:3px solid var(--er)}
|
|
.svc-dot{width:6px;height:6px;border-radius:50%;background:var(--ok);display:inline-block}
|
|
.svc-dot.down{background:var(--er)}
|
|
|
|
/* Modal chat - premium glass */
|
|
.modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,.82);z-index:1000;align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(10px)}
|
|
.modal.on{display:flex;animation:modalIn .3s ease}
|
|
@keyframes modalIn{from{opacity:0}to{opacity:1}}
|
|
.modal-box{width:900px;max-width:100%;height:680px;max-height:92vh;background:var(--card);border-radius:20px;display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow-lg),0 0 60px rgba(139,92,246,.3);border:1px solid var(--bd2);animation:modalSlide .35s ease}
|
|
@keyframes modalSlide{from{transform:translateY(20px) scale(.98)}to{transform:translateY(0) scale(1)}}
|
|
.modal-head{padding:16px 22px;border-bottom:1px solid var(--bd2);display:flex;align-items:center;gap:14px;background:linear-gradient(180deg,rgba(139,92,246,.08),transparent)}
|
|
.modal-title{flex:1}
|
|
.modal-title-name{font-size:16px;font-weight:800;letter-spacing:-.3px}
|
|
.modal-title-sub{font-size:11px;color:var(--mg);margin-top:2px;display:flex;align-items:center;gap:6px}
|
|
.modal-close{background:var(--bg2);border:1px solid var(--bd2);color:var(--fg);font-size:18px;cursor:pointer;width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;transition:all .15s}
|
|
.modal-close:hover{background:var(--er);color:#fff;border-color:var(--er)}
|
|
|
|
.chat-area{flex:1;overflow-y:auto;padding:24px;display:flex;flex-direction:column;gap:12px;scrollbar-width:thin}
|
|
.chat-area::-webkit-scrollbar{width:6px}
|
|
.chat-area::-webkit-scrollbar-thumb{background:var(--bd2);border-radius:3px}
|
|
.msg{max-width:82%;padding:12px 16px;border-radius:16px;font-size:13px;line-height:1.6;word-wrap:break-word;animation:msgIn .3s ease}
|
|
@keyframes msgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
|
|
.msg.u{background:var(--grad);color:#fff;align-self:flex-end;border-bottom-right-radius:4px;box-shadow:var(--shadow-sm)}
|
|
.msg.a{background:var(--bg2);border:1px solid var(--bd2);align-self:flex-start;border-bottom-left-radius:4px}
|
|
.msg.sys{background:rgba(251,191,36,.08);border:1px solid rgba(251,191,36,.25);color:var(--wn);align-self:center;font-size:11px;max-width:95%;text-align:center;padding:8px 14px}
|
|
.msg-meta{font-size:10px;color:var(--dm);margin-top:6px;display:flex;align-items:center;gap:6px}
|
|
|
|
.typing{display:none;align-self:flex-start;padding:12px 16px;background:var(--bg2);border-radius:16px;border:1px solid var(--bd2)}
|
|
.typing.on{display:block}
|
|
.typing span{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--ac);margin:0 2px;animation:typingDot 1.4s infinite}
|
|
.typing span:nth-child(2){animation-delay:.2s} .typing span:nth-child(3){animation-delay:.4s}
|
|
@keyframes typingDot{0%,60%,100%{transform:translateY(0);opacity:.4}30%{transform:translateY(-6px);opacity:1}}
|
|
|
|
.chat-input-bar{display:flex;gap:8px;padding:16px 22px;border-top:1px solid var(--bd2);background:rgba(7,10,21,.6)}
|
|
.chat-input{flex:1;background:var(--bg2);border:1px solid var(--bd2);padding:12px 16px;border-radius:12px;color:var(--fg);font-size:13px;font-family:inherit}
|
|
.chat-input:focus{outline:none;border-color:var(--ac);box-shadow:0 0 0 3px rgba(139,92,246,.15)}
|
|
.send-btn{padding:12px 22px;background:var(--grad);border:none;border-radius:12px;color:#fff;font-size:13px;font-weight:700;cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:6px}
|
|
.send-btn:disabled{opacity:.5;cursor:wait}
|
|
.send-btn:not(:disabled):hover{box-shadow:var(--glow);transform:translateY(-1px)}
|
|
|
|
.loading-sk{background:linear-gradient(90deg,var(--card) 0%,var(--card-h) 50%,var(--card) 100%);background-size:200% 100%;animation:skeleton 1.5s infinite;border-radius:14px;height:180px}
|
|
@keyframes skeleton{0%{background-position:200% 0}100%{background-position:-200% 0}}
|
|
|
|
.empty{text-align:center;padding:40px;color:var(--dm);font-size:12px}
|
|
.heart{color:var(--er);animation:heart 1.5s infinite}
|
|
@keyframes heart{0%,100%{transform:scale(1)}50%{transform:scale(1.15)}}
|
|
|
|
/* Badge categories */
|
|
.cat-emoji{font-size:14px;line-height:1}
|
|
|
|
/* DOCTRINE 143 SSE badge */
|
|
#sse-live-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:9px;font-weight:700;letter-spacing:.5px;color:#fff;background:#64748b;vertical-align:middle;margin-left:8px}
|
|
@keyframes flash{0%{opacity:1}50%{opacity:.3}100%{opacity:1}}
|
|
#sse-health-pulse{font-size:10px;color:var(--a2);font-weight:600}
|
|
</style>
|
|
<!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-143816 -->
|
|
<style id="doctrine60-ux-direct">
|
|
|
|
/* DOCTRINE-60-UX-ENRICH injected-direct */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0; left: 0; width: 100vw; height: 100vh;
|
|
background: radial-gradient(circle at 50% 50%, rgba(100,180,255,0.08), transparent 60%);
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
.card, .kpi, .panel, .btn {
|
|
transition: all 0.3s cubic-bezier(0.2,0,0.1,1);
|
|
}
|
|
.card:hover, .kpi:hover, .panel:hover {
|
|
box-shadow: 0 4px 20px rgba(100,180,255,0.2);
|
|
border-color: rgba(100,180,255,0.5);
|
|
}
|
|
@keyframes pulseD60 {
|
|
0%,100% { opacity: 1; transform: scale(1); }
|
|
50% { opacity: 0.7; transform: scale(1.05); }
|
|
}
|
|
.pulse, .live-indicator, .active, .online {
|
|
animation: pulseD60 3s ease-in-out infinite;
|
|
}
|
|
.modal, .chat, .speech, .overlay {
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
}
|
|
.enter-stagger {
|
|
animation: enterStagD60 0.5s cubic-bezier(0.2,0,0.1,1) forwards;
|
|
}
|
|
@keyframes enterStagD60 {
|
|
from { opacity: 0; transform: translateY(20px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<div class="brand">
|
|
<div class="logo">☁️</div>
|
|
<div>
|
|
<h1>WEVIA Cloudbot Social</h1>
|
|
<div class="sub">
|
|
<span class="pulse-dot"></span>
|
|
<span id="hdr-status">Réseau vivant</span>
|
|
·
|
|
<span id="hdr-agents">726 agents</span>
|
|
·
|
|
<span id="hdr-score">-</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<nav class="nav">
|
|
<a class="btn" href="/all-ia-hub.html">🌐 All IA Hub</a>
|
|
<a class="btn" href="/wevia-meeting-rooms.html">🏛️ Meeting</a>
|
|
<a class="btn" href="/paperclip-flow.html" style="background:linear-gradient(135deg,#7c5cff,#4fd1c7);color:#fff;border:none">Paperclip Flow</a>
|
|
<a class="btn" href="/weval-live-ops.html" style="background:linear-gradient(135deg,#e94560,#c03350);color:#fff;border:none;font-weight:800">📊 Live Ops</a>
|
|
<a class="btn" href="/wevia-master.html">🧠 Master</a>
|
|
<a class="btn" href="/wevia-orchestrator.html">🎛️ Orchestrator</a>
|
|
<a class="btn btn-primary" href="/weval-technology-platform.html">⚡ WTP</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<section class="hero">
|
|
<div class="hero-stats">
|
|
<div class="stat-card c1">
|
|
<div class="stat-icon">🤖</div>
|
|
<div class="stat-val g1" id="s-agents">726</div>
|
|
<div class="stat-lbl">Agents Network</div>
|
|
<div class="stat-extra"><span class="up">▲</span> 8 catégories actives</div>
|
|
</div>
|
|
<div class="stat-card c2">
|
|
<div class="stat-icon">🎯</div>
|
|
<div class="stat-val g2" id="s-intents">2215</div>
|
|
<div class="stat-lbl">Intents wired</div>
|
|
<div class="stat-extra"><span class="up">▲</span> <span id="s-score">-</span> Health</div>
|
|
</div>
|
|
<div class="stat-card c3">
|
|
<div class="stat-icon">⚡</div>
|
|
<div class="stat-val g3" id="s-skills">694</div>
|
|
<div class="stat-lbl">Skills disponibles</div>
|
|
<div class="stat-extra">Registry <span id="s-catalog">-</span></div>
|
|
</div>
|
|
<div class="stat-card c4">
|
|
<div class="stat-icon">🧠</div>
|
|
<div class="stat-val g4" id="s-cognitive">635</div>
|
|
<div class="stat-lbl">Cognitive fn Opus46</div>
|
|
<div class="stat-extra">Qdrant <span id="s-qdrant">-</span> vecteurs</div>
|
|
</div>
|
|
<div class="stat-card c5">
|
|
<div class="stat-icon">💬</div>
|
|
<div class="stat-val g5" id="s-conv">0</div>
|
|
<div class="stat-lbl">Conversations session</div>
|
|
<div class="stat-extra"><span id="s-active">0</span> agents interrogés</div>
|
|
</div>
|
|
<div class="stat-card c6">
|
|
<div class="stat-icon">🛡️</div>
|
|
<div class="stat-val g6" id="s-nr">153/153</div>
|
|
<div class="stat-lbl">NonReg invariant</div>
|
|
<div class="stat-extra"><span class="up">▲</span> L99 <span id="s-l99">-</span></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<main>
|
|
<aside class="sidebar">
|
|
<div class="panel">
|
|
<div class="panel-h">📂 Catégories</div>
|
|
<div class="cat-list" id="cat-list">
|
|
<div class="cat-item active" data-cat="all">🌐 Tous <span class="cat-count">-</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div class="panel-h">⚡ Actions rapides</div>
|
|
<div class="cat-list">
|
|
<div class="cat-item" onclick="startMultiAgent()">🎯 Broadcast N agents</div>
|
|
<div class="cat-item" onclick="askFavorites()">⭐ Ask my favorites</div>
|
|
<div class="cat-item" onclick="location.href='/wevia-meeting-rooms.html'">🏛️ Meeting Room</div>
|
|
<div class="cat-item" onclick="startCollab()">🤝 Collab 2 agents</div>
|
|
<div class="cat-item" onclick="sendToPaperclip()" style="border-top:1px solid var(--bd);margin-top:6px;padding-top:10px;color:var(--a2)">🚀 Déclencher Paperclip</div>
|
|
<div class="cat-item" onclick="viewPaperclipQueue()">📋 Queue Paperclip</div>
|
|
<div class="cat-item" onclick="location.href='/wevia-orchestrator.html'">🎛️ Orchestrator</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div class="panel-h">🔥 Top agents</div>
|
|
<div id="top-agents" class="cat-list">
|
|
<div class="empty" style="padding:20px 0;font-size:11px">Chargement...</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<section class="feed">
|
|
<div class="filter-bar">
|
|
<div class="search-wrap">
|
|
<input type="text" class="search" placeholder="Chercher agent (WEVIA, Ethica, Blade, Cortex, DeerFlow...)" id="q" oninput="renderAgents()">
|
|
</div>
|
|
<div class="chip on" data-st="all" onclick="filterStatus(this)">Tous</div>
|
|
<div class="chip" data-st="live" onclick="filterStatus(this)">🟢 LIVE</div>
|
|
<div class="chip" data-st="ready" onclick="filterStatus(this)">✓ Ready</div>
|
|
<div class="chip" onclick="sortBy('name')" id="sort-name">↕️ Nom</div>
|
|
<div class="chip" onclick="sortBy('cat')" id="sort-cat">📂 Cat</div>
|
|
</div>
|
|
<div class="grid" id="grid">
|
|
<div class="loading-sk"></div>
|
|
<div class="loading-sk"></div>
|
|
<div class="loading-sk"></div>
|
|
<div class="loading-sk"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<aside class="activity">
|
|
<div class="panel">
|
|
<div class="panel-h">🔔 Feed LIVE (router)</div>
|
|
<div class="live-feed" id="live-feed">
|
|
<div class="empty" style="font-size:11px">Chargement...</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div class="panel-h">🖥️ Infra live</div>
|
|
<div class="infra-list" id="infra-list">
|
|
<div class="empty" style="font-size:11px;grid-column:1/-1">Scan...</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div class="panel-h">🎓 Training</div>
|
|
<div id="training-info" style="font-size:11px;line-height:1.7;color:var(--hg)">
|
|
<div class="empty" style="font-size:11px">Loading...</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</main>
|
|
|
|
<!-- Modal chat premium -->
|
|
<div class="modal" id="chat-modal">
|
|
<div class="modal-box">
|
|
<div class="modal-head">
|
|
<div class="agent-avatar" id="m-avatar" style="width:44px;height:44px;font-size:20px">?</div>
|
|
<div class="modal-title">
|
|
<div class="modal-title-name" id="m-name">Agent</div>
|
|
<div class="modal-title-sub"><span class="pulse-dot"></span> <span id="m-api">Routing...</span></div>
|
|
</div>
|
|
<button class="act-btn" onclick="sendChatToPaperclip()" style="padding:6px 12px;margin-right:8px">🚀 Paperclip</button>
|
|
<button class="modal-close" onclick="closeModal()">✕</button>
|
|
</div>
|
|
<div class="chat-area" id="m-chat"></div>
|
|
<div class="typing" id="m-typing"><span></span><span></span><span></span></div>
|
|
<div class="chat-input-bar">
|
|
<input class="chat-input" id="m-input" placeholder="Pose une question..." onkeypress="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMsg()}">
|
|
<button class="send-btn" id="m-send" onclick="sendMsg()">Envoyer ➤</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// ========== STATE ==========
|
|
var AGENTS=[], FILTERED=[], CURRENT_AGENT=null, STATUS_FILTER="all", CURRENT_CAT="all", SORT="default";
|
|
var CONV_COUNT=0, ACTIVE_AGENTS=new Set();
|
|
var UNIVERSAL_API="/api/weval-ia-fast.php";
|
|
|
|
var AGENT_APIS={
|
|
"wevia master":"/api/wevia-master-api.php",
|
|
"weval mind":"/api/hamid-api-proxy.php",
|
|
"weval manager":"/api/weval-manager.php",
|
|
"ethica":"/api/ethica-brain.php",
|
|
"bladerazor":"/api/blade-brain.php",
|
|
"blade":"/api/blade-brain.php",
|
|
"wevcode":"/api/wevcode-superclaude.php",
|
|
"wedroid":"/api/wedroid-brain-api.php",
|
|
"consensus":"/api/chat-proxy.php",
|
|
"claude":"/api/chat-proxy.php"
|
|
};
|
|
|
|
// Icons et couleurs par categorie (visuel vivant)
|
|
var CAT_META={
|
|
"core":{icon:"⚡",color:"#8b5cf6",label:"Core"},
|
|
"claudecode":{icon:"🔮",color:"#06d6ba",label:"Claude Code"},
|
|
"deerflow":{icon:"🦌",color:"#10b981",label:"DeerFlow"},
|
|
"hermes":{icon:"⚕️",color:"#fbbf24",label:"Hermes"},
|
|
"superclaude":{icon:"🧠",color:"#ec4899",label:"Superclaude"},
|
|
"skills":{icon:"🎯",color:"#06b6d4",label:"Skills"},
|
|
"business":{icon:"💼",color:"#3b82f6",label:"Business"},
|
|
"big4":{icon:"🏆",color:"#ef4444",label:"Big 4"}
|
|
};
|
|
|
|
function catMeta(cat){return CAT_META[cat]||{icon:"🤖",color:"#64748b",label:cat||"misc"}}
|
|
|
|
function getAgentAPI(agent){
|
|
var n=(agent.name||"").toLowerCase();
|
|
for(var k in AGENT_APIS){ if(n.indexOf(k)>=0)return AGENT_APIS[k]; }
|
|
return UNIVERSAL_API;
|
|
}
|
|
|
|
// ========== LOADERS ==========
|
|
async function loadAgents(){
|
|
try{
|
|
var r=await fetch("/api/agents-catalog-api.php");
|
|
var d=await r.json();
|
|
AGENTS=d.agents||[];
|
|
document.getElementById("s-agents").textContent=AGENTS.length.toLocaleString();
|
|
document.getElementById("hdr-agents").textContent=AGENTS.length.toLocaleString()+" agents";
|
|
document.getElementById("s-catalog").textContent=AGENTS.length;
|
|
renderCats(d.categories||{});
|
|
renderAgents();
|
|
renderTopAgents();
|
|
}catch(e){
|
|
document.getElementById("grid").innerHTML='<div class="empty">⚠️ '+e.message+'</div>';
|
|
}
|
|
}
|
|
|
|
async function loadHealth(){
|
|
try{
|
|
var r=await fetch("/api/ecosystem-health.php");
|
|
var d=await r.json();
|
|
if(d.score){document.getElementById("s-score").textContent=d.score;document.getElementById("hdr-score").textContent="Health "+d.score;}
|
|
if(d.l99){document.getElementById("s-l99").textContent=d.l99.pass+"/"+d.l99.total;}
|
|
if(d.ecosystem){
|
|
if(d.ecosystem.skills)document.getElementById("s-skills").textContent=d.ecosystem.skills.toLocaleString();
|
|
}
|
|
}catch(e){}
|
|
}
|
|
|
|
async function loadTraining(){
|
|
try{
|
|
var r=await fetch("/api/training-status.php");
|
|
var d=await r.json();
|
|
if(d.cognitive&&d.cognitive.fn)document.getElementById("s-cognitive").textContent=d.cognitive.fn;
|
|
if(d.intents&&d.intents.wired)document.getElementById("s-intents").textContent=d.intents.wired.toLocaleString();
|
|
if(d.qdrant&&d.qdrant.vectors!==undefined)document.getElementById("s-qdrant").textContent=d.qdrant.vectors;
|
|
// Panel training droit
|
|
var info=document.getElementById("training-info");
|
|
info.innerHTML='';
|
|
var addRow=function(icon,label,val){ info.innerHTML+='<div style="display:flex;justify-content:space-between;padding:4px 0"><span style="color:var(--mg)">'+icon+' '+label+'</span><strong style="color:var(--fg)">'+val+'</strong></div>'; };
|
|
if(d.hf_model)addRow("🤗","HF Model",'<span style="font-family:monospace;font-size:10px">'+d.hf_model+'</span>');
|
|
if(d.wiki&&d.wiki.entries)addRow("📚","Wiki",d.wiki.entries+" entries");
|
|
if(d.vault&&d.vault.files)addRow("🔐","Vault",d.vault.files+" files");
|
|
if(d.vault&&d.vault.gold)addRow("🥇","GOLD",d.vault.gold+" backups");
|
|
if(d.qdrant)addRow("🧬","Qdrant",(d.qdrant.vectors||0)+" vectors");
|
|
if(d.cron_training){
|
|
var crons=Object.keys(d.cron_training).map(function(k){return k+":"+d.cron_training[k]}).join(", ");
|
|
addRow("⏰","Crons",'<span style="color:var(--ok);font-size:10px">active x'+Object.keys(d.cron_training).length+'</span>');
|
|
}
|
|
}catch(e){}
|
|
}
|
|
|
|
async function loadInfra(){
|
|
try{
|
|
var r=await fetch("/api/infra-monitor-api.php");
|
|
var d=await r.json();
|
|
var list=document.getElementById("infra-list");
|
|
list.innerHTML='';
|
|
var servers=d.servers||{};
|
|
// Juste S204 services (les plus importants)
|
|
var s204=servers.s204||{};
|
|
var svcs=(s204.services||[]).slice(0,8);
|
|
svcs.forEach(function(s){
|
|
var cls=s.status==="active"?"ok":"down";
|
|
var dot=s.status==="active"?"":"down";
|
|
list.innerHTML+='<div class="infra-item '+cls+'"><span><span class="svc-dot '+dot+'"></span> '+s.name.substring(0,10)+'</span><span style="font-size:10px;color:var(--mg);font-family:monospace">'+(s.port||"")+'</span></div>';
|
|
});
|
|
}catch(e){ document.getElementById("infra-list").innerHTML='<div class="empty" style="grid-column:1/-1;font-size:11px">⚠️ offline</div>'; }
|
|
}
|
|
|
|
async function loadLiveFeed(){
|
|
try{
|
|
var r=await fetch("/api/router-activity.php?k=WEVADS2026&limit=10");
|
|
var d=await r.json();
|
|
var feed=document.getElementById("live-feed");
|
|
var matches=d.matches||[];
|
|
if(!matches.length){ feed.innerHTML='<div class="empty" style="font-size:11px">Pas d activité récente</div>'; return; }
|
|
feed.innerHTML=matches.slice(0,8).map(function(m){
|
|
var ago=timeAgo(m.ts);
|
|
var msg=(m.msg||"").substring(0,80);
|
|
return '<div class="live-item">'+
|
|
'<div class="live-item-head">'+
|
|
'<div class="live-item-msg">💭 '+escapeHtml(msg)+'</div>'+
|
|
'</div>'+
|
|
'<div class="live-item-meta">⏱ '+ago+' · <span style="font-family:monospace;opacity:.6">router</span></div>'+
|
|
'</div>';
|
|
}).join("");
|
|
}catch(e){}
|
|
}
|
|
|
|
// ========== RENDER ==========
|
|
function renderCats(cats){
|
|
var el=document.getElementById("cat-list");
|
|
el.innerHTML='<div class="cat-item active" data-cat="all" onclick="selectCat(\'all\',this)"><span><span class="cat-emoji">🌐</span> Tous</span><span class="cat-count">'+AGENTS.length+'</span></div>';
|
|
Object.keys(cats).sort(function(a,b){return cats[b]-cats[a]}).forEach(function(c){
|
|
var m=catMeta(c);
|
|
el.innerHTML+='<div class="cat-item" data-cat="'+c+'" onclick="selectCat(\''+c+'\',this)" style="--cat-color:'+m.color+'"><span><span class="cat-emoji">'+m.icon+'</span> '+m.label+'</span><span class="cat-count">'+cats[c]+'</span></div>';
|
|
});
|
|
}
|
|
|
|
function renderTopAgents(){
|
|
var el=document.getElementById("top-agents");
|
|
var top=AGENTS.slice(0,7);
|
|
el.innerHTML=top.map(function(a,i){
|
|
var m=catMeta(a.cat);
|
|
return '<div class="cat-item" onclick="openChat('+AGENTS.indexOf(a)+')" style="--cat-color:'+m.color+'">'+
|
|
'<span><span class="cat-emoji">'+(a.icon||m.icon)+'</span> '+(a.name||"?").substring(0,18)+'</span>'+
|
|
'<span class="cat-count" style="background:'+m.color+'22;color:'+m.color+'">'+m.label.substring(0,4)+'</span>'+
|
|
'</div>';
|
|
}).join("");
|
|
}
|
|
|
|
function selectCat(c,el){
|
|
CURRENT_CAT=c;
|
|
document.querySelectorAll(".cat-item[data-cat]").forEach(function(x){x.classList.remove("active")});
|
|
el.classList.add("active");
|
|
renderAgents();
|
|
}
|
|
|
|
function filterStatus(el){
|
|
STATUS_FILTER=el.dataset.st;
|
|
document.querySelectorAll(".filter-bar .chip[data-st]").forEach(function(x){x.classList.remove("on")});
|
|
el.classList.add("on");
|
|
renderAgents();
|
|
}
|
|
|
|
function sortBy(key){
|
|
SORT=key; renderAgents();
|
|
}
|
|
|
|
function renderAgents(){
|
|
var q=(document.getElementById("q").value||"").toLowerCase().trim();
|
|
FILTERED=AGENTS.filter(function(a){
|
|
if(CURRENT_CAT!=="all"&&a.cat!==CURRENT_CAT)return false;
|
|
if(STATUS_FILTER==="live"&&a.status!=="live"&&a.status!=="ready")return false;
|
|
if(STATUS_FILTER==="ready"&&a.status!=="ready")return false;
|
|
if(q&&!(a.name||"").toLowerCase().includes(q)&&!(a.desc||"").toLowerCase().includes(q))return false;
|
|
return true;
|
|
});
|
|
if(SORT==="name")FILTERED.sort(function(a,b){return(a.name||"").localeCompare(b.name||"")});
|
|
if(SORT==="cat")FILTERED.sort(function(a,b){return(a.cat||"").localeCompare(b.cat||"")});
|
|
|
|
var g=document.getElementById("grid");
|
|
if(!FILTERED.length){ g.innerHTML='<div class="empty" style="grid-column:1/-1">Aucun agent. Essaye "WEVIA" ou "Ethica"</div>'; return; }
|
|
var limit=60;
|
|
g.innerHTML=FILTERED.slice(0,limit).map(function(a){
|
|
var init=(a.name||"?").charAt(0).toUpperCase();
|
|
var m=catMeta(a.cat);
|
|
var statusCls=(a.status==="ready"||a.status==="live")?"":"idle";
|
|
var iconUsed=a.icon&&a.icon.length>=2?a.icon:init;
|
|
var idx=AGENTS.indexOf(a);
|
|
// Extract metriques de la desc si elle contient numbers
|
|
var metrics=[];
|
|
var desc=a.desc||"";
|
|
var nums=desc.match(/\d[\d,\/.]*/g)||[];
|
|
nums.slice(0,3).forEach(function(n){metrics.push(n)});
|
|
return '<div class="agent-card" style="--cat-color:'+m.color+'" onclick="openChat('+idx+')">'+
|
|
'<div class="agent-head">'+
|
|
'<div class="agent-avatar" style="background:linear-gradient(135deg,'+m.color+','+m.color+'cc)">'+iconUsed+'</div>'+
|
|
'<div style="flex:1;min-width:0">'+
|
|
'<div class="agent-name">'+escapeHtml(a.name||"?")+'</div>'+
|
|
'<div class="agent-cat-lbl"><span class="cat-emoji">'+m.icon+'</span> '+m.label+'</div>'+
|
|
'</div>'+
|
|
'</div>'+
|
|
'<div class="agent-desc">'+escapeHtml(desc||"Agent WEVAL")+'</div>'+
|
|
(metrics.length?'<div class="agent-metrics">'+metrics.map(function(x){return '<span class="metric-tag">'+x+'</span>'}).join("")+'</div>':'')+
|
|
'<div class="agent-status '+statusCls+'"><span class="status-dot"></span> '+(a.status||"ready").toUpperCase()+'</div>'+
|
|
'<div class="agent-actions" onclick="event.stopPropagation()">'+
|
|
'<button class="act-btn primary" onclick="openChat('+idx+')">💬 Chat</button>'+
|
|
'<button class="act-btn" onclick="askToAll(\''+escapeAttr(a.name)+'\')">📢 Broadcast</button>'+
|
|
'</div>'+
|
|
'</div>';
|
|
}).join("");
|
|
if(FILTERED.length>limit){ g.innerHTML+='<div class="empty" style="grid-column:1/-1;padding:20px">Affichage '+limit+'/'+FILTERED.length+' — affinez la recherche pour voir plus</div>'; }
|
|
}
|
|
|
|
// ========== CHAT ==========
|
|
function openChat(idx){
|
|
CURRENT_AGENT=AGENTS[idx];
|
|
if(!CURRENT_AGENT)return;
|
|
var m=catMeta(CURRENT_AGENT.cat);
|
|
ACTIVE_AGENTS.add(CURRENT_AGENT.name);
|
|
document.getElementById("s-active").textContent=ACTIVE_AGENTS.size;
|
|
document.getElementById("m-name").textContent=CURRENT_AGENT.name;
|
|
var av=document.getElementById("m-avatar");
|
|
av.textContent=(CURRENT_AGENT.icon&&CURRENT_AGENT.icon.length>=2)?CURRENT_AGENT.icon:(CURRENT_AGENT.name||"?").charAt(0).toUpperCase();
|
|
av.style.background="linear-gradient(135deg,"+m.color+","+m.color+"cc)";
|
|
var api=getAgentAPI(CURRENT_AGENT);
|
|
document.getElementById("m-api").textContent=m.label+" · "+api;
|
|
document.getElementById("m-chat").innerHTML='<div class="msg sys">🎉 Connecté à <strong>'+escapeHtml(CURRENT_AGENT.name)+'</strong><br><span style="font-size:10px;opacity:.7">'+escapeHtml(CURRENT_AGENT.desc||"")+'</span></div>';
|
|
document.getElementById("chat-modal").classList.add("on");
|
|
setTimeout(function(){document.getElementById("m-input").focus()},100);
|
|
}
|
|
function closeModal(){ document.getElementById("chat-modal").classList.remove("on"); }
|
|
|
|
async function sendMsg(){
|
|
var inp=document.getElementById("m-input");
|
|
var msg=inp.value.trim();
|
|
if(!msg||!CURRENT_AGENT)return;
|
|
var chat=document.getElementById("m-chat");
|
|
chat.innerHTML+='<div class="msg u">'+escapeHtml(msg)+'</div>';
|
|
inp.value="";
|
|
document.getElementById("m-send").disabled=true;
|
|
document.getElementById("m-typing").classList.add("on");
|
|
chat.scrollTop=chat.scrollHeight;
|
|
|
|
var api=getAgentAPI(CURRENT_AGENT);
|
|
var t0=Date.now();
|
|
try{
|
|
var r=await fetch(api,{
|
|
method:"POST",
|
|
headers:{"Content-Type":"application/json"},
|
|
body:JSON.stringify({message:msg,msg:msg,q:msg,provider:"cerebras",session_id:"cbsocial_"+Date.now(),caps:{kb:true,infra:true}})
|
|
});
|
|
var txt=await r.text();
|
|
var data;
|
|
try{ data=JSON.parse(txt); }catch(e){ data={response:txt.substring(0,600),error:"non-JSON"}; }
|
|
var reply=data.response||data.content||data.output||data.message||data.error||data.reply||"(réponse vide)";
|
|
if(typeof reply!=="string")reply=JSON.stringify(reply).substring(0,800);
|
|
var prov=data.provider||data.model||"unknown";
|
|
var ms=Date.now()-t0;
|
|
document.getElementById("m-typing").classList.remove("on");
|
|
chat.innerHTML+='<div class="msg a">'+escapeHtml(reply)+'<div class="msg-meta">⚡ '+escapeHtml(prov)+' · ⏱ '+ms+'ms</div></div>';
|
|
CONV_COUNT++;
|
|
document.getElementById("s-conv").textContent=CONV_COUNT;
|
|
}catch(e){
|
|
document.getElementById("m-typing").classList.remove("on");
|
|
chat.innerHTML+='<div class="msg sys">⚠️ '+escapeHtml(e.message)+'</div>';
|
|
}
|
|
document.getElementById("m-send").disabled=false;
|
|
chat.scrollTop=chat.scrollHeight;
|
|
}
|
|
|
|
// ========== ACTIONS ==========
|
|
function startMultiAgent(){
|
|
var q=prompt("❓ Question à broadcast (à 10 agents core+claudecode) :");
|
|
if(!q)return;
|
|
var sel=AGENTS.filter(function(a){return ["core","claudecode"].indexOf(a.cat)>=0}).slice(0,10);
|
|
sel.forEach(function(a,i){ setTimeout(function(){ openChat(AGENTS.indexOf(a)); document.getElementById("m-input").value=q; sendMsg(); setTimeout(closeModal,2500); }, i*3500); });
|
|
}
|
|
|
|
function askFavorites(){
|
|
var favs=["WEVIA Master","Ethica","Bladerazor","DeerFlow","Manager"];
|
|
var q=prompt("Question à poser à tes IA favorites (WEVIA Master, Ethica, Blade, DeerFlow, Manager) :");
|
|
if(!q)return;
|
|
var sel=[];
|
|
favs.forEach(function(n){ var a=AGENTS.find(function(x){return(x.name||"").toLowerCase().includes(n.toLowerCase())}); if(a)sel.push(a); });
|
|
sel.forEach(function(a,i){ setTimeout(function(){ openChat(AGENTS.indexOf(a)); document.getElementById("m-input").value=q; sendMsg(); setTimeout(closeModal,2500); }, i*3500); });
|
|
}
|
|
|
|
function askToAll(agentName){
|
|
var q=prompt("Question destinée à "+agentName+" (démarrage d un broadcast) :");
|
|
if(!q)return;
|
|
var a=AGENTS.find(function(x){return x.name===agentName});
|
|
if(a){ openChat(AGENTS.indexOf(a)); setTimeout(function(){ document.getElementById("m-input").value=q; sendMsg(); }, 300); }
|
|
}
|
|
|
|
function startCollab(){
|
|
var n1=prompt("Agent 1 (ex: WEVIA Master) :"); if(!n1)return;
|
|
var n2=prompt("Agent 2 (ex: Ethica) :"); if(!n2)return;
|
|
var topic=prompt("Sujet collab :"); if(!topic)return;
|
|
var a1=AGENTS.find(function(a){return(a.name||"").toLowerCase().includes(n1.toLowerCase())});
|
|
if(!a1){ alert("Agent "+n1+" non trouvé."); return; }
|
|
openChat(AGENTS.indexOf(a1));
|
|
setTimeout(function(){
|
|
document.getElementById("m-input").value="Analyse avec "+n2+" ce sujet : "+topic;
|
|
sendMsg();
|
|
},400);
|
|
}
|
|
|
|
// ========== UTILS ==========
|
|
function escapeHtml(s){ var d=document.createElement("div"); d.textContent=(s==null?"":String(s)); return d.innerHTML.replace(/\n/g,"<br>"); }
|
|
function escapeAttr(s){ return String(s||"").replace(/'/g,"").replace(/"/g,"").substring(0,40); }
|
|
function timeAgo(ts){
|
|
try{
|
|
var t=new Date(ts);
|
|
var s=Math.floor((Date.now()-t)/1000);
|
|
if(s<60)return s+"s";
|
|
if(s<3600)return Math.floor(s/60)+"min";
|
|
if(s<86400)return Math.floor(s/3600)+"h";
|
|
return Math.floor(s/86400)+"j";
|
|
}catch(e){return ts||""}
|
|
}
|
|
|
|
// ========== INIT + LIVE REFRESH ==========
|
|
loadAgents();
|
|
loadHealth();
|
|
loadTraining();
|
|
loadInfra();
|
|
loadLiveFeed();
|
|
|
|
// Rafraichissement toutes les 30s (feed live + infra)
|
|
setInterval(function(){ loadLiveFeed(); loadInfra(); }, 30000);
|
|
setInterval(function(){ loadHealth(); loadTraining(); }, 90000);
|
|
|
|
// Focus sur recherche avec /
|
|
document.addEventListener("keydown",function(e){
|
|
if(e.key==="/"&&document.activeElement.tagName!=="INPUT"){ e.preventDefault(); document.getElementById("q").focus(); }
|
|
if(e.key==="Escape"&&document.getElementById("chat-modal").classList.contains("on")){ closeModal(); }
|
|
});
|
|
|
|
// ============ DOCTRINE 143 LIVE SSE STREAMING v1 (additif) ============
|
|
var __SSE_ES = null;
|
|
var __SSE_CONN = false;
|
|
var __SSE_EVENTS = [];
|
|
|
|
function connectSSELive(){
|
|
if(__SSE_ES && __SSE_CONN)return;
|
|
try{
|
|
__SSE_ES = new EventSource("/api/cloudbot-social-feed.php");
|
|
|
|
__SSE_ES.addEventListener("hello", function(e){
|
|
__SSE_CONN = true;
|
|
try{
|
|
var d = JSON.parse(e.data);
|
|
console.log("[SSE Cloudbot] Connected", d);
|
|
var badge = document.getElementById("sse-live-badge");
|
|
if(badge){ badge.textContent = "LIVE"; badge.style.background = "#10b981"; badge.style.animation = "pulse 1.5s infinite"; }
|
|
}catch(ex){}
|
|
});
|
|
|
|
__SSE_ES.addEventListener("router_match", function(e){
|
|
try{
|
|
var d = JSON.parse(e.data);
|
|
pushSSEEvent({type:"router", msg:d.msg, ts:d.ts, pattern:d.pattern, agent:d.agent||"Router"});
|
|
}catch(ex){}
|
|
});
|
|
|
|
__SSE_ES.addEventListener("agent_msg", function(e){
|
|
try{
|
|
var d = JSON.parse(e.data);
|
|
pushSSEEvent({type:"conversation", role:d.role, msg:d.content, ts:d.ts, session:d.session, source:d.source, agent:d.agent});
|
|
}catch(ex){}
|
|
});
|
|
|
|
__SSE_ES.addEventListener("ecosystem_health", function(e){
|
|
try{
|
|
var d = JSON.parse(e.data);
|
|
var h = document.getElementById("sse-health-pulse");
|
|
if(h){ h.textContent = (d.agents_up||"-") + "/" + (d.agents_total||"-") + " agents"; h.style.animation = "flash 0.5s"; setTimeout(function(){h.style.animation=""},500);}
|
|
}catch(ex){}
|
|
});
|
|
|
|
__SSE_ES.addEventListener("ping", function(e){ /* keep alive */ });
|
|
|
|
__SSE_ES.addEventListener("bye", function(e){
|
|
__SSE_CONN = false;
|
|
if(__SSE_ES){ __SSE_ES.close(); __SSE_ES = null; }
|
|
setTimeout(connectSSELive, 2000); // auto reconnect
|
|
});
|
|
|
|
__SSE_ES.onerror = function(){
|
|
__SSE_CONN = false;
|
|
var badge = document.getElementById("sse-live-badge");
|
|
if(badge){ badge.textContent = "RECONNECT..."; badge.style.background = "#f59e0b"; }
|
|
setTimeout(function(){
|
|
if(__SSE_ES){ __SSE_ES.close(); __SSE_ES = null; }
|
|
connectSSELive();
|
|
}, 3000);
|
|
};
|
|
}catch(e){ console.warn("SSE init failed:", e); }
|
|
}
|
|
|
|
function pushSSEEvent(ev){
|
|
__SSE_EVENTS.unshift(ev);
|
|
if(__SSE_EVENTS.length > 50) __SSE_EVENTS = __SSE_EVENTS.slice(0, 50);
|
|
renderSSEFeed();
|
|
}
|
|
|
|
function renderSSEFeed(){
|
|
var feed = document.getElementById("live-feed");
|
|
if(!feed)return;
|
|
if(!__SSE_EVENTS.length){ return; }
|
|
var html = __SSE_EVENTS.slice(0, 12).map(function(ev){
|
|
var ago = timeAgo(ev.ts);
|
|
var icon = ev.type === "conversation" ? (ev.role === "user" ? "👤" : "🤖") : (ev.type === "router" ? "🎯" : "⚡");
|
|
var color = ev.type === "conversation" ? "#06d6ba" : (ev.type === "router" ? "#8b5cf6" : "#3b82f6");
|
|
var label = ev.agent || (ev.role === "user" ? "User" : "WEVIA");
|
|
var msg = (ev.msg||"").substring(0, 120);
|
|
var meta = ev.session ? "session " + ev.session : (ev.source ? "src:"+ev.source : (ev.pattern||"live"));
|
|
return '<div class="live-item" style="border-left-color:'+color+'">'+
|
|
'<div class="live-item-head">'+
|
|
'<div class="live-item-msg">'+icon+' <strong style="color:'+color+'">'+escapeHtml(label)+':</strong> '+escapeHtml(msg)+'</div>'+
|
|
'</div>'+
|
|
'<div class="live-item-meta">🕐 '+ago+' · <span style="font-family:monospace;opacity:.7">'+escapeHtml(meta)+'</span></div>'+
|
|
'</div>';
|
|
}).join("");
|
|
feed.innerHTML = html;
|
|
}
|
|
|
|
// Start SSE on page load
|
|
setTimeout(connectSSELive, 1000);
|
|
// ============ END SSE additif ============
|
|
|
|
|
|
function startCollab(){
|
|
// DOCTRINE 143 - Real inter-agent conversation via /api/cloudbot-interagent.php
|
|
var n1 = prompt("Nom agent 1 (ex: WEVIA, Ethica, WEVCODE, Blade, WEDROID, Manager, WEVAL MIND) :");
|
|
if(!n1) return;
|
|
var n2 = prompt("Nom agent 2 (different du premier) :");
|
|
if(!n2) return;
|
|
var topic = prompt("Topic de collaboration (question/sujet a discuter) :");
|
|
if(!topic) return;
|
|
var turns = prompt("Nombre de tours (2-4 recommande, max 6) :", "3");
|
|
turns = Math.min(6, Math.max(1, parseInt(turns)||3));
|
|
openInterAgentModal(n1, n2, topic, turns);
|
|
}
|
|
|
|
function openInterAgentModal(agent1, agent2, topic, turns){
|
|
var modal = document.getElementById("chat-modal");
|
|
document.getElementById("m-title").textContent = "🤝 "+agent1+" ↔ "+agent2;
|
|
document.getElementById("m-avatar").textContent = "🤝";
|
|
document.getElementById("m-avatar").style.background = "linear-gradient(135deg,#ec4899,#8b5cf6,#06d6ba)";
|
|
var chat = document.getElementById("m-chat");
|
|
chat.innerHTML = '<div class="msg sys">🤝 <strong>Conversation inter-agents en cours</strong> · '+agent1+' ↔ '+agent2+' · Topic: '+escapeHtml(topic)+' · '+turns+' tours</div>';
|
|
chat.innerHTML += '<div class="msg sys">⏳ Initialisation... (peut prendre 30-60 sec selon les APIs agents)</div>';
|
|
modal.classList.add("on");
|
|
document.getElementById("m-input").placeholder = "Conversation auto - attendez les reponses...";
|
|
document.getElementById("m-input").disabled = true;
|
|
document.getElementById("m-send").disabled = true;
|
|
|
|
fetch("/api/cloudbot-interagent.php", {
|
|
method: "POST",
|
|
headers: {"Content-Type": "application/json"},
|
|
body: JSON.stringify({agent1: agent1, agent2: agent2, topic: topic, turns: turns})
|
|
}).then(function(r){ return r.json(); }).then(function(data){
|
|
chat.innerHTML = '<div class="msg sys">🤝 <strong>'+agent1+' ↔ '+agent2+'</strong> · Topic: '+escapeHtml(topic)+' · '+(data.turns_completed||0)+' tours</div>';
|
|
if(!data.dialogue || !data.dialogue.length){
|
|
chat.innerHTML += '<div class="msg sys" style="color:#ef4444">⚠️ Aucun dialogue (agent non trouve ou erreur API)</div>';
|
|
if(data.error) chat.innerHTML += '<div class="msg sys">ERR: '+escapeHtml(data.error)+'</div>';
|
|
document.getElementById("m-input").disabled = false;
|
|
document.getElementById("m-send").disabled = false;
|
|
return;
|
|
}
|
|
data.dialogue.forEach(function(t){
|
|
// Question de from -> to
|
|
chat.innerHTML += '<div class="msg u" style="max-width:85%"><div style="font-size:11px;font-weight:700;opacity:.9;margin-bottom:4px">🎯 '+escapeHtml(t.from)+' → '+escapeHtml(t.to)+' (tour '+t.turn+')</div>'+escapeHtml(t.message)+'</div>';
|
|
// Reponse
|
|
chat.innerHTML += '<div class="msg a"><div style="font-size:11px;font-weight:700;color:#06d6ba;margin-bottom:4px">🤖 '+escapeHtml(t.to)+' repond :</div>'+escapeHtml(t.response)+'<div class="msg-meta">via '+escapeHtml(t.provider)+' · '+t.latency_ms+'ms</div></div>';
|
|
});
|
|
chat.innerHTML += '<div class="msg sys">✅ Conversation terminee · '+(data.logged_to_db?"📝 loggee en PG (visible dans SSE feed)":"")+' · Session: '+(data.session_id||"").substring(0,30)+'</div>';
|
|
chat.scrollTop = chat.scrollHeight;
|
|
document.getElementById("m-input").disabled = false;
|
|
document.getElementById("m-send").disabled = false;
|
|
addActivity("🤝 Inter-Agent: "+agent1+" ↔ "+agent2+" sur "+topic.substring(0,30));
|
|
CONV_COUNT += data.dialogue.length;
|
|
var kc = document.getElementById("k-conv");
|
|
if(kc) kc.textContent = CONV_COUNT;
|
|
}).catch(function(e){
|
|
chat.innerHTML += '<div class="msg sys" style="color:#ef4444">⚠️ '+escapeHtml(e.message)+'</div>';
|
|
document.getElementById("m-input").disabled = false;
|
|
document.getElementById("m-send").disabled = false;
|
|
});
|
|
}
|
|
|
|
// === PAPERCLIP BRIDGE (real execution) ===
|
|
async function sendToPaperclip(){
|
|
var action = prompt("Action concrete pour Paperclip (ex: analyser logs nginx):");
|
|
if(!action) return;
|
|
var prmpt = prompt("Prompt detaille (instructions techniques):");
|
|
if(!prmpt) return;
|
|
try{
|
|
var r = await fetch("/api/paperclip-bridge.php", {
|
|
method:"POST",
|
|
headers:{"Content-Type":"application/json"},
|
|
body: JSON.stringify({source:"cloudbot-social",action:action,prompt:prmpt,agents_discussed: CURRENT_AGENT ? [CURRENT_AGENT.name] : ["Cloudbot Social"]})
|
|
});
|
|
var d = await r.json();
|
|
if(d.ok){
|
|
addActivity("Paperclip queued: " + action);
|
|
alert("OK! Action envoyee a Paperclip.\nID: " + d.id + "\nStatus: " + d.status);
|
|
} else alert("Erreur: " + (d.error || "fail"));
|
|
} catch(e){ alert("Erreur: " + e.message); }
|
|
}
|
|
|
|
async function viewPaperclipQueue(){
|
|
try{
|
|
var r = await fetch("/api/paperclip-bridge.php?action=list&limit=20");
|
|
var d = await r.json();
|
|
if(!d.ok || !d.actions || !d.actions.length){
|
|
alert("Queue Paperclip vide. Declenchez une action d abord.");
|
|
return;
|
|
}
|
|
var msg = "Queue Paperclip (" + d.count + " actions)\n\n";
|
|
d.actions.forEach(function(a){
|
|
msg += "[" + a.status + "] " + (a.reason||"").substring(0, 70) + "\n";
|
|
});
|
|
alert(msg);
|
|
} catch(e){ alert("Erreur: " + e.message); }
|
|
}
|
|
|
|
function sendChatToPaperclip(){
|
|
if(!CURRENT_AGENT) return;
|
|
var chat = document.getElementById("m-chat");
|
|
var msgs = Array.from(chat.querySelectorAll(".msg")).map(function(m){
|
|
return (m.classList.contains("u") ? "[USER] " : "[AGENT] ") + m.textContent.substring(0, 400);
|
|
}).join("\n\n");
|
|
if(!msgs){ alert("Aucune conversation."); return; }
|
|
var action = prompt("Action a executer par Paperclip:");
|
|
if(!action) return;
|
|
fetch("/api/paperclip-bridge.php", {
|
|
method:"POST",
|
|
headers:{"Content-Type":"application/json"},
|
|
body: JSON.stringify({source:"cloudbot-social",action:action,prompt:"Context chat avec " + CURRENT_AGENT.name + ":\n" + msgs + "\n\nAction: " + action,agents_discussed:[CURRENT_AGENT.name]})
|
|
}).then(function(r){return r.json()}).then(function(d){
|
|
if(d.ok){ addActivity("Chat->Paperclip: " + action.substring(0,40)); alert("Envoye! ID: " + d.id); }
|
|
else alert("Fail: " + (d.error||"?"));
|
|
});
|
|
}
|
|
|
|
</script>
|
|
|
|
<!-- DOCTRINE-60-UX-JS --><script id="doctrine60-ux-js-direct">
|
|
|
|
// DOCTRINE-60-UX-JS staggered entrance
|
|
(function(){
|
|
if (!('IntersectionObserver' in window)) return;
|
|
const obs = new IntersectionObserver((entries) => {
|
|
entries.forEach((e, i) => {
|
|
if (e.isIntersecting) {
|
|
setTimeout(() => e.target.classList.add('enter-stagger'), i * 80);
|
|
obs.unobserve(e.target);
|
|
}
|
|
});
|
|
});
|
|
document.querySelectorAll('.card, .kpi, .panel').forEach(el => obs.observe(el));
|
|
})();
|
|
|
|
</script>
|
|
</body>
|
|
<!-- WEVIA-COND-TEST-v1 -->
|
|
<!-- WEVIA CONDITIONAL TEST (doctrine 155) -->
|
|
<!-- /WEVIA-COND-TEST-v1 -->
|
|
|
|
<!-- WEVIA-ROLLBACK-LINK-P2-v1 -->
|
|
<!-- WEVIA rollback link floater -->
|
|
<!-- /WEVIA-ROLLBACK-LINK-P2-v1 -->
|
|
|
|
<!-- WEVIA-AUDIT-LINK-MULTI-v1 -->
|
|
<a href="/wevia-audit.html" style="position:fixed;bottom:16px;right:16px;padding:10px 16px;background:linear-gradient(135deg,#10b981,#047857);color:#fff;border-radius:8px;font-weight:700;font-size:13px;text-decoration:none;z-index:9999;box-shadow:0 4px 12px rgba(16,185,129,0.4)">Audit Trail</a>
|
|
<!-- /WEVIA-AUDIT-LINK-MULTI-v1 -->
|
|
|
|
</html>
|