diff options
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 6e6ef6212..19459b025 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -7,7 +7,6 @@ * with support for follow-up questions and citation management. */ -import dotenv from 'dotenv'; import { ObservableSet, action, computed, makeObservable, observable, observe, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import OpenAI, { ClientOptions } from 'openai'; @@ -19,11 +18,10 @@ import { DocData, DocViews } from '../../../../../fields/DocSymbols'; import { Id } from '../../../../../fields/FieldSymbols'; import { RichTextField } from '../../../../../fields/RichTextField'; import { ScriptField } from '../../../../../fields/ScriptField'; -import { CsvCast, DocCast, NumCast, PDFCast, RTFCast, StrCast, VideoCast, AudioCast } from '../../../../../fields/Types'; +import { CsvCast, DocCast, PDFCast, RTFCast, StrCast, VideoCast, AudioCast } from '../../../../../fields/Types'; import { DocUtils } from '../../../../documents/DocUtils'; import { CollectionViewType, DocumentType } from '../../../../documents/DocumentTypes'; import { Docs, DocumentOptions } from '../../../../documents/Documents'; -import { DocServer } from '../../../../DocServer'; import { DocumentManager } from '../../../../util/DocumentManager'; import { ImageUtils } from '../../../../util/Import & Export/ImageUtils'; import { LinkManager } from '../../../../util/LinkManager'; @@ -46,8 +44,6 @@ import { OpenWhere } from '../../OpenWhere'; import { Upload } from '../../../../../server/SharedMediaTypes'; import { AgentDocumentManager } from '../utils/AgentDocumentManager'; -dotenv.config(); - export type parsedDocData = { doc_type: string; data: unknown; @@ -57,6 +53,7 @@ export type parsedDocData = { data_useCors?: boolean; }; export type parsedDoc = DocumentOptions & parsedDocData; + /** * 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, @@ -123,7 +120,15 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this.vectorstore = new Vectorstore(this.vectorstore_id, this.docManager); // Create an agent with the vectorstore - this.agent = new Agent(this.vectorstore, this.retrieveFormattedHistory.bind(this), this.retrieveCSVData.bind(this), this.createImageInDash.bind(this), this.createCSVInDash.bind(this), this.docManager); + this.agent = new Agent( + this.vectorstore, + this.retrieveFormattedHistory.bind(this), + this.retrieveCSVData.bind(this), + this.createImageInDash.bind(this), + this.createCSVInDash.bind(this), + this.docManager, + this.dataDoc.is_dash_doc_assistant === 'true' + ); // Set up the tool created callback this.agent.setToolCreatedCallback(this.handleToolCreated); @@ -373,7 +378,6 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; } }); - this.scrollToBottom(); }; const onAnswerUpdate = (answerUpdate: string) => { @@ -381,41 +385,33 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (this._current_message) { this._current_message = { ...this._current_message, - content: [{ text: answerUpdate, type: TEXT_TYPE.NORMAL, index: 0, citation_ids: [] }], + content: [{ index: 0, type: TEXT_TYPE.NORMAL, text: answerUpdate, citation_ids: null }], }; } }); }; - // Send the user's question to the assistant and get the final message - const finalMessage = await this.agent.askAgent(trimmedText, onProcessingUpdate, onAnswerUpdate); + // Get the response from the agent + let userQuery = trimmedText; + if (this.dataDoc.is_dash_doc_assistant) { + userQuery = `The user is asking a question about Dash functionality. Their question is: "${trimmedText}". You should use the generateTutorialNode tool to answer this question.`; + } + const response = await this.agent.askAgent(userQuery, onProcessingUpdate, onAnswerUpdate); - // Update the history with the final assistant message + // Push the final message to history runInAction(() => { - if (this._current_message) { - this._history.push({ ...finalMessage }); - this._current_message = undefined; - this.dataDoc.data = JSON.stringify(this._history); - } + this._history.push(response); + this._isLoading = false; + this._current_message = undefined; }); - } catch (err) { - console.error('Error:', err); - // Handle error in processing - runInAction(() => - this._history.push({ - role: ASSISTANT_ROLE.ASSISTANT, - content: [{ index: 0, type: TEXT_TYPE.ERROR, text: `Sorry, I encountered an error while processing your request: ${err} `, citation_ids: null }], - processing_info: [], - }) - ); - } finally { + } catch (error) { + console.error('Error in askGPT:', error); runInAction(() => { this._isLoading = false; + this._current_message = undefined; }); - this.scrollToBottom(); } } - this.scrollToBottom(); }; /** @@ -488,7 +484,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const data = (doc as parsedDocData).data; const ndoc = (() => { switch (doc.doc_type) { - default: + default: case supportedDocTypes.note: return Docs.Create.TextDocument(data as string, options); case supportedDocTypes.comparison: return this.createComparison(JSON.parse(data as string) as parsedDoc[], options); case supportedDocTypes.flashcard: return this.createFlashcard(JSON.parse(data as string) as parsedDoc[], options); @@ -499,23 +495,23 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { case supportedDocTypes.web: { // Create web document with enhanced safety options const webOptions = { - ...options, + ...options, data_useCors: true }; - + // If iframe_sandbox was passed from AgentDocumentManager, add it to the options if ('_iframe_sandbox' in options) { webOptions._iframe_sandbox = options._iframe_sandbox; } - + return Docs.Create.WebDocument(data as string, webOptions); } case supportedDocTypes.dataviz: return Docs.Create.DataVizDocument('/users/rz/Downloads/addresses.csv', options); case supportedDocTypes.pdf: return Docs.Create.PdfDocument(data as string, options); case supportedDocTypes.video: return Docs.Create.VideoDocument(data as string, options); case supportedDocTypes.diagram: return Docs.Create.DiagramDocument(undefined, { text: data as unknown as RichTextField, ...options}); // text: can take a string or RichTextField but it's typed for RichTextField. - - // case supportedDocumentTypes.dataviz: + + // case supportedDocumentTypes.dataviz: // { // const { fileUrl, id } = await Networking.PostToServer('/createCSV', { // filename: (options.title as string).replace(/\s+/g, '') + '.csv', @@ -540,7 +536,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const arr = this.createCollectionWithChildren(JSON.parse(data as string) as parsedDoc[], true).filter(d=>d).map(d => d!); const collOpts = { _width:300, _height: 300, _layout_fitWidth: true, _freeform_backgroundGrid: true, ...options, }; return (() => { - switch (options.type_collection) { + switch (options.type_collection) { case CollectionViewType.Tree: return Docs.Create.TreeDocument(arr, collOpts); case CollectionViewType.Stacking: return Docs.Create.StackingDocument(arr, collOpts); case CollectionViewType.Masonry: return Docs.Create.MasonryDocument(arr, collOpts); @@ -549,9 +545,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { 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 supportedDocumentTypes.map: return Docs.Create.MapDocument([], options); // case supportedDocumentTypes.button: return Docs.Create.ButtonDocument(options); // case supportedDocumentTypes.trail: return Docs.Create.PresDocument(options); @@ -659,8 +655,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } else { console.warn(`Chunk not found for chunk ID: ${chunkId}`); } - return; - } + return; + } console.log(`Found chunk in document:`, foundChunk); @@ -669,7 +665,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const directMatchSegmentStart = this.getDirectMatchingSegmentStart(doc, citation.direct_text || '', foundChunk.indexes || []); if (directMatchSegmentStart) { await this.goToMediaTimestamp(doc, directMatchSegmentStart, foundChunk.chunkType); - } else { + } else { console.error('No direct matching segment found for the citation.'); } } else if (foundChunk.chunkType === CHUNK_TYPE.TABLE || foundChunk.chunkType === CHUNK_TYPE.IMAGE) { @@ -926,7 +922,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { console.error(`Maximum verification attempts (${attempt}) reached for document ${doc.id}`); // Last resort: force re-creation of the document view - if (isPDF) { + if (isPDF) { console.log('Forcing document recreation as last resort'); DocumentManager.Instance.showDocument(doc, { willZoomCentered: true, @@ -954,7 +950,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return; } - this.processPDFDocumentView(doc, isPDF, citation, foundChunk); + this.processPDFDocumentView(doc, isPDF, citation, foundChunk); } catch (error) { console.error(`Error on verification attempt ${attempt}:`, error); if (attempt < 5) { @@ -1068,7 +1064,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { { index: 0, type: TEXT_TYPE.NORMAL, - text: `Hey, ${this.userName()}! Welcome to Your Friendly Assistant. Link a document or ask questions to get started.`, + text: this.dataDoc.is_dash_doc_assistant + ? 'Welcome to your help assistant for Dash. Ask any Dash-related questions to get started.' + : `Hey, ${this.userName()}! Welcome to Your Friendly Assistant. Link a document or ask questions to get started.`, citation_ids: null, }, ], @@ -1409,7 +1407,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { </div> )} <div className="chat-header"> - <h2>{this.userName()}'s AI Assistant</h2> + <h2>{StrCast(this.dataDoc.title) || `${this.userName()}'s AI Assistant`}</h2> <div className="font-size-control" onClick={this.toggleFontSizeModal}> {this.renderFontSizeIcon()} </div> |