v1.8.0: bge-m3 embeddings, qwen3 LLM, retrieval fixes, input validation, memory poisoning fix

This commit is contained in:
2026-05-28 18:54:05 +00:00
parent e87b33f403
commit 7ce5c6f7d0
1433 changed files with 63814 additions and 199 deletions
+82 -10
View File
@@ -224,8 +224,25 @@ header { animation:slideDown 350ms var(--ease-out) both; }
}
.reveal { opacity:1; transform:none; }
}
/* Sticky footer — no layout impact */
#sticky-footer { position: sticky; top: 100vh; }
.stream-cursor {
display: inline-block;
width: 2px;
background: var(--color-primary, #4eded3);
margin-right: 1px;
border-radius: 1px;
animation: blink 0.75s step-end infinite;
vertical-align: text-bottom;
height: 1.1em;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
</style>
<script src="/static/analytics.js" defer></script>
<link rel="privacy-policy" href="https://rag.afaqzaid.com/privacy"/>
<meta name="description" content="AfakZaid RAG — AI-powered scholarly research platform. Search and query Arabic books and documents."/>
</head>
<body>
@@ -462,19 +479,65 @@ async function doQuery() {
const box = document.getElementById('answer-box');
const meta = document.getElementById('answer-meta');
wrap.classList.remove('hidden');
box.textContent = '...'; meta.innerHTML = '';
box.textContent = ''; meta.innerHTML = '';
// Blinking cursor while streaming
let cursor = document.createElement('span');
cursor.className = 'stream-cursor';
cursor.textContent = '|';
box.appendChild(cursor);
try {
const headers = {'Content-Type':'application/json','X-API-Key':API_KEY};
if(userToken) headers['Authorization'] = 'Bearer '+userToken;
const r = await fetch('/query',{method:'POST',headers,body:JSON.stringify({query:q,session_id:'web-'+(currentUser?.id||'guest')})});
const d = await r.json();
box.textContent = d.answer;
meta.innerHTML = [
`<span class="glass px-3 py-1 rounded-full text-xs text-primary font-bold">${d.llm}</span>`,
`<span class="glass px-3 py-1 rounded-full text-xs text-secondary">${((d.confidence||0)*100).toFixed(0)}% ثقة</span>`,
...(d.books_used||[]).map(b=>`<span class="glass px-3 py-1 rounded-full text-xs text-on-surface-variant">${b}</span>`)
].join('');
} catch(e){ box.textContent='خطأ: '+e.message; }
const r = await fetch('/query/stream', {
method: 'POST',
headers,
body: JSON.stringify({query:q, session_id:'web-'+(currentUser?.id||'guest')})
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const reader = r.body.getReader();
const decoder = new TextDecoder();
let buf = '';
while (true) {
const {done, value} = await reader.read();
if (done) break;
buf += decoder.decode(value, {stream: true});
// Process complete SSE lines
const lines = buf.split('\n');
buf = lines.pop(); // keep incomplete last line
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const raw = line.slice(6).trim();
if (raw === '[DONE]') break;
try {
const frame = JSON.parse(raw);
if (frame.t === 'token') {
// Insert token before cursor
cursor.before(document.createTextNode(frame.v));
box.scrollTop = box.scrollHeight;
} else if (frame.t === 'meta') {
const m = frame.v;
meta.innerHTML = [
`<span class="glass px-3 py-1 rounded-full text-xs text-primary font-bold">${m.llm||''}</span>`,
`<span class="glass px-3 py-1 rounded-full text-xs text-secondary">${((m.confidence||0)*100).toFixed(0)}% ثقة</span>`,
...(m.books_used||[]).map(b=>`<span class="glass px-3 py-1 rounded-full text-xs text-on-surface-variant">${b}</span>`)
].join('');
}
} catch(_) {}
}
}
} catch(e) { box.textContent = 'خطأ: ' + e.message; }
// Remove cursor
cursor.remove();
btn.disabled = false;
btn.style.animation = '';
btn.innerHTML = '<span class="msym text-lg">search</span> بحث';
@@ -544,5 +607,14 @@ loadStats();
loadBooks();
setInterval(loadStats, 30000);
</script>
<footer id="sticky-footer" style="text-align:center;padding:20px;margin-top:16px;font-size:12px;color:#888;border-top:1px solid rgba(255,255,255,0.06)">
<a href="https://rag.afaqzaid.com/privacy" rel="privacy-policy" style="color:#888;text-decoration:none;margin:0 8px">سياسة الخصوصية</a>
•
<a href="https://rag.afaqzaid.com/terms" style="color:#888;text-decoration:none;margin:0 8px">شروط الخدمة</a>
•
<span style="margin:0 8px">© 2026 أفاق زيد</span>
</footer>
</body>
</html>