From 97fdb44133c6aed043f84fd345d5ac57125e5405 Mon Sep 17 00:00:00 2001
From: "A.J. Shulman" <Shulman.aj@gmail.com>
Date: Mon, 15 Jul 2024 13:47:39 -0400
Subject: attempt at adding links

---
 src/client/views/nodes/ChatBox/ChatBox.tsx | 80 +++++++++++++++++++-----------
 1 file changed, 52 insertions(+), 28 deletions(-)

(limited to 'src/client/views/nodes/ChatBox/ChatBox.tsx')

diff --git a/src/client/views/nodes/ChatBox/ChatBox.tsx b/src/client/views/nodes/ChatBox/ChatBox.tsx
index bae6bbaa6..4d7381a57 100644
--- a/src/client/views/nodes/ChatBox/ChatBox.tsx
+++ b/src/client/views/nodes/ChatBox/ChatBox.tsx
@@ -12,15 +12,20 @@ import { ViewBoxAnnotatableComponent } from '../../DocComponent';
 import { FieldView, FieldViewProps } from '../FieldView';
 import './ChatBox.scss';
 import MessageComponentBox from './MessageComponent';
-import { ASSISTANT_ROLE, AssistantMessage, AI_Document, convertToAIDocument, Citation, CHUNK_TYPE } from './types';
+import { ASSISTANT_ROLE, AssistantMessage, AI_Document, convertToAIDocument, Citation, CHUNK_TYPE, Chunk, getChunkType } from './types';
 import { Vectorstore } from './vectorstore/VectorstoreUpload';
 import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView';
 import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
 import { Agent } from './Agent';
 import dotenv from 'dotenv';
-import { DocData } from '../../../../fields/DocSymbols';
+import { DocData, DocViews } from '../../../../fields/DocSymbols';
 import { DocumentView } from '../DocumentView';
 import { AnswerParser } from './AnswerParser';
+import { DocumentManager } from '../../../util/DocumentManager';
+import { UUID } from 'bson';
+import { v4 as uuidv4 } from 'uuid';
+import { aS } from '@fullcalendar/core/internal-common';
+
 dotenv.config();
 
 @observer
@@ -31,11 +36,10 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @observable isLoading: boolean = false;
     @observable isInitializing: boolean = true;
     @observable expandedScratchpadIndex: number | null = null;
-    @observable linked_docs_to_add: Doc[] = [];
     @observable inputValue: string = '';
-    @observable private _visibleDocs: Doc[] = [];
+    @observable private currently_linked: Doc[] = [];
     private openai: OpenAI;
-    // private vectorstore_id: string;
+    private vectorstore_id: string;
     private documents: AI_Document[] = [];
     private _oldWheel: any;
     private vectorstore: Vectorstore;
@@ -50,9 +54,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         makeObservable(this);
         this.history = [{ role: ASSISTANT_ROLE.ASSISTANT, text_content: 'Welcome to the Document Analyser Assistant! Link a document or ask questions to get started.' }];
         this.openai = this.initializeOpenAI();
-        this.vectorstore = new Vectorstore();
+        if (StrCast(this.dataDoc.vectorstore_id) == '') {
+            this.vectorstore_id = uuidv4();
+            this.dataDoc.vectorstore_id = this.vectorstore_id;
+        } else {
+            this.vectorstore_id = StrCast(this.dataDoc.vectorstore_id);
+        }
+        this.vectorstore = new Vectorstore(this.vectorstore_id);
         this.agent = new Agent(this.vectorstore); // Initialize the Agent
-
         reaction(
             () => this.history.map((msg: AssistantMessage) => ({ role: msg.role, text_content: msg.text_content, follow_up_questions: msg.follow_up_questions, citations: msg.citations })),
             serializableHistory => {
@@ -61,19 +70,17 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         );
     }
 
