aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/ChatBox/Agent.ts12
-rw-r--r--src/client/views/nodes/ChatBox/ChatBox.tsx68
-rw-r--r--src/client/views/nodes/ChatBox/tools/WikipediaTool.ts20
-rw-r--r--src/server/ApiManagers/AssistantManager.ts27
4 files changed, 82 insertions, 45 deletions
diff --git a/src/client/views/nodes/ChatBox/Agent.ts b/src/client/views/nodes/ChatBox/Agent.ts
index 63363ab0b..6757b2ce8 100644
--- a/src/client/views/nodes/ChatBox/Agent.ts
+++ b/src/client/views/nodes/ChatBox/Agent.ts
@@ -27,6 +27,11 @@ export class Agent {
};
}
+ private refreshSummaries(): void {
+ this.summaries = this.vectorstore ? this.vectorstore.getSummaries() : 'No documents available.';
+ this.tools.rag = new RAGTool(this.vectorstore, this.summaries);
+ }
+
private formatChatHistory(): string {
let history = '<chat_history>\n';
for (const message of this.messages) {
@@ -41,7 +46,7 @@ export class Agent {
}
async askAgent(question: string, maxTurns: number = 8): Promise<string> {
- this.tools.rag = new RAGTool(this.vectorstore, this.vectorstore ? this.vectorstore.getSummaries() : 'No documents available.');
+ this.refreshSummaries();
console.log(`Starting query: ${question}`);
this.messages.push({ role: 'user', content: question });
const chatHistory = this.formatChatHistory();
@@ -98,7 +103,7 @@ export class Agent {
try {
const observation = await this.processAction(currentAction, step[key]);
const nextPrompt = [{ type: 'text', text: '<observation>' }, ...observation, { type: 'text', text: '</observation>' }];
- console.log('Action result: ' + observation);
+ console.log(observation);
this.interMessages.push({ role: 'user', content: nextPrompt });
break;
} catch (error) {
@@ -114,11 +119,12 @@ export class Agent {
const answerContent = builder.build({ answer: step[key] });
this.messages.push({ role: 'assistant', content: answerContent });
this.interMessages = [];
+ console.log(this.messages);
return answerContent;
}
}
}
-
+ console.log(this.messages);
console.log('Reached maximum turns. Ending query.');
return '<error>Reached maximum turns without finding an answer</error>';
}
diff --git a/src/client/views/nodes/ChatBox/ChatBox.tsx b/src/client/views/nodes/ChatBox/ChatBox.tsx
index 2ce1ebdd2..64ab2888b 100644
--- a/src/client/views/nodes/ChatBox/ChatBox.tsx
+++ b/src/client/views/nodes/ChatBox/ChatBox.tsx
@@ -1,4 +1,4 @@
-import { action, makeObservable, observable, observe, reaction, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, observe, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import OpenAI, { ClientOptions } from 'openai';
import * as React from 'react';
@@ -18,6 +18,7 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie
import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
import { Agent } from './Agent';
import dotenv from 'dotenv';
+import { DocData } from '../../../../fields/DocSymbols';
dotenv.config();
@observer
@@ -30,7 +31,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@observable expandedScratchpadIndex: number | null = null;
@observable linked_docs_to_add: Doc[] = [];
@observable inputValue: string = '';
+ @observable private _visibleDocs: Doc[] = [];
private openai: OpenAI;
+ private vectorstore_id: string;
private documents: AI_Document[] = [];
private _oldWheel: any;
private vectorstore: Vectorstore;
@@ -46,7 +49,6 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this.openai = this.initializeOpenAI();
this.history = [{ role: ASSISTANT_ROLE.ASSISTANT, text: 'Welcome to the Document Analyser Assistant! Link a document or ask questions to get started.' }];
this.openai = this.initializeOpenAI();
- this.getOtherDocs();
this.vectorstore = new Vectorstore();
this.agent = new Agent(this.vectorstore); // Initialize the Agent
@@ -59,22 +61,20 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
@action
- getOtherDocs = async () => {
- const visible_docs = (CollectionFreeFormDocumentView.from(this._props.DocumentView?.())?._props.parent as CollectionFreeFormView)?.childDocs
- .filter(doc => doc != this.Document)
- .map(d => DocCast(d?.annotationOn, d))
- .filter(d => d);
-
+ addAIDocs = async (visible_docs: Doc[]) => {
console.log('All Docs:', visible_docs);
-
visible_docs?.forEach(async doc => {
- const local_file_path: string = CsvCast(doc.data, PDFCast(doc.data)).url?.pathname;
- if (local_file_path) {
- const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
- const ai_document: AI_Document = convertToAIDocument(document_json);
- this.documents.push(ai_document);
- await this.vectorstore.addDocument(ai_document);
- doc['ai_document'] = document_json;
+ if (doc[DocData].ai_document) {
+ this.documents.push(convertToAIDocument(JSON.parse(StrCast(doc[DocData].ai_document))));
+ } else {
+ const local_file_path: string = CsvCast(doc.data, PDFCast(doc.data))?.url?.pathname;
+ if (local_file_path) {
+ const { document_json } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
+ const ai_document: AI_Document = convertToAIDocument(document_json);
+ this.documents.push(ai_document);
+ await this.vectorstore.addDocument(ai_document);
+ doc[DocData].ai_document = JSON.stringify(document_json);
+ }
}
});
this.isInitializing = false;
@@ -120,8 +120,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
textInput.value = '';
runInAction(() => {
this.history.push({ role: ASSISTANT_ROLE.USER, text: trimmedText });
+ this.isLoading = true;
});
- this.isLoading = true;
+
const response = await this.agent.askAgent(trimmedText); // Use the chatbot to get the response
runInAction(() => {
this.history.push(this.parseAssistantResponse(response));
@@ -133,7 +134,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this.history.push({ role: ASSISTANT_ROLE.ASSISTANT, text: 'Sorry, I encountered an error while processing your request.' });
});
} finally {
- this.isLoading = false;
+ runInAction(() => {
+ this.isLoading = false;
+ });
}
}
};
@@ -236,20 +239,15 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
}
reaction(
- () => {
- const linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.Document)
- .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
- .map(d => DocCast(d?.annotationOn, d))
- .filter(d => d);
- return linkedDocs;
- },
- linked => this.linked_docs_to_add.push(...linked.filter(linkedDoc => !this.linked_docs_to_add.includes(linkedDoc)))
+ () => this.visibleDocs,
+ visibleDocs => {
+ this._visibleDocs = visibleDocs;
+ }
);
-
observe(
// right now this skips during initialization which is necessary because it would be blank
// However, it will upload the same link twice when it is
- this.linked_docs_to_add,
+ this._visibleDocs,
change => {
// observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
switch (change.type as any) {
@@ -257,9 +255,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
if ((change as any).addedCount > 0) {
// maybe check here if its already in the urls datadoc array so doesn't add twice
console.log((change as any).added as Doc[]);
- ((change as any).added as Doc[]).forEach(doc => {
- this.uploadNewDocument(doc);
- });
+ this.addAIDocs((change as any).added as Doc[]);
}
// (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
break;
@@ -269,6 +265,16 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
},
true
);
+ runInAction(() => {
+ if (!this._visibleDocs.length) {
+ this.isInitializing = false;
+ }
+ });
+ }
+
+ @computed
+ get visibleDocs() {
+ return (CollectionFreeFormDocumentView.from(this._props.DocumentView?.())?._props.parent as CollectionFreeFormView)?.childDocs.filter(doc => doc != this.Document) ?? [];
}
@action
diff --git a/src/client/views/nodes/ChatBox/tools/WikipediaTool.ts b/src/client/views/nodes/ChatBox/tools/WikipediaTool.ts
index 8ef2830d4..e2c5009a1 100644
--- a/src/client/views/nodes/ChatBox/tools/WikipediaTool.ts
+++ b/src/client/views/nodes/ChatBox/tools/WikipediaTool.ts
@@ -1,3 +1,5 @@
+import { title } from 'process';
+import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
import axios from 'axios';
@@ -10,7 +12,7 @@ export class WikipediaTool extends BaseTool<{ title: string }> {
title: {
type: 'string',
description: 'The title of the Wikipedia article to search',
- required: 'true',
+ required: true,
},
},
'Provide simply the title you want to search on Wikipedia and nothing more. If re-using this tool, try a different title for different information.',
@@ -19,15 +21,11 @@ export class WikipediaTool extends BaseTool<{ title: string }> {
}
async execute(args: { title: string }): Promise<any> {
- const response = await axios.get('https://en.wikipedia.org/w/api.php', {
- params: {
- action: 'query',
- list: 'search',
- srsearch: args.title,
- format: 'json',
- },
- });
- const result = response.data.query.search[0].snippet;
- return [{ type: 'text', text: result }];
+ try {
+ const { text } = await Networking.PostToServer('/getWikipediaSummary', { title: args.title });
+ return [{ type: 'text', text: text }];
+ } catch (error) {
+ return [{ type: 'text', text: 'An error occurred while fetching the article.' }];
+ }
}
}
diff --git a/src/server/ApiManagers/AssistantManager.ts b/src/server/ApiManagers/AssistantManager.ts
index 8a5f12c2b..d5a8ebeb3 100644
--- a/src/server/ApiManagers/AssistantManager.ts
+++ b/src/server/ApiManagers/AssistantManager.ts
@@ -150,6 +150,33 @@ export default class AssistantManager extends ApiManager {
register({
method: Method.POST,
+ subscription: '/getWikipediaSummary',
+ secureHandler: async ({ req, res }) => {
+ const { title } = req.body;
+ try {
+ const response = await axios.get('https://en.wikipedia.org/w/api.php', {
+ params: {
+ action: 'query',
+ list: 'search',
+ srsearch: title,
+ format: 'json',
+ },
+ });
+ const summary = response.data.query.search[0].snippet;
+ if (!summary || summary.length === 0 || summary === '' || summary === ' ') {
+ res.send({ text: 'No article found with that title.' });
+ } else {
+ res.send({ text: summary });
+ }
+ } catch (error: any) {
+ console.error('Error retrieving article summary from Wikipedia:', error);
+ res.status(500).send({ error: 'Error retrieving article summary from Wikipedia.', details: error.message });
+ }
+ },
+ });
+
+ register({
+ method: Method.POST,
subscription: '/createDocument',
secureHandler: async ({ req, res }) => {
const { file_path } = req.body;