|
@@ -4,29 +4,55 @@ import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
|
|
|
|
|
|
|
import { apiv3Post } from '~/client/util/apiv3-client';
|
|
import { apiv3Post } from '~/client/util/apiv3-client';
|
|
|
import { useRagSearchModal } from '~/stores/rag-search';
|
|
import { useRagSearchModal } from '~/stores/rag-search';
|
|
|
|
|
+import loggerFactory from '~/utils/logger';
|
|
|
|
|
+
|
|
|
|
|
+import { MessageCard } from './MessageCard';
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const logger = loggerFactory('growi:clinet:components:RagSearchModal');
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+type Message = {
|
|
|
|
|
+ id: string,
|
|
|
|
|
+ content: string,
|
|
|
|
|
+ isUserMessage?: boolean,
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const RagSearchModal = (): JSX.Element => {
|
|
const RagSearchModal = (): JSX.Element => {
|
|
|
- const [userMessage, setUserMessage] = useState('');
|
|
|
|
|
- const [assistantMessage, setAssistantMessage] = useState<Array<string>>([]);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const [input, setInput] = useState('');
|
|
|
|
|
+
|
|
|
|
|
+ const [threadId, setThreadId] = useState<string | undefined>();
|
|
|
|
|
+ const [messages, setMessages] = useState<Message[]>([]);
|
|
|
|
|
|
|
|
const { data: ragSearchModalData, close: closeRagSearchModal } = useRagSearchModal();
|
|
const { data: ragSearchModalData, close: closeRagSearchModal } = useRagSearchModal();
|
|
|
|
|
|
|
|
const onClickSubmitUserMessageHandler = async() => {
|
|
const onClickSubmitUserMessageHandler = async() => {
|
|
|
|
|
+ const newUserMessage = { id: messages.length.toString(), content: input, isUserMessage: true };
|
|
|
|
|
+ setMessages(msgs => [...msgs, newUserMessage]);
|
|
|
|
|
+
|
|
|
|
|
+ setInput('');
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
- const res = await apiv3Post('/openai/chat', { userMessage });
|
|
|
|
|
|
|
+ const res = await apiv3Post('/openai/chat', { userMessage: input, threadId });
|
|
|
const assistantMessageData = res.data.messages;
|
|
const assistantMessageData = res.data.messages;
|
|
|
|
|
|
|
|
- const messages: string[] = [];
|
|
|
|
|
- for (const message of assistantMessageData.data.reverse()) {
|
|
|
|
|
- messages.push(`${message.role} > ${message.content[0].text.value}`);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (assistantMessageData.data.length > 0) {
|
|
|
|
|
+ const newMessages: Message[] = assistantMessageData.data.reverse()
|
|
|
|
|
+ .map((message: any) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: message.id,
|
|
|
|
|
+ content: message.content[0].text.value,
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- setAssistantMessage(messages);
|
|
|
|
|
- setUserMessage('');
|
|
|
|
|
|
|
+ setMessages(msgs => [...msgs, ...newMessages]);
|
|
|
|
|
+ setThreadId(assistantMessageData.data[0].threadId);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
|
- //
|
|
|
|
|
|
|
+ logger.error(err.toString());
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -38,19 +64,21 @@ const RagSearchModal = (): JSX.Element => {
|
|
|
GROWI Assistant
|
|
GROWI Assistant
|
|
|
</ModalHeader>
|
|
</ModalHeader>
|
|
|
|
|
|
|
|
- <p>
|
|
|
|
|
- { assistantMessage }
|
|
|
|
|
- </p>
|
|
|
|
|
|
|
+ <div className="vstack gap-4">
|
|
|
|
|
+ { messages.map(message => (
|
|
|
|
|
+ <MessageCard key={message.id} right={message.isUserMessage}>{message.content}</MessageCard>
|
|
|
|
|
+ )) }
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <div className="input-group mb-2">
|
|
|
|
|
|
|
+ <div className="input-group mt-5">
|
|
|
<input
|
|
<input
|
|
|
type="text"
|
|
type="text"
|
|
|
className="form-control"
|
|
className="form-control"
|
|
|
placeholder="お手伝いできることはありますか?"
|
|
placeholder="お手伝いできることはありますか?"
|
|
|
aria-label="Recipient's username"
|
|
aria-label="Recipient's username"
|
|
|
aria-describedby="button-addon2"
|
|
aria-describedby="button-addon2"
|
|
|
- value={userMessage}
|
|
|
|
|
- onChange={e => setUserMessage(e.target.value)}
|
|
|
|
|
|
|
+ value={input}
|
|
|
|
|
+ onChange={e => setInput(e.target.value)}
|
|
|
/>
|
|
/>
|
|
|
<button
|
|
<button
|
|
|
type="button"
|
|
type="button"
|