aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
diff options
context:
space:
mode:
authorJoanne <zehan_ding@brown.edu>2025-06-22 23:12:46 -0400
committerJoanne <zehan_ding@brown.edu>2025-06-22 23:12:46 -0400
commit17ec2a19b2d2dc5ba3f99c43d86c27946de2ac71 (patch)
treeefb55f2b186f0636caefc8dd8680f918d1ddbb25 /src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
parent61787b3c1cf53c0230f6142bee0df30c65971012 (diff)
successfully merged documentationtext functionality with new version of agent, however still minor issues with the agent not selecting the proper tool for documentation generation without the additional context from the topbar
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx')
-rw-r--r--src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx60
1 files changed, 34 insertions, 26 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
index db01b7c88..18d0266af 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
@@ -7,23 +7,21 @@
* 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';
import * as React from 'react';
import { v4 as uuidv4 } from 'uuid';
import { ClientUtils, OmitKeys } from '../../../../../ClientUtils';
-import { Doc, DocListCast, Opt } from '../../../../../fields/Doc';
-import { DocData, DocLayout, DocViews } from '../../../../../fields/DocSymbols';
+import { Doc, Opt } from '../../../../../fields/Doc';
+import { 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';
@@ -44,11 +42,8 @@ import './ChatBox.scss';
import MessageComponentBox from './MessageComponent';
import { OpenWhere } from '../../OpenWhere';
import { Upload } from '../../../../../server/SharedMediaTypes';
-import { DocumentMetadataTool } from '../tools/DocumentMetadataTool';
import { AgentDocumentManager } from '../utils/AgentDocumentManager';
-dotenv.config();
-
export type parsedDocData = {
doc_type: string;
data: unknown;
@@ -58,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,
@@ -124,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);
@@ -388,7 +392,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
// Get the response from the agent
- const response = await this.agent.askAgent(trimmedText, onProcessingUpdate, onAnswerUpdate);
+ 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);
// Push the final message to history
runInAction(() => {
@@ -476,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);
@@ -487,22 +495,22 @@ 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 as any)._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',
@@ -527,7 +535,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);
@@ -536,9 +544,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);
@@ -646,8 +654,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);
@@ -656,7 +664,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) {
@@ -911,7 +919,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,
@@ -939,7 +947,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) {
@@ -1395,7 +1403,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</div>
)}
<div className="chat-header">
- <h2>{this.userName()}&apos;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>