forked from langfuse/langfuse-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.tsx
More file actions
108 lines (97 loc) · 3.4 KB
/
Copy pathindex.tsx
File metadata and controls
108 lines (97 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"use client";
import { Message, useChat } from "ai/react";
import { Input } from "../ui/input";
import { Button } from "../ui/button";
import { ChatList } from "./ui/ChatList";
import { ButtonScrollToBottom } from "./ui/ButtonScrollToBottom";
import React from "react";
import { Send } from "lucide-react";
import { nanoid } from "ai";
import { useMemo, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import { usePersistedNanoId } from "./hooks/persistedNanoId";
export function Chat({ className }: { className?: string }) {
const ref = useRef<HTMLDivElement>(null);
const conversationId = useMemo(() => nanoid(), []);
const userId = usePersistedNanoId("qa-chatbot-user-id");
// Controlled message history. Used to update the messages state onFinish to include the latest messageId provided by the server.
const [input, setInput] = useState("");
const controlledMessages = useRef<Message[]>([]);
const latestUserMessage = useRef<Message | null>(null);
const latestTraceId = useRef<string | null>(null);
const { messages, setMessages, append } = useChat({
body: {
conversationId,
userId: userId ? "u-" + userId : undefined,
},
api: "/api/qa-chatbot",
sendExtraMessageFields: true,
onResponse(response) {
// Get the latest message id from the server
const newTraceId = response.headers.get("X-Trace-Id");
latestTraceId.current = newTraceId;
},
onFinish(message) {
// Update controlledMessages
if (latestUserMessage.current) {
controlledMessages.current.push({
...latestUserMessage.current,
id: latestUserMessage.current.id ?? nanoid(),
});
latestUserMessage.current = null;
}
controlledMessages.current.push({
...message,
id: latestTraceId.current ?? message.id,
});
// Update "ai" messages state
setMessages(controlledMessages.current);
},
});
const messagesWithWelcome: Message[] = [welcomeMessage, ...messages];
return (
<div
className={cn(
"relative flex flex-col p-5 mt-10 h-[70vh] overflow-hidden bg-background/40 shadow-lg rounded",
className
)}
>
<div className="flex-1 overflow-y-scroll" ref={ref}>
<ChatList
messages={messagesWithWelcome}
conversationId={conversationId}
/>
</div>
<form
onSubmit={(event) => {
event.preventDefault();
const userMessage = {
id: nanoid(),
content: input,
role: "user" as const,
};
setInput("");
latestUserMessage.current = userMessage;
append(userMessage);
}}
className="relative flex gap-2"
>
<ButtonScrollToBottom outerDivRef={ref} />
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Send a message"
/>
<Button type="submit" size="icon">
<Send className="h-4 w-4" />
</Button>
</form>
</div>
);
}
const welcomeMessage: Message = {
role: "assistant",
id: "announcement-1",
content: `👋 Do you have any questions about Langfuse? Ask me!
_⚠️ Warning: Do not enter sensitive information. All chat messages can be viewed in the public demo project. Responses may be inaccurate. Please check the documentation for details or reach out to us via the chat widget._`,
} as const;