Spaces:
Paused
Paused
File size: 4,102 Bytes
872630d 85388fa 872630d |
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 |
"use client";
import { FormEvent, useEffect, useRef, useState } from 'react';
import { FileLoader } from '../components/FileLoader';
import styles from './page.module.css';
import { useChat } from 'ai/react';
const Home: React.FC = () => {
// eslint-disable-next-line no-unused-vars
const [isWorkerLoading, setIsWorkerLoading] = useState(false);
const [searchInProgress, setSearchInProgress] = useState(false);
const [searchIsLoading, setIsLoading] = useState(false);
const [fileText, setFileText] = useState<string>('');
const embeddingsWorkerRef = useRef<Worker | null>(null);
const { isLoading, messages, input, handleInputChange, handleSubmit } = useChat();
useEffect(() => {
if (typeof window === 'undefined') return;
const EmbeddingsWorker = require('worker-loader!../components/embeddingsWorker.js').default;
embeddingsWorkerRef.current = new EmbeddingsWorker();
return () => {
embeddingsWorkerRef.current?.terminate();
};
}, []);
useEffect(() => {
if (fileText && embeddingsWorkerRef.current) {
embeddingsWorkerRef.current.postMessage({
action: 'addDocumentsToStore',
documents: [fileText]
});
}
}, [fileText]);
const handleSearch = () => {
return new Promise((resolve) => {
const handleMessage = (event: any) => {
if (event.data.action === 'searchResults') {
embeddingsWorkerRef.current?.removeEventListener('message', handleMessage);
setSearchInProgress(false);
resolve(event.data.results);
}
};
embeddingsWorkerRef.current?.addEventListener('message', handleMessage);
embeddingsWorkerRef.current?.postMessage({
action: 'searchSimilarDocuments',
query: input,
topK: 5
});
});
};
const modifiedHandleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (input.trim() === '' || searchInProgress) {
return; // Prevent empty submissions or when a search is already in progress
}
setSearchInProgress(true);
try {
const results = await handleSearch();
const serializedResults = JSON.stringify(results);
const chatRequestOptions = {
data: { vectorStoreResults: serializedResults },
};
handleSubmit(e, chatRequestOptions);
} catch (error) {
console.error('Error during search:', error);
setSearchInProgress(false);
}
};
return (
<main className={styles.main}>
<div className={styles.description}>
<p>
Upload a PDF to start the analysis.
</p>
<FileLoader setFileText={setFileText} />
</div>
{fileText && (
<div className={styles.center}>
<p>Processed Text Complete</p>
</div>
)}
{isLoading || searchIsLoading && (
<div className={styles.spinner}>
<div>...</div>
</div>
)}
<div className={styles.chatContainer}>
<div className={styles.messagesContainer}>
{messages.map(m => (
<div key={m.id} className={m.role === 'user' ? styles.userMessage : styles.aiMessage}>
<span className={styles.messageRole}>{m.role === 'user' ? 'You: ' : 'AI: '}</span>
<span className={styles.messageContent}>{m.content}</span>
</div>
))}
</div>
<form onSubmit={modifiedHandleSubmit} className={styles.chatForm}>
<input
className={styles.chatInput}
value={input}
onChange={handleInputChange}
placeholder="Say something..."
/>
{(searchInProgress || isLoading) ? <button type="submit" disabled={true} className={styles.sendButton}>Loading</button> : <button type="submit" className={styles.sendButton}>Send</button>}
</form>
</div>
</main>
);
}
export default Home;
|