feat(app): add suggestion generation
This commit is contained in:
parent
68b595023e
commit
3bfaf9be28
|
@ -9,7 +9,7 @@ class LineListOutputParser extends BaseOutputParser<string[]> {
|
||||||
|
|
||||||
constructor(args?: LineListOutputParserArgs) {
|
constructor(args?: LineListOutputParserArgs) {
|
||||||
super();
|
super();
|
||||||
this.key = args.key || this.key;
|
this.key = args.key ?? this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lc_name() {
|
static lc_name() {
|
||||||
|
|
|
@ -63,6 +63,7 @@ const Chat = ({
|
||||||
dividerRef={isLast ? dividerRef : undefined}
|
dividerRef={isLast ? dividerRef : undefined}
|
||||||
isLast={isLast}
|
isLast={isLast}
|
||||||
rewrite={rewrite}
|
rewrite={rewrite}
|
||||||
|
sendMessage={sendMessage}
|
||||||
/>
|
/>
|
||||||
{!isLast && msg.role === 'assistant' && (
|
{!isLast && msg.role === 'assistant' && (
|
||||||
<div className="h-px w-full bg-[#1C1C1C]" />
|
<div className="h-px w-full bg-[#1C1C1C]" />
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { Document } from '@langchain/core/documents';
|
import { Document } from '@langchain/core/documents';
|
||||||
import Navbar from './Navbar';
|
import Navbar from './Navbar';
|
||||||
import Chat from './Chat';
|
import Chat from './Chat';
|
||||||
import EmptyChat from './EmptyChat';
|
import EmptyChat from './EmptyChat';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
|
import { getSuggestions } from '@/lib/actions';
|
||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
content: string;
|
content: string;
|
||||||
role: 'user' | 'assistant';
|
role: 'user' | 'assistant';
|
||||||
|
suggestions?: string[];
|
||||||
sources?: Document[];
|
sources?: Document[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,10 +147,15 @@ const ChatWindow = () => {
|
||||||
|
|
||||||
const [chatHistory, setChatHistory] = useState<[string, string][]>([]);
|
const [chatHistory, setChatHistory] = useState<[string, string][]>([]);
|
||||||
const [messages, setMessages] = useState<Message[]>([]);
|
const [messages, setMessages] = useState<Message[]>([]);
|
||||||
|
const messagesRef = useRef<Message[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [messageAppeared, setMessageAppeared] = useState(false);
|
const [messageAppeared, setMessageAppeared] = useState(false);
|
||||||
const [focusMode, setFocusMode] = useState('webSearch');
|
const [focusMode, setFocusMode] = useState('webSearch');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
messagesRef.current = messages;
|
||||||
|
}, [messages]);
|
||||||
|
|
||||||
const sendMessage = async (message: string) => {
|
const sendMessage = async (message: string) => {
|
||||||
if (loading) return;
|
if (loading) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
@ -177,7 +184,7 @@ const ChatWindow = () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const messageHandler = (e: MessageEvent) => {
|
const messageHandler = async (e: MessageEvent) => {
|
||||||
const data = JSON.parse(e.data);
|
const data = JSON.parse(e.data);
|
||||||
|
|
||||||
if (data.type === 'error') {
|
if (data.type === 'error') {
|
||||||
|
@ -239,8 +246,28 @@ const ChatWindow = () => {
|
||||||
['human', message],
|
['human', message],
|
||||||
['assistant', recievedMessage],
|
['assistant', recievedMessage],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
ws?.removeEventListener('message', messageHandler);
|
ws?.removeEventListener('message', messageHandler);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
|
const lastMsg = messagesRef.current[messagesRef.current.length - 1];
|
||||||
|
|
||||||
|
if (
|
||||||
|
lastMsg.role === 'assistant' &&
|
||||||
|
lastMsg.sources &&
|
||||||
|
lastMsg.sources.length > 0 &&
|
||||||
|
!lastMsg.suggestions
|
||||||
|
) {
|
||||||
|
const suggestions = await getSuggestions(messagesRef.current);
|
||||||
|
setMessages((prev) =>
|
||||||
|
prev.map((msg) => {
|
||||||
|
if (msg.id === lastMsg.id) {
|
||||||
|
return { ...msg, suggestions: suggestions };
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Message } from '@/components/ChatWindow';
|
||||||
|
|
||||||
|
export const getSuggestions = async (chatHisory: Message[]) => {
|
||||||
|
const chatModel = localStorage.getItem('chatModel');
|
||||||
|
const chatModelProvider = localStorage.getItem('chatModelProvider');
|
||||||
|
|
||||||
|
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/suggestions`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
chat_history: chatHisory,
|
||||||
|
chat_model: chatModel,
|
||||||
|
chat_model_provider: chatModelProvider,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = (await res.json()) as { suggestions: string[] };
|
||||||
|
|
||||||
|
return data.suggestions;
|
||||||
|
};
|
Loading…
Reference in New Issue