// ── Embedding Debug Page ──
registerPage('embedding-debug', {
async init() {
if (!currentUser || !currentUser.isAdmin) {
navigateTo('dashboard');
return;
}
var queryInput = document.getElementById('embDebugQuery');
var agentSelect = document.getElementById('embDebugAgent');
var topNInput = document.getElementById('embDebugTopN');
var searchBtn = document.getElementById('embDebugSearchBtn');
var statsBtn = document.getElementById('embDebugStatsBtn');
var reEmbedBtn = document.getElementById('embDebugReEmbedBtn');
var summaryEl = document.getElementById('embDebugSummary');
var resultsEl = document.getElementById('embDebugResults');
// Agents laden
try {
var resp = await fetch('/api/agents/available');
var agents = await resp.json();
(agents || []).forEach(function(a) {
var opt = document.createElement('option');
opt.value = a.agentId;
opt.textContent = a.name;
agentSelect.appendChild(opt);
});
} catch (e) { /* ignore */ }
searchBtn.addEventListener('click', doSearch);
queryInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') doSearch();
});
statsBtn.addEventListener('click', doStats);
if (reEmbedBtn) {
reEmbedBtn.addEventListener('click', async function() {
if (!confirm('Alle Embeddings löschen und neu generieren?\n\nDas kann bei vielen Messages einige Minuten dauern.')) return;
reEmbedBtn.disabled = true;
reEmbedBtn.innerHTML = ' Läuft...';
try {
var resp = await fetch('/api/admin/embedding-debug/re-embed', { method: 'POST' });
var data = await resp.json();
summaryEl.innerHTML = '
' + esc(data.status || data.error) + (data.model ? ' (Modell: ' + esc(data.model) + ')' : '') + '
';
} catch (e) {
summaryEl.innerHTML = 'Fehler: ' + esc(e.message) + '
';
} finally {
reEmbedBtn.disabled = false;
reEmbedBtn.innerHTML = ' Re-Embed All';
}
});
}
async function doSearch() {
var query = queryInput.value.trim();
if (!query) return;
searchBtn.disabled = true;
searchBtn.innerHTML = ' Suche...';
summaryEl.innerHTML = '';
resultsEl.innerHTML = '';
try {
var params = new URLSearchParams({
q: query,
agentId: agentSelect.value,
topN: topNInput.value || '20'
});
var resp = await fetch('/api/admin/embedding-debug?' + params);
var data = await resp.json();
if (data.error) {
summaryEl.innerHTML = '' + esc(data.error) + '
';
return;
}
renderSummary(data.summary);
renderResults(data.messages, data.memory);
} catch (e) {
summaryEl.innerHTML = 'Fehler: ' + esc(e.message) + '
';
} finally {
searchBtn.disabled = false;
searchBtn.innerHTML = ' Suchen';
}
}
async function doStats() {
statsBtn.disabled = true;
statsBtn.innerHTML = '';
summaryEl.innerHTML = '';
resultsEl.innerHTML = '';
try {
var resp = await fetch('/api/admin/embedding-debug/stats');
var data = await resp.json();
renderStats(data);
} catch (e) {
summaryEl.innerHTML = 'Fehler: ' + esc(e.message) + '
';
} finally {
statsBtn.disabled = false;
statsBtn.innerHTML = ' Statistiken';
}
}
function renderSummary(s) {
summaryEl.innerHTML =
'' +
'
' +
'
' + s.totalMessageResults + 'Treffer gesamt
' +
'
' + s.aboveThreshold035 + '≥ 0.35 (Threshold)
' +
'
' + s.belowThreshold + '< 0.35
' +
'
' + s.wouldAppearInAutoContext + '→ AutoContext
' +
'
' + s.filteredByChain + 'Chain-gefiltert
' +
'
' + s.filteredByLength + 'Zu kurz (<20)
' +
'
' +
(s.totalMemoryResults > 0 ?
'
' +
'
' + s.totalMemoryResults + 'Memory-Treffer
' +
'
' + s.memoryAboveThreshold + 'Memory ≥ 0.35
' +
'
' : '') +
'
';
}
function renderResults(messages, memory) {
var html = '';
if (messages && messages.length > 0) {
html += 'Message-Ergebnisse
';
html += '';
messages.forEach(function(r, i) {
var scoreClass = r.score >= 0.35 ? 'score-good' : (r.score >= 0.2 ? 'score-medium' : 'score-low');
var filterTags = '';
if (r.wouldBeFilteredByChain) filterTags += '
Chain';
if (r.wouldBeFilteredByLength) filterTags += '
Kurz';
if (r.wouldAppearInAutoContext) filterTags += '
AutoContext';
else if (r.wouldPassThreshold) filterTags += '
Threshold OK';
var hasFullText = r.fullText && r.fullText.length > (r.textPreview || '').length;
html += '
' +
'' +
'
' + esc(r.textPreview || '(kein Preview)') + '
' +
(hasFullText ? '
' + esc(r.fullText) + '
' : '') +
'
MsgID: ' + r.messageId + ' | Session: ' + esc(r.sessionId || '').substring(0, 8) + ' | Chain: ' + esc(r.chainId || '').substring(0, 8) + '
' +
'
';
});
html += '
';
}
if (memory && memory.length > 0) {
html += 'Memory-Ergebnisse
';
html += '';
memory.forEach(function(r, i) {
var scoreClass = r.score >= 0.35 ? 'score-good' : (r.score >= 0.2 ? 'score-medium' : 'score-low');
var hasFullText = r.fullText && r.fullText.length > (r.textPreview || '').length;
html += '
' +
'' +
'
' + esc(r.textPreview || '(kein Preview)') + '
' +
(hasFullText ? '
' + esc(r.fullText) + '
' : '') +
'
';
});
html += '
';
}
if (!html) {
html = 'Keine Ergebnisse gefunden (auch nicht unter Threshold).
';
}
resultsEl.innerHTML = html;
}
function renderStats(data) {
var html = 'Embedding-Statistiken
';
html += '' +
'
' + (data.totalMessages || 0).toLocaleString() + 'Message-Embeddings
' +
'
' + (data.totalMemory || 0).toLocaleString() + 'Memory-Chunks
' +
'
';
if (data.perAgent && data.perAgent.length > 0) {
html += 'Pro Agent
';
html += '| Agent | Messages | Memory |
';
data.perAgent.forEach(function(a) {
html += '| ' + esc(a.agentName || a.agentId || '(kein Agent)') + ' | ' +
'' + (a.messageCount || 0).toLocaleString() + ' | ' +
'' + (a.memoryChunks || 0).toLocaleString() + ' |
';
});
html += '
';
}
resultsEl.innerHTML = html;
}
}
});