diff options
Diffstat (limited to 'src/client/views')
22 files changed, 119 insertions, 158 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 8b8f85dfb..abe154de4 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -75,7 +75,7 @@ import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; -// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports +// eslint-disable-next-line @typescript-eslint/no-require-imports const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @observer @@ -1059,10 +1059,7 @@ export class MainView extends ObservableReactComponent<object> { docView={DocButtonState.Instance.LinkEditorDocView} /> ) : null} - {LinkInfo.Instance?.LinkInfo ? ( - // eslint-disable-next-line react/jsx-props-no-spreading - <LinkDocPreview {...LinkInfo.Instance.LinkInfo} /> - ) : null} + {LinkInfo.Instance?.LinkInfo ? <LinkDocPreview {...LinkInfo.Instance.LinkInfo} /> : null} {((page: string) => { // prettier-ignore switch (page) { diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index fc5f5cb71..226d06f37 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -252,10 +252,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents="+ Node" menuCallback={this.menuCallback} /> </div> <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}> - { - // eslint-disable-next-line react/jsx-props-no-spreading - <EditableView {...this._props.editableViewProps()} /> - } + <EditableView {...this._props.editableViewProps()} /> </div> </div> ) : null} diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 4616ec057..596975062 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -10,7 +10,7 @@ import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { ComputedField } from '../../../fields/ScriptField'; -import { Cast, FieldValue, ImageCast, NumCast, StrCast, toList } from '../../../fields/Types'; +import { Cast, FieldValue, NumCast, StrCast, toList } from '../../../fields/Types'; import { ImageField, PdfField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; import { emptyFunction } from '../../../Utils'; @@ -43,14 +43,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { public static openSidebarWidth = 250; public static sidebarResizerWidth = 5; private _searchString: string = ''; - private _initialScrollTarget: Opt; + private _initialScrollTarget: Opt<Doc>; private _pdfViewer: PDFViewer | undefined; private _searchRef = React.createRef<HTMLInputElement>(); private _disposers: { [name: string]: IReactionDisposer } = {}; private _sidebarRef = React.createRef<SidebarAnnos>(); @observable private _searching: boolean = false; - @observable private _pdf: Opt = undefined; + @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy> = undefined; @observable private _pageControls = false; @computed get pdfUrl() { @@ -242,13 +242,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { options.didMove = true; this.toggleSidebar(false); } - return new Promise<Opt>(res => { + return new Promise<Opt<DocumentView>>(res => { DocumentView.addViewRenderedCb(doc, dv => res(dv)); }); }; getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { - let ele: Opt; + let ele: Opt<HTMLDivElement>; if (this._pdfViewer?.selectionContent()) { ele = document.createElement('div'); ele.append(this._pdfViewer.selectionContent()!); @@ -327,7 +327,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._initialScrollTarget = undefined; } }; - searchStringChanged = (e: React.ChangeEvent) => { + searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => { this._searchString = e.currentTarget.value; }; @@ -365,8 +365,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } ); }; - @observable _previewNativeWidth: Opt = undefined; - @observable _previewWidth: Opt = undefined; + @observable _previewNativeWidth: Opt<number> = undefined; + @observable _previewWidth: Opt<number> = undefined; toggleSidebar = action((preview: boolean = false) => { const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']); const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; @@ -540,7 +540,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return ComponentTag === CollectionStackingView ? ( <SidebarAnnos ref={this._sidebarRef} - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} Document={this.Document} layoutDoc={this.layoutDoc} @@ -556,7 +555,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { ) : ( <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this._props.select(false), true)}> <ComponentTag - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} setContentViewBox={emptyFunction} // override setContentView to do nothing NativeWidth={this.sidebarNativeWidthFunc} @@ -610,7 +608,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { top: 0, }}> <PDFViewer - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} pdfBox={this} sidebarAddDoc={this.sidebarAddDocument} @@ -637,7 +634,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } static pdfcache = new Map<string, Pdfjs.PDFDocumentProxy>(); - static pdfpromise = new Map<string, Promise>(); + static pdfpromise = new Map<string, Promise<Pdfjs.PDFDocumentProxy>>(); render() { TraceMobx(); const pdfView = !this._pdf ? null : this.renderPdfView; diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.tsx b/src/client/views/nodes/RecordingBox/ProgressBar.tsx index 62798bc2f..7e91df7ab 100644 --- a/src/client/views/nodes/RecordingBox/ProgressBar.tsx +++ b/src/client/views/nodes/RecordingBox/ProgressBar.tsx @@ -1,5 +1,3 @@ -/* eslint-disable react/no-array-index-key */ -/* eslint-disable react/require-default-props */ import * as React from 'react'; import { useEffect, useState, useRef } from 'react'; import './ProgressBar.scss'; diff --git a/src/client/views/nodes/chatbot/agentsystem/Agent.ts b/src/client/views/nodes/chatbot/agentsystem/Agent.ts index 180d05cf3..ccf9caf15 100644 --- a/src/client/views/nodes/chatbot/agentsystem/Agent.ts +++ b/src/client/views/nodes/chatbot/agentsystem/Agent.ts @@ -1,20 +1,19 @@ +import dotenv from 'dotenv'; +import { XMLBuilder, XMLParser } from 'fast-xml-parser'; import OpenAI from 'openai'; -import { Tool, AgentMessage, AssistantMessage, TEXT_TYPE, CHUNK_TYPE, ASSISTANT_ROLE, ProcessingInfo, PROCESSING_TYPE } from '../types/types'; -import { getReactPrompt } from './prompts'; -import { XMLParser, XMLBuilder } from 'fast-xml-parser'; -import { Vectorstore } from '../vectorstore/Vectorstore'; import { ChatCompletionMessageParam } from 'openai/resources'; -import dotenv from 'dotenv'; -import { CalculateTool } from '../tools/CalculateTool'; -import { RAGTool } from '../tools/RAGTool'; -import { DataAnalysisTool } from '../tools/DataAnalysisTool'; -import { WebsiteInfoScraperTool } from '../tools/WebsiteInfoScraperTool'; -import { SearchTool } from '../tools/SearchTool'; -import { NoTool } from '../tools/NoTool'; -import { v4 as uuidv4 } from 'uuid'; import { AnswerParser } from '../response_parsers/AnswerParser'; import { StreamedAnswerParser } from '../response_parsers/StreamedAnswerParser'; +import { CalculateTool } from '../tools/CalculateTool'; import { CreateCSVTool } from '../tools/CreateCSVTool'; +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 { AgentMessage, AssistantMessage, PROCESSING_TYPE, ProcessingInfo, Tool } from '../types/types'; +import { Vectorstore } from '../vectorstore/Vectorstore'; +import { getReactPrompt } from './prompts'; dotenv.config(); @@ -25,7 +24,7 @@ dotenv.config(); export class Agent { // Private properties private client: OpenAI; - private tools: Record<string, Tool<any>>; + private tools: Record<string, Tool<any>>; // bcz: need a real type here private messages: AgentMessage[] = []; private interMessages: AgentMessage[] = []; private vectorstore: Vectorstore; @@ -102,7 +101,7 @@ export class Agent { ignoreAttributes: false, attributeNamePrefix: '@_', textNodeName: '_text', - isArray: (name, jpath, isLeafNode, isAttribute) => ['query', 'url'].indexOf(name) !== -1, + isArray: (name /* , jpath, isLeafNode, isAttribute */) => ['query', 'url'].indexOf(name) !== -1, }); const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@_' }); @@ -167,7 +166,7 @@ export class Agent { if (currentAction) { try { // Process the action with its input - const observation = await this.processAction(currentAction, actionInput.inputs); + const observation = (await this.processAction(currentAction, actionInput.inputs)) as any; // bcz: really need a type here const nextPrompt = [{ type: 'text', text: `<stage number="${i + 1}" role="user"> <observation>` }, ...observation, { type: 'text', text: '</observation></stage>' }]; console.log(observation); this.interMessages.push({ role: 'user', content: nextPrompt }); @@ -214,7 +213,7 @@ export class Agent { // Process each chunk of the streamed response for await (const chunk of stream) { - let content = chunk.choices[0]?.delta?.content || ''; + const content = chunk.choices[0]?.delta?.content || ''; fullResponse += content; // Parse the streamed content character by character @@ -267,7 +266,7 @@ export class Agent { * @param actionInput The inputs for the action. * @returns The result of the action. */ - private async processAction(action: string, actionInput: any): Promise<any> { + private async processAction(action: string, actionInput: unknown): Promise<unknown> { if (!(action in this.tools)) { throw new Error(`Unknown action: ${action}`); } diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index d4deff78b..613cb7078 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -1,30 +1,29 @@ -import { action, computed, makeObservable, observable, observe, reaction, runInAction, ObservableSet } from 'mobx'; +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 } from '../../../../../ClientUtils'; import { Doc, DocListCast } from '../../../../../fields/Doc'; +import { DocData, DocViews } from '../../../../../fields/DocSymbols'; import { CsvCast, DocCast, PDFCast, RTFCast, StrCast } from '../../../../../fields/Types'; +import { Networking } from '../../../../Network'; +import { DocUtils } from '../../../../documents/DocUtils'; import { DocumentType } from '../../../../documents/DocumentTypes'; import { Docs } from '../../../../documents/Documents'; +import { DocumentManager } from '../../../../util/DocumentManager'; import { LinkManager } from '../../../../util/LinkManager'; import { ViewBoxAnnotatableComponent } from '../../../DocComponent'; +import { DocumentView } from '../../DocumentView'; import { FieldView, FieldViewProps } from '../../FieldView'; +import { PDFBox } from '../../PDFBox'; +import { Agent } from '../agentsystem/Agent'; +import { ASSISTANT_ROLE, AssistantMessage, CHUNK_TYPE, Citation, ProcessingInfo, SimplifiedChunk, TEXT_TYPE } from '../types/types'; +import { Vectorstore } from '../vectorstore/Vectorstore'; import './ChatBox.scss'; import MessageComponentBox from './MessageComponent'; -import { ASSISTANT_ROLE, AssistantMessage, Citation, CHUNK_TYPE, TEXT_TYPE, SimplifiedChunk, ProcessingInfo } from '../types/types'; -import { Vectorstore } from '../vectorstore/Vectorstore'; -import { Agent } from '../agentsystem/Agent'; -import dotenv from 'dotenv'; -import { DocData, DocViews } from '../../../../../fields/DocSymbols'; -import { DocumentManager } from '../../../../util/DocumentManager'; -import { v4 as uuidv4 } from 'uuid'; -import { DocUtils } from '../../../../documents/DocUtils'; -import { ClientUtils } from '../../../../../ClientUtils'; import { ProgressBar } from './ProgressBar'; -import { DocumentView } from '../../DocumentView'; -import { Networking } from '../../../../Network'; -import { PDFViewer } from '../../../pdf/PDFViewer'; -import { PDFBox } from '../../PDFBox'; dotenv.config(); @@ -247,7 +246,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { * @param event The form submission event. */ @action - askGPT = async (event: React.FormEvent): Promise<any> => { + askGPT = async (event: React.FormEvent): Promise<void> => { event.preventDefault(); this.inputValue = ''; @@ -413,7 +412,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const chunkId = citation.chunk_id; // Loop through the linked documents to find the matching chunk and handle its display - for (let doc of currentLinkedDocs) { + for (const doc of currentLinkedDocs) { if (doc.chunk_simpl) { const docChunkSimpl = JSON.parse(StrCast(doc.chunk_simpl)) as { chunks: SimplifiedChunk[] }; const foundChunk = docChunkSimpl.chunks.find(chunk => chunk.chunkId === chunkId); @@ -422,24 +421,26 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { switch (foundChunk.chunkType) { case CHUNK_TYPE.IMAGE: case CHUNK_TYPE.TABLE: - const values = foundChunk.location?.replace(/[\[\]]/g, '').split(','); + { + const values = foundChunk.location?.replace(/[[\]]/g, '').split(','); - if (values?.length !== 4) { - console.error('Location string must contain exactly 4 numbers'); - return; - } + if (values?.length !== 4) { + console.error('Location string must contain exactly 4 numbers'); + return; + } - const x1 = parseFloat(values[0]) * Doc.NativeWidth(doc); - const y1 = parseFloat(values[1]) * Doc.NativeHeight(doc) + foundChunk.startPage * Doc.NativeHeight(doc); - const x2 = parseFloat(values[2]) * Doc.NativeWidth(doc); - const y2 = parseFloat(values[3]) * Doc.NativeHeight(doc) + foundChunk.startPage * Doc.NativeHeight(doc); + const x1 = parseFloat(values[0]) * Doc.NativeWidth(doc); + const y1 = parseFloat(values[1]) * Doc.NativeHeight(doc) + foundChunk.startPage * Doc.NativeHeight(doc); + const x2 = parseFloat(values[2]) * Doc.NativeWidth(doc); + const y2 = parseFloat(values[3]) * Doc.NativeHeight(doc) + foundChunk.startPage * Doc.NativeHeight(doc); - const annotationKey = Doc.LayoutFieldKey(doc) + '_annotations'; + const annotationKey = Doc.LayoutFieldKey(doc) + '_annotations'; - const existingDoc = DocListCast(doc[DocData][annotationKey]).find(d => d.citation_id === citation.citation_id); - const highlightDoc = existingDoc ?? this.createImageCitationHighlight(x1, y1, x2, y2, citation, annotationKey, doc); + const existingDoc = DocListCast(doc[DocData][annotationKey]).find(d => d.citation_id === citation.citation_id); + const highlightDoc = existingDoc ?? this.createImageCitationHighlight(x1, y1, x2, y2, citation, annotationKey, doc); - DocumentManager.Instance.showDocument(highlightDoc, { willZoomCentered: true }, () => {}); + DocumentManager.Instance.showDocument(highlightDoc, { willZoomCentered: true }, () => {}); + } break; case CHUNK_TYPE.TEXT: this.citationPopup = { text: citation.direct_text ?? 'No text available', visible: true }; @@ -695,7 +696,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { </div> )} <div className="chat-header"> - <h2>{this.userName()}'s AI Assistant</h2> + <h2>{this.userName()}'s AI Assistant</h2> </div> <div className="chat-messages" ref={this.messagesRef}> {this.history.map((message, index) => ( diff --git a/src/client/views/nodes/chatbot/response_parsers/AnswerParser.ts b/src/client/views/nodes/chatbot/response_parsers/AnswerParser.ts index 3b4fdb6f5..1ac753790 100644 --- a/src/client/views/nodes/chatbot/response_parsers/AnswerParser.ts +++ b/src/client/views/nodes/chatbot/response_parsers/AnswerParser.ts @@ -1,5 +1,5 @@ -import { ASSISTANT_ROLE, AssistantMessage, Citation, CHUNK_TYPE, TEXT_TYPE, getChunkType, ProcessingInfo } from '../types/types'; import { v4 as uuid } from 'uuid'; +import { ASSISTANT_ROLE, AssistantMessage, Citation, ProcessingInfo, TEXT_TYPE, getChunkType } from '../types/types'; export class AnswerParser { static parse(xml: string, processingInfo: ProcessingInfo[]): AssistantMessage { @@ -22,8 +22,8 @@ export class AnswerParser { } let rawTextContent = answerMatch[1].trim(); - let content: AssistantMessage['content'] = []; - let citations: Citation[] = []; + const content: AssistantMessage['content'] = []; + const citations: Citation[] = []; let contentIndex = 0; // Remove citations and follow-up questions from rawTextContent @@ -43,6 +43,7 @@ export class AnswerParser { if (citationsMatch) { const citationsContent = citationsMatch[1]; while ((citationMatch = citationRegex.exec(citationsContent)) !== null) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_, index, chunk_id, type, direct_text] = citationMatch; const citation_id = uuid(); citationMap.set(index, citation_id); @@ -102,7 +103,7 @@ export class AnswerParser { } } - let followUpQuestions: string[] = []; + const followUpQuestions: string[] = []; if (followUpQuestionsMatch) { const questionsText = followUpQuestionsMatch[1]; let questionMatch; diff --git a/src/client/views/nodes/chatbot/response_parsers/StreamedAnswerParser.ts b/src/client/views/nodes/chatbot/response_parsers/StreamedAnswerParser.ts index 3585cab4a..4149f3da9 100644 --- a/src/client/views/nodes/chatbot/response_parsers/StreamedAnswerParser.ts +++ b/src/client/views/nodes/chatbot/response_parsers/StreamedAnswerParser.ts @@ -1,5 +1,3 @@ -import { threadId } from 'worker_threads'; - enum ParserState { Outside, InGroundedText, diff --git a/src/client/views/nodes/chatbot/tools/BaseTool.ts b/src/client/views/nodes/chatbot/tools/BaseTool.ts index b57f1c8e4..10780617b 100644 --- a/src/client/views/nodes/chatbot/tools/BaseTool.ts +++ b/src/client/views/nodes/chatbot/tools/BaseTool.ts @@ -1,17 +1,17 @@ import { Tool } from '../types/types'; -export abstract class BaseTool<T extends Record<string, any> = Record<string, any>> implements Tool<T> { +export abstract class BaseTool<T extends Record<string, unknown> = Record<string, unknown>> implements Tool<T> { constructor( public name: string, public description: string, - public parameters: Record<string, any>, + public parameters: Record<string, unknown>, public citationRules: string, public briefSummary: string ) {} - abstract execute(args: T): Promise<any>; + abstract execute(args: T): Promise<unknown>; - getActionRule(): Record<string, any> { + getActionRule(): Record<string, unknown> { return { [this.name]: { name: this.name, diff --git a/src/client/views/nodes/chatbot/tools/CalculateTool.ts b/src/client/views/nodes/chatbot/tools/CalculateTool.ts index 74b7ca27b..77ab1b39b 100644 --- a/src/client/views/nodes/chatbot/tools/CalculateTool.ts +++ b/src/client/views/nodes/chatbot/tools/CalculateTool.ts @@ -18,7 +18,7 @@ export class CalculateTool extends BaseTool<{ expression: string }> { ); } - async execute(args: { expression: string }): Promise<any> { + async execute(args: { expression: string }): Promise<unknown> { // Note: Using eval() can be dangerous. Consider using a safer alternative. const result = eval(args.expression); return [{ type: 'text', text: result.toString() }]; diff --git a/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts b/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts index 55015846b..d3ded0de0 100644 --- a/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts +++ b/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts @@ -28,7 +28,7 @@ export class CreateCSVTool extends BaseTool<{ csvData: string; filename: string this._handleCSVResult = handleCSVResult; } - async execute(args: { csvData: string; filename: string }): Promise<any> { + async execute(args: { csvData: string; filename: string }): Promise<unknown> { try { console.log('Creating CSV file:', args.filename, ' with data:', args.csvData); // Post the raw CSV data to the createCSV endpoint on the server diff --git a/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts b/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts index 573428179..1e479a62c 100644 --- a/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts +++ b/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts @@ -25,7 +25,7 @@ export class GetDocsContentTool extends BaseTool<{ title: string; document_ids: this._docView = docView; } - async execute(args: { title: string; document_ids: string[] }): Promise<any> { + async execute(args: { title: string; document_ids: string[] }): Promise<unknown> { // Note: Using eval() can be dangerous. Consider using a safer alternative. const docs = args.document_ids.map(doc_id => DocCast(DocServer.GetCachedRefField(doc_id))); const collection = Docs.Create.FreeformDocument(docs, { title: args.title }); diff --git a/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts b/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts index a12ee46e5..2e663fed1 100644 --- a/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts +++ b/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts @@ -33,7 +33,7 @@ export class DataAnalysisTool extends BaseTool<{ csv_file_name: string | string[ return file?.id; } - async execute(args: { csv_file_name: string | string[] }): Promise<any> { + async execute(args: { csv_file_name: string | string[] }): Promise<unknown> { const filenames = Array.isArray(args.csv_file_name) ? args.csv_file_name : [args.csv_file_name]; const results = []; diff --git a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts index f970ca8ee..903f3f69c 100644 --- a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts +++ b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts @@ -18,7 +18,7 @@ export class GetDocsTool extends BaseTool<{ title: string; document_ids: string[ this._docView = docView; } - async execute(args: { title: string; document_ids: string[] }): Promise<any> { + async execute(args: { title: string; document_ids: string[] }): Promise<unknown> { // Note: Using eval() can be dangerous. Consider using a safer alternative. const docs = args.document_ids.map(doc_id => DocCast(DocServer.GetCachedRefField(doc_id))); const collection = Docs.Create.FreeformDocument(docs, { title: args.title }); diff --git a/src/client/views/nodes/chatbot/tools/NoTool.ts b/src/client/views/nodes/chatbot/tools/NoTool.ts index 1f0830a77..edd3160ec 100644 --- a/src/client/views/nodes/chatbot/tools/NoTool.ts +++ b/src/client/views/nodes/chatbot/tools/NoTool.ts @@ -1,7 +1,7 @@ // tools/NoTool.ts import { BaseTool } from './BaseTool'; -export class NoTool extends BaseTool<{}> { +export class NoTool extends BaseTool<Record<string, unknown>> { constructor() { super( 'no_tool', @@ -12,7 +12,8 @@ export class NoTool extends BaseTool<{}> { ); } - async execute(args: {}): Promise<any> { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async execute(args: object): Promise<unknown> { return [{ type: 'text', text: 'No tool used. Proceed with answering the question.' }]; } } diff --git a/src/client/views/nodes/chatbot/tools/RAGTool.ts b/src/client/views/nodes/chatbot/tools/RAGTool.ts index f4b7b42ea..4cc2f26ff 100644 --- a/src/client/views/nodes/chatbot/tools/RAGTool.ts +++ b/src/client/views/nodes/chatbot/tools/RAGTool.ts @@ -1,10 +1,7 @@ -import { BaseTool } from './BaseTool'; -import { Vectorstore } from '../vectorstore/Vectorstore'; -import { RAGChunk } from '../types/types'; -import * as fs from 'fs'; import { Networking } from '../../../../Network'; -import { file } from 'jszip'; -import { ChatCompletion, ChatCompletionContentPart, ChatCompletionMessageParam } from 'openai/resources'; +import { RAGChunk } from '../types/types'; +import { Vectorstore } from '../vectorstore/Vectorstore'; +import { BaseTool } from './BaseTool'; export class RAGTool extends BaseTool { constructor(private vectorstore: Vectorstore) { @@ -59,13 +56,13 @@ export class RAGTool extends BaseTool { ); } - async execute(args: { hypothetical_document_chunk: string }): Promise<any> { + async execute(args: { hypothetical_document_chunk: string }): Promise<unknown> { const relevantChunks = await this.vectorstore.retrieve(args.hypothetical_document_chunk); const formatted_chunks = await this.getFormattedChunks(relevantChunks); return formatted_chunks; } - async getFormattedChunks(relevantChunks: RAGChunk[]): Promise<any> { + async getFormattedChunks(relevantChunks: RAGChunk[]): Promise<unknown> { try { const { formattedChunks } = await Networking.PostToServer('/formatChunks', { relevantChunks }); diff --git a/src/client/views/nodes/chatbot/tools/SearchTool.ts b/src/client/views/nodes/chatbot/tools/SearchTool.ts index b926cbadc..3a4668422 100644 --- a/src/client/views/nodes/chatbot/tools/SearchTool.ts +++ b/src/client/views/nodes/chatbot/tools/SearchTool.ts @@ -1,7 +1,6 @@ -import { max } from 'lodash'; +import { v4 as uuidv4 } from 'uuid'; import { Networking } from '../../../../Network'; import { BaseTool } from './BaseTool'; -import { v4 as uuidv4 } from 'uuid'; export class SearchTool extends BaseTool<{ query: string | string[] }> { private _addLinkedUrlDoc: (url: string, id: string) => void; @@ -25,7 +24,7 @@ export class SearchTool extends BaseTool<{ query: string | string[] }> { this._max_results = max_results; } - async execute(args: { query: string | string[] }): Promise<any> { + async execute(args: { query: string | string[] }): Promise<unknown> { const queries = Array.isArray(args.query) ? args.query : [args.query]; const allResults = []; diff --git a/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts b/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts index 2118218f6..1efb389b8 100644 --- a/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts +++ b/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts @@ -1,6 +1,6 @@ +import { v4 as uuidv4 } from 'uuid'; import { Networking } from '../../../../Network'; import { BaseTool } from './BaseTool'; -import { v4 as uuidv4 } from 'uuid'; export class WebsiteInfoScraperTool extends BaseTool<{ url: string | string[] }> { private _addLinkedUrlDoc: (url: string, id: string) => void; @@ -63,7 +63,7 @@ export class WebsiteInfoScraperTool extends BaseTool<{ url: string | string[] }> this._addLinkedUrlDoc = addLinkedUrlDoc; } - async execute(args: { url: string | string[] }): Promise<any> { + async execute(args: { url: string | string[] }): Promise<unknown> { const urls = Array.isArray(args.url) ? args.url : [args.url]; const results = []; @@ -74,6 +74,7 @@ export class WebsiteInfoScraperTool extends BaseTool<{ url: string | string[] }> this._addLinkedUrlDoc(url, id); results.push({ type: 'text', text: `<chunk chunk_id=${id} chunk_type=url>\n${website_plain_text}\n</chunk>\n` }); } catch (error) { + console.log(error); results.push({ type: 'text', text: `An error occurred while scraping the website: ${url}` }); } } diff --git a/src/client/views/nodes/chatbot/tools/WikipediaTool.ts b/src/client/views/nodes/chatbot/tools/WikipediaTool.ts index 143d91d80..692dff749 100644 --- a/src/client/views/nodes/chatbot/tools/WikipediaTool.ts +++ b/src/client/views/nodes/chatbot/tools/WikipediaTool.ts @@ -1,8 +1,6 @@ -import { title } from 'process'; +import { v4 as uuidv4 } from 'uuid'; import { Networking } from '../../../../Network'; import { BaseTool } from './BaseTool'; -import axios from 'axios'; -import { v4 as uuidv4 } from 'uuid'; export class WikipediaTool extends BaseTool<{ title: string }> { private _addLinkedUrlDoc: (url: string, id: string) => void; @@ -23,7 +21,7 @@ export class WikipediaTool extends BaseTool<{ title: string }> { this._addLinkedUrlDoc = addLinkedUrlDoc; } - async execute(args: { title: string }): Promise<any> { + async execute(args: { title: string }): Promise<unknown> { try { const { text } = await Networking.PostToServer('/getWikipediaSummary', { title: args.title }); const id = uuidv4(); @@ -31,6 +29,7 @@ export class WikipediaTool extends BaseTool<{ title: string }> { this._addLinkedUrlDoc(url, id); return [{ type: 'text', text: `<chunk chunk_id=${id} chunk_type=csv}> ${text} </chunk>` }]; } catch (error) { + console.log(error); return [{ type: 'text', text: 'An error occurred while fetching the article.' }]; } } diff --git a/src/client/views/nodes/chatbot/types/types.ts b/src/client/views/nodes/chatbot/types/types.ts index f5d14ad6a..2bc7f4952 100644 --- a/src/client/views/nodes/chatbot/types/types.ts +++ b/src/client/views/nodes/chatbot/types/types.ts @@ -52,15 +52,6 @@ export interface ProcessingInfo { content: string; } -export interface AssistantMessage { - role: ASSISTANT_ROLE; - content: MessageContent[]; - follow_up_questions?: string[]; - citations?: Citation[]; - processing_info: ProcessingInfo[]; - loop_summary?: string; -} - export interface MessageContent { index: number; type: TEXT_TYPE; @@ -75,6 +66,14 @@ export interface Citation { citation_id: string; url?: string; } +export interface AssistantMessage { + role: ASSISTANT_ROLE; + content: MessageContent[]; + follow_up_questions?: string[]; + citations?: Citation[]; + processing_info: ProcessingInfo[]; + loop_summary?: string; +} export interface RAGChunk { id: string; @@ -113,14 +112,14 @@ export interface AI_Document { type: string; } -export interface Tool<T extends Record<string, any> = Record<string, any>> { +export interface Tool<T extends Record<string, unknown> = Record<string, unknown>> { name: string; description: string; - parameters: Record<string, any>; + parameters: Record<string, unknown>; citationRules: string; briefSummary: string; - execute: (args: T) => Promise<any>; - getActionRule: () => Record<string, any>; + execute: (args: T) => Promise<unknown>; + getActionRule: () => Record<string, unknown>; } export interface AgentMessage { diff --git a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts index 07a2b73bc..9575277f7 100644 --- a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts +++ b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts @@ -1,11 +1,11 @@ -import { Pinecone, Index, IndexList, PineconeRecord, RecordMetadata, QueryResponse } from '@pinecone-database/pinecone'; +import { Index, IndexList, Pinecone, PineconeRecord, QueryResponse, RecordMetadata } from '@pinecone-database/pinecone'; import { CohereClient } from 'cohere-ai'; import { EmbedResponse } from 'cohere-ai/api'; import dotenv from 'dotenv'; -import { RAGChunk, AI_Document, CHUNK_TYPE } from '../types/types'; import { Doc } from '../../../../../fields/Doc'; import { CsvCast, PDFCast, StrCast } from '../../../../../fields/Types'; import { Networking } from '../../../../Network'; +import { AI_Document, CHUNK_TYPE, RAGChunk } from '../types/types'; dotenv.config(); @@ -103,8 +103,8 @@ export class Vectorstore { const { jobId } = await Networking.PostToServer('/createDocument', { file_path: local_file_path }); // Poll the server for progress updates. - let inProgress: boolean = true; - let result: any = null; + const inProgress = true; + let result: (AI_Document & { doc_id: string }) | null = null; // bcz: is this the correct type?? while (inProgress) { // Polling interval for status updates. await new Promise(resolve => setTimeout(resolve, 2000)); @@ -127,6 +127,9 @@ export class Vectorstore { progressCallback(progress, step); } } + if (!result) { + throw new Error('no result received...'); // bcz: is this an Error? + } // Once completed, process the document and add it to the vectorstore. console.log('Document JSON:', result); @@ -175,7 +178,7 @@ export class Vectorstore { * Indexes the processed document by uploading the document's vector chunks to the Pinecone index. * @param document The processed document containing its chunks and metadata. */ - private async indexDocument(document: any) { + private async indexDocument(document: AI_Document) { console.log('Uploading vectors to content namespace...'); // Prepare Pinecone records for each chunk in the document. diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 7543b3fb1..b5c69bff0 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -51,7 +51,7 @@ interface IViewerProps extends FieldViewProps { * Handles rendering and virtualization of the pdf */ @observer -export class PDFViewer extends ObservableReactComponent { +export class PDFViewer extends ObservableReactComponent<IViewerProps> { static _annotationStyle = addStyleSheet(); constructor(props: IViewerProps) { @@ -68,12 +68,12 @@ export class PDFViewer extends ObservableReactComponent { private _pdfViewer!: PDFJSViewer.PDFViewer; private _styleRule: number | undefined; // stylesheet rule for making hyperlinks clickable private _retries = 0; // number of times tried to create the PDF viewer - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void); private _marqueeref = React.createRef<MarqueeAnnotator>(); - private _annotationLayer: React.RefObject = React.createRef(); + private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); private _disposers: { [name: string]: IReactionDisposer } = {}; - private _viewer: React.RefObject = React.createRef(); - _mainCont: React.RefObject = React.createRef(); + private _viewer: React.RefObject<HTMLDivElement> = React.createRef(); + _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _selectionText: string = ''; private _selectionContent: DocumentFragment | undefined; private _downX: number = 0; @@ -81,9 +81,9 @@ export class PDFViewer extends ObservableReactComponent { private _lastSearch = false; private _viewerIsSetup = false; private _ignoreScroll = false; - private _initialScroll: { loc: Opt; easeFunc: 'linear' | 'ease' | undefined } | undefined; + private _initialScroll: { loc: Opt<number>; easeFunc: 'linear' | 'ease' | undefined } | undefined; private _forcedScroll = true; - _getAnchor: (savedAnnotations: Opt, addAsAnnotation: boolean) => Opt = () => undefined; + _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined; selectionText = () => this._selectionText; selectionContent = () => this._selectionContent; @@ -179,7 +179,7 @@ export class PDFViewer extends ObservableReactComponent { // otherwise it will scroll smoothly. scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => { const mainCont = this._mainCont.current; - let focusSpeed: Opt; + let focusSpeed: Opt<number>; if (doc !== this._props.Document && mainCont) { const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); const scrollTo = ClientUtils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight); @@ -394,30 +394,6 @@ export class PDFViewer extends ObservableReactComponent { } }; - // @action - // createMarquee = (coords: [x1: number, x2: number, y1: number, y2: number]): void => { - // // const hit = document.elementFromPoint(e.clientX, e.clientY); - // // bcz: Change. drag selecting requires that preventDefault is NOT called. This used to happen in DocumentView, - // // but that's changed, so this shouldn't be needed. - // // if (hit && hit.localName === "span" && this.annotationsActive(true)) { // drag selecting text stops propagation - // // e.button === 0 && e.stopPropagation(); - // // } - // // if alt+left click, drag and annotate - // this._downX = coords[0]; - // this._downY = coords[2]; - - // if ((this._props.Document._freeform_scale || 1) !== 1) return; - // this._props.select(false); - // MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - // this.isAnnotating = true; - // this._textSelecting = false; - // // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee. - // this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, 'htmlAnnotation', { 'pointer-events': 'none' }); - - // this._marqueeref.current?.onInitiateSelection([coords[0], coords[2]]); - // this._marqueeref.current?.onTerminateSelection(); - // }; - @action finishMarquee = (/* x?: number, y?: number */) => { this._getAnchor = AnchorMenu.Instance?.GetAnchor; @@ -495,7 +471,7 @@ export class PDFViewer extends ObservableReactComponent { // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks }; - setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void) => { + setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => { this._setPreviewCursor = func; }; @@ -520,7 +496,6 @@ export class PDFViewer extends ObservableReactComponent { return ( <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this._props.Document), transform: `scale(${NumCast(this._props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}> {inlineAnnos.map(anno => ( - // eslint-disable-next-line react/jsx-props-no-spreading <Annotation {...this._props} fieldKey={this._props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} containerDataDoc={this._props.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} /> ))} </div> @@ -534,7 +509,7 @@ export class PDFViewer extends ObservableReactComponent { panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [ClientUtils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none'; const isInk = doc.layout_isSvg && !props?.LayoutTemplateString; @@ -554,7 +529,6 @@ export class PDFViewer extends ObservableReactComponent { pointerEvents: Doc.ActiveTool !== InkTool.None ? 'all' : undefined, }}> <CollectionFreeFormView - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} NativeWidth={returnZero} NativeHeight={returnZero} |
