Remove corpus counts from chat chrome
This commit is contained in:
@@ -19,7 +19,10 @@ import { cn } from "@duoc-thu/ui";
|
||||
|
||||
interface ChatPanelProps {
|
||||
sessionId: string;
|
||||
messages: ChatMessage[];
|
||||
onMessagesChange: React.Dispatch<React.SetStateAction<ChatMessage[]>>;
|
||||
initialQuery?: string;
|
||||
initialQueryToken?: number;
|
||||
onCitationClick?: (citation: Citation, index: number, allCitations: Citation[]) => void;
|
||||
onCitationsLoaded?: (citations: Citation[]) => void;
|
||||
activeCitationIndex?: number | null;
|
||||
@@ -28,42 +31,45 @@ interface ChatPanelProps {
|
||||
|
||||
const STARTER_QUESTIONS = [
|
||||
{
|
||||
category: "Liều Dùng Lâm Sàng",
|
||||
query: "Liều dùng Paracetamol người lớn và trẻ em theo cân nặng là bao nhiêu?",
|
||||
category: "Chỉ Định",
|
||||
query: "Levetiracetam được chỉ định trong những trường hợp nào?",
|
||||
icon: Pill,
|
||||
},
|
||||
{
|
||||
category: "Chống Chỉ Định",
|
||||
query: "Chống chỉ định tuyệt đối và tương đối của Amoxicillin là gì?",
|
||||
query: "Chống chỉ định của Metformin là gì?",
|
||||
icon: Stethoscope,
|
||||
},
|
||||
{
|
||||
category: "Tương Tác Thuốc",
|
||||
query: "Tương tác giữa Metformin và thuốc cản quang chứa iốt xử trí thế nào?",
|
||||
category: "ADR Theo Tần Suất",
|
||||
query: "Tác dụng không mong muốn của Zolpidem là gì?",
|
||||
icon: Activity,
|
||||
},
|
||||
{
|
||||
category: "Thận Trọng & ADR",
|
||||
query: "Thận trọng khi dùng Aspirin cho bệnh nhân có tiền sử loét dạ dày?",
|
||||
category: "Thời Kỳ Mang Thai",
|
||||
query: "Có thể dùng Fluoxetin trong thời kỳ mang thai không?",
|
||||
icon: Zap,
|
||||
},
|
||||
];
|
||||
|
||||
export function ChatPanel({
|
||||
sessionId,
|
||||
messages,
|
||||
onMessagesChange: setMessages,
|
||||
initialQuery,
|
||||
initialQueryToken,
|
||||
onCitationClick,
|
||||
onCitationsLoaded,
|
||||
activeCitationIndex = null,
|
||||
className,
|
||||
}: ChatPanelProps) {
|
||||
const { resolvedTheme } = useTheme();
|
||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const abortControllerRef = useRef<AbortController | null>(null);
|
||||
const initialQuerySentRef = useRef<string | undefined>(undefined);
|
||||
const initialQuerySentRef = useRef<number | undefined>(undefined);
|
||||
const stopRequestedRef = useRef(false);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
||||
@@ -87,8 +93,12 @@ export function ChatPanel({
|
||||
|
||||
setMessages((prev) => [...prev, userMsg]);
|
||||
setIsLoading(true);
|
||||
stopRequestedRef.current = false;
|
||||
|
||||
abortControllerRef.current = new AbortController();
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
abortControllerRef.current?.abort();
|
||||
}, 25_000);
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/chat", {
|
||||
@@ -115,10 +125,16 @@ export function ChatPanel({
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.name === "AbortError") {
|
||||
setError(
|
||||
stopRequestedRef.current
|
||||
? "Đã dừng chờ trên giao diện. Tác vụ đang chạy có thể cần vài giây để kết thúc an toàn."
|
||||
: "Yêu cầu vượt quá 25 giây và đã được dừng. Vui lòng thử lại với câu hỏi cụ thể hơn."
|
||||
);
|
||||
return;
|
||||
}
|
||||
setError("Không thể kết nối đến máy chủ AI Service. Vui lòng kiểm tra lại dịch vụ backend.");
|
||||
} finally {
|
||||
window.clearTimeout(timeoutId);
|
||||
setIsLoading(false);
|
||||
abortControllerRef.current = null;
|
||||
}
|
||||
@@ -126,12 +142,15 @@ export function ChatPanel({
|
||||
|
||||
const handleStop = () => {
|
||||
if (abortControllerRef.current) {
|
||||
stopRequestedRef.current = true;
|
||||
abortControllerRef.current.abort();
|
||||
setIsLoading(false);
|
||||
abortControllerRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => abortControllerRef.current?.abort();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Guard against firing twice for the same query: React 18 Strict Mode
|
||||
// (dev only) runs this effect setup twice on mount, and with no guard
|
||||
@@ -140,12 +159,16 @@ export function ChatPanel({
|
||||
// muốn của Aspirin" turns in the trace). The ref persists across the
|
||||
// Strict Mode replay, so the second invocation for the same
|
||||
// `initialQuery` is a no-op; a genuinely new query still sends once.
|
||||
if (initialQuery && initialQuerySentRef.current !== initialQuery) {
|
||||
initialQuerySentRef.current = initialQuery;
|
||||
if (
|
||||
initialQuery &&
|
||||
initialQueryToken !== undefined &&
|
||||
initialQuerySentRef.current !== initialQueryToken
|
||||
) {
|
||||
initialQuerySentRef.current = initialQueryToken;
|
||||
handleSendMessage(initialQuery);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [initialQuery]);
|
||||
}, [initialQuery, initialQueryToken]);
|
||||
|
||||
// Empty state renderer per theme
|
||||
const renderEmptyState = () => {
|
||||
@@ -165,7 +188,7 @@ export function ChatPanel({
|
||||
Tra Cứu Dược Thư Quốc Gia Việt Nam
|
||||
</h2>
|
||||
<p className="text-xs sm:text-sm text-txt-secondary mt-1.5 leading-relaxed max-w-xl mx-auto">
|
||||
Hệ thống AI y tế tra cứu chính xác theo 684 chuyên luận chính thức. Mọi thông tin đều được xác thực suy luận (Entailment Verification) kèm trích dẫn trang in PDF.
|
||||
Tra cứu 684 chuyên luận Dược thư Quốc gia Việt Nam 2018 với căn cứ theo trang in. Khi cần, bác sĩ có thể tiếp tục trao đổi để làm rõ dữ kiện và đối chiếu với bối cảnh lâm sàng.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -321,7 +344,13 @@ export function ChatPanel({
|
||||
}
|
||||
activeCitationIndex={activeCitationIndex}
|
||||
onRetry={retryQuery ? () => handleSendMessage(retryQuery) : undefined}
|
||||
onQuickReply={(text) => handleSendMessage(text)}
|
||||
onQuickReply={
|
||||
msgIdx === messages.length - 1 &&
|
||||
msg.decision === "clarify" &&
|
||||
!isLoading
|
||||
? (text) => handleSendMessage(text)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user