aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eslint.config.mjs2
-rw-r--r--src/client/documents/Documents.ts9
-rw-r--r--src/client/util/CurrentUserUtils.ts8
-rw-r--r--src/client/util/Scripting.ts13
-rw-r--r--src/client/views/MainView.tsx7
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx5
-rw-r--r--src/client/views/nodes/PDFBox.tsx21
-rw-r--r--src/client/views/nodes/RecordingBox/ProgressBar.tsx2
-rw-r--r--src/client/views/nodes/chatbot/agentsystem/Agent.ts33
-rw-r--r--src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx61
-rw-r--r--src/client/views/nodes/chatbot/response_parsers/AnswerParser.ts9
-rw-r--r--src/client/views/nodes/chatbot/response_parsers/StreamedAnswerParser.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/BaseTool.ts8
-rw-r--r--src/client/views/nodes/chatbot/tools/CalculateTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/CreateCSVTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/GetDocsTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/NoTool.ts5
-rw-r--r--src/client/views/nodes/chatbot/tools/RAGTool.ts13
-rw-r--r--src/client/views/nodes/chatbot/tools/SearchTool.ts5
-rw-r--r--src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts5
-rw-r--r--src/client/views/nodes/chatbot/tools/WikipediaTool.ts7
-rw-r--r--src/client/views/nodes/chatbot/types/types.ts25
-rw-r--r--src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts13
-rw-r--r--src/client/views/pdf/PDFViewer.tsx46
-rw-r--r--src/server/ApiManagers/AssistantManager.ts178
27 files changed, 215 insertions, 272 deletions
diff --git a/eslint.config.mjs b/eslint.config.mjs
index aebdc20d0..f7063caa5 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -48,7 +48,7 @@ export default [
'no-return-assign': 'error',
'no-await-in-loop': 'error',
'no-loop-func': 'error',
- '@typescript-eslint/no-cond-assign': 'error',
+ 'no-cond-assign': 'error',
'no-use-before-define': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'no-restricted-globals': ['error', 'event'],
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e0a9918f4..d77f76b81 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,5 +1,3 @@
-/* eslint-disable prefer-destructuring */
-/* eslint-disable default-param-last */
/* eslint-disable no-use-before-define */
import { reaction } from 'mobx';
import { basename } from 'path';
@@ -671,7 +669,6 @@ export namespace Docs {
* only when creating a DockDocument from the current user's already existing
* main document.
*/
- // eslint-disable-next-line default-param-last
function InstanceFromProto(proto: Doc, data: FieldType | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDocIn?: Doc, noView?: boolean) {
const placeholderDoc = placeholderDocIn;
const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_"
@@ -732,7 +729,6 @@ export namespace Docs {
return dataDoc;
}
- // eslint-disable-next-line default-param-last
export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) {
const imgField = url instanceof ImageField ? url : url ? new ImageField(url) : undefined;
return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField?.url.href ?? '-no image-'), ...options }, undefined, undefined, undefined, overwriteDoc);
@@ -751,7 +747,6 @@ export namespace Docs {
* @param fieldKey the field that the compiled script is written into.
* @returns the Scripting Doc
*/
- // eslint-disable-next-line default-param-last
export function ScriptingDocument(script: Opt<ScriptField> | null, options: DocumentOptions = {}, fieldKey?: string) {
return InstanceFromProto(Prototypes.get(DocumentType.SCRIPTING), script || undefined, { ...options, layout: fieldKey ? `<ScriptingBox {...props} fieldKey={'${fieldKey}'}/>` /* ScriptingBox.LayoutString(fieldKey) */ : undefined });
}
@@ -759,7 +754,6 @@ export namespace Docs {
export function ChatDocument(options?: DocumentOptions) {
return InstanceFromProto(Prototypes.get(DocumentType.CHAT), undefined, { ...(options || {}) });
}
- // eslint-disable-next-line default-param-last
export function VideoDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
return InstanceFromProto(Prototypes.get(DocumentType.VID), new VideoField(url), options, undefined, undefined, undefined, overwriteDoc);
}
@@ -779,7 +773,6 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.DIAGRAM), undefined, options);
}
- // eslint-disable-next-line default-param-last
export function AudioDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
return InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(url), options, undefined, undefined, undefined, overwriteDoc);
}
@@ -839,7 +832,6 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey);
}
- // eslint-disable-next-line default-param-last
export function LinkDocument(source: Doc, target: Doc, options: DocumentOptions = {}, id?: string) {
const linkDoc = InstanceFromProto(
Prototypes.get(DocumentType.LINK),
@@ -883,7 +875,6 @@ export namespace Docs {
return ink;
}
- // eslint-disable-next-line default-param-last
export function PdfDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) {
const width = options._width || undefined;
const height = options._height || undefined;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 96b30c429..09adf70f5 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -2,7 +2,7 @@
import { reaction, runInAction } from "mobx";
import * as rp from 'request-promise';
import { ClientUtils, OmitKeys } from "../../ClientUtils";
-import { Doc, DocListCast, DocListCastAsync, FieldType, Opt, StrListCast } from "../../fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from "../../fields/Doc";
import { DocData } from "../../fields/DocSymbols";
import { InkTool } from "../../fields/InkField";
import { List } from "../../fields/List";
@@ -366,11 +366,11 @@ pie title Minerals in my tap water
{key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, title_custom: true, waitForDoubleClickToClick: 'never'}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}},
{key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
{key: "DataViz", creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts), opts: { _width: 300, _height: 300 }},
- {key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 500, _height: 500, }},
+ {key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 500, _height: 500, }},
{key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}},
{key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}},
{key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, _layout_dontCenter:'xy', dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }},
- {key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _layout_fitWidth: true, _freeform_backgroundGrid: true, }},
+ {key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _layout_fitWidth: true, _freeform_backgroundGrid: true, }},
{key: "Slide", creator: opts => Docs.Create.TreeDocument([], opts), opts: { _width: 300, _height: 200, _type_collection: CollectionViewType.Tree,
treeView_HasOverlay: true, _text_fontSize: "20px", _layout_autoHeight: true,
dropAction:dropActionType.move, treeView_Type: TreeViewType.outline,
@@ -801,7 +801,7 @@ pie title Minerals in my tap water
{ title: "Num", icon:"", toolTip: "Frame # (click to toggle edit mode)",btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
{ title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
- { title: "Filter", icon: "=", toolTip: "Filter cards by tags", subMenu: CurrentUserUtils.tagGroupTools(),ignoreClick:true, toolType:DocumentType.COL, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, btnType: ButtonType.MultiToggleButton, width: 30, backgroundColor: doc.userVariantColor},
+ { title: "Filter", icon: "=", toolTip: "Filter cards by tags", subMenu: CurrentUserUtils.tagGroupTools(),ignoreClick:true, toolType:DocumentType.COL, funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, btnType: ButtonType.MultiToggleButton, width: 30, backgroundColor: doc.userVariantColor as string},
{ title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: {hidden: `IsExploreMode()`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
{ title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode, true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 3e7a2df02..c7b86815a 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -1,7 +1,7 @@
// export const ts = (window as any).ts;
// import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts'
// import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts'
-// import typescriptlib from 'type_decls.d';
+import typescriptlib from 'type_decls.d';
import * as ts from 'typescript';
import { Doc, FieldType } from '../../fields/Doc';
import { RefField } from '../../fields/RefField';
@@ -29,7 +29,7 @@ export interface CompiledScript {
readonly compiled: true;
readonly originalScript: string;
// eslint-disable-next-line no-use-before-define
- readonly options: Readonly;
+ readonly options: Readonly<ScriptOptions>;
run(args?: { [name: string]: unknown }, onError?: (res: string) => void, errorVal?: unknown): ScriptResult;
}
@@ -60,7 +60,6 @@ function Run(script: string | undefined, customParams: string[], diagnostics: ts
// let params: any[] = [Docs, ...fieldTypes];
const compiledFunction = (() => {
try {
- // eslint-disable-next-line no-new-func
return new Function(...paramNames, `return ${script}`);
} catch (e) {
console.log(e);
@@ -69,10 +68,8 @@ function Run(script: string | undefined, customParams: string[], diagnostics: ts
})();
if (!compiledFunction) return { compiled: false, errors };
const { capturedVariables = {} } = options;
- // eslint-disable-next-line default-param-last
const run = (args: { [name: string]: unknown } = {}, onError?: (e: string) => void, errorVal?: ts.Diagnostic): ScriptResult => {
const argsArray: unknown[] = [];
- // eslint-disable-next-line no-restricted-syntax
for (const name of customParams) {
if (name !== 'this') {
argsArray.push(name in args ? args[name] : capturedVariables[name]);
@@ -154,7 +151,7 @@ class ScriptingCompilerHost {
export type Traverser = (node: ts.Node, indentation: string) => boolean | void;
export type TraverserParam = Traverser | { onEnter: Traverser; onLeave: Traverser };
export type Transformer = {
- transformer: ts.TransformerFactory;
+ transformer: ts.TransformerFactory<ts.Node>;
getVars?: () => { [name: string]: FieldType };
};
export interface ScriptOptions {
@@ -224,7 +221,6 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
if ('this' in params || 'this' in capturedVariables) {
paramNames.push('this');
}
- // eslint-disable-next-line no-restricted-syntax
for (const key in params) {
if (key !== 'this') {
paramNames.push(key);
@@ -234,7 +230,6 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const val = params[key];
return `${key}: ${val}`;
});
- // eslint-disable-next-line no-restricted-syntax
for (const key in capturedVariables) {
if (key !== 'this') {
const val = capturedVariables[key];
@@ -248,7 +243,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const funcScript = `(function(${paramString})${reqTypes} { ${body} })`;
host.writeFile('file.ts', funcScript);
- // if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
+ if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
const program = ts.createProgram(['file.ts'], {}, host);
const testResult = program.emit();
const outputText = host.readFile('file.js');
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()}&apos;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}
diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts
index e940fb121..b4ebb1eae 100644
--- a/src/server/ApiManagers/AssistantManager.ts
+++ b/src/server/ApiManagers/AssistantManager.ts
@@ -1,23 +1,19 @@
+import { Readability } from '@mozilla/readability';
+import axios from 'axios';
+import { spawn } from 'child_process';
import * as fs from 'fs';
-import { createReadStream, writeFile } from 'fs';
+import { writeFile } from 'fs';
+import { google } from 'googleapis';
+import { JSDOM } from 'jsdom';
import OpenAI from 'openai';
import * as path from 'path';
+import * as puppeteer from 'puppeteer';
import { promisify } from 'util';
import * as uuid from 'uuid';
-import { filesDirectory, publicDirectory } from '../SocketData';
+import { AI_Document } from '../../client/views/nodes/chatbot/types/types';
import { Method } from '../RouteManager';
+import { filesDirectory, publicDirectory } from '../SocketData';
import ApiManager, { Registration } from './ApiManager';
-import axios from 'axios';
-import { RAGChunk } from '../../client/views/nodes/chatbot/types/types';
-import { UnstructuredClient } from 'unstructured-client';
-import { PartitionResponse } from 'unstructured-client/sdk/models/operations';
-import { ChunkingStrategy, Strategy } from 'unstructured-client/sdk/models/shared';
-import * as cheerio from 'cheerio';
-import { google } from 'googleapis';
-import * as puppeteer from 'puppeteer';
-import { JSDOM } from 'jsdom';
-import { Readability } from '@mozilla/readability';
-import { spawn } from 'child_process';
// Enumeration of directories where different file types are stored
export enum Directory {
@@ -34,8 +30,8 @@ export enum Directory {
}
// In-memory job tracking
-let jobResults: { [key: string]: any } = {};
-let jobProgress: { [key: string]: any } = {};
+const jobResults: { [key: string]: unknown } = {};
+const jobProgress: { [key: string]: unknown } = {};
/**
* Constructs a normalized path to a file in the server's file system.
@@ -81,10 +77,10 @@ export default class AssistantManager extends ApiManager {
*/
protected initialize(register: Registration): void {
// Initialize OpenAI API with client key
- const openai = new OpenAI({
+ const openai = new OpenAI({ // bcz: is this needed? variable is never used...
apiKey: process.env._CLIENT_OPENAI_KEY,
dangerouslyAllowBrowser: true,
- });
+ }); // prettier-ignore
// Initialize Google Custom Search API
const customsearch = google.customsearch('v1');
@@ -107,11 +103,11 @@ export default class AssistantManager extends ApiManager {
});
const summary = response.data.query.search[0]?.snippet || 'No article found with that title.';
res.send({ text: summary });
- } catch (error: any) {
+ } catch (error) {
console.error('Error retrieving Wikipedia summary:', error);
res.status(500).send({
error: 'Error retrieving article summary from Wikipedia.',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know what the error type contains...
});
}
},
@@ -134,17 +130,17 @@ export default class AssistantManager extends ApiManager {
});
const results =
- response.data.items?.map((item: any) => ({
+ response.data.items?.map(item => ({
url: item.link,
snippet: item.snippet,
})) || [];
res.send({ results });
- } catch (error: any) {
+ } catch (error) {
console.error('Error performing web search:', error);
res.status(500).send({
error: 'Failed to perform web search',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know wha tthe error type contains...
});
}
},
@@ -170,16 +166,16 @@ export default class AssistantManager extends ApiManager {
* @param retries The number of retry attempts.
* @param backoff Initial backoff time in milliseconds.
*/
- const fetchWithRetry = async (url: string, retries = 3, backoff = 300) => {
+ const fetchWithRetry = async (url: string, retries = 3, backoff = 300): Promise<unknown> => {
try {
const response = await axiosInstance.get(url);
return response.data;
- } catch (error: any) {
- if (retries > 0 && error.response?.status === 429) {
+ } catch (error) {
+ if (retries > 0 && (error as { response: { status: number } }).response?.status === 429) { // bcz: don't know the error type
console.log(`Rate limited. Retrying in ${backoff}ms...`);
await delay(backoff);
return fetchWithRetry(url, retries - 1, backoff * 2);
- }
+ } // prettier-ignore
throw error;
}
};
@@ -199,11 +195,11 @@ export default class AssistantManager extends ApiManager {
try {
const data = await fetchWithRetry(url);
res.send({ data });
- } catch (error: any) {
+ } catch (error) {
console.error('Error fetching the URL:', error);
res.status(500).send({
error: 'Failed to fetch the URL',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know wha tthe error type contains...
});
}
},
@@ -241,11 +237,11 @@ export default class AssistantManager extends ApiManager {
} else {
res.status(500).send({ error: 'Failed to extract readable content' });
}
- } catch (error: any) {
+ } catch (error) {
console.error('Error scraping website:', error);
res.status(500).send({
error: 'Failed to scrape website',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know wha tthe error type contains...
});
}
},
@@ -267,15 +263,16 @@ export default class AssistantManager extends ApiManager {
const jobId = uuid.v4();
// Spawn the Python process and track its progress/output
+ // eslint-disable-next-line no-use-before-define
spawnPythonProcess(jobId, file_name, file_data);
// Send the job ID back to the client for tracking
res.send({ jobId });
- } catch (error: any) {
+ } catch (error) {
console.error('Error initiating document creation:', error);
res.status(500).send({
error: 'Failed to initiate document creation',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know wha tthe error type contains...
});
}
},
@@ -307,13 +304,13 @@ export default class AssistantManager extends ApiManager {
const { jobId } = req.params; // Get the job ID from the URL parameters
// Check if the job result is available
if (jobResults[jobId]) {
- const result = jobResults[jobId];
+ const result = jobResults[jobId] as AI_Document & { status: string };
// If the result contains image or table chunks, save the base64 data as image files
if (result.chunks && Array.isArray(result.chunks)) {
for (const chunk of result.chunks) {
if (chunk.metadata && (chunk.metadata.type === 'image' || chunk.metadata.type === 'table')) {
- let files_directory = '/files/chunk_images/';
+ const files_directory = '/files/chunk_images/';
const directory = path.join(publicDirectory, files_directory);
// Ensure the directory exists or create it
@@ -338,7 +335,7 @@ export default class AssistantManager extends ApiManager {
}
}
}
- result['status'] = 'completed';
+ result.status = 'completed';
} else {
result.status = 'pending';
}
@@ -429,11 +426,11 @@ export default class AssistantManager extends ApiManager {
// Send the file URL and UUID back to the client
res.send({ fileUrl, id: uuidv4 });
- } catch (error: any) {
+ } catch (error) {
console.error('Error creating CSV file:', error);
res.status(500).send({
error: 'Failed to create CSV file.',
- details: error.message,
+ details: (error as { message: string }).message ?? error, // bcz: don't know what the error type contains...
});
}
},
@@ -446,59 +443,6 @@ function spawnPythonProcess(jobId: string, file_name: string, file_data: string)
const requirementsPath = path.join(__dirname, '../chunker/requirements.txt');
const pythonScriptPath = path.join(__dirname, '../chunker/pdf_chunker.py');
- // Check if venv exists
- if (!fs.existsSync(venvPath)) {
- console.log('Virtual environment not found. Creating and setting up...');
-
- // Create venv
- const createVenvProcess = spawn('python', ['-m', 'venv', venvPath]);
-
- createVenvProcess.on('close', code => {
- if (code !== 0) {
- console.error(`Failed to create virtual environment. Exit code: ${code}`);
- return;
- }
-
- console.log('Virtual environment created. Installing requirements...');
-
- // Determine the pip path based on the OS
- const pipPath = process.platform === 'win32' ? path.join(venvPath, 'Scripts', 'pip.exe') : path.join(venvPath, 'bin', 'pip3'); // Try 'pip3' for Unix-like systems
-
- if (!fs.existsSync(pipPath)) {
- console.error(`pip executable not found at ${pipPath}`);
- return;
- }
-
- // Install requirements
- const installRequirementsProcess = spawn(pipPath, ['install', '-r', requirementsPath]);
-
- installRequirementsProcess.stdout.on('data', data => {
- console.log(`pip stdout: ${data}`);
- });
-
- installRequirementsProcess.stderr.on('data', data => {
- console.error(`pip stderr: ${data}`);
- });
-
- installRequirementsProcess.on('error', error => {
- console.error(`Error starting pip process: ${error}`);
- });
-
- installRequirementsProcess.on('close', code => {
- if (code !== 0) {
- console.error(`Failed to install requirements. Exit code: ${code}`);
- return;
- }
-
- console.log('Requirements installed. Running Python script...');
- runPythonScript();
- });
- });
- } else {
- console.log('Virtual environment found. Running Python script...');
- runPythonScript();
- }
-
function runPythonScript() {
const pythonPath = process.platform === 'win32' ? path.join(venvPath, 'Scripts', 'python') : path.join(venvPath, 'bin', 'python3');
@@ -530,7 +474,7 @@ function spawnPythonProcess(jobId: string, file_name: string, file_data: string)
};
}
} catch (err) {
- console.error('Progress log from Python:', line);
+ console.error('Progress log from Python:', line, err);
}
}
});
@@ -551,4 +495,56 @@ function spawnPythonProcess(jobId: string, file_name: string, file_data: string)
}
});
}
+ // Check if venv exists
+ if (!fs.existsSync(venvPath)) {
+ console.log('Virtual environment not found. Creating and setting up...');
+
+ // Create venv
+ const createVenvProcess = spawn('python', ['-m', 'venv', venvPath]);
+
+ createVenvProcess.on('close', code => {
+ if (code !== 0) {
+ console.error(`Failed to create virtual environment. Exit code: ${code}`);
+ return;
+ }
+
+ console.log('Virtual environment created. Installing requirements...');
+
+ // Determine the pip path based on the OS
+ const pipPath = process.platform === 'win32' ? path.join(venvPath, 'Scripts', 'pip.exe') : path.join(venvPath, 'bin', 'pip3'); // Try 'pip3' for Unix-like systems
+
+ if (!fs.existsSync(pipPath)) {
+ console.error(`pip executable not found at ${pipPath}`);
+ return;
+ }
+
+ // Install requirements
+ const installRequirementsProcess = spawn(pipPath, ['install', '-r', requirementsPath]);
+
+ installRequirementsProcess.stdout.on('data', data => {
+ console.log(`pip stdout: ${data}`);
+ });
+
+ installRequirementsProcess.stderr.on('data', data => {
+ console.error(`pip stderr: ${data}`);
+ });
+
+ installRequirementsProcess.on('error', error => {
+ console.error(`Error starting pip process: ${error}`);
+ });
+
+ installRequirementsProcess.on('close', closecode => {
+ if (closecode !== 0) {
+ console.error(`Failed to install requirements. Exit code: ${closecode}`);
+ return;
+ }
+
+ console.log('Requirements installed. Running Python script...');
+ runPythonScript();
+ });
+ });
+ } else {
+ console.log('Virtual environment found. Running Python script...');
+ runPythonScript();
+ }
}