diff options
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx | 178 |
1 files changed, 60 insertions, 118 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 076f49831..47d4fb8a7 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -14,10 +14,9 @@ import OpenAI, { ClientOptions } from 'openai'; import * as React from 'react'; import { v4 as uuidv4 } from 'uuid'; import { ClientUtils } from '../../../../../ClientUtils'; -import { Doc, DocListCast, FieldType, Opt } from '../../../../../fields/Doc'; +import { Doc, DocListCast, Opt } from '../../../../../fields/Doc'; import { DocData, DocViews } from '../../../../../fields/DocSymbols'; import { CsvCast, DocCast, NumCast, PDFCast, RTFCast, StrCast } from '../../../../../fields/Types'; -import { Networking } from '../../../../Network'; import { DocUtils } from '../../../../documents/DocUtils'; import { CollectionViewType, DocumentType } from '../../../../documents/DocumentTypes'; import { Docs, DocumentOptions } from '../../../../documents/Documents'; @@ -33,9 +32,11 @@ import { Vectorstore } from '../vectorstore/Vectorstore'; import './ChatBox.scss'; import MessageComponentBox from './MessageComponent'; import { ProgressBar } from './ProgressBar'; +import { supportedDocumentTypes } from '../tools/CreateDocumentTool'; dotenv.config(); +type parsedDoc = { doc_type: string; id: string; data: unknown; title: string; width: number; height: number; backgroundColor: string }; /** * ChatBox is the main class responsible for managing the interaction between the user and the assistant, * handling documents, and integrating with OpenAI for tasks such as document analysis, chat functionality, @@ -399,48 +400,26 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @param id The unique ID for the document. */ @action - 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) - : 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, - }) - ) - ) // 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; - // }); + private createCollectionWithChildren = (data: parsedDoc[], insideCol: boolean): Opt<Doc>[] => + data.map(doc => this.whichDoc(doc.doc_type, doc.data, { backgroundColor: doc.backgroundColor, _width: doc.width, _height: doc.height }, doc.id, insideCol)); @action - whichDoc = (doc_type: string, data: unknown, options: DocumentOptions, id: string, insideCol: boolean): Promise<Opt<Doc>> => - (async () => { + whichDoc = (doc_type: string, data: unknown, options: DocumentOptions, id: string, insideCol: boolean): Opt<Doc> => { + const ndoc = (() => { switch (doc_type) { - case 'text': return Docs.Create.TextDocument(data as string, options); - case 'flashcard': return this.createFlashcard(data as string[], options); - case 'deck': return this.createDeck(data as string, options); - case 'image': return Docs.Create.ImageDocument(data as string, options); - case 'equation': return Docs.Create.EquationDocument(data as string, options); - case 'noteboard': return Docs.Create.NoteTakingDocument([], options); - case 'simulation': return Docs.Create.SimulationDocument(options); - case 'collection': return this.createCollectionWithChildren(data as { doc_type: string; id: string; data: any; title: string; width: number; height: number; backgroundColor: string }[] , true). - then((arr, collOpts = { ...options, _layout_fitWidth: true, _freeform_backgroundGrid: true }) => - (() => { + case supportedDocumentTypes.text: return Docs.Create.TextDocument(data as string, options); + case supportedDocumentTypes.comparison: return this.createComparison(data as parsedDoc[], options); + case supportedDocumentTypes.flashcard: return this.createFlashcard(data as parsedDoc[], options); + case supportedDocumentTypes.deck: return this.createDeck(data as parsedDoc[], options); + case supportedDocumentTypes.image: return Docs.Create.ImageDocument(data as string, options); + case supportedDocumentTypes.equation: return Docs.Create.EquationDocument(data as string, options); + case supportedDocumentTypes.notetaking: return Docs.Create.NoteTakingDocument([], options); + case supportedDocumentTypes.web: return Docs.Create.WebDocument(data as string, { ...options, data_useCors: true }); + case supportedDocumentTypes.dataviz: return Docs.Create.DataVizDocument('/users/rz/Downloads/addresses.csv', options); + case supportedDocumentTypes.collection: { + const arr = this.createCollectionWithChildren(data as parsedDoc[], true).filter(d=>d).map(d => d!); + const collOpts = { ...options, _layout_fitWidth: true, _width:300, _height: 300, _freeform_backgroundGrid: true }; + return (() => { switch (options.type_collection) { case CollectionViewType.Tree: return Docs.Create.TreeDocument(arr, collOpts); case CollectionViewType.Masonry: return Docs.Create.MasonryDocument(arr, collOpts); @@ -450,31 +429,26 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { case CollectionViewType.Multicolumn: return Docs.Create.CarouselDocument(arr, collOpts); default: return Docs.Create.FreeformDocument(arr, collOpts); } - })() - ); - case 'web': return Docs.Create.WebDocument(data as string, { ...options, data_useCors: true }); - case 'comparison': return this.createComparison(data as {left: {width:number ,height: number, backgroundColor: string, data: string}, right: {width:number ,height: number, backgroundColor: string, data: string}}, options); - case 'diagram': return Docs.Create.DiagramDocument(options); - case 'audio': return Docs.Create.AudioDocument(data as string, 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); + })(); + } + // case supportedDocumentTypes.diagram: return Docs.Create.DiagramDocument(options); + // case supportedDocumentTypes.audio: return Docs.Create.AudioDocument(data as string, options); + // case supportedDocumentTypes.map: return Docs.Create.MapDocument([], options); + // case supportedDocumentTypes.button: return Docs.Create.ButtonDocument(options); + // case supportedDocumentTypes.script: return Docs.Create.ScriptingDocument(null, options); + // case supportedDocumentTypes.chat: return Docs.Create.ChatDocument(options); + // case supportedDocumentTypes.trail: return Docs.Create.PresDocument(options); + // case supportedDocumentTypes.trail: return Docs.Create.FreeformDocument([], options); default: return Docs.Create.TextDocument(data as string, 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)); - } - return doc; - }); + })(); + + if (ndoc) { + ndoc.x = NumCast((options.x as number) ?? 0) + (insideCol ? 0 : NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc.width)) + 100; + ndoc.y = NumCast(options.y as number) + (insideCol ? 0 : NumCast(this.layoutDoc.y)); + } + return ndoc; + }; /** * Creates a document in the dashboard. @@ -494,32 +468,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { DocumentManager.Instance.showDocument(doc, { willZoomCentered: true }, () => {}); } }; - const doc = (() => { - switch (doc_type.toLowerCase()) { - case 'flashcard': return this.createFlashcard(data as string[], options); - case 'text': return Docs.Create.TextDocument(data as string || '', options); - case 'image': return Docs.Create.ImageDocument(data as string || '', options); - case 'pdf': return Docs.Create.PdfDocument(data as string || '', options); - case 'video': return Docs.Create.VideoDocument(data as string || '', options); - case 'audio': return Docs.Create.AudioDocument(data as string || '', options); - case 'web': return Docs.Create.WebDocument(data as string || '', options); - case 'equation': return Docs.Create.EquationDocument(data as string || '', options); - case 'chat': return Docs.Create.ChatDocument(options); - case 'functionplot': return Docs.Create.FunctionPlotDocument([], options); - case 'dataviz': 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 as FieldType) }); - 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 - })(); + const doc = this.whichDoc(doc_type, data, options, uuidv4(), false); if (doc) linkAndShowDoc(doc); }; @@ -531,17 +480,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc} A carousel document containing the flashcard deck. */ @action - createDeck = (data: string | unknown[], options: DocumentOptions) => { + createDeck = (data: parsedDoc[], options: DocumentOptions) => { const flashcardDeck: Doc[] = []; - // Parse `data` only if it’s a string - const deckData = typeof data === 'string' ? (JSON.parse(data) as unknown) : data; - const flashcardArray = Array.isArray(deckData) ? deckData : Object.values(deckData as object); // Process each flashcard document in the `deckData` array - if (flashcardArray.length == 2 && flashcardArray[0].doc_type == 'text' && flashcardArray[1].doc_type == 'text') { - this.createFlashcard(flashcardArray as string[], options); + if (data.length == 2 && data[0].doc_type == 'text' && data[1].doc_type == 'text') { + this.createFlashcard(data, options); } else { - flashcardArray.forEach(doc => { - const flashcardDoc = this.createFlashcard(doc, options); + data.forEach(doc => { + const flashcardDoc = this.createFlashcard(doc.data as parsedDoc[] | string[], options); if (flashcardDoc) flashcardDeck.push(flashcardDoc); }); } @@ -564,25 +510,21 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc | undefined} The created flashcard document, or undefined if the flashcard cannot be created. */ @action - createFlashcard = (data: string[], options: DocumentOptions) => { - const deckData = typeof data === 'string' ? JSON.parse(data) : data; - const flashcardArray = Array.isArray(deckData) ? deckData : (Object.values(deckData)[2] as string[]); - const [front, back] = flashcardArray; - - if (typeof front === 'string' && typeof back === 'string') { - const sideOptions: DocumentOptions = { - backgroundColor: options.backgroundColor, - _width: options._width, - _height: options._height || 300, - }; + createFlashcard = (data: parsedDoc[] | string[], options: DocumentOptions) => { + const [front, back] = data; - // Create front and back text documents - const side1 = Docs.Create.CenteredTextCreator('question', front, sideOptions); - const side2 = Docs.Create.CenteredTextCreator('answer', back, sideOptions); + const sideOptions: DocumentOptions = { + backgroundColor: options.backgroundColor, + _width: options._width, + _height: options._height || 300, + }; - // Create the flashcard document with both sides - return Docs.Create.FlashcardDocument('flashcard', side1, side2, sideOptions); - } + // Create front and back text documents + const side1 = typeof front === 'string' ? Docs.Create.CenteredTextCreator('question', front as string, sideOptions) : this.whichDoc(front.doc_type, front.data, options, front.id, false); + const side2 = typeof back === 'string' ? Docs.Create.CenteredTextCreator('answer', back as string, sideOptions) : this.whichDoc(back.doc_type, back.data, options, back.id, false); + + // Create the flashcard document with both sides + return Docs.Create.FlashcardDocument('flashcard', side1, side2, sideOptions); }; /** @@ -593,10 +535,10 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @returns {Doc} The created comparison document. */ @action - createComparison = (doc: { left: { width: number; height: number; backgroundColor: string; data: string }; right: { width: number; height: number; backgroundColor: string; data: string } }, options: DocumentOptions) => + createComparison = (doc: parsedDoc[], options: DocumentOptions) => Docs.Create.ComparisonDocument(options.title as string, { - 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 }), + data_back: Docs.Create.TextDocument(doc[0].data as string, { backgroundColor: doc[0].backgroundColor, _width: doc[0].width, _height: doc[0].height }), + data_front: Docs.Create.TextDocument(doc[1].data as string, { backgroundColor: doc[1].backgroundColor, _width: doc[1].width, _height: doc[1].height }), _width: options._width, _height: options._height || 300, backgroundColor: options.backgroundColor, |