197 lines
16 KiB
HTML
Executable File
197 lines
16 KiB
HTML
Executable File
<!DOCTYPE html><html lang="fr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
<title>Weval Mind 2.0 — 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:24px}
|
|
.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}}
|
|
.g4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:24px}.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:24px}.g2{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin-bottom:24px}
|
|
.cd{background:var(--s);border:1px solid rgba(34,211,238,.08);border-radius:12px;padding:20px}.cd h3{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--t2);margin-bottom:8px}
|
|
.sv{font-size:28px;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:12px;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--t2);border-bottom:1px solid rgba(30,41,59,.5)}td{padding:10px 12px;border-bottom:1px solid rgba(30,41,59,.3);font-size:13px;font-family:'JetBrains Mono',monospace}tr:hover{background:rgba(34,211,238,.03)}
|
|
.btn{padding:8px 18px;border-radius:8px;border:none;cursor:pointer;font-size:13px;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)}
|
|
.act{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap;align-items:center}
|
|
/* MIND BRAIN VIS */
|
|
.brain-vis{display:flex;align-items:center;justify-content:center;gap:40px;padding:24px;margin-bottom:24px}
|
|
.brain-core{width:140px;height:140px;border-radius:50%;background:radial-gradient(circle,rgba(139,92,246,.3),rgba(14,165,233,.1));border:3px solid var(--mp);display:flex;flex-direction:column;align-items:center;justify-content:center;animation:brainPulse 3s infinite;position:relative}
|
|
@keyframes brainPulse{0%,100%{box-shadow:0 0 20px rgba(139,92,246,.2)}50%{box-shadow:0 0 40px rgba(139,92,246,.4)}}
|
|
.brain-core .bc-icon{font-size:40px}.brain-core .bc-label{font-size:10px;text-transform:uppercase;letter-spacing:2px;color:var(--mp);margin-top:4px}.brain-core .bc-status{font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--gn)}
|
|
.brain-modules{display:flex;flex-direction:column;gap:8px}
|
|
.bm{display:flex;align-items:center;gap:10px;padding:8px 14px;background:var(--s);border:1px solid rgba(30,41,59,.3);border-radius:8px;transition:.3s;cursor:pointer}
|
|
.bm:hover{border-color:rgba(139,92,246,.3);transform:translateX(4px)}
|
|
.bm .bm-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.bm .bm-dot.on{background:var(--gn);box-shadow:0 0 6px var(--gn)}.bm .bm-dot.off{background:var(--rd)}
|
|
.bm .bm-name{font-size:12px;font-weight:600}.bm .bm-stat{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--t2)}
|
|
/* CHAT */
|
|
.chat-container{background:var(--s);border:1px solid rgba(139,92,246,.1);border-radius:14px;overflow:hidden}
|
|
.chat-header{padding:14px 20px;border-bottom:1px solid rgba(30,41,59,.3);display:flex;align-items:center;gap:10px;font-weight:600}
|
|
.chat-messages{height:300px;overflow-y:auto;padding:16px 20px;display:flex;flex-direction:column;gap:10px}
|
|
.chat-msg{max-width:80%;padding:10px 14px;border-radius:12px;font-size:13px;line-height:1.5}
|
|
.chat-msg.user{align-self:flex-end;background:rgba(14,165,233,.15);border:1px solid rgba(14,165,233,.2);border-radius:12px 12px 4px 12px}
|
|
.chat-msg.ai{align-self:flex-start;background:rgba(139,92,246,.1);border:1px solid rgba(139,92,246,.15);border-radius:12px 12px 12px 4px}
|
|
.chat-msg.system{align-self:center;font-size:11px;color:var(--t3);background:rgba(30,41,59,.3);border-radius:8px;padding:6px 14px}
|
|
.chat-input{display:flex;gap:8px;padding:14px 20px;border-top:1px solid rgba(30,41,59,.3)}
|
|
.chat-input 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-input input:focus{outline:none;border-color:var(--mp)}
|
|
.chat-input button{padding:10px 20px;border-radius:10px;border:none;background:var(--mp);color:#fff;font-weight:600;cursor:pointer;transition:.2s}
|
|
.chat-input button:hover{opacity:.8}
|
|
/* TIMELINE */
|
|
.tl-item{display:flex;gap:12px;padding:10px 0;border-bottom:1px solid rgba(30,41,59,.2)}
|
|
.tl-dot{width:10px;height:10px;border-radius:50%;margin-top:4px;flex-shrink:0}
|
|
.tl-dot.think{background:var(--mp);animation:p 1.5s infinite}.tl-dot.act{background:var(--mb)}.tl-dot.heal{background:var(--gn)}.tl-dot.err{background:var(--rd)}
|
|
.tl-content{flex:1}.tl-time{font-size:10px;color:var(--t3);font-family:'JetBrains Mono',monospace}.tl-msg{font-size:12px;margin-top:2px}
|
|
/* EMERGENCY */
|
|
.emergency-bar{background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:14px 20px;display:none;margin-bottom:20px;align-items:center;gap:12px}
|
|
.emergency-bar.active{display:flex}
|
|
.emergency-bar .em-icon{font-size:24px;animation:emFlash 1s infinite}
|
|
@keyframes emFlash{0%,100%{opacity:1}50%{opacity:.3}}
|
|
/* PROVIDERS GRID */
|
|
.prov{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
|
|
.prov-card{background:var(--bg);border:1px solid rgba(30,41,59,.3);border-radius:8px;padding:10px;text-align:center;transition:.3s;cursor:pointer}
|
|
.prov-card:hover{border-color:rgba(139,92,246,.3)}
|
|
.prov-card .prov-name{font-size:11px;font-weight:600;margin-bottom:4px}
|
|
.prov-card .prov-status{font-size:18px}
|
|
.prov-card .prov-lat{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--t3)}
|
|
@media(max-width:1200px){.g4{grid-template-columns:repeat(2,1fr)}.brain-vis{flex-direction:column}.prov{grid-template-columns:repeat(2,1fr)}}
|
|
@media(max-width:768px){.g4,.g3,.g2{grid-template-columns:1fr}.prov{grid-template-columns: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 <span class="badge mp">AI Autonome</span></div><div class="live" id="clock">LIVE</div></div>
|
|
|
|
<div class="emergency-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:12px;color:var(--t2)">—</div></div><button class="btn btn-rd" onclick="handleEmergency()">⚡ Traiter</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>
|
|
<div class="cd"><h3>🩺 Auto-Réparations</h3><div class="sv" style="color:var(--gn)" id="k-heals">0</div></div>
|
|
<div class="cd"><h3>💬 Chat Queries</h3><div class="sv" style="color:var(--mb)" id="k-queries">0</div></div>
|
|
<div class="cd"><h3>📊 Précision Diagnostic</h3><div class="sv" style="color:var(--or)" id="k-precision">85%</div></div>
|
|
</div>
|
|
|
|
<div class="brain-vis">
|
|
<div class="brain-modules" id="modules-left"></div>
|
|
<div class="brain-core"><div class="bc-icon">🧠</div><div class="bc-label">Weval Mind</div><div class="bc-status" id="brain-status">● Active</div></div>
|
|
<div class="brain-modules" id="modules-right"></div>
|
|
</div>
|
|
|
|
<div class="g2">
|
|
<div>
|
|
<div class="cd" style="margin-bottom:16px"><h3>🤖 HAMID IA — Providers (11)</h3><div class="prov" id="providers"></div></div>
|
|
<div class="cd"><h3>⏱️ Cycles Autonomes</h3><div id="timeline" style="max-height:250px;overflow-y:auto"></div></div>
|
|
</div>
|
|
<div class="chat-container">
|
|
<div class="chat-header">💬 Weval Mind Chat <span class="badge mp" style="margin-left:auto">AI</span></div>
|
|
<div class="chat-messages" id="chat-msgs">
|
|
<div class="chat-msg system">Weval Mind 2.0 — Connecté. Posez vos questions.</div>
|
|
</div>
|
|
<div class="chat-input">
|
|
<input type="text" id="chat-in" placeholder="Ask Weval Mind..." onkeydown="if(event.key==='Enter')sendChat()">
|
|
<button onclick="sendChat()">Envoyer</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="act" style="margin-top:20px">
|
|
<button class="btn btn-mb" onclick="runCycle()">🔄 Run Autonomous Cycle</button>
|
|
<button class="btn btn-gn" onclick="autoSurgeon()">🩺 Auto-Surgeon Scan</button>
|
|
<button class="btn btn-pu" onclick="viewCapabilities()">📋 Capabilities</button>
|
|
<button class="btn btn-cy" onclick="load()">🔄 Refresh</button>
|
|
</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 HAMID_PROVIDERS=['Cerebras','Groq','DeepSeek','Gemini','Claude','Hyperbolic','Mistral','Cohere','SambaNova','Ollama','OpenRouter'];
|
|
const MIND_MODULES=[
|
|
{name:'Perception',icon:'👁️',desc:'Env scanning'},
|
|
{name:'Diagnostic',icon:'🔍',desc:'Problem analysis'},
|
|
{name:'Planning',icon:'📋',desc:'Action plans'},
|
|
{name:'Execution',icon:'⚡',desc:'Auto-repair'},
|
|
{name:'Learning',icon:'📚',desc:'Continuous'},
|
|
{name:'Surgery',icon:'🩺',desc:'Deep repair'},
|
|
{name:'Chat NLU',icon:'💬',desc:'Natural lang'},
|
|
{name:'Monitoring',icon:'📊',desc:'24/7 watch'}
|
|
];
|
|
|
|
function uc(){document.getElementById('clock').innerHTML='LIVE '+new Date().toLocaleTimeString('fr-FR')}setInterval(uc,1000);uc();
|
|
|
|
function renderModules(){
|
|
const left=MIND_MODULES.slice(0,4);const right=MIND_MODULES.slice(4);
|
|
document.getElementById('modules-left').innerHTML=left.map(m=>`<div class="bm"><div class="bm-dot on"></div><div><div class="bm-name">${m.icon} ${m.name}</div><div class="bm-stat">${m.desc}</div></div></div>`).join('');
|
|
document.getElementById('modules-right').innerHTML=right.map(m=>`<div class="bm"><div class="bm-dot on"></div><div><div class="bm-name">${m.icon} ${m.name}</div><div class="bm-stat">${m.desc}</div></div></div>`).join('');
|
|
}renderModules();
|
|
|
|
function renderProviders(data){
|
|
document.getElementById('providers').innerHTML=HAMID_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+50);
|
|
return`<div class="prov-card"><div class="prov-status">${ok?'✅':'❌'}</div><div class="prov-name">${p}</div><div class="prov-lat">${ok?lat+'ms':'offline'}</div></div>`}).join('')}
|
|
|
|
let chatHistory=[];
|
|
async 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="chat-msg user">${msg}</div>`;
|
|
msgs.innerHTML+=`<div class="chat-msg ai" id="typing" style="opacity:.5">🧠 Thinking...</div>`;
|
|
msgs.scrollTop=msgs.scrollHeight;
|
|
try{
|
|
const r=await fetch(API.chat,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg})});
|
|
const d=await r.json();
|
|
const typing=document.getElementById('typing');
|
|
if(typing)typing.remove();
|
|
const response=d.response||d.data?.response||d.message||'Je réfléchis...';
|
|
msgs.innerHTML+=`<div class="chat-msg ai">${response}</div>`;
|
|
msgs.scrollTop=msgs.scrollHeight;
|
|
}catch(e){const typing=document.getElementById('typing');if(typing){typing.textContent='⚠️ Connection error — trying HAMID fallback...';typing.id=''}
|
|
try{const r2=await fetch(API.hamid,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'chat',message:msg})});const d2=await r2.json();msgs.innerHTML+=`<div class="chat-msg ai">🤖 [HAMID] ${d2.response||d2.data?.response||'Fallback active'}</div>`;msgs.scrollTop=msgs.scrollHeight}catch(e2){msgs.innerHTML+=`<div class="chat-msg ai" style="border-color:rgba(239,68,68,.3)">⚠️ Both Mind & HAMID unreachable</div>`;msgs.scrollTop=msgs.scrollHeight}}}
|
|
|
|
async function runCycle(){
|
|
try{const r=await fetch(API.mind+'?action=autonomous_cycle');const d=await r.json();
|
|
addTimeline('Cycle exécuté: '+(d.status||'done'),'act');load()
|
|
}catch(e){addTimeline('Cycle error: '+e.message,'err')}}
|
|
|
|
async function autoSurgeon(){
|
|
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();
|
|
addTimeline('Surgeon scan: '+(d.diagnosis||d.status||'completed'),'heal');load()
|
|
}catch(e){addTimeline('Surgeon error: '+e.message,'err')}}
|
|
|
|
async function viewCapabilities(){
|
|
try{const r=await fetch(API.mind+'?action=capabilities');const d=await r.json();
|
|
const caps=d.modules||d.data?.modules||[];
|
|
const msgs=document.getElementById('chat-msgs');
|
|
msgs.innerHTML+=`<div class="chat-msg system">📋 ${caps.length||8} capabilities loaded</div>`;
|
|
msgs.innerHTML+=`<div class="chat-msg ai">${caps.map?caps.map(c=>`• ${c.name||c}: ${c.status||'active'}`).join('<br>'):'Perception, Diagnostic, Planning, Execution, Learning, Surgery, Chat NLU, Monitoring'}</div>`;
|
|
msgs.scrollTop=msgs.scrollHeight}catch(e){}}
|
|
|
|
async function handleEmergency(){
|
|
try{await fetch(API.mind,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'emergency',type:'auto'})});
|
|
document.getElementById('em-bar').classList.remove('active');addTimeline('Emergency handled','heal');load()
|
|
}catch(e){addTimeline('Emergency failed: '+e.message,'err')}}
|
|
|
|
let timelineItems=[];
|
|
function addTimeline(msg,type){
|
|
timelineItems.unshift({time:new Date().toLocaleTimeString('fr-FR'),msg,type});
|
|
if(timelineItems.length>20)timelineItems.pop();renderTimeline()}
|
|
function renderTimeline(){
|
|
document.getElementById('timeline').innerHTML=timelineItems.map(t=>`<div class="tl-item"><div class="tl-dot ${t.type}"></div><div class="tl-content"><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">Aucun cycle récent</div>'}
|
|
renderTimeline();
|
|
|
|
async function load(){
|
|
// Weval Mind status
|
|
try{const r=await fetch(API.mind+'?action=autonomous_cycle');const d=await r.json();
|
|
if(d.data||d.status){
|
|
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}
|
|
addTimeline('Status refresh OK','act')}}catch(e){document.getElementById('brain-status').innerHTML='<span style="color:var(--rd)">● Offline</span>'}
|
|
|
|
// HAMID providers
|
|
try{const r=await fetch(API.hamid+'?action=providers');const d=await r.json();renderProviders(d.data||d.providers||{})}catch(e){renderProviders({})}
|
|
}
|
|
load();setInterval(load,30000);
|
|
</script>
|
|
</body></html>
|