Spaces:
Runtime error
Runtime error
File size: 6,004 Bytes
ed9ee96 ed45bdf b801bb1 ed9ee96 5d239ba f373356 36355a5 6aff6a4 36355a5 c79b0f3 ed9ee96 70ff588 5d239ba ed45bdf 287282f ed9ee96 a942b58 70ff588 a942b58 fe0c091 1300e36 f373356 1300e36 f373356 70ff588 f373356 81c1854 70ff588 81c1854 fe0c091 f373356 fe0c091 81c1854 f1b879c 81c1854 ed9ee96 5d239ba ed9ee96 fe0c091 287282f 6aff6a4 fe0c091 287282f fe0c091 f1b879c fe0c091 f1b879c 5d239ba f1b879c ed9ee96 ed45bdf 22ff301 ed45bdf ed9ee96 36355a5 c79b0f3 ed9ee96 c79b0f3 ed9ee96 b801bb1 ed9ee96 36355a5 b801bb1 c79b0f3 ed9ee96 36355a5 ed9ee96 6aff6a4 ed9ee96 287282f ed9ee96 c79b0f3 5d239ba a942b58 b801bb1 ed9ee96 d5151b8 ed9ee96 36355a5 ed9ee96 |
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
import useLLM from "@react-llm/headless";
import Image from "next/image";
import { useCallback, useEffect, useState } from "react";
import MessageList from './MessageList';
import {FileLoader} from './FileLoader';
import Loader from "./Loader";
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { XenovaTransformersEmbeddings } from '../embed/hf';
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { SEND_MESSAGE } from '../utils'
import {
Button,
TextInput,
} from "react95";
function ChatWindow({
stopStrings,
maxTokens,
}) {
const { loadingStatus, send, isGenerating, deleteMessages } = useLLM();
const [fileText, setFileText] = useState();
const [userInput, setUserInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const handleChange = (event) => {
setUserInput(event.target.value);
};
const isReady = loadingStatus.progress === 1;
const handleClearChat = () => {
deleteMessages();
}
const handleClearFile = () => {
setFileText(null);
}
const qaHandler = async (fileText, userInput) => {
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await textSplitter.createDocuments([fileText]);
let qaPrompt;
try {
const vectorStore = await MemoryVectorStore.fromTexts(
[...docs.map(doc => doc.pageContent)],
[...docs.map((v, k) => k)],
new XenovaTransformersEmbeddings()
)
const queryResult = await vectorStore.similaritySearch(userInput, 2);
qaPrompt =
`You are an AI assistant providing helpful advice. You are given the following extracted parts of a long document and a question. Provide a conversational answer based on the context provided.
You should only provide hyperlinks that reference the context below. Do NOT make up hyperlinks.
If you can't find the answer in the context below, just say "Hmm, I'm not sure." Don't try to make up an answer.
If the question is not related to the context, politely respond that you are tuned to only answer questions that are related to the context.
Question: ${userInput}
=========
${queryResult.map(result => result.pageContent).join('')}
=========
Answer:
`
return qaPrompt;
} catch (err) {
console.log(err);
}
}
const handleSubmit = useCallback(async () => {
if (isGenerating || !isReady) {
return;
}
if (fileText) {
const qaPrompt = await qaHandler(fileText, userInput);
send(qaPrompt, maxTokens, stopStrings);
} else {
send(userInput, maxTokens, stopStrings);
}
setUserInput("");
}, [
userInput,
send,
isGenerating,
isReady,
maxTokens,
stopStrings,
fileText
]);
useEffect(() => {
const handleKeyPress = (event) => {
if (event.key === "Enter") {
event.preventDefault();
handleSubmit();
}
};
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleSubmit]);
const loadFile = async (fileText) => {
console.log('file loaded, demo mode');
if (fileText) {
setIsLoading(true);
const qaPrompt = await qaHandler(fileText, "Based on the context provide a summary of the document as a helpful assistant");
send(qaPrompt, maxTokens, stopStrings);
setIsLoading(false);
}
}
useEffect(() => {
loadFile(fileText);
}, [fileText])
return (
<div className="window sm:w-[500px] w-full">
<div className="window-content w-full">
<div className="flex flex-col w-full">
<MessageList
screenName={"me"}
assistantScreenName={"vicuna"}
/>
{/* <Separator /> */}
<div className="h-4" />
{isReady && (
<div>
<form onSubmit={handleSubmit}>
<div className="flex" style={{ color: 'white', textarea: { color: 'white' } }}>
<TextInput
value={userInput}
placeholder="Say something..."
onChange={handleChange}
fullWidth
multiline
rows={3}
/>
</div>
</form>
<div className="flex justify-start m-2">
<div>
<Button
onClick={handleSubmit}
className="submit"
style={{ backgroundColor: "black", height: "65px", width: "65px", float: "right" }}
>
<Image
src={SEND_MESSAGE}
alt="Send Message"
style={{
filter:
!isReady || isGenerating || isLoading
? "grayscale(100%)"
: undefined,
}}
width="40"
height="40"
/>
</Button>
<FileLoader setFileText={setFileText} />
<Button onClick={handleClearChat}>Clear Chat</Button>
</div>
<div
className="w-full h-1 mt-2"
style={{
backgroundColor:
!isReady || isGenerating ? "gray" : "green",
width: "100%",
height: "5px",
marginTop: "2px",
}}
></div>
</div>
</div>
)}
{!isReady && <Loader />}
</div>
</div>
</div>
);
}
export default ChatWindow; |