Fix live multi-turn: pass the resolved drug, stop did-you-mean garbage

This commit is contained in:
2026-08-05 16:54:35 +07:00
parent ef08b4929e
commit 1e8cbdb586
29 changed files with 2013 additions and 83 deletions
+6 -2
View File
@@ -8,9 +8,13 @@ export function buildMockResponse(userContent: string): SendMessageResponse {
message: {
id,
role: "assistant",
// Deliberately carries no dose. A fixture that states a plausible
// milligram figure is indistinguishable from a real answer in a
// screenshot, and screenshots outlive the code that produced them.
content:
`(Mock) Paracetamol được chỉ định để giảm đau, hạ sốt. Liều thường dùng ở người ` +
`lớn là 500-1000mg mỗi 4-6 giờ, tối đa 4g/ngày. Đây là dữ liệu giả lập cho câu hỏi: "${userContent}".`,
`⚠️ DỮ LIỆU GIẢ LẬP — KHÔNG PHẢI NỘI DUNG DƯỢC THƯ. Đây là phản hồi mẫu ` +
`dùng khi backend chưa sẵn sàng, không chứa số liệu y khoa và không được ` +
`dùng để tra cứu. Câu hỏi nhận được: "${userContent}".`,
citations: [
{
drugName: "PARACETAMOL",
+38 -4
View File
@@ -1,9 +1,43 @@
import type { SendMessageResponse } from "@duoc-thu/shared-types";
import { buildMockResponse } from "./mockFixtures";
const MOCK_LATENCY_MS = 400;
/**
* Sends a question to the real RAG backend through the app's own route
* handler, which holds the service URL and maps the response.
*
* The mock is retained but is now opt-in via `NEXT_PUBLIC_USE_MOCK_CHAT`, and
* every mocked answer is labelled as such in its own text. Silently falling
* back to a plausible-looking fake answer is the exact failure this project
* cannot afford: a fabricated dose that looks like a real one.
*/
const USE_MOCK = process.env.NEXT_PUBLIC_USE_MOCK_CHAT === "true";
export async function sendChatMessage(content: string): Promise<SendMessageResponse> {
await new Promise((resolve) => setTimeout(resolve, MOCK_LATENCY_MS));
return buildMockResponse(content);
export class ChatUnavailableError extends Error {
constructor(readonly status: number) {
super(`Chat backend unavailable (${status})`);
this.name = "ChatUnavailableError";
}
}
export async function sendChatMessage(
content: string,
conversationId?: string
): Promise<SendMessageResponse> {
if (USE_MOCK) {
await new Promise((resolve) => setTimeout(resolve, 400));
return buildMockResponse(content);
}
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content, conversationId }),
});
if (!response.ok) {
// Surfaced to the user as an error state, never as an answer.
throw new ChatUnavailableError(response.status);
}
return (await response.json()) as SendMessageResponse;
}