From 9983e5602ce18d771180b5c28d0ef78c71ef89e3 Mon Sep 17 00:00:00 2001 From: "A.J. Shulman" Date: Mon, 2 Sep 2024 14:32:14 -0400 Subject: added loading animation --- src/client/views/nodes/ChatBox/ChatBox.tsx | 28 ++++----- .../views/nodes/ChatBox/vectorstore/Vectorstore.ts | 34 +++++++---- src/server/ApiManagers/AssistantManager.ts | 71 ++++++++++++---------- 3 files changed, 70 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ChatBox/ChatBox.tsx b/src/client/views/nodes/ChatBox/ChatBox.tsx index 7e238e28b..fdc0e3a17 100644 --- a/src/client/views/nodes/ChatBox/ChatBox.tsx +++ b/src/client/views/nodes/ChatBox/ChatBox.tsx @@ -33,13 +33,13 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { @observable.deep current_message: AssistantMessage | undefined = undefined; @observable isLoading: boolean = false; - @observable isUploadingDocs: boolean = false; @observable uploadProgress: number = 0; // Track progress percentage @observable currentStep: string = ''; // Track current step name @observable expandedScratchpadIndex: number | null = null; @observable inputValue: string = ''; @observable private linked_docs_to_add: ObservableSet = observable.set(); @observable private linked_csv_files: { filename: string; id: string; text: string }[] = []; + @observable private isUploadingDocs: boolean = false; private openai: OpenAI; private vectorstore_id: string; private vectorstore: Vectorstore; @@ -76,21 +76,25 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { @action addDocToVectorstore = async (newLinkedDoc: Doc) => { - this.isUploadingDocs = true; this.uploadProgress = 0; this.currentStep = 'Initializing...'; + this.isUploadingDocs = true; - await this.vectorstore.addAIDoc(newLinkedDoc, this.updateProgress); - - runInAction(() => { + try { + await this.vectorstore.addAIDoc(newLinkedDoc, this.updateProgress); + } catch (error) { + console.error('Error uploading document:', error); + this.currentStep = 'Error during upload'; + } finally { this.isUploadingDocs = false; this.uploadProgress = 0; this.currentStep = ''; - }); + } }; @action updateProgress = (progress: number, step: string) => { + console.log('Progress:', progress, step); this.uploadProgress = progress; this.currentStep = step; }; @@ -394,17 +398,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { observe(this.linked_docs_to_add, change => { if (change.type === 'add') { - runInAction(() => { - this.isUploadingDocs = true; - }); if (PDFCast(change.newValue.data)) { this.addDocToVectorstore(change.newValue); } else if (CsvCast(change.newValue.data)) { this.addCSVForAnalysis(change.newValue); } - runInAction(() => { - this.isUploadingDocs = false; - }); } else if (change.type === 'delete') { console.log('Deleted docs: ', change.oldValue); } @@ -495,6 +493,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { console.log('Follow-up question clicked:', question); this.inputValue = question; }; + render() { return (
@@ -506,11 +505,6 @@ export class ChatBox extends ViewBoxAnnotatableComponent() {
)} - {this.isUploadingDocs && ( -
-
-
- )}

{this.userName()}'s AI Assistant

