aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/DocumentTypes.ts1
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/views/nodes/ChatBox/ChatBox.tsx36
-rw-r--r--src/client/views/nodes/ChatBox/MessageComponent.tsx33
-rw-r--r--src/client/views/nodes/ChatBox/tools/CollectionTool.ts0
-rw-r--r--src/client/views/nodes/ChatBox/tools/RAGTool.ts9
-rw-r--r--src/client/views/nodes/ChatBox/vectorstore/VectorstoreUpload.ts45
7 files changed, 95 insertions, 34 deletions
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 8f95068db..cb1625381 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -28,6 +28,7 @@ export enum DocumentType {
DATAVIZ = 'dataviz',
LOADING = 'loading',
SIMULATION = 'simulation', // physics simulation
+ MESSAGE = 'message', // chat message
// special purpose wrappers that either take no data or are compositions of lower level types
LINK = 'link',
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index a67e6b4f6..ea5eca804 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -791,6 +791,11 @@ export namespace Docs {
export function RTFDocument(field: RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') {
return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey);
}
+
+ export function MessageDocument(field: string, options: DocumentOptions = {}, fieldKey: string = 'data') {
+ return InstanceFromProto(Prototypes.get(DocumentType.MESSAGE), field, options, undefined, fieldKey);
+ }
+
export function TextDocument(text: string, options: DocumentOptions = {}, fieldKey: string = 'text') {
const rtf = {
doc: {
diff --git a/src/client/views/nodes/ChatBox/ChatBox.tsx b/src/client/views/nodes/ChatBox/ChatBox.tsx
index 64ab2888b..9b2a92564 100644
--- a/src/client/views/nodes/ChatBox/ChatBox.tsx
+++ b/src/client/views/nodes/ChatBox/ChatBox.tsx
@@ -11,7 +11,7 @@ import { LinkManager } from '../../../util/LinkManager';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
import './ChatBox.scss';
-import MessageComponent from './MessageComponent';
+import MessageComponentBox from './MessageComponent';
import { ASSISTANT_ROLE, AssistantMessage, AI_Document, convertToAIDocument, Citation } from './types';
import { Vectorstore } from './vectorstore/VectorstoreUpload';
import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView';
@@ -19,6 +19,7 @@ import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
import { Agent } from './Agent';
import dotenv from 'dotenv';
import { DocData } from '../../../../fields/DocSymbols';
+import { DocumentView } from '../DocumentView';
dotenv.config();
@observer
@@ -33,7 +34,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@observable inputValue: string = '';
@observable private _visibleDocs: Doc[] = [];
private openai: OpenAI;
- private vectorstore_id: string;
+ // private vectorstore_id: string;
private documents: AI_Document[] = [];
private _oldWheel: any;
private vectorstore: Vectorstore;
@@ -61,22 +62,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
@action
- addAIDocs = async (visible_docs: Doc[]) => {
- console.log('All Docs:', visible_docs);
- visible_docs?.forEach(async doc => {
- if (doc[DocData].ai_document) {
- this.documents.push(convertToAIDocument(JSON.parse(StrCast(doc[DocData].ai_document))));
- } else {
- const local_file_path: string = CsvCast(doc.data, PDFCast(doc.data))?.url?.pathname;
- if (local_file_path) {
- const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
- const ai_document: AI_Document = convertToAIDocument(document_json);
- this.documents.push(ai_document);
- await this.vectorstore.addDocument(ai_document);
- doc[DocData].ai_document = JSON.stringify(document_json);
- }
- }
- });
+ addDocsToVectorstore = async (visible_docs: Doc[]) => {
+ await this.vectorstore.addAIDocs(visible_docs);
this.isInitializing = false;
};
@@ -107,6 +94,10 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
};
+ // getAssistantResponse() {
+ // return Docs.Create.MessageDocument(text, {});
+ // }
+
@action
askGPT = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
event.preventDefault();
@@ -241,7 +232,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
reaction(
() => this.visibleDocs,
visibleDocs => {
- this._visibleDocs = visibleDocs;
+ this._visibleDocs.push(...visibleDocs.filter(visibleDoc => !this._visibleDocs.includes(visibleDoc)));
}
);
observe(
@@ -255,7 +246,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
if ((change as any).addedCount > 0) {
// maybe check here if its already in the urls datadoc array so doesn't add twice
console.log((change as any).added as Doc[]);
- this.addAIDocs((change as any).added as Doc[]);
+ this.addDocsToVectorstore((change as any).added as Doc[]);
}
// (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
break;
@@ -295,10 +286,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}}>
<div className="messages">
{this.history.map((message, index) => (
- <MessageComponent key={index} message={message} index={index} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
+ //<DocumentView key={index} Document={message} index={index} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
+ <MessageComponentBox key={index} message={message} index={index} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
))}
{this.current_message && (
- <MessageComponent
+ <MessageComponentBox
key={this.history.length}
message={this.current_message}
index={this.history.length}
diff --git a/src/client/views/nodes/ChatBox/MessageComponent.tsx b/src/client/views/nodes/ChatBox/MessageComponent.tsx
index 91671a24a..38faf7e00 100644
--- a/src/client/views/nodes/ChatBox/MessageComponent.tsx
+++ b/src/client/views/nodes/ChatBox/MessageComponent.tsx
@@ -2,6 +2,8 @@ import React from 'react';
import { observer } from 'mobx-react';
import { AssistantMessage, CHUNK_TYPE, Citation } from './types';
import { TbInfoCircleFilled } from 'react-icons/tb';
+import { Docs } from '../../../documents/Documents';
+import { DocumentType } from '../../../documents/DocumentTypes';
interface MessageComponentProps {
message: AssistantMessage;
@@ -11,7 +13,18 @@ interface MessageComponentProps {
updateMessageCitations: (index: number, citations: Citation[]) => void;
}
-const MessageComponent: React.FC<MessageComponentProps> = function ({ message, index, onFollowUpClick, onCitationClick, updateMessageCitations }) {
+const MessageComponentBox: React.FC<MessageComponentProps> = function ({ message, index, onFollowUpClick, onCitationClick, updateMessageCitations }) {
+ // public static LayoutString(fieldKey: string) {
+ // return FieldView.LayoutString(MessageComponentBox, fieldKey);
+ // }
+
+ // the presentation view that renders this slide
+
+ // @computed
+ // get chatBoxView() {
+ // return this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as ChatBox;
+ // }
+
const renderContent = (text: string) => {
const citationRegex = /<citation chunk_id="([^"]*)" type="([^"]*)">([^<]*)<\/citation>/g;
const parts = [];
@@ -68,4 +81,20 @@ const MessageComponent: React.FC<MessageComponentProps> = function ({ message, i
);
};
-export default observer(MessageComponent);
+// Docs.Prototypes.TemplateMap.set(DocumentType.MESSAGE, {
+// layout: { view: MessageComponentBox, dataField: 'data' },
+// options: {
+// acl: '',
+// _height: 35,
+// _xMargin: 10,
+// _yMargin: 10,
+// _layout_nativeDimEditable: true,
+// _layout_reflowVertical: true,
+// _layout_reflowHorizontal: true,
+// defaultDoubleClick: 'ignore',
+// systemIcon: 'BsFileEarmarkTextFill',
+// layout_borderRounding: '10px',
+// },
+// });
+
+export default observer(MessageComponentBox);
diff --git a/src/client/views/nodes/ChatBox/tools/CollectionTool.ts b/src/client/views/nodes/ChatBox/tools/CollectionTool.ts
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/client/views/nodes/ChatBox/tools/CollectionTool.ts
diff --git a/src/client/views/nodes/ChatBox/tools/RAGTool.ts b/src/client/views/nodes/ChatBox/tools/RAGTool.ts
index 185efa0ba..36e4bc3ce 100644
--- a/src/client/views/nodes/ChatBox/tools/RAGTool.ts
+++ b/src/client/views/nodes/ChatBox/tools/RAGTool.ts
@@ -39,6 +39,7 @@ export class RAGTool extends BaseTool<{ hypothetical_document_chunk: string }> {
!!!IMPORTANT Before you close the tag with </answer>, within the answer tags provide a set of 3 follow-up questions inside a <follow_up_questions> tag and individually within <question> tags. These should relate to the document, the current query, and the chat_history and should aim to help the user better understand whatever they are looking for.
Also, ensure that the answer tags are wrapped with the correct step tags as well.`,
+
`Performs a RAG (Retrieval-Augmented Generation) search on user documents and returns a
set of document chunks (either images or text) that can be used to provide a grounded response based on
user documents
@@ -49,6 +50,14 @@ export class RAGTool extends BaseTool<{ hypothetical_document_chunk: string }> {
);
}
+ changeSummaries(summaries: string) {
+ this.briefSummary = `Performs a RAG (Retrieval-Augmented Generation) search on user documents and returns a set of document chunks (either images or text) that can be used to provide a grounded response based on user documents.
+
+!!!IMPORTANT Use the RAG tool ANYTIME the question may potentially (even if you are not sure) relate to one of the user's documents.
+Here are the summaries of the user's documents:
+${summaries}`;
+ }
+
async execute(args: { hypothetical_document_chunk: string }): Promise<any> {
const relevantChunks = await this.vectorstore.retrieve(args.hypothetical_document_chunk);
return this.getFormattedChunks(relevantChunks);
diff --git a/src/client/views/nodes/ChatBox/vectorstore/VectorstoreUpload.ts b/src/client/views/nodes/ChatBox/vectorstore/VectorstoreUpload.ts
index 1f483ad61..5e8e6b23a 100644
--- a/src/client/views/nodes/ChatBox/vectorstore/VectorstoreUpload.ts
+++ b/src/client/views/nodes/ChatBox/vectorstore/VectorstoreUpload.ts
@@ -3,7 +3,11 @@ import { CohereClient } from 'cohere-ai';
import { EmbedResponse } from 'cohere-ai/api';
import dotenv from 'dotenv';
-import { Chunk, AI_Document } from '../types';
+import { Chunk, AI_Document, convertToAIDocument } from '../types';
+import { Doc } from '../../../../../fields/Doc';
+import { DocData } from '../../../../../fields/DocSymbols';
+import { CsvCast, PDFCast, StrCast } from '../../../../../fields/Types';
+import { Networking } from '../../../../Network';
dotenv.config();
@@ -12,7 +16,7 @@ export class Vectorstore {
private index!: Index;
private cohere: CohereClient;
private indexName: string = 'pdf-chatbot';
- private documents: AI_Document[] = [];
+ documents: AI_Document[] = [];
constructor() {
const pineconeApiKey = process.env.PINECONE_API_KEY;
@@ -49,10 +53,35 @@ export class Vectorstore {
this.index = this.pinecone.Index(this.indexName);
}
- async addDocument(document: AI_Document) {
- this.documents.push(document);
- await this.indexDocument(document);
- console.log(`Document added: ${document.file_name}`);
+ async addAIDocs(visible_docs: Doc[]) {
+ console.log('All Docs:', visible_docs);
+ visible_docs?.forEach(async doc => {
+ await this.addAIDoc(doc);
+ });
+ }
+
+ async addAIDoc(doc: Doc) {
+ if (doc[DocData]?.ai_document) {
+ this.documents.push(convertToAIDocument(JSON.parse(StrCast(doc[DocData].ai_document))));
+ console.log(`Document already added: ${doc[DocData].file_name}`);
+ } else {
+ console.log(doc);
+ const local_file_path: string = CsvCast(doc.data)?.url?.pathname ?? PDFCast(doc.data)?.url?.pathname;
+ console.log('Local File Path:', local_file_path);
+ if (local_file_path) {
+ const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
+ console.log('Document JSON:', document_json);
+ const ai_document: AI_Document = convertToAIDocument(document_json);
+ this.documents.push(ai_document);
+ await this.indexDocument(ai_document);
+ console.log(`Document added: ${ai_document.file_name}`);
+ doc[DocData].ai_document = JSON.stringify(document_json);
+ }
+ }
+ }
+
+ getSummaries(): string {
+ return this.documents.map((doc, index) => `${index + 1}) ${doc.summary}`).join('\n') + '\n';
}
private async indexDocument(document: AI_Document) {
@@ -111,8 +140,4 @@ export class Vectorstore {
return [];
}
}
-
- getSummaries(): string {
- return this.documents.map((doc, index) => `${index + 1}) ${doc.summary}`).join('\n') + '\n';
- }
}