diff --git a/ui/index.html b/ui/index.html index 03ca6a6..0265d0a 100644 --- a/ui/index.html +++ b/ui/index.html @@ -44,6 +44,12 @@ h1{margin:0;font-size:18px;color:var(--accent)} .skillshead>span{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;font-weight:600} .addbtn{font-size:11px;padding:3px 11px 4px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;cursor:pointer;line-height:1.2} .addbtn:hover{border-color:var(--accent);color:var(--accent)} +.mem-count{font-size:10px;color:var(--dim);font-weight:400;letter-spacing:0;text-transform:none;margin-left:4px} +.mem-search{width:100%;box-sizing:border-box;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:5px 9px;font:inherit;font-size:12px;margin:0 0 6px} +.mem-search:focus{outline:none;border-color:var(--accent)} +.mem-list{max-height:240px;overflow-y:auto;overscroll-behavior:contain} +.mem-list .preset{margin:3px 0;padding:5px 9px} +.mem-more{font-size:11px;color:var(--dim);text-align:center;padding:6px 0 2px} #brand-a{display:inline-block;line-height:1;max-width:0;opacity:0;overflow:hidden;color:#fff;transition:max-width .35s ease,opacity .35s ease} #brand.agent #brand-a{max-width:1ch;opacity:1;margin-right:.04em} /* interrupteur (switch) */ @@ -188,8 +194,9 @@ button:disabled{opacity:.5;cursor:not-allowed}
⚠️ active l'accès machine (shell complet via bash sur le serveur) et la mémoire — l'IA peut inspecter, lancer des scripts et lire/écrire ses pages mémoire (timeout 30s, max 300s)
activé par défaut : coupe l'IA après ~8 appels d'outils (message [stop: trop d'appels d'outils]). Désactive-le si tu veux la laisser enchaîner sans plafond (l'anti-boucle reste actif).
-
Mémoire
-
+
Mémoire
+ +
System prompt @@ -420,10 +427,40 @@ async function loadAgent(){ document.getElementById('agent-badge').innerHTML = on ? 'on' : 'off'; document.getElementById('brand').classList.toggle('agent', on); - const pages = s.pages || s.skills || []; - document.getElementById('mem-list').innerHTML = pages.length - ? pages.map(x=>'
'+x.name+' — '+x.desc+'
').join('') - : '
(aucune page mémoire)
'; + memPages = (s.pages || s.skills || []).slice().sort((a,b)=>a.name.localeCompare(b.name)); + memShown = MEM_PAGE; + document.getElementById('mem-count').textContent = memPages.length ? '('+memPages.length+')' : ''; + document.getElementById('mem-search').style.display = memPages.length > MEM_PAGE ? '' : 'none'; + renderMemList(); +} +// Liste mémoire scalable : recherche + rendu plafonné (les milliers de pages ne +// déroulent plus une barre géante). memShown grimpe par paliers via « voir plus ». +let memPages=[], memShown=0; const MEM_PAGE=50; +function renderMemList(){ + const q=(document.getElementById('mem-search').value||'').trim().toLowerCase(); + const list=document.getElementById('mem-list'); + list.textContent=''; + if(!memPages.length){ list.innerHTML='
(aucune page mémoire)
'; return; } + const matches = q ? memPages.filter(x=>(x.name+' '+(x.desc||'')).toLowerCase().includes(q)) : memPages; + if(!matches.length){ list.innerHTML='
(aucun résultat pour « '+q.replace(/[<>&]/g,'')+' »)
'; return; } + const shown = matches.slice(0, memShown); + shown.forEach(x=>{ + const row=document.createElement('div'); row.className='preset'; row.style.fontSize='12px'; + row.onclick=()=>openMem(x.name); + const span=document.createElement('span'); + const b=document.createElement('b'); b.style.color='var(--text)'; b.textContent=x.name; span.appendChild(b); + if(x.desc){ const d=document.createElement('span'); d.className='muted'; d.textContent=' — '+x.desc; span.appendChild(d); } + const btn=document.createElement('button'); btn.textContent='edit'; btn.style.cssText='margin:0;padding:2px 8px;font-size:11px'; + btn.onclick=e=>{ e.stopPropagation(); openMem(x.name); }; + row.appendChild(span); row.appendChild(btn); list.appendChild(row); + }); + if(matches.length > shown.length){ + const more=document.createElement('div'); more.className='mem-more'; + more.textContent='+ voir plus ('+(matches.length-shown.length)+' de plus)'; + more.style.cursor='pointer'; + more.onclick=()=>{ memShown+=MEM_PAGE; renderMemList(); }; + list.appendChild(more); + } } // alias : plusieurs appelants rafraîchissent juste la liste des pages mémoire const loadMem = loadAgent;