Fix dashboard: always use hybrid (no HNSW dependency), 15s timeout, error display
The search hung because pure AI mode calls HNSW which is RAM-only — gone after every lakehouse restart. Now ALL AI/hybrid searches go through the /search endpoint which uses brute-force when HNSW isn't loaded. Added 15s AbortController timeout so fetch never hangs. Added window.onerror handler to show JS errors on page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5c93338f40
commit
e7e988dcc0
@ -104,6 +104,11 @@ body{font-family:'Inter','SF Pro',system-ui,sans-serif;background:#0a0a0f;color:
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onerror = function(msg, url, line) {
|
||||
document.body.insertAdjacentHTML('afterbegin',
|
||||
'<div style="background:#7f1d1d;color:#fca5a5;padding:12px;font-size:12px">JS Error: ' + msg + ' (line ' + line + ')</div>');
|
||||
};
|
||||
|
||||
const base = window.location.pathname.replace(/\/+$/, '');
|
||||
const GW = window.location.origin + base;
|
||||
let mode = 'ai';
|
||||
@ -139,9 +144,10 @@ async function doSearch() {
|
||||
|
||||
const t0 = Date.now();
|
||||
|
||||
// If ANY filter is set, always use hybrid — filters only work through SQL
|
||||
const hasFilters = state || role || rel > 0.5;
|
||||
const effectiveMode = (mode === 'crm') ? 'crm' : (hasFilters ? 'hybrid' : mode);
|
||||
// ALWAYS use hybrid for AI modes — it handles filters AND works even
|
||||
// when HNSW isn't loaded (falls back to brute-force). Pure HNSW mode
|
||||
// hangs when the RAM index isn't built.
|
||||
const effectiveMode = (mode === 'crm') ? 'crm' : 'hybrid';
|
||||
|
||||
try {
|
||||
let data;
|
||||
@ -159,33 +165,29 @@ async function doSearch() {
|
||||
data = await r.json();
|
||||
renderCRMResults(data, query, Date.now() - t0);
|
||||
|
||||
} else if (effectiveMode === 'ai') {
|
||||
// Pure AI vector search — no filters, just meaning
|
||||
const r = await fetch(GW + '/api/vectors/hnsw/search', {
|
||||
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({index_name: 'workers_500k_v1', query: query, top_k: 10})
|
||||
});
|
||||
data = await r.json();
|
||||
renderAIResults(data, query, Date.now() - t0);
|
||||
|
||||
} else {
|
||||
// Hybrid — SQL filters enforce structure, AI ranks by relevance
|
||||
// Always works — uses brute-force when HNSW isn't loaded
|
||||
let filter = "CAST(reliability AS DOUBLE) >= " + rel;
|
||||
if (state) filter += " AND state = '" + state + "'";
|
||||
if (role) filter += " AND role = '" + role + "'";
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(function() { controller.abort(); }, 15000);
|
||||
const r = await fetch(GW + '/search', {
|
||||
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
question: query, index_name: 'workers_500k_v1',
|
||||
sql_filter: filter, dataset: 'workers_500k',
|
||||
id_column: 'worker_id', top_k: 10, generate: false
|
||||
})
|
||||
}),
|
||||
signal: controller.signal
|
||||
});
|
||||
clearTimeout(timeout);
|
||||
data = await r.json();
|
||||
renderHybridResults(data, query, Date.now() - t0);
|
||||
}
|
||||
} catch (e) {
|
||||
document.getElementById('results').innerHTML = '<div class="empty">Error: ' + e.message + '</div>';
|
||||
document.getElementById('results').innerHTML = '<div class="empty">Search error: ' + e.message + '<br><br>If filters were set, try Hybrid mode. If the search is slow, the AI index may be loading — try again in 10 seconds.</div>';
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user