-    @action
-    addDocsToVectorstore = async (visible_docs: Doc[]) => {
-        await this.vectorstore.addAIDocs(visible_docs);
-        this.isInitializing = false;
+    addDocsToVectorstore = async (linkedDocs: Doc[]) => {
+        await this.vectorstore.addAIDocs(linkedDocs);
     };
 
-    @action
-    uploadNewDocument = async (newDoc: Doc) => {
-        const local_file_path: string = CsvCast(newDoc.data, PDFCast(newDoc.data)).url.pathname;
-        const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
-        this.documents.push(...document_json.map(convertToAIDocument));
-        newDoc['ai_document'] = document_json;
-    };
+    // @action
+    // uploadNewDocument = async (newDoc: Doc) => {
+    //     const local_file_path: string = CsvCast(newDoc.data, PDFCast(newDoc.data)).url.pathname;
+    //     const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
+    //     this.documents.push(...document_json.map(convertToAIDocument));
+    //     //newDoc['ai_document'] = document_json;
+    // };
 
     @action
     toggleToolLogs = (index: number) => {
@@ -142,6 +149,24 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @action
     handleCitationClick = (citation: Citation) => {
         console.log('Citation clicked:', citation);
+        const currentLinkedDocs: Doc[] = this.linkedDocs;
+        const chunk_id = citation.chunk_id;
+        for (let doc of currentLinkedDocs) {
+            const doc_chunks: Chunk[] = JSON.parse(StrCast(doc.ai_document)).chunks;
+            const chunk_file_name = doc_chunks.find(chunk => chunk.id === chunk_id)?.metadata.file_path;
+            const doc_url = CsvCast(doc.data, PDFCast(doc.data)).url.pathname;
+            console.log('URL: ' + doc_url + ' Citation URL: ' + chunk_file_name);
+            //const ai_field_id = doc[this.Document[Id] + '_ai_field_id'];
+            if (chunk_file_name == doc_url) {
+                DocumentManager.Instance.showDocument(doc, {}, () => {
+                    console.log(doc.data);
+                    //look at context path for each docview and choose the doc view that has as
+                    //its parent the same collection view the chatbox is in
+                    const first_view = Array.from(doc[DocViews])[0];
+                    first_view.ComponentView?.search?.(citation.direct_text);
+                });
+            }
+        }
         // You can implement additional functionality here, such as showing a modal with the full citation content
     };
 
@@ -183,6 +208,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     componentDidMount() {
         this._props.setContentViewBox?.(this);
+        this.currently_linked = this.linkedDocs;
         if (this.dataDoc.data) {
             try {
                 const storedHistory = JSON.parse(StrCast(this.dataDoc.data));
@@ -201,15 +227,15 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             }
         }
         reaction(
-            () => this.visibleDocs,
-            visibleDocs => {
-                this._visibleDocs.push(...visibleDocs.filter(visibleDoc => !this._visibleDocs.includes(visibleDoc)));
+            () => this.linkedDocs,
+            linkedDocs => {
+                this.currently_linked.push(...linkedDocs.filter(linkedDoc => !this.currently_linked.includes(linkedDoc)));
             }
         );
         observe(
             // right now this skips during initialization which is necessary because it would be blank
             // However, it will upload the same link twice when it is
-            this._visibleDocs,
+            this.currently_linked,
             change => {
                 // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
                 switch (change.type as any) {
@@ -228,15 +254,13 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             },
             true
         );
-        runInAction(() => {
-            if (!this._visibleDocs.length) {
-                this.isInitializing = false;
-            }
-        });
+        if (this.isInitializing) {
+            this.isInitializing = false;
+        }
     }
 
     @computed
-    get visibleDocs() {
+    get linkedDocs() {
         //return (CollectionFreeFormDocumentView.from(this._props.DocumentView?.())?._props.parent as CollectionFreeFormView)?.childDocs.filter(doc => doc != this.Document) ?? [];
         return LinkManager.Instance.getAllRelatedLinks(this.Document)
             .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
-- 
cgit v1.2.3-70-g09d2

