aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/chatbot/agentsystem/Agent.ts8
-rw-r--r--src/client/views/nodes/chatbot/tools/BaseTool.ts57
-rw-r--r--src/client/views/nodes/chatbot/tools/CalculateTool.ts20
-rw-r--r--src/client/views/nodes/chatbot/tools/CreateCSVTool.ts27
-rw-r--r--src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts3
-rw-r--r--src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts12
-rw-r--r--src/client/views/nodes/chatbot/tools/GetDocsTool.ts32
-rw-r--r--src/client/views/nodes/chatbot/tools/NoTool.ts54
-rw-r--r--src/client/views/nodes/chatbot/tools/RAGTool.ts7
-rw-r--r--src/client/views/nodes/chatbot/tools/SearchTool.ts20
-rw-r--r--src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts7
-rw-r--r--src/client/views/nodes/chatbot/tools/WikipediaTool.ts3
-rw-r--r--src/client/views/nodes/chatbot/types/types.ts49
13 files changed, 202 insertions, 97 deletions
diff --git a/src/client/views/nodes/chatbot/agentsystem/Agent.ts b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
index ccf9caf15..0747ddd60 100644
--- a/src/client/views/nodes/chatbot/agentsystem/Agent.ts
+++ b/src/client/views/nodes/chatbot/agentsystem/Agent.ts
@@ -11,7 +11,7 @@ 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 { AgentMessage, AssistantMessage, Observation, PROCESSING_TYPE, ProcessingInfo, Tool } from '../types/types';
import { Vectorstore } from '../vectorstore/Vectorstore';
import { getReactPrompt } from './prompts';
@@ -24,7 +24,6 @@ dotenv.config();
export class Agent {
// Private properties
private client: OpenAI;
- private tools: Record<string, Tool<any>>; // bcz: need a real type here
private messages: AgentMessage[] = [];
private interMessages: AgentMessage[] = [];
private vectorstore: Vectorstore;
@@ -36,6 +35,7 @@ export class Agent {
private processingNumber: number = 0;
private processingInfo: ProcessingInfo[] = [];
private streamedAnswerParser: StreamedAnswerParser = new StreamedAnswerParser();
+ private tools: Record<string, Tool<ToolArgument>>;
/**
* The constructor initializes the agent with the vector store and toolset, and sets up the OpenAI client.
@@ -166,7 +166,7 @@ export class Agent {
if (currentAction) {
try {
// Process the action with its input
- const observation = (await this.processAction(currentAction, actionInput.inputs)) as any; // bcz: really need a type here
+ const observation = (await this.processAction(currentAction, actionInput.inputs)) as Observation[];
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 });
@@ -266,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: unknown): Promise<unknown> {
+ private async processAction(action: string, actionInput: Record<string, unknown>): Promise<Observation[]> {
if (!(action in this.tools)) {
throw new Error(`Unknown action: ${action}`);
}
diff --git a/src/client/views/nodes/chatbot/tools/BaseTool.ts b/src/client/views/nodes/chatbot/tools/BaseTool.ts
index a77f567a5..4f8f81bcb 100644
--- a/src/client/views/nodes/chatbot/tools/BaseTool.ts
+++ b/src/client/views/nodes/chatbot/tools/BaseTool.ts
@@ -1,3 +1,5 @@
+import { Tool, ParameterArray, ParametersType, Observation, ParamConfig } from '../types/types';
+
/**
* @file BaseTool.ts
* @description This file defines the abstract BaseTool class, which serves as a blueprint
@@ -6,27 +8,52 @@
* and retrieving action rules for use within the assistant's workflow.
*/
-import { Tool } from '../types/types';
+export abstract class BaseTool implements Tool<ParamConfig[]> {
+ name: string;
+ description: string;
+ parameterRules: ParameterArray; // Still using ParameterArray
+ citationRules: string;
+ briefSummary: string;
+ paramConfig: ParamConfig[];
-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, unknown>,
- public citationRules: string,
- public briefSummary: string
- ) {}
+ name: string,
+ description: string,
+ parameterRules: ParameterArray, // Allow tuple types for parameters
+ citationRules: string,
+ briefSummary: string
+ ) {
+ this.name = name;
+ this.description = description;
+ this.parameterRules = parameterRules;
+ this.citationRules = citationRules;
+ this.briefSummary = briefSummary;
+ this.paramConfig = this.parameterRules.map(param => ({
+ name: param.name,
+ type: param.type,
+ })); // Convert ParameterArray to ParamConfig[]
+ }
- abstract execute(args: T): Promise<unknown>;
+ // Abstract execute method with dynamic types based on parameters
+ abstract execute(args: ParametersType<ParamConfig[]>): Promise<Observation[]>;
+ // Implement the getActionRule method
getActionRule(): Record<string, unknown> {
return {
- [this.name]: {
- name: this.name,
- citationRules: this.citationRules,
- description: this.description,
- parameters: this.parameters,
- },
+ tool: this.name,
+ description: this.description,
+ parameters: this.parameterRules.reduce(
+ (acc, param) => {
+ acc[param.name] = {
+ type: param.type,
+ description: param.description,
+ required: param.required,
+ max_inputs: param.max_inputs,
+ };
+ return acc;
+ },
+ {} as Record<string, Omit<ParameterArray[number], 'name'>>
+ ),
};
}
}
diff --git a/src/client/views/nodes/chatbot/tools/CalculateTool.ts b/src/client/views/nodes/chatbot/tools/CalculateTool.ts
index 77ab1b39b..050e6f708 100644
--- a/src/client/views/nodes/chatbot/tools/CalculateTool.ts
+++ b/src/client/views/nodes/chatbot/tools/CalculateTool.ts
@@ -1,26 +1,28 @@
+import { Observation, ParametersType } from '../types/types';
import { BaseTool } from './BaseTool';
-export class CalculateTool extends BaseTool<{ expression: string }> {
+export class CalculateTool extends BaseTool {
constructor() {
super(
'calculate',
'Perform a calculation',
- {
- expression: {
+ [
+ {
+ name: 'expression',
type: 'string',
description: 'The mathematical expression to evaluate',
- required: 'true',
- max_inputs: '1',
+ required: true,
},
- },
+ ],
'Provide a mathematical expression to calculate that would work with JavaScript eval().',
'Runs a calculation and returns the number - uses JavaScript so be sure to use floating point syntax if necessary'
);
}
- async execute(args: { expression: string }): Promise<unknown> {
- // Note: Using eval() can be dangerous. Consider using a safer alternative.
- const result = eval(args.expression);
+ async execute(args: { expression: string }): Promise<Observation[]> {
+ // Since the 'expression' parameter is typed as 'string', TypeScript will ensure 'args.expression' is a string
+ const result = eval(args.expression); // Be cautious with eval(), as it can be dangerous. Consider using a safer alternative if possible.
+
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 d3ded0de0..fff57c6d4 100644
--- a/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts
+++ b/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts
@@ -1,7 +1,8 @@
import { BaseTool } from './BaseTool';
import { Networking } from '../../../../Network';
+import { Observation } from '../types/types';
-export class CreateCSVTool extends BaseTool<{ csvData: string; filename: string }> {
+export class CreateCSVTool extends BaseTool<{ csvData: { type: string; description: string; required: boolean }; filename: { type: string; description: string; required: boolean } }> {
private _handleCSVResult: (url: string, filename: string, id: string, data: string) => void;
constructor(handleCSVResult: (url: string, title: string, id: string, data: string) => void) {
@@ -9,18 +10,16 @@ export class CreateCSVTool extends BaseTool<{ csvData: string; filename: string
'createCSV',
'Creates a CSV file from raw CSV data and saves it to the server',
{
- type: 'object',
- properties: {
- csvData: {
- type: 'string',
- description: 'A string of comma-separated values representing the CSV data.',
- },
- filename: {
- type: 'string',
- description: 'The base name of the CSV file to be created. Should end in ".csv".',
- },
+ csvData: {
+ type: 'string',
+ description: 'A string of comma-separated values representing the CSV data.',
+ required: true,
+ },
+ filename: {
+ type: 'string',
+ description: 'The base name of the CSV file to be created. Should end in ".csv".',
+ required: true,
},
- required: ['csvData', 'filename'],
},
'Provide a CSV string and a filename to create a CSV file.',
'Creates a CSV file from the provided CSV string and saves it to the server with a unique identifier, returning the file URL and UUID.'
@@ -28,13 +27,11 @@ export class CreateCSVTool extends BaseTool<{ csvData: string; filename: string
this._handleCSVResult = handleCSVResult;
}
- async execute(args: { csvData: string; filename: string }): Promise<unknown> {
+ async execute(args: { csvData: string; filename: string }): Promise<Observation[]> {
try {
console.log('Creating CSV file:', args.filename, ' with data:', args.csvData);
- // Post the raw CSV data to the createCSV endpoint on the server
const { fileUrl, id } = await Networking.PostToServer('/createCSV', { filename: args.filename, data: args.csvData });
- // Handle the result by invoking the callback
this._handleCSVResult(fileUrl, args.filename, id, args.csvData);
return [
diff --git a/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts b/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts
index 1e479a62c..fb0d9ca4c 100644
--- a/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts
+++ b/src/client/views/nodes/chatbot/tools/CreateCollectionTool.ts
@@ -3,6 +3,7 @@ import { DocServer } from '../../../../DocServer';
import { Docs } from '../../../../documents/Documents';
import { DocumentView } from '../../DocumentView';
import { OpenWhere } from '../../OpenWhere';
+import { Observation } from '../types/types';
import { BaseTool } from './BaseTool';
export class GetDocsContentTool extends BaseTool<{ title: string; document_ids: string[] }> {
@@ -25,7 +26,7 @@ export class GetDocsContentTool extends BaseTool<{ title: string; document_ids:
this._docView = docView;
}
- async execute(args: { title: string; document_ids: string[] }): Promise<unknown> {
+ async execute(args: { title: string; document_ids: string[] }): Promise<Observation[]> {
// 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 2e663fed1..b97576095 100644
--- a/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts
+++ b/src/client/views/nodes/chatbot/tools/DataAnalysisTool.ts
@@ -1,6 +1,7 @@
+import { Observation } from '../types/types';
import { BaseTool } from './BaseTool';
-export class DataAnalysisTool extends BaseTool<{ csv_file_name: string | string[] }> {
+export class DataAnalysisTool extends BaseTool<{ csv_file_name: { type: string | string[]; description: string; required: boolean } }> {
private csv_files_function: () => { filename: string; id: string; text: string }[];
constructor(csv_files: () => { filename: string; id: string; text: string }[]) {
@@ -11,12 +12,11 @@ export class DataAnalysisTool extends BaseTool<{ csv_file_name: string | string[
csv_file_name: {
type: 'string',
description: 'Name(s) of the CSV file(s) to analyze',
- required: 'true',
- max_inputs: '3',
+ required: true,
},
},
'Provide the name(s) of up to 3 CSV files to analyze based on the user query and whichever available CSV files may be relevant.',
- 'Provides the full CSV file text for your analysis based on the user query and the available CSV file(s). '
+ 'Provides the full CSV file text for your analysis based on the user query and the available CSV file(s).'
);
this.csv_files_function = csv_files;
}
@@ -33,9 +33,9 @@ export class DataAnalysisTool extends BaseTool<{ csv_file_name: string | string[
return file?.id;
}
- async execute(args: { csv_file_name: string | string[] }): Promise<unknown> {
+ async execute(args: { csv_file_name: string | string[] }): Promise<Observation[]> {
const filenames = Array.isArray(args.csv_file_name) ? args.csv_file_name : [args.csv_file_name];
- const results = [];
+ const results: Observation[] = [];
for (const filename of filenames) {
const fileContent = this.getFileContent(filename);
diff --git a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
index 903f3f69c..b6e549d93 100644
--- a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
+++ b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
@@ -1,29 +1,39 @@
-import { DocCast } from '../../../../../fields/Types';
+import { Observation } from '../types/types';
+import { BaseTool } from './BaseTool';
import { DocServer } from '../../../../DocServer';
import { Docs } from '../../../../documents/Documents';
import { DocumentView } from '../../DocumentView';
import { OpenWhere } from '../../OpenWhere';
-import { BaseTool } from './BaseTool';
-export class GetDocsTool extends BaseTool<{ title: string; document_ids: string[] }> {
+export class GetDocsTool extends BaseTool<{ title: { type: string; description: string; required: boolean }; document_ids: { type: string; description: string; required: boolean } }> {
private _docView: DocumentView;
+
constructor(docView: DocumentView) {
super(
'retrieveDocs',
'Retrieves the contents of all Documents that the user is interacting with in Dash',
- {},
+ {
+ title: {
+ type: 'string',
+ description: 'Title of the collection being created from retrieved documents',
+ required: true,
+ },
+ document_ids: {
+ type: 'string[]',
+ description: 'List of document IDs to retrieve',
+ required: true,
+ },
+ },
'No need to provide anything. Just run the tool and it will retrieve the contents of all Documents that the user is interacting with in Dash.',
- 'Returns the the documents in Dash in JSON form. This will include the title of the document, the location in the FreeFormDocument, and the content of the document, any applicable data fields, the layout of the document, etc.'
+ 'Returns the documents in Dash in JSON form.'
);
this._docView = docView;
}
- 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)));
+ async execute(args: { title: string; document_ids: string[] }): Promise<Observation[]> {
+ const docs = args.document_ids.map(doc_id => DocServer.GetCachedRefField(doc_id));
const collection = Docs.Create.FreeformDocument(docs, { title: args.title });
- this._docView._props.addDocTab(collection, OpenWhere.addRight); //in future, create popup prompting user where to add
- return [{ type: 'text', text: 'Collection created in Dash called ' + args.title }];
+ this._docView._props.addDocTab(collection, OpenWhere.addRight);
+ return [{ type: 'text', text: `Collection created in Dash called ${args.title}` }];
}
}
-//export function create_collection(docView: DocumentView, document_ids: string[], title: string): string {}
diff --git a/src/client/views/nodes/chatbot/tools/NoTool.ts b/src/client/views/nodes/chatbot/tools/NoTool.ts
index edd3160ec..103abcdbe 100644
--- a/src/client/views/nodes/chatbot/tools/NoTool.ts
+++ b/src/client/views/nodes/chatbot/tools/NoTool.ts
@@ -1,19 +1,51 @@
-// tools/NoTool.ts
+import { v4 as uuidv4 } from 'uuid';
+import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
+import { Observation } from '../types/types';
-export class NoTool extends BaseTool<Record<string, unknown>> {
- constructor() {
+export class SearchTool extends BaseTool<{ query: { type: string | string[]; description: string; required: boolean } }> {
+ private _addLinkedUrlDoc: (url: string, id: string) => void;
+ private _max_results: number;
+
+ constructor(addLinkedUrlDoc: (url: string, id: string) => void, max_results: number = 5) {
super(
- 'no_tool',
- 'Use this when no external tool or action is required to answer the question.',
- {},
- 'When using the "no_tool" action, simply provide an empty <action_input> element. The observation will always be "No tool used. Proceed with answering the question."',
- 'Use when no external tool or action is required to answer the question.'
+ 'searchTool',
+ 'Search the web to find a wide range of websites related to a query or multiple queries',
+ {
+ query: {
+ type: 'string',
+ description: 'The search query or queries to use for finding websites',
+ required: true,
+ },
+ },
+ 'Provide up to 3 search queries to find a broad range of websites.',
+ 'Returns a list of websites and their overviews based on the search queries.'
);
+ this._addLinkedUrlDoc = addLinkedUrlDoc;
+ this._max_results = max_results;
}
- // 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.' }];
+ async execute(args: { query: string | string[] }): Promise<Observation[]> {
+ const queries = Array.isArray(args.query) ? args.query : [args.query];
+ const allResults = [];
+
+ for (const query of queries) {
+ try {
+ const { results } = await Networking.PostToServer('/getWebSearchResults', { query, max_results: this._max_results });
+ const data = results.map((result: { url: string; snippet: string }) => {
+ const id = uuidv4();
+ return {
+ type: 'text',
+ text: `<chunk chunk_id="${id}" chunk_type="text"><url>${result.url}</url><overview>${result.snippet}</overview></chunk>`,
+ };
+ });
+ allResults.push(...data);
+ } catch (error) {
+ console.log(error);
+ allResults.push({ type: 'text', text: `An error occurred while performing the web search for query: ${query}` });
+ }
+ }
+
+ return allResults;
}
}
diff --git a/src/client/views/nodes/chatbot/tools/RAGTool.ts b/src/client/views/nodes/chatbot/tools/RAGTool.ts
index 4cc2f26ff..4babf540a 100644
--- a/src/client/views/nodes/chatbot/tools/RAGTool.ts
+++ b/src/client/views/nodes/chatbot/tools/RAGTool.ts
@@ -1,5 +1,6 @@
+import { O } from '@fullcalendar/core/internal-common';
import { Networking } from '../../../../Network';
-import { RAGChunk } from '../types/types';
+import { Observation, RAGChunk } from '../types/types';
import { Vectorstore } from '../vectorstore/Vectorstore';
import { BaseTool } from './BaseTool';
@@ -56,13 +57,13 @@ export class RAGTool extends BaseTool {
);
}
- async execute(args: { hypothetical_document_chunk: string }): Promise<unknown> {
+ async execute(args: { hypothetical_document_chunk: string }): Promise<Observation[]> {
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<unknown> {
+ async getFormattedChunks(relevantChunks: RAGChunk[]): Promise<Observation[]> {
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 3a4668422..103abcdbe 100644
--- a/src/client/views/nodes/chatbot/tools/SearchTool.ts
+++ b/src/client/views/nodes/chatbot/tools/SearchTool.ts
@@ -1,10 +1,12 @@
import { v4 as uuidv4 } from 'uuid';
import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
+import { Observation } from '../types/types';
-export class SearchTool extends BaseTool<{ query: string | string[] }> {
+export class SearchTool extends BaseTool<{ query: { type: string | string[]; description: string; required: boolean } }> {
private _addLinkedUrlDoc: (url: string, id: string) => void;
private _max_results: number;
+
constructor(addLinkedUrlDoc: (url: string, id: string) => void, max_results: number = 5) {
super(
'searchTool',
@@ -13,32 +15,28 @@ export class SearchTool extends BaseTool<{ query: string | string[] }> {
query: {
type: 'string',
description: 'The search query or queries to use for finding websites',
- required: 'true',
- max_inputs: '3',
+ required: true,
},
},
- 'Provide up to 3 search queries to find a broad range of websites. This tool is intended to help you identify relevant websites, but not to be used for providing the final answer. Use this information to determine which specific website to investigate further.',
- 'Returns a list of websites and their overviews based on the search queries, helping to identify which websites might contain relevant information.'
+ 'Provide up to 3 search queries to find a broad range of websites.',
+ 'Returns a list of websites and their overviews based on the search queries.'
);
this._addLinkedUrlDoc = addLinkedUrlDoc;
this._max_results = max_results;
}
- async execute(args: { query: string | string[] }): Promise<unknown> {
+ async execute(args: { query: string | string[] }): Promise<Observation[]> {
const queries = Array.isArray(args.query) ? args.query : [args.query];
const allResults = [];
for (const query of queries) {
try {
const { results } = await Networking.PostToServer('/getWebSearchResults', { query, max_results: this._max_results });
- const data: { type: string; text: string }[] = results.map((result: { url: string; snippet: string }) => {
+ const data = results.map((result: { url: string; snippet: string }) => {
const id = uuidv4();
return {
type: 'text',
- text: `<chunk chunk_id="${id}" chunk_type="text">
- <url>${result.url}</url>
- <overview>${result.snippet}</overview>
- </chunk>`,
+ text: `<chunk chunk_id="${id}" chunk_type="text"><url>${result.url}</url><overview>${result.snippet}</overview></chunk>`,
};
});
allResults.push(...data);
diff --git a/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts b/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts
index 1efb389b8..8a4181b43 100644
--- a/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts
+++ b/src/client/views/nodes/chatbot/tools/WebsiteInfoScraperTool.ts
@@ -1,6 +1,7 @@
import { v4 as uuidv4 } from 'uuid';
import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
+import { Observation } from '../types/types';
export class WebsiteInfoScraperTool extends BaseTool<{ url: string | string[] }> {
private _addLinkedUrlDoc: (url: string, id: string) => void;
@@ -63,16 +64,16 @@ export class WebsiteInfoScraperTool extends BaseTool<{ url: string | string[] }>
this._addLinkedUrlDoc = addLinkedUrlDoc;
}
- async execute(args: { url: string | string[] }): Promise<unknown> {
+ async execute(args: { url: string | string[] }): Promise<Observation[]> {
const urls = Array.isArray(args.url) ? args.url : [args.url];
- const results = [];
+ const results: Observation[] = [];
for (const url of urls) {
try {
const { website_plain_text } = await Networking.PostToServer('/scrapeWebsite', { url });
const id = uuidv4();
this._addLinkedUrlDoc(url, id);
- results.push({ type: 'text', text: `<chunk chunk_id=${id} chunk_type=url>\n${website_plain_text}\n</chunk>\n` });
+ results.push({ type: 'text', text: `<chunk chunk_id=${id} chunk_type=url>\n${website_plain_text}\n</chunk>` });
} 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 692dff749..ee5661905 100644
--- a/src/client/views/nodes/chatbot/tools/WikipediaTool.ts
+++ b/src/client/views/nodes/chatbot/tools/WikipediaTool.ts
@@ -1,6 +1,7 @@
import { v4 as uuidv4 } from 'uuid';
import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
+import { Observation } from '../types/types';
export class WikipediaTool extends BaseTool<{ title: string }> {
private _addLinkedUrlDoc: (url: string, id: string) => void;
@@ -21,7 +22,7 @@ export class WikipediaTool extends BaseTool<{ title: string }> {
this._addLinkedUrlDoc = addLinkedUrlDoc;
}
- async execute(args: { title: string }): Promise<unknown> {
+ async execute(args: { title: string }): Promise<Observation[]> {
try {
const { text } = await Networking.PostToServer('/getWikipediaSummary', { title: args.title });
const id = uuidv4();
diff --git a/src/client/views/nodes/chatbot/types/types.ts b/src/client/views/nodes/chatbot/types/types.ts
index 2bc7f4952..fcf33702d 100644
--- a/src/client/views/nodes/chatbot/types/types.ts
+++ b/src/client/views/nodes/chatbot/types/types.ts
@@ -112,17 +112,52 @@ export interface AI_Document {
type: string;
}
-export interface Tool<T extends Record<string, unknown> = Record<string, unknown>> {
+export interface AgentMessage {
+ role: 'system' | 'user' | 'assistant';
+ content: string | Observation[];
+}
+
+export type Observation = { type: 'text'; text: string } | { type: 'image_url'; image_url: { url: string } };
+
+// Utility type to map string representations of types to actual TypeScript types
+export interface Tool<P extends ParamConfig[] = ParamConfig[]> {
name: string;
description: string;
- parameters: Record<string, unknown>;
+ parameterRules: ParameterArray;
citationRules: string;
briefSummary: string;
- execute: (args: T) => Promise<unknown>;
+ execute: (args: ParametersType<P>) => Promise<Observation[]>; // Allow flexibility in args type
getActionRule: () => Record<string, unknown>;
}
-export interface AgentMessage {
- role: 'system' | 'user' | 'assistant';
- content: string | { type: string; text?: string; image_url?: { url: string } }[];
-}
+// ParameterArray defines the structure of parameter configurations
+export type ParameterArray = {
+ type: 'string' | 'number' | 'boolean' | 'string[]' | 'number[]';
+ name: string;
+ description: string;
+ required?: boolean;
+ max_inputs?: number;
+}[];
+
+// ParamConfig is a more generic representation of individual parameters
+export type ParamConfig = {
+ name: string;
+ type: string;
+};
+
+// Utility type to map string representations of types to actual TypeScript types
+type TypeMap = {
+ string: string;
+ number: number;
+ boolean: boolean;
+ 'number[]': number[];
+ 'string[]': string[];
+};
+
+// Map ParamConfig's type field to actual TypeScript types
+export type ParamType<P extends ParamConfig> = P['type'] extends keyof TypeMap ? TypeMap[P['type']] : unknown;
+
+// Create a ParametersType that infers the argument types from ParamConfig[]
+export type ParametersType<P extends ParamConfig[]> = {
+ [K in P[number] as K['name']]: ParamType<K>;
+};