Files
duocthu/packages/api-client/src/sendChatMessage.ts
T

44 lines
1.4 KiB
TypeScript

import type { SendMessageResponse } from "@duoc-thu/shared-types";
import { buildMockResponse } from "./mockFixtures";
/**
* 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 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;
}