diff --git a/src/client/views/nodes/ChatBox/vectorstore/Vectorstore.ts b/src/client/views/nodes/ChatBox/vectorstore/Vectorstore.ts index 388574bff..408274703 100644 --- a/src/client/views/nodes/ChatBox/vectorstore/Vectorstore.ts +++ b/src/client/views/nodes/ChatBox/vectorstore/Vectorstore.ts @@ -77,27 +77,35 @@ export class Vectorstore { console.log('Local File Path:', local_file_path); if (local_file_path) { + console.log('Creating AI Document...'); // Start the document creation process - const response = await Networking.PostToServer('/createDocument', { file_path: local_file_path }); - const jobId = response.job_id; + const { jobId } = await Networking.PostToServer('/createDocument', { file_path: local_file_path }); // Poll the server for progress updates + let inProgress: boolean = true; let result: any = null; + while (inProgress) { + await new Promise(resolve => setTimeout(resolve, 2000)); // Polling interval + + const resultResponse = await Networking.FetchFromServer(`/getResult/${jobId}`); + const resultResponseJson = JSON.parse(resultResponse); + //console.log('Result Response:', resultResponseJson); + if (resultResponseJson.status === 'completed') { + console.log('Result here:', resultResponseJson); + result = resultResponseJson; + break; + } - while (!result) { - await new Promise(resolve => setTimeout(resolve, 5000)); // Polling interval + const progressResponse = await Networking.FetchFromServer(`/getProgress/${jobId}`); + const progressResponseJson = JSON.parse(progressResponse); + //console.log('Progress Response:', progressResponseJson); - const progressResponse = JSON.parse(await Networking.FetchFromServer(`/getProgress/${jobId}`)); - if (progressResponse) { - const progress = progressResponse.progress; - const step = progressResponse.step; + if (progressResponseJson) { + console.log('Progress:', progressResponseJson); + const progress = progressResponseJson.progress; + const step = progressResponseJson.step; progressCallback(progress, step); } - - const resultResponse = JSON.parse(await Networking.FetchFromServer(`/getResult/${jobId}`)); - if (resultResponse.status === 200) { - result = resultResponse.data; - } } // Process the final document result diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts index 54d78cd15..2ffc99e58 100644 --- a/src/server/ApiManagers/AssistantManager.ts +++ b/src/server/ApiManagers/AssistantManager.ts @@ -204,23 +204,42 @@ export default class AssistantManager extends ApiManager { } ); - const jobId = response.data.job_id; + const jobId = response.data['job_id']; + console.log('Job ID:', jobId); - let progress; - let result; - while (!result) { - await new Promise(resolve => setTimeout(resolve, 5000)); // Wait for 5 seconds - const progressResponse = await axios.get(`http://localhost:8080/getProgress/${jobId}`); - const progress = progressResponse.data; + res.send({ jobId }); + } catch (error: any) { + console.error('Error communicating with chatbot:', error); + res.status(500).send({ error: 'Failed to communicate with the chatbot', details: error.message }); + } + }, + }); - // Accessing the correct keys - console.log(`Current step: ${progress.step}, Progress within step: ${progress.progress}%`); + register({ + method: Method.GET, + subscription: '/getProgress/:jobId', + secureHandler: async ({ req, res }) => { + const { jobId } = req.params; + try { + const progressResponse = await axios.get(`http://localhost:8080/getProgress/${jobId}`); + console.log(`Current step: ${progressResponse.data.step}, Progress within step: ${progressResponse.data.progress}%`); + res.json(progressResponse.data); + } catch (error) { + console.error('Error getting progress:', error); + res.status(500).send({ error: 'Failed to get progress', details: JSON.parse(error as string).message }); + } + }, + }); - const resultResponse = await axios.get(`http://localhost:8080/getResult/${jobId}`); - if (resultResponse.status === 200) { - result = resultResponse.data; - } - } + register({ + method: Method.GET, + subscription: '/getResult/:jobId', + secureHandler: async ({ req, res }) => { + const { jobId } = req.params; + try { + const finalResponse = await axios.get(`http://localhost:8080/getResult/${jobId}`); + console.log('Result:', finalResponse.data); + const result = finalResponse.data; if (result.chunks && Array.isArray(result.chunks)) { for (const chunk of result.chunks) { @@ -249,29 +268,15 @@ export default class AssistantManager extends ApiManager { } } } + result['status'] = 'completed'; } else { - console.warn("Result does not contain an iterable 'chunks' property"); + console.warn('Not ready'); + result.status = 'pending'; } - - res.send({ document_json: result }); - } catch (error: any) { - console.error('Error communicating with chatbot:', error); - res.status(500).send({ error: 'Failed to communicate with the chatbot', details: error.message }); - } - }, - }); - - register({ - method: Method.GET, - subscription: '/getProgress/:jobId', - secureHandler: async ({ req, res }) => { - const { jobId } = req.params; - try { - const progressResponse = await axios.get(`http://localhost:8080/getProgress/${jobId}`); - res.json(progressResponse.data); + res.json(result); } catch (error) { console.error('Error getting progress:', error); - res.status(500).send({ error: 'Failed to get progress', details: JSON.parse(error as string).message }); + res.status(500).send({ error: 'Failed to get progress', details: error }); } }, }); -- cgit v1.2.3-70-g09d2