mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-21 22:18:13 +02:00
Rebaptise AJEAN en Loki (fork, lignée conservée)
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki) - LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ; units loki-engine / loki-ui ; binaire et aide CLI - updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les binaires AJEAN amont) Conservé à l'identique : le domaine ajean.link (service de tunnel amont), les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et LICENSE (historique et licence de l'amont). go build/vet/test : verts.
This commit is contained in:
157 files changed
+928
-928
No files matched your search
@@ -0,0 +1,68 @@
|
||||
// marked: GFM on, no auto-breaks (single newlines stay inline).
|
||||
marked.setOptions({ gfm: true, breaks: false });
|
||||
// Pre-process to fix common LLM markdown mistakes before handing to marked:
|
||||
// - code fences glued to preceding text on the same line ("foo ```ruby ...")
|
||||
// - fences without a closing newline
|
||||
// - 3+ consecutive blank lines collapsed to one (LLMs love padding)
|
||||
function fixMd(s){
|
||||
if(!s) return '';
|
||||
// Force a newline before a fence that's been glued to preceding text
|
||||
// (common LLM mistake: "...crée le fichier et```ruby"). We do NOT split
|
||||
// *after* the fence — the part after the fence is the language identifier.
|
||||
s = s.replace(/([^\n])(\s*)(```+|~~~+)(?=\w*\s*\n)/g, '$1\n$3');
|
||||
// Collapse runs of blank lines that LLMs love to emit.
|
||||
s = s.replace(/\n{3,}/g, '\n\n');
|
||||
return s;
|
||||
}
|
||||
function md(src){ return src ? marked.parse(fixMd(src)) : ''; }
|
||||
// Les garde-fous du serveur ("[stop: trop d'appels d'outils]") sont concaténés
|
||||
// au texte de la réponse : ils arrivent donc en clair, au milieu du markdown.
|
||||
// markNotices les sort du fil pour qu'on ne les prenne pas pour une phrase du
|
||||
// modèle. En cours de streaming, la parenthèse fermante manque encore → aucune
|
||||
// correspondance, donc pas d'encart qui clignote à chaque token.
|
||||
const NOTICE_RE=/\[stop\s*:\s*([^\]]+)\]/g;
|
||||
function markNotices(root){
|
||||
const walk=document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
||||
const hits=[];
|
||||
while(walk.nextNode()){
|
||||
const n=walk.currentNode;
|
||||
// Un exemple dans un bloc de code reste du code.
|
||||
if(n.parentElement && n.parentElement.closest('pre,code')) continue;
|
||||
NOTICE_RE.lastIndex=0;
|
||||
if(NOTICE_RE.test(n.nodeValue)) hits.push(n);
|
||||
}
|
||||
hits.forEach(n=>{
|
||||
const frag=document.createDocumentFragment();
|
||||
let rest=n.nodeValue, m;
|
||||
NOTICE_RE.lastIndex=0;
|
||||
while((m=NOTICE_RE.exec(rest))!==null){
|
||||
if(m.index) frag.appendChild(document.createTextNode(rest.slice(0,m.index)));
|
||||
const tag=document.createElement('span');
|
||||
tag.className='stopnote'; tag.textContent=m[1].trim();
|
||||
frag.appendChild(tag);
|
||||
rest=rest.slice(m.index+m[0].length);
|
||||
NOTICE_RE.lastIndex=0;
|
||||
}
|
||||
if(rest) frag.appendChild(document.createTextNode(rest));
|
||||
n.parentNode.replaceChild(frag, n);
|
||||
});
|
||||
}
|
||||
let msgs = [];
|
||||
let busy = false;
|
||||
function toggleSide(){ document.getElementById('side').classList.toggle('open'); document.getElementById('backdrop').classList.toggle('open'); document.body.classList.toggle('drawer-open'); }
|
||||
// Prompt système : persisté CÔTÉ SERVEUR (/api/sysprompt, partagé entre
|
||||
// appareils, utilisé par la génération serveur). localStorage = simple cache
|
||||
// d'affichage hors-ligne. Debounce : on n'écrit qu'après une pause de frappe.
|
||||
let _sysT = null;
|
||||
function saveSys(){
|
||||
const v = document.getElementById('sysprompt').value;
|
||||
localStorage.setItem('loki.sys', v);
|
||||
clearTimeout(_sysT);
|
||||
_sysT = setTimeout(()=>{ jpost('/api/sysprompt', {text:v}).catch(()=>{}); }, 600);
|
||||
}
|
||||
async function loadSys(){
|
||||
try{
|
||||
const d = await jget('/api/sysprompt');
|
||||
if(d && d.ok){ document.getElementById('sysprompt').value = d.text || ''; localStorage.setItem('loki.sys', d.text || ''); }
|
||||
}catch(e){}
|
||||
}
|
||||
Reference in new issue
Block a user