Wire token-budget packing into the overview/rerank fallback path

This commit is contained in:
2026-08-10 12:02:31 +07:00
parent 60b4397032
commit 46469468bb
18 changed files with 768 additions and 38 deletions
+27 -5
View File
@@ -40,20 +40,36 @@ export function Composer({
}
}, [initialValue]);
// Fetch suggestions from API route when query length > 1
// Fetch suggestions from API route when query length > 1.
//
// `term` is the LAST WORD being typed, not the whole textarea — a natural
// sentence like "cho tôi thuốc parace" has no drug alias containing that
// full phrase, so matching against it always returns empty (found live
// 2026-08-10: this silently killed every suggestion once a user typed a
// sentence instead of a bare drug name, which is the more common case).
useEffect(() => {
const term = value.trim();
const words = value.trim().split(/\s+/);
const term = words[words.length - 1] ?? "";
if (term.length < 2) {
setSuggestions([]);
setShowSuggestions(false);
return;
}
// Race guard: a slower request for an earlier keystroke must not
// overwrite a faster one for a later keystroke — found live 2026-08-10
// typing fast could show a stale, unrelated suggestion list because the
// fetch callback set state unconditionally regardless of whether `term`
// (and therefore `value`) had already changed by the time it resolved.
let cancelled = false;
const timer = setTimeout(async () => {
try {
const res = await fetch(`/api/suggest?q=${encodeURIComponent(term)}`);
if (cancelled) return;
if (res.ok) {
const data = await res.json();
if (cancelled) return;
if (data?.suggestions && Array.isArray(data.suggestions) && data.suggestions.length > 0) {
setSuggestions(data.suggestions);
setShowSuggestions(true);
@@ -64,15 +80,21 @@ export function Composer({
const filtered = SAMPLE_SUGGESTIONS.filter((s) =>
s.toLowerCase().includes(term.toLowerCase())
);
if (cancelled) return;
setSuggestions(filtered);
setShowSuggestions(filtered.length > 0);
} catch {
setSuggestions([]);
setShowSuggestions(false);
if (!cancelled) {
setSuggestions([]);
setShowSuggestions(false);
}
}
}, 200);
return () => clearTimeout(timer);
return () => {
cancelled = true;
clearTimeout(timer);
};
}, [value]);
// Close suggestions on outside click