aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/chatbot/agentsystem/Agent.ts15
-rw-r--r--src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx472
2 files changed, 203 insertions, 284 deletions
diff --git a/src/client/views/nodes/chatbot/agentsystem/Agent.ts b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
index a2a575f19..4d3f1e4e7 100644
--- a/src/client/views/nodes/chatbot/agentsystem/Agent.ts
+++ b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
@@ -1,25 +1,22 @@
import dotenv from 'dotenv';
import { XMLBuilder, XMLParser } from 'fast-xml-parser';
+import { escape } from 'lodash'; // Imported escape from lodash
import OpenAI from 'openai';
import { ChatCompletionMessageParam } from 'openai/resources';
-import { escape } from 'lodash'; // Imported escape from lodash
+import { DocumentOptions } from '../../../../documents/Documents';
import { AnswerParser } from '../response_parsers/AnswerParser';
import { StreamedAnswerParser } from '../response_parsers/StreamedAnswerParser';
+import { BaseTool } from '../tools/BaseTool';
import { CalculateTool } from '../tools/CalculateTool';
-import { CreateCSVTool } from '../tools/CreateCSVTool';
+import { CreateAnyDocumentTool } from '../tools/CreateAnyDocTool';
+import { CreateDocTool } from '../tools/CreateDocumentTool';
import { DataAnalysisTool } from '../tools/DataAnalysisTool';
import { NoTool } from '../tools/NoTool';
-import { RAGTool } from '../tools/RAGTool';
import { SearchTool } from '../tools/SearchTool';
-import { WebsiteInfoScraperTool } from '../tools/WebsiteInfoScraperTool';
+import { Parameter, ParametersType, TypeMap } from '../types/tool_types';
import { AgentMessage, ASSISTANT_ROLE, AssistantMessage, Observation, PROCESSING_TYPE, ProcessingInfo, TEXT_TYPE } from '../types/types';
import { Vectorstore } from '../vectorstore/Vectorstore';
import { getReactPrompt } from './prompts';
-import { BaseTool } from '../tools/BaseTool';
-import { Parameter, ParametersType, TypeMap } from '../types/tool_types';
-import { CreateDocTool } from '../tools/CreateDocumentTool';
-import { DocumentOptions } from '../../../../documents/Documents';
-import { CreateAnyDocumentTool } from '../tools/CreateAnyDocTool';
dotenv.config();
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
index b89498d7d..83b50c8c6 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
@@ -14,12 +14,12 @@ import OpenAI, { ClientOptions } from 'openai';
import * as React from 'react';
import { v4 as uuidv4 } from 'uuid';
import { ClientUtils } from '../../../../../ClientUtils';
-import { Doc, DocListCast } from '../../../../../fields/Doc';
+import { Doc, DocListCast, Opt } from '../../../../../fields/Doc';
import { DocData, DocViews } from '../../../../../fields/DocSymbols';
-import { CsvCast, DocCast, PDFCast, RTFCast, StrCast, NumCast } from '../../../../../fields/Types';
+import { CsvCast, DocCast, NumCast, PDFCast, RTFCast, StrCast } from '../../../../../fields/Types';
import { Networking } from '../../../../Network';
import { DocUtils } from '../../../../documents/DocUtils';
-import { DocumentType } from '../../../../documents/DocumentTypes';
+import { CollectionViewType, DocumentType } from '../../../../documents/DocumentTypes';
import { Docs, DocumentOptions } from '../../../../documents/Documents';
import { DocumentManager } from '../../../../util/DocumentManager';
import { LinkManager } from '../../../../util/LinkManager';
@@ -33,7 +33,6 @@ import { Vectorstore } from '../vectorstore/Vectorstore';
import './ChatBox.scss';
import MessageComponentBox from './MessageComponent';
import { ProgressBar } from './ProgressBar';
-import { RichTextField } from '../../../../../fields/RichTextField';
dotenv.config();
@@ -45,17 +44,17 @@ dotenv.config();
@observer
export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// MobX observable properties to track UI state and data
- @observable history: AssistantMessage[] = [];
- @observable.deep current_message: AssistantMessage | undefined = undefined;
- @observable isLoading: boolean = false;
- @observable uploadProgress: number = 0;
- @observable currentStep: string = '';
- @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;
- @observable private citationPopup: { text: string; visible: boolean } = { text: '', visible: false };
+ @observable private _history: AssistantMessage[] = [];
+ @observable.deep private _current_message: AssistantMessage | undefined = undefined;
+ @observable private _isLoading: boolean = false;
+ @observable private _uploadProgress: number = 0;
+ @observable private _currentStep: string = '';
+ @observable private _expandedScratchpadIndex: number | null = null;
+ @observable private _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;
+ @observable private _citationPopup: { text: string; visible: boolean } = { text: '', visible: false };
// Private properties for managing OpenAI API, vector store, agent, and UI elements
private openai: OpenAI;
@@ -96,7 +95,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// Reaction to update dataDoc when chat history changes
reaction(
() =>
- this.history.map((msg: AssistantMessage) => ({
+ this._history.map((msg: AssistantMessage) => ({
role: msg.role,
content: msg.content,
follow_up_questions: msg.follow_up_questions,
@@ -115,20 +114,20 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@action
addDocToVectorstore = async (newLinkedDoc: Doc) => {
- this.uploadProgress = 0;
- this.currentStep = 'Initializing...';
- this.isUploadingDocs = true;
+ this._uploadProgress = 0;
+ this._currentStep = 'Initializing...';
+ this._isUploadingDocs = true;
try {
// Add the document to the vectorstore
await this.vectorstore.addAIDoc(newLinkedDoc, this.updateProgress);
} catch (error) {
console.error('Error uploading document:', error);
- this.currentStep = 'Error during upload';
+ this._currentStep = 'Error during upload';
} finally {
- this.isUploadingDocs = false;
- this.uploadProgress = 0;
- this.currentStep = '';
+ this._isUploadingDocs = false;
+ this._uploadProgress = 0;
+ this._currentStep = '';
}
};
@@ -139,8 +138,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@action
updateProgress = (progress: number, step: string) => {
- this.uploadProgress = progress;
- this.currentStep = step;
+ this._uploadProgress = progress;
+ this._currentStep = step;
};
/**
@@ -177,7 +176,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const csvId = id ?? uuidv4();
// Add CSV details to linked files
- this.linked_csv_files.push({
+ this._linked_csv_files.push({
filename: CsvCast(newLinkedDoc.data).url.pathname,
id: csvId,
text: csvData,
@@ -199,7 +198,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@action
toggleToolLogs = (index: number) => {
- this.expandedScratchpadIndex = this.expandedScratchpadIndex === index ? null : index;
+ this._expandedScratchpadIndex = this._expandedScratchpadIndex === index ? null : index;
};
/**
@@ -258,7 +257,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
askGPT = async (event: React.FormEvent): Promise<void> => {
event.preventDefault();
- this.inputValue = '';
+ this._inputValue = '';
// Extract the user's message
const textInput = (event.currentTarget as HTMLFormElement).elements.namedItem('messageInput') as HTMLInputElement;
@@ -268,13 +267,13 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
try {
textInput.value = '';
// Add the user's message to the history
- this.history.push({
+ this._history.push({
role: ASSISTANT_ROLE.USER,
content: [{ index: 0, type: TEXT_TYPE.NORMAL, text: trimmedText, citation_ids: null }],
processing_info: [],
});
- this.isLoading = true;
- this.current_message = {
+ this._isLoading = true;
+ this._current_message = {
role: ASSISTANT_ROLE.ASSISTANT,
content: [],
citations: [],
@@ -284,9 +283,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// Define callbacks for real-time processing updates
const onProcessingUpdate = (processingUpdate: ProcessingInfo[]) => {
runInAction(() => {
- if (this.current_message) {
- this.current_message = {
- ...this.current_message,
+ if (this._current_message) {
+ this._current_message = {
+ ...this._current_message,
processing_info: processingUpdate,
};
}
@@ -296,9 +295,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const onAnswerUpdate = (answerUpdate: string) => {
runInAction(() => {
- if (this.current_message) {
- this.current_message = {
- ...this.current_message,
+ if (this._current_message) {
+ this._current_message = {
+ ...this._current_message,
content: [{ text: answerUpdate, type: TEXT_TYPE.NORMAL, index: 0, citation_ids: [] }],
};
}
@@ -310,22 +309,22 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// Update the history with the final assistant message
runInAction(() => {
- if (this.current_message) {
- this.history.push({ ...finalMessage });
- this.current_message = undefined;
- this.dataDoc.data = JSON.stringify(this.history);
+ if (this._current_message) {
+ this._history.push({ ...finalMessage });
+ this._current_message = undefined;
+ this.dataDoc.data = JSON.stringify(this._history);
}
});
} catch (err) {
console.error('Error:', err);
// Handle error in processing
- this.history.push({
+ this._history.push({
role: ASSISTANT_ROLE.ASSISTANT,
content: [{ index: 0, type: TEXT_TYPE.ERROR, text: 'Sorry, I encountered an error while processing your request.', citation_ids: null }],
processing_info: [],
});
} finally {
- this.isLoading = false;
+ this._isLoading = false;
this.scrollToBottom();
}
}
@@ -339,8 +338,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@action
updateMessageCitations = (index: number, citations: Citation[]) => {
- if (this.history[index]) {
- this.history[index].citations = citations;
+ if (this._history[index]) {
+ this._history[index].citations = citations;
}
};
@@ -381,17 +380,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
* @param data The CSV data content.
*/
@action
- createCSVInDash = async (url: string, title: string, id: string, data: string) => {
- const doc = DocCast(await DocUtils.DocumentFromType('csv', url, { title: title, text: RTFCast(data) }));
-
- const linkDoc = Docs.Create.LinkDocument(this.Document, doc);
- LinkManager.Instance.addLink(linkDoc);
-
- doc && this._props.addDocument?.(doc);
- await DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {});
-
- this.addCSVForAnalysis(doc, id);
- };
+ createCSVInDash = (url: string, title: string, id: string, data: string) =>
+ DocUtils.DocumentFromType('csv', url, { title: title, text: RTFCast(data) }).then(doc => {
+ if (doc) {
+ LinkManager.Instance.addLink(Docs.Create.LinkDocument(this.Document, doc));
+ this._props.addDocument?.(doc);
+ DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {}).then(() => this.addCSVForAnalysis(doc, id));
+ }
+ });
/**
* Creates a text document in the dashboard and adds it for analysis.
@@ -401,40 +397,35 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
* @param id The unique ID for the document.
*/
@action
- private createCollectionWithChildren = async (data: any, insideCol: boolean): Promise<Doc[]> => {
- // Create an array of promises for each document
- const childDocPromises = data.map(async doc => {
- const parsedDoc = doc;
- if (parsedDoc.doc_type !== 'collection') {
- // Handle non-collection documents
- return await this.whichDoc(parsedDoc.doc_type, parsedDoc.data, { backgroundColor: parsedDoc.backgroundColor, _width: parsedDoc.width, _height: parsedDoc.height }, parsedDoc.id, insideCol);
- } else {
- // Recursively process collections
- const nestedDocs = await this.createCollectionWithChildren(parsedDoc.data, true);
- const collectionOptions: DocumentOptions = {
- title: parsedDoc.title,
- backgroundColor: parsedDoc.backgroundColor,
- _width: parsedDoc.width,
- _height: parsedDoc.height,
- _layout_fitWidth: true,
- _freeform_backgroundGrid: true,
- };
- const collectionDoc = DocCast(Docs.Create.FreeformDocument(nestedDocs, collectionOptions));
- return collectionDoc;
- }
- });
-
- // Await all child document creations concurrently
- const nestedResults = await Promise.all(childDocPromises);
- // Flatten any nested arrays from recursive collection calls
- const childDocs = nestedResults.flat() as Doc[];
- childDocs.forEach(doc => {
- console.log(DocCast(doc));
- console.log(DocCast(doc)[DocData].data);
- console.log(DocCast(doc)[DocData].data);
- });
- return childDocs;
- };
+ private createCollectionWithChildren = (data: { doc_type: string; id: string; data: any; title: string; width: number; height: number; backgroundColor: string }[], insideCol: boolean): Promise<Doc[]> =>
+ Promise.all(
+ data.map(doc =>
+ doc.doc_type !== 'collection' // Handle non-collection documents
+ ? this.whichDoc(doc.doc_type, doc.data, { backgroundColor: doc.backgroundColor, _width: doc.width, _height: doc.height }, doc.id, insideCol)
+ : // Recursively process collections
+ this.createCollectionWithChildren(doc.data, true).then(nestedDocs =>
+ Docs.Create.FreeformDocument(nestedDocs, {
+ title: doc.title,
+ backgroundColor: doc.backgroundColor,
+ _width: doc.width,
+ _height: doc.height,
+ _layout_fitWidth: true,
+ _freeform_backgroundGrid: true,
+ })
+ )
+ )
+ .flat() // prettier-ignore
+ ).then(childDocs => childDocs.filter(doc => doc).map(doc => doc!));
+ // .then(nestedResults => {
+ // // Flatten any nested arrays from recursive collection calls
+ // const childDocs = nestedResults.flat() as Doc[];
+ // childDocs.forEach(doc => {
+ // console.log(DocCast(doc));
+ // console.log(DocCast(doc)[DocData].data);
+ // console.log(DocCast(doc)[DocData].data);
+ // });
+ // return childDocs;
+ // });
// @action
// createSingleFlashcard = (data: any, options: DocumentOptions) => {
@@ -442,101 +433,53 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// }
@action
- whichDoc = async (doc_type: string, data: string, options: DocumentOptions, id: string, insideCol: boolean): Promise<Doc> => {
- let doc;
- switch (doc_type) {
- case 'text':
- doc = DocCast(Docs.Create.TextDocument(data, options));
- break;
- case 'flashcard':
- doc = this.createFlashcard(data, options);
- break;
- case 'deck':
- doc = this.createDeck(data, options);
- break;
- case 'image':
- doc = DocCast(Docs.Create.ImageDocument(data, options));
- break;
- case 'equation':
- doc = DocCast(Docs.Create.EquationDocument(data, options));
- break;
- case 'noteboard':
- doc = DocCast(Docs.Create.NoteTakingDocument([], options));
- break;
- case 'simulation':
- doc = DocCast(Docs.Create.SimulationDocument(options));
- break;
- case 'collection': {
- const arr = await this.createCollectionWithChildren(data, true);
- options._layout_fitWidth = true;
- options._freeform_backgroundGrid = true;
- if (options.type_collection == 'tree') {
- doc = DocCast(Docs.Create.TreeDocument(arr, options));
- } else if (options.type_collection == 'masonry') {
- doc = DocCast(Docs.Create.MasonryDocument(arr, options));
- } else if (options.type_collection == 'card') {
- doc = DocCast(Docs.Create.CardDeckDocument(arr, options));
- } else if (options.type_collection == 'carousel') {
- doc = DocCast(Docs.Create.CarouselDocument(arr, options));
- } else if (options.type_collection == '3d-carousel') {
- doc = DocCast(Docs.Create.Carousel3DDocument(arr, options));
- } else if (options.type_collection == 'multicolumn') {
- doc = DocCast(Docs.Create.CarouselDocument(arr, options));
- } else {
- doc = DocCast(Docs.Create.FreeformDocument(arr, options));
- }
- break;
+ whichDoc = (doc_type: string, data: string, options: DocumentOptions, id: string, insideCol: boolean): Promise<Opt<Doc>> =>
+ (async () => {
+ switch (doc_type) {
+ case 'text': return Docs.Create.TextDocument(data, options);
+ case 'flashcard': return this.createFlashcard(data, options);
+ case 'deck': return this.createDeck(data, options);
+ case 'image': return Docs.Create.ImageDocument(data, options);
+ case 'equation': return Docs.Create.EquationDocument(data, options);
+ case 'noteboard': return Docs.Create.NoteTakingDocument([], options);
+ case 'simulation': return Docs.Create.SimulationDocument(options);
+ case 'collection': return this.createCollectionWithChildren(data as any, true).
+ then((arr, collOpts = { ...options, _layout_fitWidth: true, _freeform_backgroundGrid: true }) =>
+ (() => {
+ switch (options.type_collection) {
+ case CollectionViewType.Tree: return Docs.Create.TreeDocument(arr, collOpts);
+ case CollectionViewType.Masonry: return Docs.Create.MasonryDocument(arr, collOpts);
+ case CollectionViewType.Card: return Docs.Create.CardDeckDocument(arr, collOpts);
+ case CollectionViewType.Carousel: return Docs.Create.CarouselDocument(arr, collOpts);
+ case CollectionViewType.Carousel3D: return Docs.Create.Carousel3DDocument(arr, collOpts);
+ case CollectionViewType.Multicolumn: return Docs.Create.CarouselDocument(arr, collOpts);
+ default: return Docs.Create.FreeformDocument(arr, collOpts);
+ }
+ })()
+ );
+ case 'web': return Docs.Create.WebDocument(data, { ...options, data_useCors: true });
+ case 'comparison': return this.createComparison(data, options);
+ case 'diagram': return Docs.Create.DiagramDocument(options);
+ case 'audio': return Docs.Create.AudioDocument(data, options);
+ case 'map': return Docs.Create.MapDocument([], options);
+ case 'screengrab': return Docs.Create.ScreenshotDocument(options);
+ case 'webcam': return Docs.Create.WebCamDocument('', options);
+ case 'button': return Docs.Create.ButtonDocument(options);
+ case 'script': return Docs.Create.ScriptingDocument(null, options);
+ case 'dataviz': return Docs.Create.DataVizDocument('/users/rz/Downloads/addresses.csv', options);
+ case 'chat': return Docs.Create.ChatDocument(options);
+ case 'trail': return Docs.Create.PresDocument(options);
+ case 'tab': return Docs.Create.FreeformDocument([], options);
+ case 'slide': return Docs.Create.TreeDocument([], options);
+ default: return Docs.Create.TextDocument(data, options);
+ } // prettier-ignore
+ })().then(doc => {
+ if (doc) {
+ doc.x = NumCast((options.x as number) ?? 0) + (insideCol ? 0 : NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc.width)) + 100;
+ doc.y = NumCast(options.y as number) + (insideCol ? 0 : NumCast(this.layoutDoc.y));
}
- case 'web':
- options.data_useCors = true;
- doc = DocCast(Docs.Create.WebDocument(data, options));
- break;
- case 'comparison':
- doc = this.createComparison(data, options);
- break;
- case 'diagram':
- doc = Docs.Create.DiagramDocument(options);
- break;
- case 'audio':
- doc = Docs.Create.AudioDocument(data, options);
- break;
- case 'map':
- doc = Docs.Create.MapDocument([], options);
- break;
- case 'screengrab':
- doc = Docs.Create.ScreenshotDocument(options);
- break;
- case 'webcam':
- doc = Docs.Create.WebCamDocument('', options);
- break;
- case 'button':
- doc = Docs.Create.ButtonDocument(options);
- break;
- case 'script':
- doc = Docs.Create.ScriptingDocument(null, options);
- break;
- case 'dataviz':
- doc = Docs.Create.DataVizDocument('/users/rz/Downloads/addresses.csv', options);
- break;
- case 'chat':
- doc = Docs.Create.ChatDocument(options);
- break;
- case 'trail':
- doc = Docs.Create.PresDocument(options);
- break;
- case 'tab':
- doc = Docs.Create.FreeformDocument([], options);
- break;
- case 'slide':
- doc = Docs.Create.TreeDocument([], options);
- break;
- default:
- doc = DocCast(Docs.Create.TextDocument(data, options));
- }
- doc!.x = NumCast(options.x ?? 0) + (insideCol ? 0 : NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc.width)) + 100;
- doc!.y = NumCast(options.y) + (insideCol ? 0 : NumCast(this.layoutDoc.y));
- return doc;
- };
+ return doc;
+ });
/**
* Creates a document in the dashboard.
@@ -548,57 +491,42 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
* @returns {Promise<void>} A promise that resolves once the document is created and displayed.
*/
@action
- createDocInDash = async (doc_type: string, data: string | undefined, options: DocumentOptions, id: string) => {
- let doc;
-
- switch (doc_type.toLowerCase()) {
- case 'text':
- doc = Docs.Create.TextDocument(data || '', options);
- break;
- case 'image':
- doc = Docs.Create.ImageDocument(data || '', options);
- break;
- case 'pdf':
- doc = Docs.Create.PdfDocument(data || '', options);
- break;
- case 'video':
- doc = Docs.Create.VideoDocument(data || '', options);
- break;
- case 'audio':
- doc = Docs.Create.AudioDocument(data || '', options);
- break;
- case 'web':
- doc = Docs.Create.WebDocument(data || '', options);
- break;
- case 'equation':
- doc = Docs.Create.EquationDocument(data || '', options);
- break;
- case 'functionplot':
- case 'function_plot':
- doc = Docs.Create.FunctionPlotDocument([], options);
- break;
- case 'dataviz':
- case 'data_viz': {
- const { fileUrl, id } = await Networking.PostToServer('/createCSV', {
- filename: (options.title as string).replace(/\s+/g, '') + '.csv',
- data: data,
- });
- doc = Docs.Create.DataVizDocument(fileUrl, { ...options, text: RTFCast(data) });
- this.addCSVForAnalysis(doc, id);
- break;
+ createDocInDash = (doc_type: string, data: string | undefined, options: DocumentOptions, id: string) => {
+ const linkAndShowDoc = (doc: Opt<Doc>) => {
+ if (doc) {
+ LinkManager.Instance.addLink(Docs.Create.LinkDocument(this.Document, doc));
+ this._props.addDocument?.(doc);
+ DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {});
}
- case 'chat':
- doc = Docs.Create.ChatDocument(options);
- break;
- // Add more cases for other document types
- default:
- console.error('Unknown or unsupported document type:', doc_type);
- return;
- }
- const linkDoc = Docs.Create.LinkDocument(this.Document, doc);
- LinkManager.Instance.addLink(linkDoc);
- doc && this._props.addDocument?.(doc);
- await DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {});
+ };
+ const doc = (() => {
+ switch (doc_type.toLowerCase()) {
+ case 'text': return Docs.Create.TextDocument(data || '', options);
+ case 'image': return Docs.Create.ImageDocument(data || '', options);
+ case 'pdf': return Docs.Create.PdfDocument(data || '', options);
+ case 'video': return Docs.Create.VideoDocument(data || '', options);
+ case 'audio': return Docs.Create.AudioDocument(data || '', options);
+ case 'web': return Docs.Create.WebDocument(data || '', options);
+ case 'equation': return Docs.Create.EquationDocument(data || '', options);
+ case 'chat': return Docs.Create.ChatDocument(options);
+ case 'functionplot':
+ case 'function_plot': return Docs.Create.FunctionPlotDocument([], options);
+ case 'dataviz':
+ case 'data_viz': Networking.PostToServer('/createCSV', {
+ filename: (options.title as string).replace(/\s+/g, '') + '.csv',
+ data: data,
+ })?.then(({ fileUrl, id }) => {
+ const vdoc = Docs.Create.DataVizDocument(fileUrl, { ...options, text: RTFCast(data) });
+ this.addCSVForAnalysis(vdoc, id);
+ linkAndShowDoc(vdoc);
+ });
+ return undefined;
+ // Add more cases for other document types
+ default: console.error('Unknown or unsupported document type:', doc_type);
+ return undefined;
+ } // prettier-ignore
+ })();
+ if (doc) linkAndShowDoc(doc);
};
/**
@@ -625,16 +553,13 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
// Create a carousel to contain the flashcard deck
- const carouselDoc = DocCast(
- Docs.Create.CarouselDocument(flashcardDeck, {
- title: options.title || 'Flashcard Deck',
- _width: options._width || 300,
- _height: options._height || 300,
- _layout_fitWidth: false,
- _layout_autoHeight: true,
- })
- );
- return carouselDoc;
+ return Docs.Create.CarouselDocument(flashcardDeck, {
+ title: options.title || 'Flashcard Deck',
+ _width: options._width || 300,
+ _height: options._height || 300,
+ _layout_fitWidth: false,
+ _layout_autoHeight: true,
+ });
};
/**
@@ -662,8 +587,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const side2 = Docs.Create.CenteredTextCreator(back.title, back.data, sideOptions);
// Create the flashcard document with both sides
- const flashcardDoc = DocCast(Docs.Create.FlashcardDocument(data.title, side1, side2, sideOptions));
- return flashcardDoc;
+ return Docs.Create.FlashcardDocument(data.title, side1, side2, sideOptions);
}
};
@@ -675,15 +599,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
* @returns {Doc} The created comparison document.
*/
@action
- createComparison = (doc: any, options: any) => {
- const comp = Docs.Create.ComparisonDocument(options.title, { _width: options.width, _height: options.height | 300, backgroundColor: options.backgroundColor });
- const [left, right] = doc;
- const docLeft = DocCast(Docs.Create.TextDocument(left.data, { backgroundColor: left.backgroundColor, _width: left.width, _height: left.height }));
- const docRight = DocCast(Docs.Create.TextDocument(right.data, { backgroundColor: right.backgroundColor, _width: right.width, _height: right.height }));
- comp[DocData].data_back = docLeft;
- comp[DocData].data_front = docRight;
- return comp;
- };
+ createComparison = (doc: { left: any; right: any }, options: any) =>
+ Docs.Create.ComparisonDocument(options.title, {
+ data_back: Docs.Create.TextDocument(doc.left.data, { backgroundColor: doc.left.backgroundColor, _width: doc.left.width, _height: doc.left.height }),
+ data_front: Docs.Create.TextDocument(doc.right.data, { backgroundColor: doc.right.backgroundColor, _width: doc.right.width, _height: doc.right.height }),
+ _width: options.width,
+ _height: options.height | 300,
+ backgroundColor: options.backgroundColor,
+ });
/**
* Event handler to manage citations click in the message components.
@@ -692,7 +615,6 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
handleCitationClick = (citation: Citation) => {
const currentLinkedDocs: Doc[] = this.linkedDocs;
-
const chunkId = citation.chunk_id;
// Loop through the linked documents to find the matching chunk and handle its display
@@ -727,8 +649,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
break;
case CHUNK_TYPE.TEXT:
- this.citationPopup = { text: citation.direct_text ?? 'No text available', visible: true };
- setTimeout(() => (this.citationPopup.visible = false), 3000); // Hide after 3 seconds
+ this._citationPopup = { text: citation.direct_text ?? 'No text available', visible: true };
+ setTimeout(() => (this._citationPopup.visible = false), 3000); // Hide after 3 seconds
DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {
const firstView = Array.from(doc[DocViews])[0] as DocumentView;
@@ -796,7 +718,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
try {
const storedHistory = JSON.parse(StrCast(this.dataDoc.data));
runInAction(() => {
- this.history.push(
+ this._history.push(
...storedHistory.map((msg: AssistantMessage) => ({
role: msg.role,
content: msg.content,
@@ -811,7 +733,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
} else {
// Default welcome message
runInAction(() => {
- this.history.push({
+ this._history.push({
role: ASSISTANT_ROLE.ASSISTANT,
content: [
{
@@ -835,11 +757,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
.filter(d => d);
return linkedDocs;
},
- linked => linked.forEach(doc => this.linked_docs_to_add.add(doc))
+ linked => linked.forEach(doc => this._linked_docs_to_add.add(doc))
);
// Observe changes to linked documents and handle document addition
- observe(this.linked_docs_to_add, change => {
+ observe(this._linked_docs_to_add, change => {
if (change.type === 'add') {
if (PDFCast(change.newValue.data)) {
this.addDocToVectorstore(change.newValue);
@@ -913,7 +835,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
* Getter that retrieves all linked CSV files for analysis.
*/
@computed get linkedCSVs(): { filename: string; id: string; text: string }[] {
- return this.linked_csv_files;
+ return this._linked_csv_files;
}
/**
@@ -921,7 +843,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@computed get formattedHistory(): string {
let history = '<chat_history>\n';
- for (const message of this.history) {
+ for (const message of this._history) {
history += `<${message.role}>${message.content.map(content => content.text).join(' ')}`;
if (message.loop_summary) {
history += `<loop_summary>${message.loop_summary}</loop_summary>`;
@@ -957,7 +879,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
*/
@action
handleFollowUpClick = (question: string) => {
- this.inputValue = question;
+ this._inputValue = question;
};
/**
@@ -966,11 +888,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
render() {
return (
<div className="chat-box">
- {this.isUploadingDocs && (
+ {this._isUploadingDocs && (
<div className="uploading-overlay">
<div className="progress-container">
<ProgressBar />
- <div className="step-name">{this.currentStep}</div>
+ <div className="step-name">{this._currentStep}</div>
</div>
</div>
)}
@@ -978,18 +900,18 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<h2>{this.userName()}&apos;s AI Assistant</h2>
</div>
<div className="chat-messages" ref={this.messagesRef}>
- {this.history.map((message, index) => (
+ {this._history.map((message, index) => (
<MessageComponentBox key={index} message={message} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
))}
- {this.current_message && (
- <MessageComponentBox key={this.history.length} message={this.current_message} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
+ {this._current_message && (
+ <MessageComponentBox key={this._history.length} message={this._current_message} onFollowUpClick={this.handleFollowUpClick} onCitationClick={this.handleCitationClick} updateMessageCitations={this.updateMessageCitations} />
)}
</div>
<form onSubmit={this.askGPT} className="chat-input">
- <input type="text" name="messageInput" autoComplete="off" placeholder="Type your message here..." value={this.inputValue} onChange={e => (this.inputValue = e.target.value)} disabled={this.isLoading} />
- <button className="submit-button" type="submit" disabled={this.isLoading || !this.inputValue.trim()}>
- {this.isLoading ? (
+ <input type="text" name="messageInput" autoComplete="off" placeholder="Type your message here..." value={this._inputValue} onChange={e => (this._inputValue = e.target.value)} disabled={this._isLoading} />
+ <button className="submit-button" type="submit" disabled={this._isLoading || !this._inputValue.trim()}>
+ {this._isLoading ? (
<div className="spinner"></div>
) : (
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round">
@@ -1000,10 +922,10 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</button>
</form>
{/* Popup for citation */}
- {this.citationPopup.visible && (
+ {this._citationPopup.visible && (
<div className="citation-popup">
<p>
- <strong>Text from your document: </strong> {this.citationPopup.text}
+ <strong>Text from your document: </strong> {this._citationPopup.text}
</p>
</div>
)}