feat(Vector Store Tool Node): Add Vector Store Tool (#9865)

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
oleg 2024-06-27 13:21:03 +02:00 committed by GitHub
parent 54c2b2f15a
commit df2bc84d2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 0 deletions

View file

@ -0,0 +1,113 @@
import type { IExecuteFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { VectorStoreQATool } from 'langchain/tools';
import type { VectorStore } from '@langchain/core/vectorstores';
import type { BaseLanguageModel } from '@langchain/core/language_models/base';
import { VectorDBQAChain } from 'langchain/chains';
import { getConnectionHintNoticeField } from '../../../utils/sharedFields';
import { logWrapper } from '../../../utils/logWrapper';
export class ToolVectorStore implements INodeType {
description: INodeTypeDescription = {
displayName: 'Vector Store Tool',
name: 'toolVectorStore',
icon: 'fa:database',
group: ['transform'],
version: [1],
description: 'Retrieve context from vector store',
defaults: {
name: 'Vector Store Tool',
},
codex: {
categories: ['AI'],
subcategories: {
AI: ['Tools'],
},
resources: {
primaryDocumentation: [
{
url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolvectorstore/',
},
],
},
},
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
inputs: [
{
displayName: 'Vector Store',
maxConnections: 1,
type: NodeConnectionType.AiVectorStore,
required: true,
},
{
displayName: 'Model',
maxConnections: 1,
type: NodeConnectionType.AiLanguageModel,
required: true,
},
],
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
outputs: [NodeConnectionType.AiTool],
outputNames: ['Tool'],
properties: [
getConnectionHintNoticeField([NodeConnectionType.AiAgent]),
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'e.g. state_of_union_address',
validateType: 'string-alphanumeric',
description: 'Name of the vector store',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
placeholder: 'The most recent state of the Union address',
typeOptions: {
rows: 3,
},
},
{
displayName: 'Limit',
name: 'topK',
type: 'number',
default: 4,
description: 'The maximum number of results to return',
},
],
};
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> {
const name = this.getNodeParameter('name', itemIndex) as string;
const toolDescription = this.getNodeParameter('description', itemIndex) as string;
const topK = this.getNodeParameter('topK', itemIndex, 4) as number;
const vectorStore = (await this.getInputConnectionData(
NodeConnectionType.AiVectorStore,
itemIndex,
)) as VectorStore;
const llm = (await this.getInputConnectionData(
NodeConnectionType.AiLanguageModel,
0,
)) as BaseLanguageModel;
const description = VectorStoreQATool.getDescription(name, toolDescription);
const vectorStoreTool = new VectorStoreQATool(name, description, {
llm,
vectorStore,
});
vectorStoreTool.chain = VectorDBQAChain.fromLLM(llm, vectorStore, {
k: topK,
});
return {
response: logWrapper(vectorStoreTool, this),
};
}
}

View file

@ -100,6 +100,7 @@
"dist/nodes/tools/ToolCode/ToolCode.node.js", "dist/nodes/tools/ToolCode/ToolCode.node.js",
"dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js", "dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js",
"dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js", "dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js",
"dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js",
"dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js", "dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js",
"dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js", "dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js",
"dist/nodes/tools/ToolWorkflow/ToolWorkflow.node.js", "dist/nodes/tools/ToolWorkflow/ToolWorkflow.node.js",