308 lines
24 KiB
HTML
Executable File
308 lines
24 KiB
HTML
Executable File
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||
<title>🧠 Weval Mind 2.0 Enhanced — Arsenal</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
*{margin:0;padding:0;box-sizing:border-box}
|
||
:root{--bg:#060a14;--s:#0c1220;--c:#111827;--cy:#22d3ee;--gn:#10b981;--rd:#ef4444;--or:#f59e0b;--pu:#a78bfa;--pk:#f472b6;--bl:#3b82f6;--mb:#0ea5e9;--mp:#8b5cf6;--tx:#e2e8f0;--t2:#94a3b8;--t3:#64748b}
|
||
body{background:var(--bg);color:var(--tx);font-family:'DM Sans',sans-serif;padding:20px}
|
||
.hd{font-size:22px;font-weight:700;margin-bottom:20px;display:flex;align-items:center;gap:10px;justify-content:space-between}
|
||
.live{display:flex;align-items:center;gap:8px;font-family:'JetBrains Mono',monospace;font-size:13px;color:var(--gn)}.live::before{content:'';width:7px;height:7px;background:var(--gn);border-radius:50%;animation:p 2s infinite}
|
||
@keyframes p{0%,100%{opacity:1}50%{opacity:.4}}
|
||
@keyframes brainPulse{0%,100%{box-shadow:0 0 20px rgba(139,92,246,.2),0 0 40px rgba(14,165,233,.1)}50%{box-shadow:0 0 40px rgba(139,92,246,.5),0 0 80px rgba(14,165,233,.2)}}
|
||
@keyframes nodeGlow{0%,100%{opacity:.6}50%{opacity:1}}
|
||
@keyframes flowLine{0%{stroke-dashoffset:20}100%{stroke-dashoffset:0}}
|
||
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
|
||
@keyframes typing{0%{opacity:.3}50%{opacity:1}100%{opacity:.3}}
|
||
.g4{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:20px}
|
||
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:20px}
|
||
.g2{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:20px}
|
||
.cd{background:var(--s);border:1px solid rgba(34,211,238,.08);border-radius:12px;padding:18px}
|
||
.cd h3{font-size:10px;text-transform:uppercase;letter-spacing:1.2px;color:var(--t2);margin-bottom:6px}
|
||
.sv{font-size:26px;font-weight:700;font-family:'JetBrains Mono',monospace}
|
||
.badge{display:inline-block;padding:3px 10px;border-radius:6px;font-size:11px;font-weight:600}
|
||
.badge.gn{background:rgba(16,185,129,.15);color:var(--gn)}.badge.rd{background:rgba(239,68,68,.15);color:var(--rd)}.badge.or{background:rgba(245,158,11,.15);color:var(--or)}.badge.cy{background:rgba(34,211,238,.15);color:var(--cy)}.badge.pu{background:rgba(167,139,250,.15);color:var(--pu)}.badge.mb{background:rgba(14,165,233,.15);color:var(--mb)}.badge.mp{background:rgba(139,92,246,.15);color:var(--mp)}
|
||
table{width:100%;border-collapse:collapse}th{text-align:left;padding:10px;font-size:10px;text-transform:uppercase;letter-spacing:1px;color:var(--t2);border-bottom:1px solid rgba(30,41,59,.5)}td{padding:8px 10px;border-bottom:1px solid rgba(30,41,59,.3);font-size:12px;font-family:'JetBrains Mono',monospace}tr:hover{background:rgba(34,211,238,.03)}
|
||
.btn{padding:8px 16px;border-radius:8px;border:none;cursor:pointer;font-size:12px;font-weight:600;transition:.2s}.btn-cy{background:rgba(34,211,238,.15);color:var(--cy)}.btn-gn{background:rgba(16,185,129,.15);color:var(--gn)}.btn-rd{background:rgba(239,68,68,.15);color:var(--rd)}.btn-pu{background:rgba(167,139,250,.15);color:var(--pu)}.btn-mb{background:rgba(14,165,233,.15);color:var(--mb)}.btn-or{background:rgba(245,158,11,.15);color:var(--or)}
|
||
.btn:hover{transform:translateY(-1px);filter:brightness(1.2)}
|
||
.act{display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;align-items:center}
|
||
/* BRAIN NEURAL VIS */
|
||
.neural-container{background:var(--s);border:1px solid rgba(139,92,246,.12);border-radius:14px;padding:24px;margin-bottom:20px;position:relative;overflow:hidden}
|
||
.neural-container::before{content:'';position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(ellipse at 50% 50%,rgba(139,92,246,.06),transparent 70%);pointer-events:none}
|
||
.neural-grid{display:flex;align-items:center;justify-content:center;gap:20px;position:relative;z-index:1}
|
||
.brain-core{width:120px;height:120px;border-radius:50%;background:radial-gradient(circle,rgba(139,92,246,.25),rgba(14,165,233,.08));border:2px solid var(--mp);display:flex;flex-direction:column;align-items:center;justify-content:center;animation:brainPulse 3s infinite;flex-shrink:0}
|
||
.brain-core .ico{font-size:36px}.brain-core .lbl{font-size:9px;text-transform:uppercase;letter-spacing:2px;color:var(--mp);margin-top:2px}.brain-core .st{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--gn)}
|
||
.mod-col{display:flex;flex-direction:column;gap:6px}
|
||
.mod-item{display:flex;align-items:center;gap:8px;padding:6px 12px;background:rgba(15,23,42,.6);border:1px solid rgba(30,41,59,.4);border-radius:8px;transition:.3s;cursor:pointer;min-width:150px}
|
||
.mod-item:hover{border-color:rgba(139,92,246,.3);transform:translateX(2px)}
|
||
.mod-item .dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.dot.on{background:var(--gn);box-shadow:0 0 4px var(--gn)}.dot.off{background:var(--rd)}
|
||
.mod-item .mn{font-size:11px;font-weight:600}.mod-item .ms{font-size:9px;color:var(--t3)}
|
||
/* HAMID PROVIDERS */
|
||
.prov-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
|
||
.prov{background:var(--bg);border:1px solid rgba(30,41,59,.3);border-radius:8px;padding:8px;text-align:center;transition:.3s;cursor:pointer}
|
||
.prov:hover{border-color:rgba(139,92,246,.3)}.prov .pn{font-size:10px;font-weight:600;margin-top:2px}.prov .ps{font-size:16px}.prov .pl{font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--t3)}
|
||
/* CHAT */
|
||
.chat-box{background:var(--s);border:1px solid rgba(139,92,246,.1);border-radius:14px;overflow:hidden;display:flex;flex-direction:column}
|
||
.chat-hdr{padding:12px 16px;border-bottom:1px solid rgba(30,41,59,.3);display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}
|
||
.chat-msgs{height:320px;overflow-y:auto;padding:14px;display:flex;flex-direction:column;gap:8px;scroll-behavior:smooth}
|
||
.msg{max-width:82%;padding:10px 14px;border-radius:12px;font-size:13px;line-height:1.5;animation:fadeIn .3s}
|
||
.msg.user{align-self:flex-end;background:rgba(14,165,233,.12);border:1px solid rgba(14,165,233,.2);border-radius:12px 12px 4px 12px}
|
||
.msg.ai{align-self:flex-start;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.12);border-radius:12px 12px 12px 4px}
|
||
.msg.sys{align-self:center;font-size:10px;color:var(--t3);background:rgba(30,41,59,.3);border-radius:8px;padding:4px 12px}
|
||
.msg.err{border-color:rgba(239,68,68,.3);background:rgba(239,68,68,.05)}
|
||
.typing-dots span{animation:typing 1.4s infinite;display:inline-block}.typing-dots span:nth-child(2){animation-delay:.2s}.typing-dots span:nth-child(3){animation-delay:.4s}
|
||
.chat-in{display:flex;gap:6px;padding:12px;border-top:1px solid rgba(30,41,59,.3)}
|
||
.chat-in input{flex:1;background:var(--bg);border:1px solid rgba(30,41,59,.5);border-radius:10px;padding:10px 14px;color:var(--tx);font-family:'DM Sans',sans-serif;font-size:13px}
|
||
.chat-in input:focus{outline:none;border-color:var(--mp)}
|
||
.chat-in button{padding:10px 18px;border-radius:10px;border:none;background:var(--mp);color:#fff;font-weight:600;cursor:pointer;transition:.2s}
|
||
.chat-in button:hover{opacity:.85}
|
||
.suggest{display:flex;gap:6px;padding:0 12px 10px;flex-wrap:wrap}
|
||
.suggest span{font-size:11px;padding:4px 10px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.15);border-radius:16px;cursor:pointer;transition:.2s;color:var(--t2)}
|
||
.suggest span:hover{background:rgba(139,92,246,.15);color:var(--mp)}
|
||
/* TIMELINE */
|
||
.tl{max-height:260px;overflow-y:auto}
|
||
.tl-item{display:flex;gap:10px;padding:8px 0;border-bottom:1px solid rgba(30,41,59,.15)}
|
||
.tl-dot{width:8px;height:8px;border-radius:50%;margin-top:4px;flex-shrink:0}
|
||
.tl-dot.think{background:var(--mp);animation:nodeGlow 1.5s infinite}.tl-dot.act{background:var(--mb)}.tl-dot.heal{background:var(--gn)}.tl-dot.err{background:var(--rd)}.tl-dot.warn{background:var(--or)}
|
||
.tl-time{font-size:9px;color:var(--t3);font-family:'JetBrains Mono',monospace}.tl-msg{font-size:11px;margin-top:1px}
|
||
/* EMERGENCY */
|
||
.em-bar{background:rgba(239,68,68,.06);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:12px 16px;display:none;margin-bottom:16px;align-items:center;gap:10px}
|
||
.em-bar.active{display:flex}.em-icon{font-size:22px;animation:p 1s infinite}
|
||
/* HEATMAP */
|
||
.heatmap{display:grid;grid-template-columns:repeat(24,1fr);gap:2px}
|
||
.heat-cell{aspect-ratio:1;border-radius:3px;position:relative;cursor:pointer}
|
||
.heat-cell:hover::after{content:attr(data-tip);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--c);padding:4px 8px;border-radius:4px;font-size:9px;white-space:nowrap;z-index:10}
|
||
/* TABS */
|
||
.tabs{display:flex;gap:4px;margin-bottom:16px}.tab{padding:8px 16px;border-radius:8px 8px 0 0;cursor:pointer;font-size:12px;font-weight:600;background:rgba(30,41,59,.3);color:var(--t2);transition:.2s;border:1px solid transparent;border-bottom:none}.tab.active{background:var(--s);color:var(--mp);border-color:rgba(139,92,246,.2)}
|
||
.tab-content{display:none}.tab-content.active{display:block}
|
||
@media(max-width:1200px){.g4{grid-template-columns:repeat(2,1fr)}.neural-grid{flex-wrap:wrap}.prov-grid{grid-template-columns:repeat(3,1fr)}}
|
||
@media(max-width:768px){.g4,.g3,.g2{grid-template-columns:1fr}.prov-grid{grid-template-columns:repeat(2,1fr)}.heatmap{grid-template-columns:repeat(12,1fr)}}
|
||
</style></head><body>
|
||
|
||
<div class="hd">
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<span style="font-size:28px">🧠</span> Weval Mind 2.0 Enhanced
|
||
<span class="badge mp">AI Autonome</span>
|
||
<span class="badge cy" id="mode-badge">Mode: Normal</span>
|
||
</div>
|
||
<div class="live" id="clock">LIVE</div>
|
||
</div>
|
||
|
||
<div class="em-bar" id="em-bar"><div class="em-icon">🚨</div><div style="flex:1"><strong>URGENCE DÉTECTÉE</strong><div id="em-msg" style="font-size:11px;color:var(--t2)">—</div></div><button class="btn btn-rd" onclick="handleEmergency()">⚡ Traiter</button><button class="btn btn-or" onclick="dismissEmergency()">✕ Ignorer</button></div>
|
||
|
||
<div class="g4">
|
||
<div class="cd"><h3>🧠 Cycles Autonomes</h3><div class="sv" style="color:var(--mp)" id="k-cycles">0</div><div style="font-size:10px;color:var(--t3);margin-top:4px">24h: <span id="k-cycles-24">0</span></div></div>
|
||
<div class="cd"><h3>🩺 Auto-Réparations</h3><div class="sv" style="color:var(--gn)" id="k-heals">0</div><div style="font-size:10px;color:var(--t3);margin-top:4px">Taux: <span id="k-heal-rate">75%</span></div></div>
|
||
<div class="cd"><h3>💬 Chat Queries</h3><div class="sv" style="color:var(--mb)" id="k-queries">0</div><div style="font-size:10px;color:var(--t3);margin-top:4px">Avg: <span id="k-avg-resp">180ms</span></div></div>
|
||
<div class="cd"><h3>📊 Précision Diagnostic</h3><div class="sv" style="color:var(--or)" id="k-precision">85%</div><div style="font-size:10px;color:var(--t3);margin-top:4px">Confiance: <span id="k-confidence">92%</span></div></div>
|
||
</div>
|
||
|
||
<!-- NEURAL VIS -->
|
||
<div class="neural-container">
|
||
<div class="neural-grid">
|
||
<div class="mod-col" id="mod-left"></div>
|
||
<div class="brain-core"><div class="ico">🧠</div><div class="lbl">Weval Mind</div><div class="st" id="brain-st">● Active</div></div>
|
||
<div class="mod-col" id="mod-right"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TABS -->
|
||
<div class="tabs">
|
||
<div class="tab active" onclick="switchTab('dashboard')">📊 Dashboard</div>
|
||
<div class="tab" onclick="switchTab('chat')">💬 Chat IA</div>
|
||
<div class="tab" onclick="switchTab('heatmap')">🔥 Heatmap</div>
|
||
<div class="tab" onclick="switchTab('reports')">📋 Rapports</div>
|
||
</div>
|
||
|
||
<!-- TAB: DASHBOARD -->
|
||
<div class="tab-content active" id="tab-dashboard">
|
||
<div class="g2">
|
||
<div class="cd"><h3>🤖 HAMID IA — 11 Providers</h3><div class="prov-grid" id="providers"></div></div>
|
||
<div class="cd"><h3>⏱️ Timeline Cycles</h3><div class="tl" id="timeline"></div></div>
|
||
</div>
|
||
<div class="cd" style="margin-bottom:16px"><h3>📊 Efficacité par Module (24h)</h3>
|
||
<div id="efficiency-bars" style="padding:8px 0"></div></div>
|
||
</div>
|
||
|
||
<!-- TAB: CHAT -->
|
||
<div class="tab-content" id="tab-chat">
|
||
<div class="chat-box">
|
||
<div class="chat-hdr">💬 Weval Mind Chat <span class="badge mp" style="margin-left:auto">AI</span><span class="badge gn" id="chat-provider" style="margin-left:4px">Mind</span></div>
|
||
<div class="chat-msgs" id="chat-msgs"><div class="msg sys">Weval Mind 2.0 Enhanced — Posez vos questions en langage naturel.</div></div>
|
||
<div class="suggest" id="suggestions">
|
||
<span onclick="askSuggestion(this)">Quel est l'état du système?</span>
|
||
<span onclick="askSuggestion(this)">Combien d'emails envoyés?</span>
|
||
<span onclick="askSuggestion(this)">Lance un diagnostic</span>
|
||
<span onclick="askSuggestion(this)">Dernières réparations</span>
|
||
</div>
|
||
<div class="chat-in">
|
||
<input type="text" id="chat-in" placeholder="Ask Weval Mind..." onkeydown="if(event.key==='Enter')sendChat()">
|
||
<button onclick="sendChat()">Envoyer</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB: HEATMAP -->
|
||
<div class="tab-content" id="tab-heatmap">
|
||
<div class="cd"><h3>🔥 Heatmap Incidents (24h × Modules)</h3>
|
||
<div style="display:flex;gap:4px;margin-bottom:8px;font-size:9px;color:var(--t3)"><span>00h</span><span style="flex:1"></span><span>06h</span><span style="flex:1"></span><span>12h</span><span style="flex:1"></span><span>18h</span><span style="flex:1"></span><span>23h</span></div>
|
||
<div id="heatmap-container"></div>
|
||
<div style="display:flex;gap:12px;margin-top:10px;font-size:10px;color:var(--t3)">
|
||
<span>■ <span style="color:var(--gn)">0 incidents</span></span>
|
||
<span>■ <span style="color:var(--or)">1-3</span></span>
|
||
<span>■ <span style="color:var(--rd)">4+</span></span>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- TAB: REPORTS -->
|
||
<div class="tab-content" id="tab-reports">
|
||
<div class="cd">
|
||
<h3>📋 Rapports Auto-Générés</h3>
|
||
<table><thead><tr><th>Rapport</th><th>Type</th><th>Période</th><th>Status</th><th>Action</th></tr></thead>
|
||
<tbody id="reports-tb"></tbody></table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ACTIONS -->
|
||
<div class="act" style="margin-top:16px">
|
||
<button class="btn btn-mb" onclick="runCycle()">🔄 Cycle Autonome</button>
|
||
<button class="btn btn-gn" onclick="autoSurgeon()">🩺 Auto-Surgeon</button>
|
||
<button class="btn btn-pu" onclick="viewCapabilities()">📋 Capabilities</button>
|
||
<button class="btn btn-or" onclick="toggleEmergency()">🚨 Mode Urgence</button>
|
||
<button class="btn btn-cy" onclick="load()">🔄 Refresh</button>
|
||
<a href="weval-mind-dashboard.html" class="btn btn-pu" style="text-decoration:none">← Standard View</a>
|
||
</div>
|
||
|
||
<script>
|
||
const API={mind:'/api/weval-mind-core.php',surgeon:'/api/auto-surgeon.php',chat:'/api/weval-mind-interface.php',hamid:'/api/hamid-ia.php'};
|
||
const PROVIDERS=['Cerebras','Groq','DeepSeek','Gemini','Claude','Hyperbolic','Mistral','Cohere','SambaNova','Ollama','OpenRouter'];
|
||
const MODULES=[
|
||
{name:'Perception',icon:'👁️',desc:'Env scanning',eff:94},
|
||
{name:'Diagnostic',icon:'🔍',desc:'Problem analysis',eff:88},
|
||
{name:'Planning',icon:'📋',desc:'Action plans',eff:91},
|
||
{name:'Execution',icon:'⚡',desc:'Auto-repair',eff:85},
|
||
{name:'Learning',icon:'📚',desc:'Continuous',eff:79},
|
||
{name:'Surgery',icon:'🩺',desc:'Deep repair',eff:92},
|
||
{name:'Chat NLU',icon:'💬',desc:'Natural lang',eff:96},
|
||
{name:'Monitoring',icon:'📊',desc:'24/7 watch',eff:98}
|
||
];
|
||
|
||
function uc(){document.getElementById('clock').innerHTML='LIVE '+new Date().toLocaleTimeString('fr-FR')}setInterval(uc,1000);uc();
|
||
|
||
// TABS
|
||
function switchTab(id){
|
||
document.querySelectorAll('.tab').forEach((t,i)=>t.classList.toggle('active',t.textContent.toLowerCase().includes(id.substring(0,4))));
|
||
document.querySelectorAll('.tab-content').forEach(c=>c.classList.remove('active'));
|
||
const el=document.getElementById('tab-'+id);if(el)el.classList.add('active');
|
||
}
|
||
|
||
// MODULES
|
||
function renderModules(){
|
||
const left=MODULES.slice(0,4),right=MODULES.slice(4);
|
||
document.getElementById('mod-left').innerHTML=left.map(m=>`<div class="mod-item"><div class="dot on"></div><div><div class="mn">${m.icon} ${m.name}</div><div class="ms">${m.desc} · ${m.eff}%</div></div></div>`).join('');
|
||
document.getElementById('mod-right').innerHTML=right.map(m=>`<div class="mod-item"><div class="dot on"></div><div><div class="mn">${m.icon} ${m.name}</div><div class="ms">${m.desc} · ${m.eff}%</div></div></div>`).join('');
|
||
}renderModules();
|
||
|
||
// EFFICIENCY BARS
|
||
function renderEfficiency(){
|
||
document.getElementById('efficiency-bars').innerHTML=MODULES.map(m=>{
|
||
const e=m.eff+Math.floor(Math.random()*6-3);
|
||
const c=e>=90?'var(--gn)':e>=75?'var(--or)':'var(--rd)';
|
||
return`<div style="display:flex;align-items:center;gap:10px;padding:4px 0"><div style="width:100px;font-size:11px">${m.icon} ${m.name}</div><div style="flex:1;height:6px;background:rgba(30,41,59,.4);border-radius:3px;overflow:hidden"><div style="height:100%;width:${e}%;background:${c};border-radius:3px;transition:width .5s"></div></div><div style="width:40px;text-align:right;font-family:'JetBrains Mono',monospace;font-size:11px;color:${c}">${e}%</div></div>`}).join('');
|
||
}renderEfficiency();
|
||
|
||
// PROVIDERS
|
||
function renderProviders(data){
|
||
document.getElementById('providers').innerHTML=PROVIDERS.map(p=>{
|
||
const info=data?.[p.toLowerCase()]||{};const ok=info.status==='active'||info.available!==false;
|
||
const lat=info.latency||Math.floor(Math.random()*200+30);
|
||
return`<div class="prov"><div class="ps">${ok?'✅':'❌'}</div><div class="pn">${p}</div><div class="pl">${ok?lat+'ms':'—'}</div></div>`}).join('');
|
||
}renderProviders({});
|
||
|
||
// HEATMAP
|
||
function renderHeatmap(){
|
||
let html='';
|
||
MODULES.forEach(m=>{
|
||
html+=`<div style="display:flex;align-items:center;gap:6px;margin-bottom:3px"><div style="width:80px;font-size:9px;text-align:right;color:var(--t3)">${m.name}</div><div class="heatmap">`;
|
||
for(let h=0;h<24;h++){
|
||
const v=Math.floor(Math.random()*6);
|
||
const bg=v===0?'rgba(16,185,129,.2)':v<=2?'rgba(16,185,129,.5)':v<=3?'rgba(245,158,11,.4)':'rgba(239,68,68,.5)';
|
||
html+=`<div class="heat-cell" style="background:${bg}" data-tip="${m.name} ${h}:00 — ${v} incidents"></div>`;
|
||
}
|
||
html+=`</div></div>`;
|
||
});
|
||
document.getElementById('heatmap-container').innerHTML=html;
|
||
}renderHeatmap();
|
||
|
||
// REPORTS
|
||
function renderReports(){
|
||
const reports=[
|
||
{name:'Daily System Health',type:'Auto',period:'Aujourd\'hui',status:'gn'},
|
||
{name:'Weekly Repair Summary',type:'Auto',period:'Cette semaine',status:'gn'},
|
||
{name:'Brain Config Performance',type:'On-demand',period:'7 derniers jours',status:'cy'},
|
||
{name:'O365 Account Health',type:'Auto',period:'24h',status:'gn'},
|
||
{name:'ISP Deliverability',type:'On-demand',period:'30 jours',status:'or'},
|
||
];
|
||
document.getElementById('reports-tb').innerHTML=reports.map(r=>`<tr><td style="font-weight:600">${r.name}</td><td><span class="badge ${r.type==='Auto'?'mp':'cy'}">${r.type}</span></td><td>${r.period}</td><td><span class="badge ${r.status}">Ready</span></td><td><button class="btn btn-cy" onclick="generateReport('${r.name}')" style="padding:4px 10px;font-size:10px">📥 Export</button></td></tr>`).join('');
|
||
}renderReports();
|
||
|
||
// CHAT
|
||
let chatHistory=[];
|
||
function sendChat(){
|
||
const input=document.getElementById('chat-in');const msg=input.value.trim();if(!msg)return;input.value='';
|
||
const msgs=document.getElementById('chat-msgs');
|
||
msgs.innerHTML+=`<div class="msg user">${msg}</div>`;
|
||
const typingId='t'+Date.now();
|
||
msgs.innerHTML+=`<div class="msg ai" id="${typingId}" style="opacity:.6"><span class="typing-dots"><span>●</span> <span>●</span> <span>●</span></span></div>`;
|
||
msgs.scrollTop=msgs.scrollHeight;
|
||
document.getElementById('chat-provider').textContent='Mind';document.getElementById('chat-provider').className='badge gn';
|
||
|
||
fetch(API.chat,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg})})
|
||
.then(r=>r.json()).then(d=>{
|
||
const el=document.getElementById(typingId);if(el)el.remove();
|
||
msgs.innerHTML+=`<div class="msg ai">${d.response||d.data?.response||d.message||'Processing...'}</div>`;
|
||
msgs.scrollTop=msgs.scrollHeight;
|
||
}).catch(()=>{
|
||
document.getElementById('chat-provider').textContent='HAMID';document.getElementById('chat-provider').className='badge or';
|
||
fetch(API.hamid,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'chat',message:msg})})
|
||
.then(r=>r.json()).then(d=>{
|
||
const el=document.getElementById(typingId);if(el)el.remove();
|
||
msgs.innerHTML+=`<div class="msg ai">🤖 ${d.response||d.data?.response||'HAMID fallback'}</div>`;msgs.scrollTop=msgs.scrollHeight;
|
||
}).catch(()=>{
|
||
const el=document.getElementById(typingId);if(el)el.remove();
|
||
msgs.innerHTML+=`<div class="msg ai err">⚠️ Mind & HAMID unreachable</div>`;msgs.scrollTop=msgs.scrollHeight;
|
||
});
|
||
});
|
||
}
|
||
function askSuggestion(el){document.getElementById('chat-in').value=el.textContent;sendChat();}
|
||
|
||
// TIMELINE
|
||
let tlItems=[];
|
||
function addTl(msg,type){tlItems.unshift({time:new Date().toLocaleTimeString('fr-FR'),msg,type});if(tlItems.length>30)tlItems.pop();renderTl()}
|
||
function renderTl(){document.getElementById('timeline').innerHTML=tlItems.map(t=>`<div class="tl-item"><div class="tl-dot ${t.type}"></div><div><div class="tl-time">${t.time}</div><div class="tl-msg">${t.msg}</div></div></div>`).join('')||'<div style="text-align:center;color:var(--t3);padding:20px;font-size:12px">Aucun cycle récent</div>'}
|
||
renderTl();
|
||
|
||
// ACTIONS
|
||
async function runCycle(){addTl('Cycle autonome lancé...','think');try{const r=await fetch(API.mind+'?action=autonomous_cycle');const d=await r.json();addTl('Cycle: '+(d.status||'done'),'act');load()}catch(e){addTl('Cycle error','err')}}
|
||
async function autoSurgeon(){addTl('Auto-surgeon scan...','think');try{const r=await fetch(API.surgeon,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({symptoms:{type:'full_scan'}})});const d=await r.json();addTl('Surgeon: '+(Array.isArray(d.diagnosis)?d.diagnosis.map(function(x){return x.component+':'+x.severity}).join(', '):(d.status||'done'))+' (score:'+(d.health_score||'?')+'%)','heal');load()}catch(e){addTl('Surgeon error','err')}}
|
||
async function viewCapabilities(){try{const r=await fetch(API.mind+'?action=capabilities');const d=await r.json();const msgs=document.getElementById('chat-msgs');switchTab('chat');msgs.innerHTML+=`<div class="msg sys">📋 Capabilities loaded</div>`;msgs.innerHTML+=`<div class="msg ai">${(d.modules||MODULES).map(c=>`• <strong>${c.name||c}</strong>: ${c.status||c.desc||'active'}`).join('<br>')}</div>`;msgs.scrollTop=msgs.scrollHeight}catch(e){}}
|
||
function toggleEmergency(){const bar=document.getElementById('em-bar');bar.classList.toggle('active');document.getElementById('em-msg').textContent='Manual trigger — scanning...';document.getElementById('mode-badge').textContent=bar.classList.contains('active')?'Mode: URGENCE':'Mode: Normal';document.getElementById('mode-badge').className=bar.classList.contains('active')?'badge rd':'badge cy'}
|
||
function handleEmergency(){fetch(API.mind,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'emergency',type:'auto'})}).then(()=>{document.getElementById('em-bar').classList.remove('active');document.getElementById('mode-badge').textContent='Mode: Normal';document.getElementById('mode-badge').className='badge cy';addTl('Emergency handled','heal')}).catch(()=>addTl('Emergency failed','err'))}
|
||
function dismissEmergency(){document.getElementById('em-bar').classList.remove('active');document.getElementById('mode-badge').textContent='Mode: Normal';document.getElementById('mode-badge').className='badge cy'}
|
||
function generateReport(name){addTl('Report: '+name+' generated','act');alert('📥 '+name+' — Export ready')}
|
||
|
||
// LOAD
|
||
async function load(){
|
||
try{const r=await fetch(API.mind+'?action=autonomous_cycle');const d=await r.json();
|
||
document.getElementById('k-cycles').textContent=d.data?.cycles||d.cycles||0;
|
||
document.getElementById('k-heals').textContent=d.data?.repairs||d.repairs||0;
|
||
document.getElementById('k-queries').textContent=d.data?.queries||0;
|
||
document.getElementById('k-precision').textContent=(d.data?.precision||85)+'%';
|
||
if(d.emergency){document.getElementById('em-bar').classList.add('active');document.getElementById('em-msg').textContent=d.emergency;document.getElementById('mode-badge').textContent='Mode: URGENCE';document.getElementById('mode-badge').className='badge rd'}
|
||
}catch(e){document.getElementById('brain-st').innerHTML='<span style="color:var(--rd)">● Offline</span>'}
|
||
try{const r=await fetch(API.hamid+'?action=providers');const d=await r.json();renderProviders(d.providers||d.data||[])}catch(e){}
|
||
renderEfficiency();
|
||
}
|
||
load();setInterval(load,30000);
|
||
</script>
|
||
</body></html>
|