UNPKG

@n8n/n8n-nodes-langchain

Version:

![Banner image](https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png)

385 lines 17.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.RetrieverWorkflow = void 0; const documents_1 = require("@langchain/core/documents"); const retrievers_1 = require("@langchain/core/retrievers"); const manual = __importStar(require("n8n-nodes-base/dist/nodes/Set/v2/manual.mode")); const n8n_workflow_1 = require("n8n-workflow"); const ai_utilities_1 = require("@n8n/ai-utilities"); function objectToString(obj, level = 0) { let result = ''; for (const key in obj) { const value = obj[key]; if (typeof value === 'object' && value !== null) { result += `${' '.repeat(level)}- "${key}":\n${objectToString(value, level + 1)}`; } else { result += `${' '.repeat(level)}- "${key}": "${value}"\n`; } } return result; } class RetrieverWorkflow { constructor() { this.description = { displayName: 'Workflow Retriever', name: 'retrieverWorkflow', icon: 'node:workflow-retriever', iconColor: 'black', group: ['transform'], version: [1, 1.1], description: 'Use an n8n Workflow as Retriever', defaults: { name: 'Workflow Retriever', }, codex: { categories: ['AI'], subcategories: { AI: ['Retrievers'], }, resources: { primaryDocumentation: [ { url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.retrieverworkflow/', }, ], }, }, inputs: [], outputs: [ { displayName: 'Retriever', maxConnections: 1, type: n8n_workflow_1.NodeConnectionTypes.AiRetriever, }, ], properties: [ { displayName: 'The workflow will receive "query" as input and the output of the last node will be returned and converted to Documents', name: 'executeNotice', type: 'notice', default: '', }, { displayName: 'Source', name: 'source', type: 'options', options: [ { name: 'Database', value: 'database', description: 'Load the workflow from the database by ID', }, { name: 'Parameter', value: 'parameter', description: 'Load the workflow from a parameter', }, ], default: 'database', description: 'Where to get the workflow to execute from', }, { displayName: 'Workflow ID', name: 'workflowId', type: 'string', displayOptions: { show: { source: ['database'], '@version': [{ _cnd: { eq: 1 } }], }, }, default: '', required: true, description: 'The workflow to execute', }, { displayName: 'Workflow', name: 'workflowId', type: 'workflowSelector', displayOptions: { show: { source: ['database'], '@version': [{ _cnd: { gte: 1.1 } }], }, }, default: '', required: true, }, { displayName: 'Workflow JSON', name: 'workflowJson', type: 'json', typeOptions: { rows: 10, }, displayOptions: { show: { source: ['parameter'], }, }, default: '\n\n\n', required: true, description: 'The workflow JSON code to execute', }, { displayName: 'Workflow Values', name: 'fields', placeholder: 'Add Value', type: 'fixedCollection', description: 'Set the values which should be made available in the workflow', typeOptions: { multipleValues: true, sortable: true, }, default: {}, options: [ { name: 'values', displayName: 'Values', values: [ { displayName: 'Name', name: 'name', type: 'string', default: '', placeholder: 'e.g. fieldName', description: 'Name of the field to set the value of. Supports dot-notation. Example: data.person[0].name.', requiresDataPath: 'single', }, { displayName: 'Type', name: 'type', type: 'options', description: 'The field value type', options: [ { name: 'String', value: 'stringValue', }, { name: 'Number', value: 'numberValue', }, { name: 'Boolean', value: 'booleanValue', }, { name: 'Array', value: 'arrayValue', }, { name: 'Object', value: 'objectValue', }, ], default: 'stringValue', }, { displayName: 'Value', name: 'stringValue', type: 'string', default: '', displayOptions: { show: { type: ['stringValue'], }, }, validateType: 'string', ignoreValidationDuringExecution: true, }, { displayName: 'Value', name: 'numberValue', type: 'string', default: '', displayOptions: { show: { type: ['numberValue'], }, }, validateType: 'number', ignoreValidationDuringExecution: true, }, { displayName: 'Value', name: 'booleanValue', type: 'options', default: 'true', options: [ { name: 'True', value: 'true', }, { name: 'False', value: 'false', }, ], displayOptions: { show: { type: ['booleanValue'], }, }, validateType: 'boolean', ignoreValidationDuringExecution: true, }, { displayName: 'Value', name: 'arrayValue', type: 'string', default: '', placeholder: 'e.g. [ arrayItem1, arrayItem2, arrayItem3 ]', displayOptions: { show: { type: ['arrayValue'], }, }, validateType: 'array', ignoreValidationDuringExecution: true, }, { displayName: 'Value', name: 'objectValue', type: 'json', default: '={}', typeOptions: { rows: 2, }, displayOptions: { show: { type: ['objectValue'], }, }, validateType: 'object', ignoreValidationDuringExecution: true, }, ], }, ], }, ], }; } async supplyData(itemIndex) { const workflowProxy = this.getWorkflowDataProxy(0); class WorkflowRetriever extends retrievers_1.BaseRetriever { constructor(executeFunctions, fields) { super(fields); this.executeFunctions = executeFunctions; this.lc_namespace = ['n8n-nodes-langchain', 'retrievers', 'workflow']; } async _getRelevantDocuments(query, config) { const source = this.executeFunctions.getNodeParameter('source', itemIndex); const baseMetadata = { source: 'workflow', workflowSource: source, }; const workflowInfo = {}; if (source === 'database') { const nodeVersion = this.executeFunctions.getNode().typeVersion; if (nodeVersion === 1) { workflowInfo.id = this.executeFunctions.getNodeParameter('workflowId', itemIndex); } else { const { value } = this.executeFunctions.getNodeParameter('workflowId', itemIndex, {}); workflowInfo.id = value; } baseMetadata.workflowId = workflowInfo.id; } else if (source === 'parameter') { const workflowJson = this.executeFunctions.getNodeParameter('workflowJson', itemIndex); try { workflowInfo.code = JSON.parse(workflowJson); } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), `The provided workflow is not valid JSON: "${error.message}"`, { itemIndex, }); } baseMetadata.workflowId = workflowProxy.$workflow.id; } const rawData = { query }; const workflowFieldsJson = this.executeFunctions.getNodeParameter('fields.values', itemIndex, [], { rawExpressions: true, }); for (const entry of workflowFieldsJson) { if (entry.type === 'objectValue' && entry.objectValue.startsWith('=')) { rawData[entry.name] = entry.objectValue.replace(/^=+/, ''); } } const options = { include: 'all', }; const newItem = await manual.execute.call(this.executeFunctions, { json: { query } }, itemIndex, options, rawData, this.executeFunctions.getNode()); const items = [newItem]; let receivedData; try { receivedData = await this.executeFunctions.executeWorkflow(workflowInfo, items, config?.getChild(), { parentExecution: { executionId: workflowProxy.$execution.id, workflowId: workflowProxy.$workflow.id, }, }); } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), error); } const receivedItems = receivedData.data?.[0] ?? []; const returnData = []; for (const [index, itemData] of receivedItems.entries()) { const pageContent = objectToString(itemData.json); returnData.push(new documents_1.Document({ pageContent: `### ${index + 1}. Context data:\n${pageContent}`, metadata: { ...baseMetadata, itemIndex: index, executionId: receivedData.executionId, }, })); } return returnData; } } const retriever = new WorkflowRetriever(this, {}); return { response: (0, ai_utilities_1.logWrapper)(retriever, this), }; } } exports.RetrieverWorkflow = RetrieverWorkflow; //# sourceMappingURL=RetrieverWorkflow.node.js.map